mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 09:23:48 +00:00
accounts/abi: get rid of tests that don't test like they should and redo abi
Signed-off-by: RJ Catalano <rj@monax.io>
This commit is contained in:
parent
9e1851f83a
commit
2609e0a827
2 changed files with 248 additions and 327 deletions
|
|
@ -25,90 +25,10 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// toGoSliceType parses the input and casts it to the proper slice defined by the ABI
|
type unpacker interface {
|
||||||
// argument in T.
|
tupleUnpack(v interface{}, output []byte) error
|
||||||
func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
|
singleUnpack(v interface{}, output []byte) error
|
||||||
index := i * 32
|
tupleReturn() bool
|
||||||
// The slice must, at very least be large enough for the index+32 which is exactly the size required
|
|
||||||
// for the [offset in output, size of offset].
|
|
||||||
if index+32 > len(output) {
|
|
||||||
return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), index+32)
|
|
||||||
}
|
|
||||||
|
|
||||||
elem := t.Type.Elem
|
|
||||||
|
|
||||||
// this value will become our slice or our array, depending on the type
|
|
||||||
var refSlice reflect.Value
|
|
||||||
var slice []byte
|
|
||||||
var size int
|
|
||||||
var offset int
|
|
||||||
if t.Type.T == SliceTy {
|
|
||||||
// get the offset which determines the start of this array ...
|
|
||||||
offset = int(binary.BigEndian.Uint64(output[index+24 : index+32]))
|
|
||||||
if offset+32 > len(output) {
|
|
||||||
return nil, fmt.Errorf("abi: cannot marshal in to go slice: offset %d would go over slice boundary (len=%d)", len(output), offset+32)
|
|
||||||
}
|
|
||||||
|
|
||||||
slice = output[offset:]
|
|
||||||
// ... starting with the size of the array in elements ...
|
|
||||||
size = int(binary.BigEndian.Uint64(slice[24:32]))
|
|
||||||
slice = slice[32:]
|
|
||||||
// ... and make sure that we've at the very least the amount of bytes
|
|
||||||
// available in the buffer.
|
|
||||||
if size*32 > len(slice) {
|
|
||||||
return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), offset+32+size*32)
|
|
||||||
}
|
|
||||||
|
|
||||||
// reslice to match the required size
|
|
||||||
slice = slice[:size*32]
|
|
||||||
// declare our slice
|
|
||||||
refSlice = reflect.MakeSlice(reflect.SliceOf(elem.Type), size, size)
|
|
||||||
} else if t.Type.T == ArrayTy {
|
|
||||||
//get the number of elements in the array
|
|
||||||
size = t.Type.Size
|
|
||||||
// declare our slice
|
|
||||||
refSlice = reflect.New(reflect.ArrayOf(size, elem.Type)).Elem()
|
|
||||||
//check to make sure array size matches up
|
|
||||||
if index+32*size > len(output) {
|
|
||||||
return nil, fmt.Errorf("abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)", len(output), index+32*size)
|
|
||||||
}
|
|
||||||
//slice is there for a fixed amount of times
|
|
||||||
slice = output[index : index+size*32]
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < size; i++ {
|
|
||||||
var (
|
|
||||||
inter interface{} // interface type
|
|
||||||
returnOutput = slice[i*32 : i*32+32] // the return output
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
// set inter to the correct type (cast)
|
|
||||||
switch elem.T {
|
|
||||||
case IntTy, UintTy:
|
|
||||||
inter = readInteger(elem.Kind, returnOutput)
|
|
||||||
case BoolTy:
|
|
||||||
inter, err = readBool(returnOutput)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
case AddressTy:
|
|
||||||
inter = common.BytesToAddress(returnOutput)
|
|
||||||
case HashTy:
|
|
||||||
inter = common.BytesToHash(returnOutput)
|
|
||||||
case FixedBytesTy:
|
|
||||||
inter = returnOutput
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("abi: unsupported slice type passed in")
|
|
||||||
}
|
|
||||||
|
|
||||||
//fmt.Printf("type: %T, value: %v\n", inter, inter)
|
|
||||||
//fmt.Printf("%v\n", elem.stringKind)
|
|
||||||
// append the item to our reflect slice
|
|
||||||
refSlice.Index(i).Set(reflect.ValueOf(inter))
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the interface
|
|
||||||
return refSlice.Interface(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func readInteger(kind reflect.Kind, b []byte) interface{} {
|
func readInteger(kind reflect.Kind, b []byte) interface{} {
|
||||||
|
|
@ -152,58 +72,134 @@ func readBool(word []byte) (bool, error) {
|
||||||
default:
|
default:
|
||||||
return false, errBadBool
|
return false, errBadBool
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func readFunctionType(t Type, word []byte) (funcTy [24]byte, err error) {
|
||||||
|
if t.T != FunctionTy {
|
||||||
|
return [24]byte{}, fmt.Errorf("abi: invalid type in call to make function type byte array.")
|
||||||
|
}
|
||||||
|
if garbage := binary.BigEndian.Uint64(word[24:32]); garbage != 0 {
|
||||||
|
err = fmt.Errorf("abi: got improperly encoded function type, got %v", word)
|
||||||
|
} else {
|
||||||
|
copy(funcTy[:], word[0:24])
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func readFixedBytes(t Type, word []byte) (interface{}, error) {
|
||||||
|
if t.T != FixedBytesTy {
|
||||||
|
return nil, fmt.Errorf("abi: invalid type in call to make fixed byte array.")
|
||||||
|
}
|
||||||
|
// convert
|
||||||
|
array := reflect.New(t.Type).Elem()
|
||||||
|
|
||||||
|
reflect.Copy(array, reflect.ValueOf(word[0:t.Size]))
|
||||||
|
return array.Interface(), nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) {
|
||||||
|
if start+32*size > len(output) {
|
||||||
|
return nil, fmt.Errorf("abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)", len(output), start+32*size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// this value will become our slice or our array, depending on the type
|
||||||
|
var refSlice reflect.Value
|
||||||
|
slice := output[start : start+size*32]
|
||||||
|
if t.T == SliceTy {
|
||||||
|
// declare our slice
|
||||||
|
refSlice = reflect.MakeSlice(t.Type, size, size)
|
||||||
|
} else if t.T == ArrayTy {
|
||||||
|
// declare our array
|
||||||
|
refSlice = reflect.New(t.Type).Elem()
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("abi: invalid type in array/slice unpacking stage")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, j := start, 0; j*32 < len(slice); i, j = i+32, j+1 {
|
||||||
|
inter, err := toGoType(i, *t.Elem, output)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// append the item to our reflect slice
|
||||||
|
refSlice.Index(j).Set(reflect.ValueOf(inter))
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the interface
|
||||||
|
return refSlice.Interface(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// toGoType parses the input and casts it to the proper type defined by the ABI
|
// toGoType parses the input and casts it to the proper type defined by the ABI
|
||||||
// argument in T.
|
// argument in T.
|
||||||
func toGoType(i int, t Argument, output []byte) (interface{}, error) {
|
func toGoType(index int, t Type, output []byte) (interface{}, error) {
|
||||||
// we need to treat slices differently
|
|
||||||
if t.Type.T == SliceTy || t.Type.T == ArrayTy {
|
|
||||||
return toGoSlice(i, t, output)
|
|
||||||
}
|
|
||||||
|
|
||||||
index := i * 32
|
|
||||||
if index+32 > len(output) {
|
if index+32 > len(output) {
|
||||||
return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), index+32)
|
return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), index+32)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the given index output and check whether we need to read
|
// Parse the given index output and check whether we need to read
|
||||||
// a different offset and length based on the type (i.e. string, bytes)
|
// a different offset and length based on the type (i.e. string, bytes)
|
||||||
var returnOutput []byte
|
var (
|
||||||
switch t.Type.T {
|
returnOutput []byte
|
||||||
case StringTy, BytesTy: // variable arrays are written at the end of the return bytes
|
i, j int
|
||||||
// parse offset from which we should start reading
|
err error
|
||||||
offset := int(binary.BigEndian.Uint64(output[index+24 : index+32]))
|
)
|
||||||
if offset+32 > len(output) {
|
|
||||||
return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32)
|
|
||||||
}
|
|
||||||
// parse the size up until we should be reading
|
|
||||||
size := int(binary.BigEndian.Uint64(output[offset+24 : offset+32]))
|
|
||||||
if offset+32+size > len(output) {
|
|
||||||
return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32+size)
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the bytes for this return value
|
if t.requiresLengthPrefix() {
|
||||||
returnOutput = output[offset+32 : offset+32+size]
|
i, j, err = lengthPrefixPointsTo(index, output)
|
||||||
default:
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
returnOutput = output[index : index+32]
|
returnOutput = output[index : index+32]
|
||||||
}
|
}
|
||||||
|
switch t.T {
|
||||||
// convert the bytes to whatever is specified by the ABI.
|
case SliceTy:
|
||||||
switch t.Type.T {
|
return forEachUnpack(t, output, i, j)
|
||||||
|
case ArrayTy:
|
||||||
|
return forEachUnpack(t, output, i, t.Size)
|
||||||
|
case StringTy: // variable arrays are written at the end of the return bytes
|
||||||
|
return string(output[i : i+j]), nil
|
||||||
case IntTy, UintTy:
|
case IntTy, UintTy:
|
||||||
return readInteger(t.Type.Kind, returnOutput), nil
|
return readInteger(t.Kind, returnOutput), nil
|
||||||
case BoolTy:
|
case BoolTy:
|
||||||
return readBool(returnOutput)
|
return readBool(returnOutput)
|
||||||
case AddressTy:
|
case AddressTy:
|
||||||
return common.BytesToAddress(returnOutput), nil
|
return common.BytesToAddress(returnOutput), nil
|
||||||
case HashTy:
|
case HashTy:
|
||||||
return common.BytesToHash(returnOutput), nil
|
return common.BytesToHash(returnOutput), nil
|
||||||
case BytesTy, FixedBytesTy, FunctionTy:
|
case BytesTy:
|
||||||
return returnOutput, nil
|
return output[i : i+j], nil
|
||||||
case StringTy:
|
case FixedBytesTy:
|
||||||
return string(returnOutput), nil
|
return readFixedBytes(t, returnOutput)
|
||||||
|
case FunctionTy:
|
||||||
|
return readFunctionType(t, returnOutput)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("abi: unknown type %v", t.T)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// interprets a 32 byte slice as an offset and then determines which indice to look to decode the type.
|
||||||
|
func lengthPrefixPointsTo(index int, output []byte) (start int, length int, err error) {
|
||||||
|
offset := int(binary.BigEndian.Uint64(output[index+24 : index+32]))
|
||||||
|
if offset+32 > len(output) {
|
||||||
|
return 0, 0, fmt.Errorf("abi: cannot marshal in to go slice: offset %d would go over slice boundary (len=%d)", len(output), offset+32)
|
||||||
|
}
|
||||||
|
length = int(binary.BigEndian.Uint64(output[offset+24 : offset+32]))
|
||||||
|
if offset+32+length > len(output) {
|
||||||
|
return 0, 0, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32+length)
|
||||||
|
}
|
||||||
|
start = offset + 32
|
||||||
|
|
||||||
|
//fmt.Printf("LENGTH PREFIX INFO: \nsize: %v\noffset: %v\nstart: %v\n", length, offset, start)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func bytesAreProper(output []byte) error {
|
||||||
|
if len(output) == 0 {
|
||||||
|
return fmt.Errorf("abi: unmarshalling empty output")
|
||||||
|
} else if len(output)%32 != 0 {
|
||||||
|
return fmt.Errorf("abi: improperly formatted output")
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("abi: unknown type %v", t.Type.T)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,10 +110,24 @@ func TestSimpleMethodUnpack(t *testing.T) {
|
||||||
{
|
{
|
||||||
`[ { "type": "bytes32" } ]`,
|
`[ { "type": "bytes32" } ]`,
|
||||||
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
|
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
|
||||||
|
[32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
"fixedBytes32",
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`[ { "type": "bytes" } ]`,
|
||||||
|
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000"),
|
||||||
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
|
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
|
||||||
"bytes",
|
"bytes",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
`[ { "type": "bytes" } ]`,
|
||||||
|
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000"),
|
||||||
|
nil,
|
||||||
|
"fixedBytes32",
|
||||||
|
"abi: cannot unmarshal []uint8 in to [32]uint8",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "bytes32" } ]`,
|
`[ { "type": "bytes32" } ]`,
|
||||||
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
|
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
|
||||||
|
|
@ -121,13 +135,6 @@ func TestSimpleMethodUnpack(t *testing.T) {
|
||||||
"hash",
|
"hash",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
`[ { "type": "bytes32" } ]`,
|
|
||||||
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
|
|
||||||
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
|
|
||||||
"interface",
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
`[ { "type": "function" } ]`,
|
`[ { "type": "function" } ]`,
|
||||||
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
|
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
|
||||||
|
|
@ -193,6 +200,11 @@ func TestSimpleMethodUnpack(t *testing.T) {
|
||||||
var v []byte
|
var v []byte
|
||||||
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
||||||
outvar = v
|
outvar = v
|
||||||
|
case "fixedBytes32":
|
||||||
|
// this is a bit presumptive but will work for testing for now
|
||||||
|
var v [32]byte
|
||||||
|
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
||||||
|
outvar = v
|
||||||
case "hash":
|
case "hash":
|
||||||
var v common.Hash
|
var v common.Hash
|
||||||
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
||||||
|
|
@ -201,8 +213,6 @@ func TestSimpleMethodUnpack(t *testing.T) {
|
||||||
var v [24]byte
|
var v [24]byte
|
||||||
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
||||||
outvar = v
|
outvar = v
|
||||||
case "interface":
|
|
||||||
err = abi.Unpack(&outvar, "method", test.marshalledOutput)
|
|
||||||
default:
|
default:
|
||||||
t.Errorf("unsupported type '%v' please add it to the switch statement in this test", test.outVar)
|
t.Errorf("unsupported type '%v' please add it to the switch statement in this test", test.outVar)
|
||||||
continue
|
continue
|
||||||
|
|
@ -228,156 +238,163 @@ func TestSimpleMethodUnpack(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArraysAndSlicesUnpack(t *testing.T) {
|
func TestArraysAndSlicesUnpack(t *testing.T) {
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
def string // definition of the **output** ABI params
|
def string // definition of the **output** ABI params
|
||||||
marshalledOutput []byte // evm return data
|
marshalledOutput []byte // evm return data
|
||||||
expectedOut interface{} // the expected output
|
expectedOut interface{} // the expected output
|
||||||
outVar interface{} // the output variable (e.g. uint32, *big.Int, etc)
|
outVar string // the output variable (e.g. uint32, *big.Int, etc)
|
||||||
err string // empty or error if expected
|
err string // empty or error if expected
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
`[ { "type": "uint8[]" } ]`,
|
`[ { "type": "uint8[]" } ]`,
|
||||||
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[]uint8{1, 2},
|
[]uint8{1, 2},
|
||||||
[]uint8{},
|
"[]uint8",
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`[ { "type": "uint8[][]" } ]`,
|
||||||
|
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000E0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
|
[][]uint8{{1, 2}, {1, 2}},
|
||||||
|
"[][]uint8",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "uint8[2]" } ]`,
|
`[ { "type": "uint8[2]" } ]`,
|
||||||
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[2]uint8{1, 2},
|
[2]uint8{1, 2},
|
||||||
[2]uint8{},
|
"[2]uint8",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "uint16[]" } ]`,
|
`[ { "type": "uint16[]" } ]`,
|
||||||
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[]uint16{1, 2},
|
[]uint16{1, 2},
|
||||||
[]uint16{},
|
"[]uint16",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "uint16[2]" } ]`,
|
`[ { "type": "uint16[2]" } ]`,
|
||||||
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[2]uint16{1, 2},
|
[2]uint16{1, 2},
|
||||||
[2]uint16{},
|
"[2]uint16",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "uint32[]" } ]`,
|
`[ { "type": "uint32[]" } ]`,
|
||||||
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[]uint32{1, 2},
|
[]uint32{1, 2},
|
||||||
[]uint32{},
|
"[]uint32",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "uint32[2]" } ]`,
|
`[ { "type": "uint32[2]" } ]`,
|
||||||
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[2]uint32{1, 2},
|
[2]uint32{1, 2},
|
||||||
[2]uint32{},
|
"[2]uint32",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "uint64[]" } ]`,
|
`[ { "type": "uint64[]" } ]`,
|
||||||
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[]uint64{1, 2},
|
[]uint64{1, 2},
|
||||||
[]uint64{},
|
"[]uint64",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "uint64[2]" } ]`,
|
`[ { "type": "uint64[2]" } ]`,
|
||||||
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[2]uint64{1, 2},
|
[2]uint64{1, 2},
|
||||||
[2]uint64{},
|
"[2]uint64",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "uint256[]" } ]`,
|
`[ { "type": "uint256[]" } ]`,
|
||||||
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[]*big.Int{big.NewInt(1), big.NewInt(2)},
|
[]*big.Int{big.NewInt(1), big.NewInt(2)},
|
||||||
[]*big.Int{},
|
"[]*big.Int",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "uint256[3]" } ]`,
|
`[ { "type": "uint256[3]" } ]`,
|
||||||
append(pad([]byte{1}, 32, true), append(pad([]byte{2}, 32, true), pad([]byte{3}, 32, true)...)...),
|
append(pad([]byte{1}, 32, true), append(pad([]byte{2}, 32, true), pad([]byte{3}, 32, true)...)...),
|
||||||
[3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
|
[3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
|
||||||
[3]*big.Int{},
|
"[3]*big.Int",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "int8[]" } ]`,
|
`[ { "type": "int8[]" } ]`,
|
||||||
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[]int8{1, 2},
|
[]int8{1, 2},
|
||||||
[]int8{},
|
"[]int8",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "int8[2]" } ]`,
|
`[ { "type": "int8[2]" } ]`,
|
||||||
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[2]int8{1, 2},
|
[2]int8{1, 2},
|
||||||
[2]int8{},
|
"[2]int8",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "int16[]" } ]`,
|
`[ { "type": "int16[]" } ]`,
|
||||||
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[]int16{1, 2},
|
[]int16{1, 2},
|
||||||
[]int16{},
|
"[]int16",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "int16[2]" } ]`,
|
`[ { "type": "int16[2]" } ]`,
|
||||||
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[2]int16{1, 2},
|
[2]int16{1, 2},
|
||||||
[2]int16{},
|
"[2]int16",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "int32[]" } ]`,
|
`[ { "type": "int32[]" } ]`,
|
||||||
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[]int32{1, 2},
|
[]int32{1, 2},
|
||||||
[]int32{},
|
"[]int32",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "int32[2]" } ]`,
|
`[ { "type": "int32[2]" } ]`,
|
||||||
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[2]int32{1, 2},
|
[2]int32{1, 2},
|
||||||
[2]int32{},
|
"[2]int32",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "int64[]" } ]`,
|
`[ { "type": "int64[]" } ]`,
|
||||||
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[]int64{1, 2},
|
[]int64{1, 2},
|
||||||
[]int64{},
|
"[]int64",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "int64[2]" } ]`,
|
`[ { "type": "int64[2]" } ]`,
|
||||||
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[2]int64{1, 2},
|
[2]int64{1, 2},
|
||||||
[2]int64{},
|
"[2]int64",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "int256[]" } ]`,
|
`[ { "type": "int256[]" } ]`,
|
||||||
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
|
||||||
[]*big.Int{big.NewInt(1), big.NewInt(2)},
|
[]*big.Int{big.NewInt(1), big.NewInt(2)},
|
||||||
[]*big.Int{},
|
"[]*big.Int",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
`[ { "type": "int256[3]" } ]`,
|
`[ { "type": "int256[3]" } ]`,
|
||||||
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003"),
|
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003"),
|
||||||
[3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
|
[3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
|
||||||
[3]*big.Int{},
|
"[3]*big.Int",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
|
//t.Log(test.marshalledOutput)
|
||||||
|
|
||||||
abiDefinition := fmt.Sprintf(`[{ "name" : "method", "outputs": %s}]`, test.def)
|
abiDefinition := fmt.Sprintf(`[{ "name" : "method", "outputs": %s}]`, test.def)
|
||||||
abi, err := JSON(strings.NewReader(abiDefinition))
|
abi, err := JSON(strings.NewReader(abiDefinition))
|
||||||
|
|
@ -386,7 +403,88 @@ func TestArraysAndSlicesUnpack(t *testing.T) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
err = abi.Unpack(&test.outVar, "method", test.marshalledOutput)
|
var outvar interface{}
|
||||||
|
switch test.outVar {
|
||||||
|
case "[][]uint8":
|
||||||
|
var v [][]uint8
|
||||||
|
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
||||||
|
outvar = v
|
||||||
|
case "[]uint8":
|
||||||
|
var v []uint8
|
||||||
|
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
||||||
|
outvar = v
|
||||||
|
case "[2]uint8":
|
||||||
|
var v [2]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 "[2]uint16":
|
||||||
|
var v [2]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 "[2]uint32":
|
||||||
|
var v [2]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 "[2]uint64":
|
||||||
|
var v [2]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 "[2]int8":
|
||||||
|
var v [2]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 "[2]int16":
|
||||||
|
var v [2]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 "[2]int32":
|
||||||
|
var v [2]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 "[2]int64":
|
||||||
|
var v [2]int64
|
||||||
|
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
||||||
|
outvar = v
|
||||||
|
case "[3]*big.Int":
|
||||||
|
var v [3]*big.Int
|
||||||
|
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
|
||||||
|
default:
|
||||||
|
t.Errorf("unsupported type '%v' please add it to the switch statement in this test", test.outVar)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil && len(test.err) == 0 {
|
if err != nil && len(test.err) == 0 {
|
||||||
t.Errorf("%d failed. Expected no err but got: %v", i, err)
|
t.Errorf("%d failed. Expected no err but got: %v", i, err)
|
||||||
|
|
@ -402,69 +500,14 @@ func TestArraysAndSlicesUnpack(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if !reflect.DeepEqual(test.expectedOut, test.outVar) {
|
if !reflect.DeepEqual(test.expectedOut, outvar) {
|
||||||
t.Errorf("%d failed. Output error: expected %v, got %v", i, test.expectedOut, test.outVar)
|
t.Errorf("%d failed. Output error: expected %v, got %v", i, test.expectedOut, outvar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnpackSetInterfaceSlice(t *testing.T) {
|
|
||||||
var (
|
|
||||||
var1 = new(uint8)
|
|
||||||
var2 = new(uint8)
|
|
||||||
)
|
|
||||||
out := []interface{}{var1, var2}
|
|
||||||
abi, err := JSON(strings.NewReader(`[{"type":"function", "name":"ints", "outputs":[{"type":"uint8"}, {"type":"uint8"}]}]`))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
marshalledReturn := append(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")...)
|
|
||||||
err = abi.Unpack(&out, "ints", marshalledReturn)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if *var1 != 1 {
|
|
||||||
t.Error("expected var1 to be 1, got", *var1)
|
|
||||||
}
|
|
||||||
if *var2 != 2 {
|
|
||||||
t.Error("expected var2 to be 2, got", *var2)
|
|
||||||
}
|
|
||||||
|
|
||||||
out = []interface{}{var1}
|
|
||||||
err = abi.Unpack(&out, "ints", marshalledReturn)
|
|
||||||
|
|
||||||
expErr := "abi: cannot marshal in to slices of unequal size (require: 2, got: 1)"
|
|
||||||
if err == nil || err.Error() != expErr {
|
|
||||||
t.Error("expected err:", expErr, "Got:", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnpackSetInterfaceArrayOutput(t *testing.T) {
|
|
||||||
var (
|
|
||||||
var1 = new([1]uint32)
|
|
||||||
var2 = new([1]uint32)
|
|
||||||
)
|
|
||||||
out := []interface{}{var1, var2}
|
|
||||||
abi, err := JSON(strings.NewReader(`[{"type":"function", "name":"ints", "outputs":[{"type":"uint32[1]"}, {"type":"uint32[1]"}]}]`))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
marshalledReturn := append(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")...)
|
|
||||||
err = abi.Unpack(&out, "ints", marshalledReturn)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if *var1 != [1]uint32{1} {
|
|
||||||
t.Error("expected var1 to be [1], got", *var1)
|
|
||||||
}
|
|
||||||
if *var2 != [1]uint32{2} {
|
|
||||||
t.Error("expected var2 to be [2], got", *var2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMultiReturnWithStruct(t *testing.T) {
|
func TestMultiReturnWithStruct(t *testing.T) {
|
||||||
const definition = `[
|
const definition = `[
|
||||||
{ "name" : "multi", "constant" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
|
{ "name" : "multi", "constant" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
|
||||||
|
|
@ -518,101 +561,6 @@ func TestMultiReturnWithStruct(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultiReturnWithSlice(t *testing.T) {
|
|
||||||
const definition = `[
|
|
||||||
{ "name" : "multi", "constant" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]`
|
|
||||||
|
|
||||||
abi, err := JSON(strings.NewReader(definition))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// using buff to make the code readable
|
|
||||||
buff := new(bytes.Buffer)
|
|
||||||
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"))
|
|
||||||
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040"))
|
|
||||||
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000005"))
|
|
||||||
stringOut := "hello"
|
|
||||||
buff.Write(common.RightPadBytes([]byte(stringOut), 32))
|
|
||||||
|
|
||||||
var inter []interface{}
|
|
||||||
err = abi.Unpack(&inter, "multi", buff.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(inter) != 2 {
|
|
||||||
t.Fatal("expected 2 results got", len(inter))
|
|
||||||
}
|
|
||||||
|
|
||||||
if num, ok := inter[0].(*big.Int); !ok || num.Cmp(big.NewInt(1)) != 0 {
|
|
||||||
t.Error("expected index 0 to be 1 got", num)
|
|
||||||
}
|
|
||||||
|
|
||||||
if str, ok := inter[1].(string); !ok || str != stringOut {
|
|
||||||
t.Error("expected index 1 to be", stringOut, "got", str)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMarshalArrays(t *testing.T) {
|
|
||||||
const definition = `[
|
|
||||||
{ "name" : "bytes32", "constant" : false, "outputs": [ { "type": "bytes32" } ] },
|
|
||||||
{ "name" : "bytes10", "constant" : false, "outputs": [ { "type": "bytes10" } ] }
|
|
||||||
]`
|
|
||||||
|
|
||||||
abi, err := JSON(strings.NewReader(definition))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
output := common.LeftPadBytes([]byte{1}, 32)
|
|
||||||
|
|
||||||
var bytes10 [10]byte
|
|
||||||
err = abi.Unpack(&bytes10, "bytes32", output)
|
|
||||||
if err == nil || err.Error() != "abi: cannot unmarshal src (len=32) in to dst (len=10)" {
|
|
||||||
t.Error("expected error or bytes32 not be assignable to bytes10:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var bytes32 [32]byte
|
|
||||||
err = abi.Unpack(&bytes32, "bytes32", output)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("didn't expect error:", err)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(bytes32[:], output) {
|
|
||||||
t.Error("expected bytes32[31] to be 1 got", bytes32[31])
|
|
||||||
}
|
|
||||||
|
|
||||||
type (
|
|
||||||
B10 [10]byte
|
|
||||||
B32 [32]byte
|
|
||||||
)
|
|
||||||
|
|
||||||
var b10 B10
|
|
||||||
err = abi.Unpack(&b10, "bytes32", output)
|
|
||||||
if err == nil || err.Error() != "abi: cannot unmarshal src (len=32) in to dst (len=10)" {
|
|
||||||
t.Error("expected error or bytes32 not be assignable to bytes10:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var b32 B32
|
|
||||||
err = abi.Unpack(&b32, "bytes32", output)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("didn't expect error:", err)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(b32[:], output) {
|
|
||||||
t.Error("expected bytes32[31] to be 1 got", bytes32[31])
|
|
||||||
}
|
|
||||||
|
|
||||||
output[10] = 1
|
|
||||||
var shortAssignLong [32]byte
|
|
||||||
err = abi.Unpack(&shortAssignLong, "bytes10", output)
|
|
||||||
if err != nil {
|
|
||||||
t.Error("didn't expect error:", err)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(output, shortAssignLong[:]) {
|
|
||||||
t.Errorf("expected %x to be %x", shortAssignLong, output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnmarshal(t *testing.T) {
|
func TestUnmarshal(t *testing.T) {
|
||||||
const definition = `[
|
const definition = `[
|
||||||
{ "name" : "int", "constant" : false, "outputs": [ { "type": "uint256" } ] },
|
{ "name" : "int", "constant" : false, "outputs": [ { "type": "uint256" } ] },
|
||||||
|
|
@ -685,11 +633,11 @@ func TestUnmarshal(t *testing.T) {
|
||||||
t.Errorf("expected %x got %x", bytesOut, Bytes)
|
t.Errorf("expected %x got %x", bytesOut, Bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// marshall dynamic bytes max length 63
|
// marshall dynamic bytes max length 64
|
||||||
buff.Reset()
|
buff.Reset()
|
||||||
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020"))
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020"))
|
||||||
buff.Write(common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000003f"))
|
buff.Write(common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000003f"))
|
||||||
bytesOut = common.RightPadBytes([]byte("hello"), 63)
|
bytesOut = common.RightPadBytes([]byte("hello"), 64)
|
||||||
buff.Write(bytesOut)
|
buff.Write(bytesOut)
|
||||||
|
|
||||||
err = abi.Unpack(&Bytes, "bytes", buff.Bytes())
|
err = abi.Unpack(&Bytes, "bytes", buff.Bytes())
|
||||||
|
|
@ -697,8 +645,8 @@ func TestUnmarshal(t *testing.T) {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(Bytes, bytesOut) {
|
if !bytes.Equal(Bytes, bytesOut[:len(bytesOut)-1]) {
|
||||||
t.Errorf("expected %x got %x", bytesOut, Bytes)
|
t.Errorf("expected %x got %x", bytesOut[:len(bytesOut)-1], Bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// marshal dynamic bytes output empty
|
// marshal dynamic bytes output empty
|
||||||
|
|
@ -750,29 +698,6 @@ func TestUnmarshal(t *testing.T) {
|
||||||
t.Error("expected error")
|
t.Error("expected error")
|
||||||
}
|
}
|
||||||
|
|
||||||
// marshal mixed bytes
|
|
||||||
buff.Reset()
|
|
||||||
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040"))
|
|
||||||
fixed := common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")
|
|
||||||
buff.Write(fixed)
|
|
||||||
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020"))
|
|
||||||
bytesOut = common.RightPadBytes([]byte("hello"), 32)
|
|
||||||
buff.Write(bytesOut)
|
|
||||||
|
|
||||||
var out []interface{}
|
|
||||||
err = abi.Unpack(&out, "mixedBytes", buff.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("didn't expect error:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(bytesOut, out[0].([]byte)) {
|
|
||||||
t.Errorf("expected %x, got %x", bytesOut, out[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(fixed, out[1].([]byte)) {
|
|
||||||
t.Errorf("expected %x, got %x", fixed, out[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
buff.Reset()
|
buff.Reset()
|
||||||
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"))
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"))
|
||||||
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"))
|
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue