forked from cerc-io/plugeth
Merge pull request #3533 from karalabe/modum-io-develop-2
accounts/abi: support custom int slice types
This commit is contained in:
commit
88cc1ca55a
@ -91,8 +91,30 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
|
|||||||
// first we need to create a slice of the type
|
// first we need to create a slice of the type
|
||||||
var refSlice reflect.Value
|
var refSlice reflect.Value
|
||||||
switch elem.T {
|
switch elem.T {
|
||||||
case IntTy, UintTy, BoolTy: // int, uint, bool can all be of type big int.
|
case IntTy, UintTy, BoolTy:
|
||||||
refSlice = reflect.ValueOf([]*big.Int(nil))
|
// create a new reference slice matching the element type
|
||||||
|
switch t.Type.Kind {
|
||||||
|
case reflect.Bool:
|
||||||
|
refSlice = reflect.ValueOf([]bool(nil))
|
||||||
|
case reflect.Uint8:
|
||||||
|
refSlice = reflect.ValueOf([]uint8(nil))
|
||||||
|
case reflect.Uint16:
|
||||||
|
refSlice = reflect.ValueOf([]uint16(nil))
|
||||||
|
case reflect.Uint32:
|
||||||
|
refSlice = reflect.ValueOf([]uint32(nil))
|
||||||
|
case reflect.Uint64:
|
||||||
|
refSlice = reflect.ValueOf([]uint64(nil))
|
||||||
|
case reflect.Int8:
|
||||||
|
refSlice = reflect.ValueOf([]int8(nil))
|
||||||
|
case reflect.Int16:
|
||||||
|
refSlice = reflect.ValueOf([]int16(nil))
|
||||||
|
case reflect.Int32:
|
||||||
|
refSlice = reflect.ValueOf([]int32(nil))
|
||||||
|
case reflect.Int64:
|
||||||
|
refSlice = reflect.ValueOf([]int64(nil))
|
||||||
|
default:
|
||||||
|
refSlice = reflect.ValueOf([]*big.Int(nil))
|
||||||
|
}
|
||||||
case AddressTy: // address must be of slice Address
|
case AddressTy: // address must be of slice Address
|
||||||
refSlice = reflect.ValueOf([]common.Address(nil))
|
refSlice = reflect.ValueOf([]common.Address(nil))
|
||||||
case HashTy: // hash must be of slice hash
|
case HashTy: // hash must be of slice hash
|
||||||
@ -147,7 +169,27 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
|
|||||||
// set inter to the correct type (cast)
|
// set inter to the correct type (cast)
|
||||||
switch elem.T {
|
switch elem.T {
|
||||||
case IntTy, UintTy:
|
case IntTy, UintTy:
|
||||||
inter = common.BytesToBig(returnOutput)
|
bigNum := common.BytesToBig(returnOutput)
|
||||||
|
switch t.Type.Kind {
|
||||||
|
case reflect.Uint8:
|
||||||
|
inter = uint8(bigNum.Uint64())
|
||||||
|
case reflect.Uint16:
|
||||||
|
inter = uint16(bigNum.Uint64())
|
||||||
|
case reflect.Uint32:
|
||||||
|
inter = uint32(bigNum.Uint64())
|
||||||
|
case reflect.Uint64:
|
||||||
|
inter = bigNum.Uint64()
|
||||||
|
case reflect.Int8:
|
||||||
|
inter = int8(bigNum.Int64())
|
||||||
|
case reflect.Int16:
|
||||||
|
inter = int16(bigNum.Int64())
|
||||||
|
case reflect.Int32:
|
||||||
|
inter = int32(bigNum.Int64())
|
||||||
|
case reflect.Int64:
|
||||||
|
inter = bigNum.Int64()
|
||||||
|
default:
|
||||||
|
inter = common.BytesToBig(returnOutput)
|
||||||
|
}
|
||||||
case BoolTy:
|
case BoolTy:
|
||||||
inter = common.BytesToBig(returnOutput).Uint64() > 0
|
inter = common.BytesToBig(returnOutput).Uint64() > 0
|
||||||
case AddressTy:
|
case AddressTy:
|
||||||
|
@ -332,6 +332,30 @@ func TestUnpackSetInterfaceSlice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(pad([]byte{1}, 32, true), pad([]byte{2}, 32, true)...)
|
||||||
|
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 TestPack(t *testing.T) {
|
func TestPack(t *testing.T) {
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
typ string
|
typ string
|
||||||
|
@ -91,7 +91,12 @@ func NewType(t string) (typ Type, err error) {
|
|||||||
}
|
}
|
||||||
typ.Elem = &sliceType
|
typ.Elem = &sliceType
|
||||||
typ.stringKind = sliceType.stringKind + t[len(res[1]):]
|
typ.stringKind = sliceType.stringKind + t[len(res[1]):]
|
||||||
return typ, nil
|
// Altough we know that this is an array, we cannot return
|
||||||
|
// as we don't know the type of the element, however, if it
|
||||||
|
// is still an array, then don't determine the type.
|
||||||
|
if typ.Elem.IsArray || typ.Elem.IsSlice {
|
||||||
|
return typ, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the type and size of the abi-type.
|
// parse the type and size of the abi-type.
|
||||||
@ -112,7 +117,12 @@ func NewType(t string) (typ Type, err error) {
|
|||||||
varSize = 256
|
varSize = 256
|
||||||
t += "256"
|
t += "256"
|
||||||
}
|
}
|
||||||
typ.stringKind = t
|
|
||||||
|
// only set stringKind if not array or slice, as for those,
|
||||||
|
// the correct string type has been set
|
||||||
|
if !(typ.IsArray || typ.IsSlice) {
|
||||||
|
typ.stringKind = t
|
||||||
|
}
|
||||||
|
|
||||||
switch varType {
|
switch varType {
|
||||||
case "int":
|
case "int":
|
||||||
|
@ -34,17 +34,17 @@ func TestTypeRegexp(t *testing.T) {
|
|||||||
{"int", Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}},
|
{"int", Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}},
|
||||||
{"int8", Type{Kind: reflect.Int8, Type: big_t, Size: 8, T: IntTy, stringKind: "int8"}},
|
{"int8", Type{Kind: reflect.Int8, Type: big_t, Size: 8, T: IntTy, stringKind: "int8"}},
|
||||||
{"int256", Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}},
|
{"int256", Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}},
|
||||||
{"int[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}},
|
{"int[]", Type{IsSlice: true, SliceSize: -1, Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}},
|
||||||
{"int[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}},
|
{"int[2]", Type{IsArray: true, SliceSize: 2, Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}},
|
||||||
{"int32[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Int32, Type: big_t, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}},
|
{"int32[]", Type{IsSlice: true, SliceSize: -1, Kind: reflect.Int32, Type: big_t, Size: 32, T: IntTy, Elem: &Type{Kind: reflect.Int32, Type: big_t, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}},
|
||||||
{"int32[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{Kind: reflect.Int32, Type: big_t, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}},
|
{"int32[2]", Type{IsArray: true, SliceSize: 2, Kind: reflect.Int32, Type: big_t, Size: 32, T: IntTy, Elem: &Type{Kind: reflect.Int32, Type: big_t, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}},
|
||||||
{"uint", Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}},
|
{"uint", Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}},
|
||||||
{"uint8", Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}},
|
{"uint8", Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}},
|
||||||
{"uint256", Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}},
|
{"uint256", Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}},
|
||||||
{"uint[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}},
|
{"uint[]", Type{IsSlice: true, SliceSize: -1, Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, Elem: &Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}},
|
||||||
{"uint[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}},
|
{"uint[2]", Type{IsArray: true, SliceSize: 2, Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, Elem: &Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}},
|
||||||
{"uint32[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Uint32, Type: big_t, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}},
|
{"uint32[]", Type{IsSlice: true, SliceSize: -1, Kind: reflect.Uint32, Type: ubig_t, Size: 32, T: UintTy, Elem: &Type{Kind: reflect.Uint32, Type: big_t, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}},
|
||||||
{"uint32[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{Kind: reflect.Uint32, Type: big_t, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}},
|
{"uint32[2]", Type{IsArray: true, SliceSize: 2, Kind: reflect.Uint32, Type: ubig_t, Size: 32, T: UintTy, Elem: &Type{Kind: reflect.Uint32, Type: big_t, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}},
|
||||||
{"bytes", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: BytesTy, stringKind: "bytes"}},
|
{"bytes", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: BytesTy, stringKind: "bytes"}},
|
||||||
{"bytes32", Type{IsArray: true, SliceSize: 32, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: FixedBytesTy, stringKind: "bytes32"}},
|
{"bytes32", Type{IsArray: true, SliceSize: 32, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: FixedBytesTy, stringKind: "bytes32"}},
|
||||||
{"bytes[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}},
|
{"bytes[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}},
|
||||||
@ -52,11 +52,11 @@ func TestTypeRegexp(t *testing.T) {
|
|||||||
{"bytes32[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{IsArray: true, SliceSize: 32, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: FixedBytesTy, stringKind: "bytes32"}, stringKind: "bytes32[]"}},
|
{"bytes32[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{IsArray: true, SliceSize: 32, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: FixedBytesTy, stringKind: "bytes32"}, stringKind: "bytes32[]"}},
|
||||||
{"bytes32[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{IsArray: true, SliceSize: 32, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: FixedBytesTy, stringKind: "bytes32"}, stringKind: "bytes32[2]"}},
|
{"bytes32[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{IsArray: true, SliceSize: 32, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: FixedBytesTy, stringKind: "bytes32"}, stringKind: "bytes32[2]"}},
|
||||||
{"string", Type{Kind: reflect.String, Size: -1, T: StringTy, stringKind: "string"}},
|
{"string", Type{Kind: reflect.String, Size: -1, T: StringTy, stringKind: "string"}},
|
||||||
{"string[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.String, Size: -1, T: StringTy, stringKind: "string"}, stringKind: "string[]"}},
|
{"string[]", Type{IsSlice: true, SliceSize: -1, Kind: reflect.String, T: StringTy, Size: -1, Elem: &Type{Kind: reflect.String, T: StringTy, Size: -1, stringKind: "string"}, stringKind: "string[]"}},
|
||||||
{"string[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{Kind: reflect.String, Size: -1, T: StringTy, stringKind: "string"}, stringKind: "string[2]"}},
|
{"string[2]", Type{IsArray: true, SliceSize: 2, Kind: reflect.String, T: StringTy, Size: -1, Elem: &Type{Kind: reflect.String, T: StringTy, Size: -1, stringKind: "string"}, stringKind: "string[2]"}},
|
||||||
{"address", Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}},
|
{"address", Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}},
|
||||||
{"address[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}},
|
{"address[]", Type{IsSlice: true, SliceSize: -1,Kind: reflect.Array, Type:address_t, T: AddressTy, Size:20, Elem: &Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}},
|
||||||
{"address[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}},
|
{"address[2]", Type{IsArray: true, SliceSize: 2,Kind: reflect.Array, Type:address_t, T: AddressTy, Size:20, Elem: &Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}},
|
||||||
|
|
||||||
// TODO when fixed types are implemented properly
|
// TODO when fixed types are implemented properly
|
||||||
// {"fixed", Type{}},
|
// {"fixed", Type{}},
|
||||||
|
Loading…
Reference in New Issue
Block a user