accounts/abi: reduce duplication in unpack tests

This commit is contained in:
Felix Lange 2017-09-10 12:11:37 +02:00 committed by Bas van Kervel
parent 5c2d42ff01
commit c86e965cb9
No known key found for this signature in database
GPG key ID: BFB23B252EF5812B

View file

@ -18,6 +18,7 @@ package abi
import (
"bytes"
"encoding/hex"
"fmt"
"math/big"
"reflect"
@ -27,531 +28,258 @@ import (
"github.com/ethereum/go-ethereum/common"
)
func TestSingleValueUnpack(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 string // empty or error if expected
}{
{
`[ { "type": "bool" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"),
bool(true),
"bool",
"",
},
{
`[ { "type": "uint32" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"),
uint32(1),
"uint32",
"",
},
{
`[ { "type": "uint32" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"),
nil,
"uint16",
"abi: cannot unmarshal uint32 in to uint16",
},
{
`[ { "type": "uint17" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"),
nil,
"uint16",
"abi: cannot unmarshal *big.Int in to uint16",
},
{
`[ { "type": "uint17" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"),
big.NewInt(1),
"*big.Int",
"",
},
{
`[ { "type": "int32" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"),
int32(1),
"int32",
"",
},
{
`[ { "type": "int32" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"),
nil,
"int16",
"abi: cannot unmarshal int32 in to int16",
},
{
`[ { "type": "int17" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"),
nil,
"int16",
"abi: cannot unmarshal *big.Int in to int16",
},
{
`[ { "type": "int17" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"),
big.NewInt(1),
"*big.Int",
"",
},
{
`[ { "type": "address" } ]`,
common.Hex2Bytes("0000000000000000000000000100000000000000000000000000000000000000"),
common.Address{1},
"address",
"",
},
{
`[ { "type": "bytes32" } ]`,
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"),
"bytes",
"",
},
{
`[ { "type": "bytes" } ]`,
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000"),
nil,
"fixedBytes32",
"abi: cannot unmarshal []uint8 in to [32]uint8",
},
{
`[ { "type": "bytes32" } ]`,
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000"),
nil,
"bytes",
"abi: cannot unmarshal [32]uint8 in to []uint8",
},
{
`[ { "type": "bytes32" } ]`,
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
"hash",
"",
},
{
`[ { "type": "function" } ]`,
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
[24]byte{1},
"function",
"",
},
} {
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 "bool":
var v bool
err = abi.Unpack(&v, "method", test.marshalledOutput)
outvar = v
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 "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)
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 "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":
var v common.Hash
err = abi.Unpack(&v, "method", test.marshalledOutput)
outvar = v.Bytes()[:]
case "function":
var v [24]byte
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 {
t.Errorf("%d failed. Expected no err but got: %v", i, err)
continue
}
if err == nil && len(test.err) != 0 {
t.Errorf("%d failed. Expected err: %v but got none", i, test.err)
continue
}
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
}
if err == nil {
if !reflect.DeepEqual(test.expectedOut, outvar) {
t.Errorf("%d failed. Output error: expected %v, got %v", i, test.expectedOut, outvar)
}
}
}
type unpackTest struct {
def string // ABI definition JSON
enc string // evm return data
want interface{} // the expected output
err string // empty or error if expected
}
func TestSingleArraysAndSlicesUnpack(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 string // empty or error if expected
}{
{
`[ { "type": "uint8[]" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[]uint8{1, 2},
"[]uint8",
"",
},
{
`[ { "type": "uint8[2]" } ]`,
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[2]uint8{1, 2},
"[2]uint8",
"",
},
// multi dimensional, if these pass, all types that don't require length prefix should pass
{
`[ { "type": "uint8[][]" } ]`,
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000E0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[][]uint8{{1, 2}, {1, 2}},
"[][]uint8",
"",
},
{
`[ { "type": "uint8[2][2]" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[2][2]uint8{{1, 2}, {1, 2}},
"[2][2]uint8",
"",
},
{
`[ { "type": "uint8[][2]" } ]`,
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001"),
[2][]uint8{{1}, {1}},
"[2][]uint8",
"",
},
{
`[ { "type": "uint8[2][]" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[][2]uint8{{1, 2}},
"[][2]uint8",
"",
},
{
`[ { "type": "uint16[]" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[]uint16{1, 2},
"[]uint16",
"",
},
{
`[ { "type": "uint16[2]" } ]`,
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[2]uint16{1, 2},
"[2]uint16",
"",
},
{
`[ { "type": "uint32[]" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[]uint32{1, 2},
"[]uint32",
"",
},
{
`[ { "type": "uint32[2]" } ]`,
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[2]uint32{1, 2},
"[2]uint32",
"",
},
{
`[ { "type": "uint64[]" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[]uint64{1, 2},
"[]uint64",
"",
},
{
`[ { "type": "uint64[2]" } ]`,
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[2]uint64{1, 2},
"[2]uint64",
"",
},
{
`[ { "type": "uint256[]" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[]*big.Int{big.NewInt(1), big.NewInt(2)},
"[]*big.Int",
"",
},
{
`[ { "type": "uint256[3]" } ]`,
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",
"",
},
{
`[ { "type": "int8[]" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[]int8{1, 2},
"[]int8",
"",
},
{
`[ { "type": "int8[2]" } ]`,
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[2]int8{1, 2},
"[2]int8",
"",
},
{
`[ { "type": "int16[]" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[]int16{1, 2},
"[]int16",
"",
},
{
`[ { "type": "int16[2]" } ]`,
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[2]int16{1, 2},
"[2]int16",
"",
},
{
`[ { "type": "int32[]" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[]int32{1, 2},
"[]int32",
"",
},
{
`[ { "type": "int32[2]" } ]`,
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[2]int32{1, 2},
"[2]int32",
"",
},
{
`[ { "type": "int64[]" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[]int64{1, 2},
"[]int64",
"",
},
{
`[ { "type": "int64[2]" } ]`,
common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[2]int64{1, 2},
"[2]int64",
"",
},
{
`[ { "type": "int256[]" } ]`,
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"),
[]*big.Int{big.NewInt(1), big.NewInt(2)},
"[]*big.Int",
"",
},
{
`[ { "type": "int256[3]" } ]`,
common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003"),
[3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
"[3]*big.Int",
"",
},
} {
abiDefinition := fmt.Sprintf(`[{ "name" : "method", "outputs": %s}]`, test.def)
abi, err := JSON(strings.NewReader(abiDefinition))
func (test unpackTest) checkError(err error) error {
if err != nil {
if len(test.err) == 0 {
return fmt.Errorf("expected no err but got: %v", err)
} else if err.Error() != test.err {
return fmt.Errorf("expected err: '%v' got err: %q", test.err, err)
}
} else if len(test.err) > 0 {
return fmt.Errorf("expected err: %v but got none", test.err)
}
return nil
}
var unpackTests = []unpackTest{
{
def: `[{ "type": "bool" }]`,
enc: "0000000000000000000000000000000000000000000000000000000000000001",
want: true,
},
{
def: `[{"type": "uint32"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000001",
want: uint32(1),
},
{
def: `[{"type": "uint32"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000001",
want: uint16(0),
err: "abi: cannot unmarshal uint32 in to uint16",
},
{
def: `[{"type": "uint17"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000001",
want: uint16(0),
err: "abi: cannot unmarshal *big.Int in to uint16",
},
{
def: `[{"type": "uint17"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000001",
want: big.NewInt(1),
},
{
def: `[{"type": "int32"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000001",
want: int32(1),
},
{
def: `[{"type": "int32"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000001",
want: int16(0),
err: "abi: cannot unmarshal int32 in to int16",
},
{
def: `[{"type": "int17"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000001",
want: int16(0),
err: "abi: cannot unmarshal *big.Int in to int16",
},
{
def: `[{"type": "int17"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000001",
want: big.NewInt(1),
},
{
def: `[{"type": "address"}]`,
enc: "0000000000000000000000000100000000000000000000000000000000000000",
want: common.Address{1},
},
{
def: `[{"type": "bytes32"}]`,
enc: "0100000000000000000000000000000000000000000000000000000000000000",
want: [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},
},
{
def: `[{"type": "bytes"}]`,
enc: "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000",
want: common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
def: `[{"type": "bytes"}]`,
enc: "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000",
want: [32]byte{},
err: "abi: cannot unmarshal []uint8 in to [32]uint8",
},
{
def: `[{"type": "bytes32"}]`,
enc: "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000",
want: []byte(nil),
err: "abi: cannot unmarshal [32]uint8 in to []uint8",
},
{
def: `[{"type": "bytes32"}]`,
enc: "0100000000000000000000000000000000000000000000000000000000000000",
want: common.HexToHash("0100000000000000000000000000000000000000000000000000000000000000"),
},
{
def: `[{"type": "function"}]`,
enc: "0100000000000000000000000000000000000000000000000000000000000000",
want: [24]byte{1},
},
// slices
{
def: `[{"type": "uint8[]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: []uint8{1, 2},
},
{
def: `[{"type": "uint8[2]"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: [2]uint8{1, 2},
},
// multi dimensional, if these pass, all types that don't require length prefix should pass
{
def: `[{"type": "uint8[][]"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000E0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: [][]uint8{{1, 2}, {1, 2}},
},
{
def: `[{"type": "uint8[2][2]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: [2][2]uint8{{1, 2}, {1, 2}},
},
{
def: `[{"type": "uint8[][2]"}]`,
enc: "000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001",
want: [2][]uint8{{1}, {1}},
},
{
def: `[{"type": "uint8[2][]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: [][2]uint8{{1, 2}},
},
{
def: `[{"type": "uint16[]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: []uint16{1, 2},
},
{
def: `[{"type": "uint16[2]"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: [2]uint16{1, 2},
},
{
def: `[{"type": "uint32[]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: []uint32{1, 2},
},
{
def: `[{"type": "uint32[2]"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: [2]uint32{1, 2},
},
{
def: `[{"type": "uint64[]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: []uint64{1, 2},
},
{
def: `[{"type": "uint64[2]"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: [2]uint64{1, 2},
},
{
def: `[{"type": "uint256[]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: []*big.Int{big.NewInt(1), big.NewInt(2)},
},
{
def: `[{"type": "uint256[3]"}]`,
enc: "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
want: [3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
},
{
def: `[{"type": "int8[]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: []int8{1, 2},
},
{
def: `[{"type": "int8[2]"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: [2]int8{1, 2},
},
{
def: `[{"type": "int16[]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: []int16{1, 2},
},
{
def: `[{"type": "int16[2]"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: [2]int16{1, 2},
},
{
def: `[{"type": "int32[]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: []int32{1, 2},
},
{
def: `[{"type": "int32[2]"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: [2]int32{1, 2},
},
{
def: `[{"type": "int64[]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: []int64{1, 2},
},
{
def: `[{"type": "int64[2]"}]`,
enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: [2]int64{1, 2},
},
{
def: `[{"type": "int256[]"}]`,
enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
want: []*big.Int{big.NewInt(1), big.NewInt(2)},
},
{
def: `[{"type": "int256[3]"}]`,
enc: "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003",
want: [3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
},
}
func TestUnpack(t *testing.T) {
for i, test := range unpackTests {
def := fmt.Sprintf(`[{ "name" : "method", "outputs": %s}]`, test.def)
abi, err := JSON(strings.NewReader(def))
if err != nil {
t.Errorf("%d failed. %v", i, err)
t.Fatalf("invalid ABI definition %s: %v", def, err)
}
encb, err := hex.DecodeString(test.enc)
if err != nil {
t.Fatalf("invalid hex: %s" + test.enc)
}
outptr := reflect.New(reflect.TypeOf(test.want))
err = abi.Unpack(outptr.Interface(), "method", encb)
if err := test.checkError(err); err != nil {
t.Errorf("test %d (%v) failed: %v", i, test.def, err)
continue
}
var outvar interface{}
switch test.outVar {
case "[][]uint8":
var v [][]uint8
err = abi.Unpack(&v, "method", test.marshalledOutput)
outvar = v
case "[2][2]uint8":
var v [2][2]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 "[2][]uint8":
var v [2][]uint8
err = abi.Unpack(&v, "method", test.marshalledOutput)
outvar = v
case "[2][2][2]uint8":
var v [2][2][2]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 "[]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
out := outptr.Elem().Interface()
if !reflect.DeepEqual(test.want, out) {
t.Errorf("test %d (%v) failed: expected %v, got %v", i, test.def, test.want, out)
}
if err != nil && len(test.err) == 0 {
t.Errorf("%d failed. Expected no err but got: %v", i, err)
continue
}
if err == nil && len(test.err) != 0 {
t.Errorf("%d failed. Expected err: %v but got none", i, test.err)
continue
}
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
}
if err == nil {
if !reflect.DeepEqual(test.expectedOut, outvar) {
t.Errorf("%d failed. Output error: expected %v, got %v", i, test.expectedOut, outvar)
}
}
}
}