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
4880868c
Commit
4880868c
authored
Apr 20, 2016
by
Jeffrey Wilcke
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
accounts/abi: fixed string and fixed size bytes packing
parent
c3d52504
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
137 additions
and
85 deletions
+137
-85
abi.go
accounts/abi/abi.go
+4
-4
abi_test.go
accounts/abi/abi_test.go
+120
-74
error.go
accounts/abi/error.go
+3
-4
method.go
accounts/abi/method.go
+1
-1
packing.go
accounts/abi/packing.go
+1
-1
type.go
accounts/abi/type.go
+8
-1
No files found.
accounts/abi/abi.go
View file @
4880868c
...
...
@@ -197,13 +197,13 @@ func toGoType(i int, t Argument, output []byte) (interface{}, error) {
case
reflect
.
Uint64
:
return
uint64
(
bigNum
.
Uint64
()),
nil
case
reflect
.
Int8
:
return
u
int8
(
bigNum
.
Int64
()),
nil
return
int8
(
bigNum
.
Int64
()),
nil
case
reflect
.
Int16
:
return
u
int16
(
bigNum
.
Int64
()),
nil
return
int16
(
bigNum
.
Int64
()),
nil
case
reflect
.
Int32
:
return
u
int32
(
bigNum
.
Int64
()),
nil
return
int32
(
bigNum
.
Int64
()),
nil
case
reflect
.
Int64
:
return
u
int64
(
bigNum
.
Int64
()),
nil
return
int64
(
bigNum
.
Int64
()),
nil
case
reflect
.
Ptr
:
return
bigNum
,
nil
}
...
...
accounts/abi/abi_test.go
View file @
4880868c
...
...
@@ -18,7 +18,6 @@ package abi
import
(
"bytes"
"errors"
"fmt"
"log"
"math/big"
...
...
@@ -53,35 +52,35 @@ func TestTypeCheck(t *testing.T) {
for
i
,
test
:=
range
[]
struct
{
typ
string
input
interface
{}
err
error
err
string
}{
{
"uint"
,
big
.
NewInt
(
1
),
nil
},
{
"int"
,
big
.
NewInt
(
1
),
nil
},
{
"uint30"
,
big
.
NewInt
(
1
),
nil
},
{
"uint30"
,
uint8
(
1
),
varErr
(
reflect
.
Ptr
,
reflect
.
Uint8
)
},
{
"uint16"
,
uint16
(
1
),
nil
},
{
"uint16"
,
uint8
(
1
),
varErr
(
reflect
.
Uint16
,
reflect
.
Uint8
)
},
{
"uint16[]"
,
[]
uint16
{
1
,
2
,
3
},
nil
},
{
"uint16[]"
,
[
3
]
uint16
{
1
,
2
,
3
},
nil
},
{
"uint16[]"
,
[]
uint32
{
1
,
2
,
3
},
typeErr
(
formatSliceString
(
reflect
.
Uint16
,
-
1
),
formatSliceString
(
reflect
.
Uint32
,
-
1
))
},
{
"uint16[3]"
,
[
3
]
uint32
{
1
,
2
,
3
},
typeErr
(
formatSliceString
(
reflect
.
Uint16
,
3
),
formatSliceString
(
reflect
.
Uint32
,
3
))
},
{
"uint16[3]"
,
[
4
]
uint16
{
1
,
2
,
3
},
typeErr
(
formatSliceString
(
reflect
.
Uint16
,
3
),
formatSliceString
(
reflect
.
Uint16
,
4
))
},
{
"uint16[3]"
,
[]
uint16
{
1
,
2
,
3
},
nil
},
{
"uint16[3]"
,
[]
uint16
{
1
,
2
,
3
,
4
},
typeErr
(
formatSliceString
(
reflect
.
Uint16
,
3
),
formatSliceString
(
reflect
.
Uint16
,
4
))
},
{
"address[]"
,
[]
common
.
Address
{
common
.
Address
{
1
}},
nil
},
{
"address[1]"
,
[]
common
.
Address
{
common
.
Address
{
1
}},
nil
},
{
"address[1]"
,
[
1
]
common
.
Address
{
common
.
Address
{
1
}},
nil
},
{
"address[2]"
,
[
1
]
common
.
Address
{
common
.
Address
{
1
}},
typeErr
(
formatSliceString
(
reflect
.
Array
,
2
),
formatSliceString
(
reflect
.
Array
,
1
))
},
{
"bytes32"
,
[
32
]
byte
{},
nil
},
{
"bytes32"
,
[
33
]
byte
{},
typeErr
(
formatSliceString
(
reflect
.
Uint8
,
32
),
formatSliceString
(
reflect
.
Uint8
,
33
))
},
{
"bytes32"
,
common
.
Hash
{
1
},
nil
},
{
"bytes31"
,
[
31
]
byte
{},
nil
},
{
"bytes31"
,
[
32
]
byte
{},
typeErr
(
formatSliceString
(
reflect
.
Uint8
,
31
),
formatSliceString
(
reflect
.
Uint8
,
32
))
},
{
"bytes"
,
[]
byte
{
0
,
1
},
nil
},
{
"bytes"
,
[
2
]
byte
{
0
,
1
},
nil
},
{
"bytes"
,
common
.
Hash
{
1
},
nil
},
{
"string"
,
"hello world"
,
nil
},
{
"bytes32[]"
,
[][
32
]
byte
{[
32
]
byte
{}},
nil
},
{
"uint"
,
big
.
NewInt
(
1
),
""
},
{
"int"
,
big
.
NewInt
(
1
),
""
},
{
"uint30"
,
big
.
NewInt
(
1
),
""
},
{
"uint30"
,
uint8
(
1
),
"abi: cannot use uint8 as type ptr as argument"
},
{
"uint16"
,
uint16
(
1
),
""
},
{
"uint16"
,
uint8
(
1
),
"abi: cannot use uint8 as type uint16 as argument"
},
{
"uint16[]"
,
[]
uint16
{
1
,
2
,
3
},
""
},
{
"uint16[]"
,
[
3
]
uint16
{
1
,
2
,
3
},
""
},
{
"uint16[]"
,
[]
uint32
{
1
,
2
,
3
},
"abi: cannot use []uint32 as type []uint16 as argument"
},
{
"uint16[3]"
,
[
3
]
uint32
{
1
,
2
,
3
},
"abi: cannot use [3]uint32 as type [3]uint16 as argument"
},
{
"uint16[3]"
,
[
4
]
uint16
{
1
,
2
,
3
},
"abi: cannot use [4]uint16 as type [3]uint16 as argument"
},
{
"uint16[3]"
,
[]
uint16
{
1
,
2
,
3
},
""
},
{
"uint16[3]"
,
[]
uint16
{
1
,
2
,
3
,
4
},
"abi: cannot use [4]uint16 as type [3]uint16 as argument"
},
{
"address[]"
,
[]
common
.
Address
{
common
.
Address
{
1
}},
""
},
{
"address[1]"
,
[]
common
.
Address
{
common
.
Address
{
1
}},
""
},
{
"address[1]"
,
[
1
]
common
.
Address
{
common
.
Address
{
1
}},
""
},
{
"address[2]"
,
[
1
]
common
.
Address
{
common
.
Address
{
1
}},
"abi: cannot use [1]array as type [2]array as argument"
},
{
"bytes32"
,
[
32
]
byte
{},
""
},
{
"bytes32"
,
[
33
]
byte
{},
"abi: cannot use [33]uint8 as type [32]uint8 as argument"
},
{
"bytes32"
,
common
.
Hash
{
1
},
""
},
{
"bytes31"
,
[
31
]
byte
{},
""
},
{
"bytes31"
,
[
32
]
byte
{},
"abi: cannot use [32]uint8 as type [31]uint8 as argument"
},
{
"bytes"
,
[]
byte
{
0
,
1
},
""
},
{
"bytes"
,
[
2
]
byte
{
0
,
1
},
""
},
{
"bytes"
,
common
.
Hash
{
1
},
""
},
{
"string"
,
"hello world"
,
""
},
{
"bytes32[]"
,
[][
32
]
byte
{[
32
]
byte
{}},
""
},
}
{
typ
,
err
:=
NewType
(
test
.
typ
)
if
err
!=
nil
{
...
...
@@ -89,16 +88,16 @@ func TestTypeCheck(t *testing.T) {
}
err
=
typeCheck
(
typ
,
reflect
.
ValueOf
(
test
.
input
))
if
err
!=
nil
&&
test
.
err
==
nil
{
if
err
!=
nil
&&
len
(
test
.
err
)
==
0
{
t
.
Errorf
(
"%d failed. Expected no err but got: %v"
,
i
,
err
)
continue
}
if
err
==
nil
&&
test
.
err
!=
nil
{
if
err
==
nil
&&
len
(
test
.
err
)
!=
0
{
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
()
{
if
err
!=
nil
&&
len
(
test
.
err
)
!=
0
&&
err
.
Error
()
!=
test
.
err
{
t
.
Errorf
(
"%d failed. Expected err: '%v' got err: '%v'"
,
i
,
test
.
err
,
err
)
}
}
...
...
@@ -110,63 +109,93 @@ func TestSimpleMethodUnpack(t *testing.T) {
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
err
string
// empty
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"
)
,
"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"
)
,
"abi: cannot unmarshal *big.Int in to uint16"
,
},
{
`[ { "type": "uint17" } ]`
,
pad
([]
byte
{
1
},
32
,
true
),
big
.
NewInt
(
1
),
"*big.Int"
,
""
,
},
{
`[ { "type": "int32" } ]`
,
pad
([]
byte
{
1
},
32
,
true
),
int32
(
1
),
"int32"
,
""
,
},
{
`[ { "type": "int32" } ]`
,
pad
([]
byte
{
1
},
32
,
true
),
nil
,
"int16"
,
"abi: cannot unmarshal int32 in to int16"
,
},
{
`[ { "type": "int17" } ]`
,
pad
([]
byte
{
1
},
32
,
true
),
nil
,
"int16"
,
"abi: cannot unmarshal *big.Int in to int16"
,
},
{
`[ { "type": "int17" } ]`
,
pad
([]
byte
{
1
},
32
,
true
),
big
.
NewInt
(
1
),
"*big.Int"
,
""
,
},
{
`[ { "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
,
""
,
},
{
`[ { "type": "bytes32" } ]`
,
pad
([]
byte
{
1
},
32
,
false
),
pad
([]
byte
{
1
},
32
,
false
),
"interface"
,
nil
,
""
,
},
}
{
abiDefinition
:=
fmt
.
Sprintf
(
`[{ "name" : "method", "outputs": %s}]`
,
test
.
def
)
...
...
@@ -194,6 +223,22 @@ func TestSimpleMethodUnpack(t *testing.T) {
var
v
uint64
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
case
"int8"
:
var
v
int8
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
case
"int16"
:
var
v
int16
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
case
"int32"
:
var
v
int32
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
case
"int64"
:
var
v
int64
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
outvar
=
v
case
"*big.Int"
:
var
v
*
big
.
Int
err
=
abi
.
Unpack
(
&
v
,
"method"
,
test
.
marshalledOutput
)
...
...
@@ -217,15 +262,15 @@ func TestSimpleMethodUnpack(t *testing.T) {
continue
}
if
err
!=
nil
&&
test
.
err
==
nil
{
if
err
!=
nil
&&
len
(
test
.
err
)
==
0
{
t
.
Errorf
(
"%d failed. Expected no err but got: %v"
,
i
,
err
)
continue
}
if
err
==
nil
&&
test
.
err
!=
nil
{
if
err
==
nil
&&
len
(
test
.
err
)
!=
0
{
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
()
{
if
err
!=
nil
&&
len
(
test
.
err
)
!=
0
&&
err
.
Error
()
!=
test
.
err
{
t
.
Errorf
(
"%d failed. Expected err: '%v' got err: '%v'"
,
i
,
test
.
err
,
err
)
continue
}
...
...
@@ -253,6 +298,7 @@ func TestPack(t *testing.T) {
}{
{
"uint16"
,
uint16
(
2
),
pad
([]
byte
{
2
},
32
,
true
)},
{
"uint16[]"
,
[]
uint16
{
1
,
2
},
formatSliceOutput
([]
byte
{
1
},
[]
byte
{
2
})},
{
"bytes20"
,
[
20
]
byte
{
1
},
pad
([]
byte
{
1
},
32
,
false
)},
{
"uint256[]"
,
[]
*
big
.
Int
{
big
.
NewInt
(
1
),
big
.
NewInt
(
2
)},
formatSliceOutput
([]
byte
{
1
},
[]
byte
{
2
})},
{
"address[]"
,
[]
common
.
Address
{
common
.
Address
{
1
},
common
.
Address
{
2
}},
formatSliceOutput
(
pad
([]
byte
{
1
},
20
,
false
),
pad
([]
byte
{
2
},
20
,
false
))},
{
"bytes32[]"
,
[]
common
.
Hash
{
common
.
Hash
{
1
},
common
.
Hash
{
2
}},
formatSliceOutput
(
pad
([]
byte
{
1
},
32
,
false
),
pad
([]
byte
{
2
},
32
,
false
))},
...
...
@@ -346,26 +392,26 @@ func TestMethodPack(t *testing.T) {
const
jsondata
=
`
[
{ "type" : "function", "name" : "balance", "const" : true },
{ "type" : "function", "name" : "send", "const" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }
{ "type" : "function", "name" : "balance", "const
ant
" : true },
{ "type" : "function", "name" : "send", "const
ant
" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }
]`
const
jsondata2
=
`
[
{ "type" : "function", "name" : "balance", "const" : true },
{ "type" : "function", "name" : "send", "const" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] },
{ "type" : "function", "name" : "test", "const" : false, "inputs" : [ { "name" : "number", "type" : "uint32" } ] },
{ "type" : "function", "name" : "string", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "string" } ] },
{ "type" : "function", "name" : "bool", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "bool" } ] },
{ "type" : "function", "name" : "address", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "address" } ] },
{ "type" : "function", "name" : "uint64[2]", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[2]" } ] },
{ "type" : "function", "name" : "uint64[]", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[]" } ] },
{ "type" : "function", "name" : "foo", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" } ] },
{ "type" : "function", "name" : "bar", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] },
{ "type" : "function", "name" : "slice", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] },
{ "type" : "function", "name" : "slice256", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "uint256[2]" } ] },
{ "type" : "function", "name" : "sliceAddress", "const" : false, "inputs" : [ { "name" : "inputs", "type" : "address[]" } ] },
{ "type" : "function", "name" : "sliceMultiAddress", "const" : false, "inputs" : [ { "name" : "a", "type" : "address[]" }, { "name" : "b", "type" : "address[]" } ] }
{ "type" : "function", "name" : "balance", "const
ant
" : true },
{ "type" : "function", "name" : "send", "const
ant
" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] },
{ "type" : "function", "name" : "test", "const
ant
" : false, "inputs" : [ { "name" : "number", "type" : "uint32" } ] },
{ "type" : "function", "name" : "string", "const
ant
" : false, "inputs" : [ { "name" : "inputs", "type" : "string" } ] },
{ "type" : "function", "name" : "bool", "const
ant
" : false, "inputs" : [ { "name" : "inputs", "type" : "bool" } ] },
{ "type" : "function", "name" : "address", "const
ant
" : false, "inputs" : [ { "name" : "inputs", "type" : "address" } ] },
{ "type" : "function", "name" : "uint64[2]", "const
ant
" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[2]" } ] },
{ "type" : "function", "name" : "uint64[]", "const
ant
" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[]" } ] },
{ "type" : "function", "name" : "foo", "const
ant
" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" } ] },
{ "type" : "function", "name" : "bar", "const
ant
" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] },
{ "type" : "function", "name" : "slice", "const
ant
" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] },
{ "type" : "function", "name" : "slice256", "const
ant
" : false, "inputs" : [ { "name" : "inputs", "type" : "uint256[2]" } ] },
{ "type" : "function", "name" : "sliceAddress", "const
ant
" : false, "inputs" : [ { "name" : "inputs", "type" : "address[]" } ] },
{ "type" : "function", "name" : "sliceMultiAddress", "const
ant
" : false, "inputs" : [ { "name" : "a", "type" : "address[]" }, { "name" : "b", "type" : "address[]" } ] }
]`
func
TestReader
(
t
*
testing
.
T
)
{
...
...
@@ -537,9 +583,9 @@ func ExampleJSON() {
func
TestInputVariableInputLength
(
t
*
testing
.
T
)
{
const
definition
=
`[
{ "type" : "function", "name" : "strOne", "const" : true, "inputs" : [ { "name" : "str", "type" : "string" } ] },
{ "type" : "function", "name" : "bytesOne", "const" : true, "inputs" : [ { "name" : "str", "type" : "bytes" } ] },
{ "type" : "function", "name" : "strTwo", "const" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "str1", "type" : "string" } ] }
{ "type" : "function", "name" : "strOne", "const
ant
" : true, "inputs" : [ { "name" : "str", "type" : "string" } ] },
{ "type" : "function", "name" : "bytesOne", "const
ant
" : true, "inputs" : [ { "name" : "str", "type" : "bytes" } ] },
{ "type" : "function", "name" : "strTwo", "const
ant
" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "str1", "type" : "string" } ] }
]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
...
...
@@ -701,7 +747,7 @@ func TestBareEvents(t *testing.T) {
func
TestMultiReturnWithStruct
(
t
*
testing
.
T
)
{
const
definition
=
`[
{ "name" : "multi", "const" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
{ "name" : "multi", "const
ant
" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
if
err
!=
nil
{
...
...
@@ -754,7 +800,7 @@ func TestMultiReturnWithStruct(t *testing.T) {
func
TestMultiReturnWithSlice
(
t
*
testing
.
T
)
{
const
definition
=
`[
{ "name" : "multi", "const" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
{ "name" : "multi", "const
ant
" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
if
err
!=
nil
{
...
...
@@ -790,8 +836,8 @@ func TestMultiReturnWithSlice(t *testing.T) {
func
TestMarshalArrays
(
t
*
testing
.
T
)
{
const
definition
=
`[
{ "name" : "bytes32", "const" : false, "outputs": [ { "type": "bytes32" } ] },
{ "name" : "bytes10", "const" : false, "outputs": [ { "type": "bytes10" } ] }
{ "name" : "bytes32", "const
ant
" : false, "outputs": [ { "type": "bytes32" } ] },
{ "name" : "bytes10", "const
ant
" : false, "outputs": [ { "type": "bytes10" } ] }
]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
...
...
@@ -849,14 +895,14 @@ func TestMarshalArrays(t *testing.T) {
func
TestUnmarshal
(
t
*
testing
.
T
)
{
const
definition
=
`[
{ "name" : "int", "const" : false, "outputs": [ { "type": "uint256" } ] },
{ "name" : "bool", "const" : false, "outputs": [ { "type": "bool" } ] },
{ "name" : "bytes", "const" : false, "outputs": [ { "type": "bytes" } ] },
{ "name" : "fixed", "const" : false, "outputs": [ { "type": "bytes32" } ] },
{ "name" : "multi", "const" : false, "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] },
{ "name" : "addressSliceSingle", "const" : false, "outputs": [ { "type": "address[]" } ] },
{ "name" : "addressSliceDouble", "const" : false, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] },
{ "name" : "mixedBytes", "const" : true, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]`
{ "name" : "int", "const
ant
" : false, "outputs": [ { "type": "uint256" } ] },
{ "name" : "bool", "const
ant
" : false, "outputs": [ { "type": "bool" } ] },
{ "name" : "bytes", "const
ant
" : false, "outputs": [ { "type": "bytes" } ] },
{ "name" : "fixed", "const
ant
" : false, "outputs": [ { "type": "bytes32" } ] },
{ "name" : "multi", "const
ant
" : false, "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] },
{ "name" : "addressSliceSingle", "const
ant
" : false, "outputs": [ { "type": "address[]" } ] },
{ "name" : "addressSliceDouble", "const
ant
" : false, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] },
{ "name" : "mixedBytes", "const
ant
" : true, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]`
abi
,
err
:=
JSON
(
strings
.
NewReader
(
definition
))
if
err
!=
nil
{
...
...
accounts/abi/error.go
View file @
4880868c
...
...
@@ -33,7 +33,7 @@ func formatSliceString(kind reflect.Kind, sliceSize int) string {
// sliceTypeCheck checks that the given slice can by assigned to the reflection
// type in t.
func
sliceTypeCheck
(
t
Type
,
val
reflect
.
Value
)
error
{
if
!
(
val
.
Kind
()
==
reflect
.
Slice
||
val
.
Kind
()
==
reflect
.
Array
)
{
if
val
.
Kind
()
!=
reflect
.
Slice
&&
val
.
Kind
()
!=
reflect
.
Array
{
return
typeErr
(
formatSliceString
(
t
.
Kind
,
t
.
SliceSize
),
val
.
Type
())
}
if
t
.
IsArray
&&
val
.
Len
()
!=
t
.
SliceSize
{
...
...
@@ -48,14 +48,13 @@ func sliceTypeCheck(t Type, val reflect.Value) error {
return
sliceTypeCheck
(
*
t
.
Elem
,
val
.
Index
(
0
))
}
elemKind
:=
val
.
Type
()
.
Elem
()
.
Kind
()
if
elemKind
!=
t
.
Elem
.
Kind
{
if
elemKind
:=
val
.
Type
()
.
Elem
()
.
Kind
();
elemKind
!=
t
.
Elem
.
Kind
{
return
typeErr
(
formatSliceString
(
t
.
Elem
.
Kind
,
t
.
SliceSize
),
val
.
Type
())
}
return
nil
}
// typeCheck checks that the
t given reflection val
can be assigned to the reflection
// typeCheck checks that the
given reflection value
can be assigned to the reflection
// type in t.
func
typeCheck
(
t
Type
,
value
reflect
.
Value
)
error
{
if
t
.
IsSlice
||
t
.
IsArray
{
...
...
accounts/abi/method.go
View file @
4880868c
...
...
@@ -58,7 +58,7 @@ func (m Method) pack(method Method, args ...interface{}) ([]byte, error) {
}
// check for a slice type (string, bytes, slice)
if
input
.
Type
.
T
==
StringTy
||
input
.
Type
.
T
==
BytesTy
||
input
.
Type
.
IsSlice
||
input
.
Type
.
IsArray
{
if
input
.
Type
.
requiresLengthPrefix
()
{
// calculate the offset
offset
:=
len
(
method
.
Inputs
)
*
32
+
len
(
variableInput
)
// set the offset
...
...
accounts/abi/packing.go
View file @
4880868c
...
...
@@ -59,7 +59,7 @@ func packElement(t Type, reflectValue reflect.Value) []byte {
reflectValue
=
mustArrayToByteSlice
(
reflectValue
)
}
return
common
.
Lef
tPadBytes
(
reflectValue
.
Bytes
(),
32
)
return
common
.
Righ
tPadBytes
(
reflectValue
.
Bytes
(),
32
)
}
panic
(
"abi: fatal error"
)
}
accounts/abi/type.go
View file @
4880868c
...
...
@@ -89,6 +89,7 @@ func NewType(t string) (typ Type, err error) {
return
Type
{},
err
}
typ
.
Elem
=
&
sliceType
typ
.
stringKind
=
sliceType
.
stringKind
+
t
[
len
(
res
[
1
])
:
]
return
typ
,
nil
}
...
...
@@ -110,6 +111,7 @@ func NewType(t string) (typ Type, err error) {
varSize
=
256
t
+=
"256"
}
typ
.
stringKind
=
t
switch
varType
{
case
"int"
:
...
...
@@ -149,7 +151,6 @@ func NewType(t string) (typ Type, err error) {
default
:
return
Type
{},
fmt
.
Errorf
(
"unsupported arg type: %s"
,
t
)
}
typ
.
stringKind
=
t
return
}
...
...
@@ -181,3 +182,9 @@ func (t Type) pack(v reflect.Value) ([]byte, error) {
return
packElement
(
t
,
v
),
nil
}
// requireLengthPrefix returns whether the type requires any sort of length
// prefixing.
func
(
t
Type
)
requiresLengthPrefix
()
bool
{
return
t
.
T
!=
FixedBytesTy
&&
(
t
.
T
==
StringTy
||
t
.
T
==
BytesTy
||
t
.
IsSlice
||
t
.
IsArray
)
}
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