mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-28 15:46:43 +00:00
Merge 5fbce1ad39 into 061889d4ea
This commit is contained in:
commit
489ce69695
3 changed files with 53 additions and 3 deletions
|
|
@ -304,12 +304,21 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
|
|||
// struct will match named return values to the struct's field
|
||||
// names
|
||||
case reflect.Struct:
|
||||
idx := 0
|
||||
for i := 0; i < len(method.Outputs); i++ {
|
||||
marshalledValue, err := toGoType(i, method.Outputs[i], output)
|
||||
marshalledValue, err := toGoType(idx, method.Outputs[i], output)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reflectValue := reflect.ValueOf(marshalledValue)
|
||||
kind := reflectValue.Type().Kind()
|
||||
if (kind == reflect.Array || kind == reflect.Slice) &&
|
||||
reflectValue.Type().Elem().Kind() != reflect.Uint8 {
|
||||
// This is a slice of something other than bytes.
|
||||
idx += reflectValue.Len()
|
||||
} else {
|
||||
idx++
|
||||
}
|
||||
|
||||
for j := 0; j < typ.NumField(); j++ {
|
||||
field := typ.Field(j)
|
||||
|
|
|
|||
|
|
@ -1002,7 +1002,8 @@ func TestUnmarshal(t *testing.T) {
|
|||
{ "name" : "intArraySingle", "constant" : false, "outputs": [ { "type": "uint256[3]" } ] },
|
||||
{ "name" : "addressSliceSingle", "constant" : false, "outputs": [ { "type": "address[]" } ] },
|
||||
{ "name" : "addressSliceDouble", "constant" : false, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] },
|
||||
{ "name" : "mixedBytes", "constant" : true, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]`
|
||||
{ "name" : "mixedBytes", "constant" : true, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] },
|
||||
{ "name" : "arraysStruct", "constant" : true, "outputs": [ { "name": "a", "type": "bytes4[2]" }, { "name": "b", "type": "bytes20[2]" } ] }]`
|
||||
|
||||
abi, err := JSON(strings.NewReader(definition))
|
||||
if err != nil {
|
||||
|
|
@ -1238,4 +1239,37 @@ func TestUnmarshal(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Fatal("expected error:", err)
|
||||
}
|
||||
|
||||
// marshal arrays of arrays
|
||||
buff.Reset()
|
||||
buff.Write(common.Hex2Bytes("0000000100000000000000000000000000000000000000000000000000000000")) // a[0]
|
||||
buff.Write(common.Hex2Bytes("0000000200000000000000000000000000000000000000000000000000000000")) // a[1]
|
||||
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000003000000000000000000000000")) // b[0]
|
||||
buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000004000000000000000000000000")) // b[1]
|
||||
|
||||
var arraysStruct struct {
|
||||
A [2][4]byte
|
||||
B [2][20]byte
|
||||
}
|
||||
err = abi.Unpack(&arraysStruct, "arraysStruct", buff.Bytes())
|
||||
if err != nil {
|
||||
t.Fatal("didn't expect error:", err)
|
||||
}
|
||||
|
||||
exp4 := [4]byte{0, 0, 0, 1}
|
||||
if arraysStruct.A[0] != exp4 {
|
||||
t.Errorf("expected %x, got %x", exp4, arraysStruct.A[0])
|
||||
}
|
||||
exp4 = [4]byte{0, 0, 0, 2}
|
||||
if arraysStruct.A[1] != exp4 {
|
||||
t.Errorf("expected %x, got %x", exp4, arraysStruct.A[1])
|
||||
}
|
||||
exp20 := [20]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3}
|
||||
if arraysStruct.B[0] != exp20 {
|
||||
t.Errorf("expected %x, got %x", exp20, arraysStruct.B[0])
|
||||
}
|
||||
exp20 = [20]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}
|
||||
if arraysStruct.B[1] != exp20 {
|
||||
t.Errorf("expected %x, got %x", exp20, arraysStruct.B[1])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,14 @@ func set(dst, src reflect.Value, output Argument) error {
|
|||
if dst.Len() < output.Type.SliceSize {
|
||||
return fmt.Errorf("abi: cannot unmarshal src (len=%d) in to dst (len=%d)", output.Type.SliceSize, dst.Len())
|
||||
}
|
||||
reflect.Copy(dst, src)
|
||||
switch dstType.Elem().Kind() {
|
||||
case reflect.Array:
|
||||
for i := 0; i < dst.Len(); i++ {
|
||||
reflect.Copy(dst.Index(i), src.Index(i))
|
||||
}
|
||||
default:
|
||||
reflect.Copy(dst, src)
|
||||
}
|
||||
case dstType.Kind() == reflect.Interface:
|
||||
dst.Set(src)
|
||||
case dstType.Kind() == reflect.Ptr:
|
||||
|
|
|
|||
Loading…
Reference in a new issue