accounts/abi: add support for function types (#3405)
This commit is contained in:
parent
06b381d1c9
commit
2126d81488
@ -169,7 +169,7 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
|
|||||||
// argument in T.
|
// argument in T.
|
||||||
func toGoType(i int, t Argument, output []byte) (interface{}, error) {
|
func toGoType(i int, t Argument, output []byte) (interface{}, error) {
|
||||||
// we need to treat slices differently
|
// we need to treat slices differently
|
||||||
if (t.Type.IsSlice || t.Type.IsArray) && t.Type.T != BytesTy && t.Type.T != StringTy && t.Type.T != FixedBytesTy {
|
if (t.Type.IsSlice || t.Type.IsArray) && t.Type.T != BytesTy && t.Type.T != StringTy && t.Type.T != FixedBytesTy && t.Type.T != FunctionTy {
|
||||||
return toGoSlice(i, t, output)
|
return toGoSlice(i, t, output)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +233,7 @@ func toGoType(i int, t Argument, output []byte) (interface{}, error) {
|
|||||||
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:
|
case BytesTy, FixedBytesTy, FunctionTy:
|
||||||
return returnOutput, nil
|
return returnOutput, nil
|
||||||
case StringTy:
|
case StringTy:
|
||||||
return string(returnOutput), nil
|
return string(returnOutput), nil
|
||||||
|
@ -81,6 +81,7 @@ func TestTypeCheck(t *testing.T) {
|
|||||||
{"bytes", common.Hash{1}, ""},
|
{"bytes", common.Hash{1}, ""},
|
||||||
{"string", "hello world", ""},
|
{"string", "hello world", ""},
|
||||||
{"bytes32[]", [][32]byte{[32]byte{}}, ""},
|
{"bytes32[]", [][32]byte{[32]byte{}}, ""},
|
||||||
|
{"function", [24]byte{}, ""},
|
||||||
} {
|
} {
|
||||||
typ, err := NewType(test.typ)
|
typ, err := NewType(test.typ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -197,6 +198,13 @@ func TestSimpleMethodUnpack(t *testing.T) {
|
|||||||
"interface",
|
"interface",
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
`[ { "type": "function" } ]`,
|
||||||
|
pad([]byte{1}, 32, false),
|
||||||
|
[24]byte{1},
|
||||||
|
"function",
|
||||||
|
"",
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
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))
|
||||||
@ -255,6 +263,10 @@ func TestSimpleMethodUnpack(t *testing.T) {
|
|||||||
var v common.Hash
|
var v common.Hash
|
||||||
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
||||||
outvar = v
|
outvar = v
|
||||||
|
case "function":
|
||||||
|
var v [24]byte
|
||||||
|
err = abi.Unpack(&v, "method", test.marshalledOutput)
|
||||||
|
outvar = v
|
||||||
case "interface":
|
case "interface":
|
||||||
err = abi.Unpack(&outvar, "method", test.marshalledOutput)
|
err = abi.Unpack(&outvar, "method", test.marshalledOutput)
|
||||||
default:
|
default:
|
||||||
@ -333,6 +345,7 @@ func TestPack(t *testing.T) {
|
|||||||
{"uint256[]", []*big.Int{big.NewInt(1), big.NewInt(2)}, formatSliceOutput([]byte{1}, []byte{2})},
|
{"uint256[]", []*big.Int{big.NewInt(1), big.NewInt(2)}, formatSliceOutput([]byte{1}, []byte{2})},
|
||||||
{"address[]", []common.Address{common.Address{1}, common.Address{2}}, formatSliceOutput(pad([]byte{1}, 20, false), pad([]byte{2}, 20, false))},
|
{"address[]", []common.Address{common.Address{1}, common.Address{2}}, formatSliceOutput(pad([]byte{1}, 20, false), pad([]byte{2}, 20, false))},
|
||||||
{"bytes32[]", []common.Hash{common.Hash{1}, common.Hash{2}}, formatSliceOutput(pad([]byte{1}, 32, false), pad([]byte{2}, 32, false))},
|
{"bytes32[]", []common.Hash{common.Hash{1}, common.Hash{2}}, formatSliceOutput(pad([]byte{1}, 32, false), pad([]byte{2}, 32, false))},
|
||||||
|
{"function", [24]byte{1}, pad([]byte{1}, 32, false)},
|
||||||
} {
|
} {
|
||||||
typ, err := NewType(test.typ)
|
typ, err := NewType(test.typ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -54,7 +54,7 @@ func packElement(t Type, reflectValue reflect.Value) []byte {
|
|||||||
reflectValue = mustArrayToByteSlice(reflectValue)
|
reflectValue = mustArrayToByteSlice(reflectValue)
|
||||||
}
|
}
|
||||||
return packBytesSlice(reflectValue.Bytes(), reflectValue.Len())
|
return packBytesSlice(reflectValue.Bytes(), reflectValue.Len())
|
||||||
case FixedBytesTy:
|
case FixedBytesTy, FunctionTy:
|
||||||
if reflectValue.Kind() == reflect.Array {
|
if reflectValue.Kind() == reflect.Array {
|
||||||
reflectValue = mustArrayToByteSlice(reflectValue)
|
reflectValue = mustArrayToByteSlice(reflectValue)
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ const (
|
|||||||
BytesTy
|
BytesTy
|
||||||
HashTy
|
HashTy
|
||||||
FixedpointTy
|
FixedpointTy
|
||||||
|
FunctionTy
|
||||||
)
|
)
|
||||||
|
|
||||||
// Type is the reflection of the supported argument type
|
// Type is the reflection of the supported argument type
|
||||||
@ -148,6 +149,12 @@ func NewType(t string) (typ Type, err error) {
|
|||||||
typ.T = FixedBytesTy
|
typ.T = FixedBytesTy
|
||||||
typ.SliceSize = varSize
|
typ.SliceSize = varSize
|
||||||
}
|
}
|
||||||
|
case "function":
|
||||||
|
sliceType, _ := NewType("uint8")
|
||||||
|
typ.Elem = &sliceType
|
||||||
|
typ.IsArray = true
|
||||||
|
typ.T = FunctionTy
|
||||||
|
typ.SliceSize = 24
|
||||||
default:
|
default:
|
||||||
return Type{}, fmt.Errorf("unsupported arg type: %s", t)
|
return Type{}, fmt.Errorf("unsupported arg type: %s", t)
|
||||||
}
|
}
|
||||||
@ -168,7 +175,7 @@ func (t Type) pack(v reflect.Value) ([]byte, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t.IsSlice || t.IsArray) && t.T != BytesTy && t.T != FixedBytesTy {
|
if (t.IsSlice || t.IsArray) && t.T != BytesTy && t.T != FixedBytesTy && t.T != FunctionTy {
|
||||||
var packed []byte
|
var packed []byte
|
||||||
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
for i := 0; i < v.Len(); i++ {
|
||||||
|
Loading…
Reference in New Issue
Block a user