diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index c3d49da66..3af8d41c6 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -91,8 +91,31 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) { // first we need to create a slice of the type var refSlice reflect.Value switch elem.T { - case IntTy, UintTy, BoolTy: // int, uint, bool can all be of type big int. - refSlice = reflect.ValueOf([]*big.Int(nil)) + case IntTy, UintTy, BoolTy: //we need to create the correct type of array otherwise we see the following issue; + //cannot unmarshal []*big.Int in to []uint32 as described in + //https://github.com/ethereum/go-ethereum/issues/2802 + 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 refSlice = reflect.ValueOf([]common.Address(nil)) case HashTy: // hash must be of slice hash @@ -147,7 +170,27 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) { // set inter to the correct type (cast) switch elem.T { 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: inter = common.BytesToBig(returnOutput).Uint64() > 0 case AddressTy: diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 2bd341bd2..6fde7bf71 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -91,7 +91,11 @@ func NewType(t string) (typ Type, err error) { } typ.Elem = &sliceType 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 { + return typ, nil + } } // parse the type and size of the abi-type.