forked from cerc-io/plugeth
accounts/abi: add support for unpacking returned bytesN arrays (#15242)
This commit is contained in:
parent
5e4fd8e7db
commit
7df52e324c
@ -77,6 +77,8 @@ func set(dst, src reflect.Value, output Argument) error {
|
|||||||
switch {
|
switch {
|
||||||
case dstType.AssignableTo(srcType):
|
case dstType.AssignableTo(srcType):
|
||||||
dst.Set(src)
|
dst.Set(src)
|
||||||
|
case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice:
|
||||||
|
return setSlice(dst, src, output)
|
||||||
case dstType.Kind() == reflect.Interface:
|
case dstType.Kind() == reflect.Interface:
|
||||||
dst.Set(src)
|
dst.Set(src)
|
||||||
case dstType.Kind() == reflect.Ptr:
|
case dstType.Kind() == reflect.Ptr:
|
||||||
@ -87,6 +89,19 @@ func set(dst, src reflect.Value, output Argument) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setSlice attempts to assign src to dst when slices are not assignable by default
|
||||||
|
// e.g. src: [][]byte -> dst: [][15]byte
|
||||||
|
func setSlice(dst, src reflect.Value, output Argument) error {
|
||||||
|
slice := reflect.MakeSlice(dst.Type(), src.Len(), src.Len())
|
||||||
|
for i := 0; i < src.Len(); i++ {
|
||||||
|
v := src.Index(i)
|
||||||
|
reflect.Copy(slice.Index(i), v)
|
||||||
|
}
|
||||||
|
|
||||||
|
dst.Set(slice)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// requireAssignable assures that `dest` is a pointer and it's not an interface.
|
// requireAssignable assures that `dest` is a pointer and it's not an interface.
|
||||||
func requireAssignable(dst, src reflect.Value) error {
|
func requireAssignable(dst, src reflect.Value) error {
|
||||||
if dst.Kind() != reflect.Ptr && dst.Kind() != reflect.Interface {
|
if dst.Kind() != reflect.Ptr && dst.Kind() != reflect.Interface {
|
||||||
|
@ -364,6 +364,55 @@ func TestUnpack(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnpackSetDynamicArrayOutput(t *testing.T) {
|
||||||
|
abi, err := JSON(strings.NewReader(`[{"constant":true,"inputs":[],"name":"testDynamicFixedBytes15","outputs":[{"name":"","type":"bytes15[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"testDynamicFixedBytes32","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"}]`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
marshalledReturn32 = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000230783132333435363738393000000000000000000000000000000000000000003078303938373635343332310000000000000000000000000000000000000000")
|
||||||
|
marshalledReturn15 = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000230783031323334350000000000000000000000000000000000000000000000003078393837363534000000000000000000000000000000000000000000000000")
|
||||||
|
|
||||||
|
out32 [][32]byte
|
||||||
|
out15 [][15]byte
|
||||||
|
)
|
||||||
|
|
||||||
|
// test 32
|
||||||
|
err = abi.Unpack(&out32, "testDynamicFixedBytes32", marshalledReturn32)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(out32) != 2 {
|
||||||
|
t.Fatalf("expected array with 2 values, got %d", len(out32))
|
||||||
|
}
|
||||||
|
expected := common.Hex2Bytes("3078313233343536373839300000000000000000000000000000000000000000")
|
||||||
|
if !bytes.Equal(out32[0][:], expected) {
|
||||||
|
t.Errorf("expected %x, got %x\n", expected, out32[0])
|
||||||
|
}
|
||||||
|
expected = common.Hex2Bytes("3078303938373635343332310000000000000000000000000000000000000000")
|
||||||
|
if !bytes.Equal(out32[1][:], expected) {
|
||||||
|
t.Errorf("expected %x, got %x\n", expected, out32[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
// test 15
|
||||||
|
err = abi.Unpack(&out15, "testDynamicFixedBytes32", marshalledReturn15)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(out15) != 2 {
|
||||||
|
t.Fatalf("expected array with 2 values, got %d", len(out15))
|
||||||
|
}
|
||||||
|
expected = common.Hex2Bytes("307830313233343500000000000000")
|
||||||
|
if !bytes.Equal(out15[0][:], expected) {
|
||||||
|
t.Errorf("expected %x, got %x\n", expected, out15[0])
|
||||||
|
}
|
||||||
|
expected = common.Hex2Bytes("307839383736353400000000000000")
|
||||||
|
if !bytes.Equal(out15[1][:], expected) {
|
||||||
|
t.Errorf("expected %x, got %x\n", expected, out15[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type methodMultiOutput struct {
|
type methodMultiOutput struct {
|
||||||
Int *big.Int
|
Int *big.Int
|
||||||
String string
|
String string
|
||||||
|
Loading…
Reference in New Issue
Block a user