Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
e0dc45fc
Commit
e0dc45fc
authored
Apr 20, 2016
by
Jeffrey Wilcke
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
accounts/abi: fixed strict go-like unpacking
parent
5127ec10
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
158 additions
and
27 deletions
+158
-27
abi.go
accounts/abi/abi.go
+26
-5
abi_test.go
accounts/abi/abi_test.go
+132
-22
No files found.
accounts/abi/abi.go
View file @
e0dc45fc
...
...
@@ -180,12 +180,33 @@ func toGoType(i int, t Argument, output []byte) (interface{}, error) {
returnOutput
=
output
[
index
:
index
+
32
]
}
// c
ast bytes to abi return type
// c
onvert the bytes to whatever is specified by the ABI.
switch
t
.
Type
.
T
{
case
IntTy
:
return
common
.
BytesToBig
(
returnOutput
),
nil
case
UintTy
:
return
common
.
BytesToBig
(
returnOutput
),
nil
case
IntTy
,
UintTy
:
bigNum
:=
common
.
BytesToBig
(
returnOutput
)
// If the type is a integer convert to the integer type
// specified by the ABI.
switch
t
.
Type
.
Kind
{
case
reflect
.
Uint8
:
return
uint8
(
bigNum
.
Uint64
()),
nil
case
reflect
.
Uint16
:
return
uint16
(
bigNum
.
Uint64
()),
nil
case
reflect
.
Uint32
:
return
uint32
(
bigNum
.
Uint64
()),
nil
case
reflect
.
Uint64
:
return
uint64
(
bigNum
.
Uint64
()),
nil
case
reflect
.
Int8
:
return
uint8
(
bigNum
.
Int64
()),
nil
case
reflect
.
Int16
:
return
uint16
(
bigNum
.
Int64
()),
nil
case
reflect
.
Int32
:
return
uint32
(
bigNum
.
Int64
()),
nil
case
reflect
.
Int64
:
return
uint64
(
bigNum
.
Int64
()),
nil
case
reflect
.
Ptr
:
return
bigNum
,
nil
}
case
BoolTy
:
return
common
.
BytesToBig
(
returnOutput
)
.
Uint64
()
>
0
,
nil
case
AddressTy
:
...
...
accounts/abi/abi_test.go
View file @
e0dc45fc
...
...
@@ -18,6 +18,7 @@ package abi
import
(
"bytes"
"errors"
"fmt"
"log"
"math/big"
...
...
@@ -103,6 +104,137 @@ func TestTypeCheck(t *testing.T) {
}
}
func
TestSimpleMethodUnpack
(
t
*
testing
.
T
)
{
for
i
,
test
:=
range
[]
struct
{
def
string
// definition of the **output** ABI params
marshalledOutput
[]
byte
// evm return data
expectedOut
interface
{}
// the expected output
outVar
string
// the output variable (e.g. uint32, *big.Int, etc)
err
error
// nil or error if expected
}{
{
`[ { "type": "uint32" } ]`
,
pad
([]
byte
{
1
},
32
,
true
),
uint32
(
1
),
"uint32"
,
nil
,
},
{
`[ { "type": "uint32" } ]`
,
pad
([]
byte
{
1
},
32
,
true
),
nil
,
"uint16"
,
errors
.
New
(
"abi: cannot unmarshal uint32 in to uint16"
),
},
{
`[ { "type": "uint17" } ]`
,
pad
([]
byte
{
1
},
32
,
true
),
nil
,
"uint16"
,
errors
.
New
(
"abi: cannot unmarshal *big.Int in to uint16"
),
},
{
`[ { "type": "uint17" } ]`
,
pad
([]
byte
{
1
},
32
,
true
),
big
.
NewInt
(
1
),
"*big.Int"
,
nil
,
},
{
`[ { "type": "address" } ]`
,
pad
(
pad
([]
byte
{
1
},
20
,
false
),
32
,
true
),
common
.
Address
{
1
},
"address"
,
nil
,
},
{
`[ { "type": "bytes32" } ]`
,
pad
([]
byte
{
1
},
32
,
false
),
pad
([]
byte
{
1
},
32
,
false
),
"bytes"
,
nil
,
},
{
`[ { "type": "bytes32" } ]`
,
pad
([]
byte
{
1
},
32
,
false
),
pad
([]
byte
{
1
},
32
,
false
),
"hash"
,
nil
,
},
}
{
abiDefinition
:=
fmt
.
Sprintf
(
`[{ "name" : "method", "outputs": %s}]`
,
test
.
def
)
abi
,
err
:=
JSON
(
strings
.
NewReader
(
abiDefinition
))
if
err
!=
nil
{
t
.
Errorf
(
"%d failed. %v"
,
i
,
err
)
continue
}
var
outvar
interface
{}
switch
test
.
outVar
{
case
"uint8"
:
var
v
uint8
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
case
"uint16"
:
var
v
uint16
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
case
"uint32"
:
var
v
uint32
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
case
"uint64"
:
var
v
uint64
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
case
"*big.Int"
:
var
v
*
big
.
Int
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
case
"address"
:
var
v
common
.
Address
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
case
"bytes"
:
var
v
[]
byte
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
case
"hash"
:
var
v
common
.
Hash
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
default
:
t
.
Errorf
(
"unsupported type '%v' please add it to the switch statement in this test"
,
test
.
outVar
)
continue
}
if
err
!=
nil
&&
test
.
err
==
nil
{
t
.
Errorf
(
"%d failed. Expected no err but got: %v"
,
i
,
err
)
continue
}
if
err
==
nil
&&
test
.
err
!=
nil
{
t
.
Errorf
(
"%d failed. Expected err: %v but got none"
,
i
,
test
.
err
)
continue
}
if
err
!=
nil
&&
test
.
err
!=
nil
&&
err
.
Error
()
!=
test
.
err
.
Error
()
{
t
.
Errorf
(
"%d failed. Expected err: '%v' got err: '%v'"
,
i
,
test
.
err
,
err
)
continue
}
if
err
==
nil
{
// bit of an ugly hack for hash type but I don't feel like finding a proper solution
if
test
.
outVar
==
"hash"
{
tmp
:=
outvar
.
(
common
.
Hash
)
// without assignment it's unaddressable
outvar
=
tmp
[
:
]
}
if
!
reflect
.
DeepEqual
(
test
.
expectedOut
,
outvar
)
{
t
.
Errorf
(
"%d failed. Output error: expected %v, got %v"
,
i
,
test
.
expectedOut
,
outvar
)
}
}
}
}
func
TestPack
(
t
*
testing
.
T
)
{
for
i
,
test
:=
range
[]
struct
{
typ
string
...
...
@@ -354,28 +486,6 @@ func TestMethodSignature(t *testing.T) {
}
}
func
TestOldPack
(
t
*
testing
.
T
)
{
abi
,
err
:=
JSON
(
strings
.
NewReader
(
jsondata2
))
if
err
!=
nil
{
t
.
Error
(
err
)
t
.
FailNow
()
}
sig
:=
crypto
.
Keccak256
([]
byte
(
"foo(uint32)"
))[
:
4
]
sig
=
append
(
sig
,
make
([]
byte
,
32
)
...
)
sig
[
35
]
=
10
packed
,
err
:=
abi
.
Pack
(
"foo"
,
uint32
(
10
))
if
err
!=
nil
{
t
.
Error
(
err
)
t
.
FailNow
()
}
if
!
bytes
.
Equal
(
packed
,
sig
)
{
t
.
Errorf
(
"expected %x got %x"
,
sig
,
packed
)
}
}
func
TestMultiPack
(
t
*
testing
.
T
)
{
abi
,
err
:=
JSON
(
strings
.
NewReader
(
jsondata2
))
if
err
!=
nil
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment