diff options
Diffstat (limited to 'accounts/abi/type.go')
-rw-r--r-- | accounts/abi/type.go | 119 |
1 files changed, 56 insertions, 63 deletions
diff --git a/accounts/abi/type.go b/accounts/abi/type.go index c08b744f7..18cd04672 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -96,63 +96,57 @@ func NewType(t string) (typ Type, err error) { t += "256" } - if isslice { + switch vtype { + case "int": + typ.Kind = reflect.Ptr + typ.Type = big_t + typ.Size = 256 + typ.T = IntTy + case "uint": + typ.Kind = reflect.Ptr + typ.Type = ubig_t + typ.Size = 256 + typ.T = UintTy + case "bool": + typ.Kind = reflect.Bool + typ.T = BoolTy + case "real": // TODO + typ.Kind = reflect.Invalid + case "address": typ.Kind = reflect.Slice - typ.Size = size - switch vtype { - case "int": - typ.Type = big_ts - case "uint": - typ.Type = ubig_ts - default: - return Type{}, fmt.Errorf("unsupported arg slice type: %s", t) - } - } else { - switch vtype { - case "int": - typ.Kind = reflect.Ptr - typ.Type = big_t - typ.Size = 256 - typ.T = IntTy - case "uint": - typ.Kind = reflect.Ptr - typ.Type = ubig_t - typ.Size = 256 - typ.T = UintTy - case "bool": - typ.Kind = reflect.Bool - typ.T = BoolTy - case "real": // TODO - typ.Kind = reflect.Invalid - case "address": - typ.Kind = reflect.Slice - typ.Type = address_t - typ.Size = 20 - typ.T = AddressTy - case "string": - typ.Kind = reflect.String - typ.Size = -1 - typ.T = StringTy - if vsize > 0 { - typ.Size = 32 - } - case "hash": - typ.Kind = reflect.Slice + typ.Type = address_t + typ.Size = 20 + typ.T = AddressTy + case "string": + typ.Kind = reflect.String + typ.Size = -1 + typ.T = StringTy + if vsize > 0 { typ.Size = 32 - typ.Type = hash_t - typ.T = HashTy - case "bytes": - typ.Kind = reflect.Slice - typ.Type = byte_ts - typ.Size = vsize - if vsize == 0 { - typ.T = BytesTy - } else { - typ.T = FixedBytesTy - } - default: - return Type{}, fmt.Errorf("unsupported arg type: %s", t) } + case "hash": + typ.Kind = reflect.Slice + typ.Size = 32 + typ.Type = hash_t + typ.T = HashTy + case "bytes": + typ.Kind = reflect.Slice + typ.Type = byte_ts + typ.Size = vsize + if vsize == 0 { + typ.T = BytesTy + } else { + typ.T = FixedBytesTy + } + default: + return Type{}, fmt.Errorf("unsupported arg type: %s", t) + } + + // if the type is a slice we must set Kind to a reflect.Slice + // so that serialisation can be determined based on this kind. + if isslice { + typ.Kind = reflect.Slice + typ.Size = size } typ.stringKind = t @@ -203,7 +197,7 @@ func (t Type) pack(v interface{}) ([]byte, error) { return packBytesSlice([]byte(value.String()), value.Len()), nil case reflect.Slice: - // if the param is a bytes type, pack the slice up as a string + // Byte slice is a special case, it gets treated as a single value if t.T == BytesTy { return packBytesSlice(value.Bytes(), value.Len()), nil } @@ -212,21 +206,20 @@ func (t Type) pack(v interface{}) ([]byte, error) { return nil, fmt.Errorf("%v out of bound. %d for %d", value.Kind(), value.Len(), t.Size) } - // Address is a special slice. The slice acts as one rather than a list of elements. - if t.T == AddressTy { - return common.LeftPadBytes(v.([]byte), 32), nil - } - // Signed / Unsigned check - if (t.T != IntTy && isSigned(value)) || (t.T == UintTy && isSigned(value)) { + if value.Type() == big_t && (t.T != IntTy && isSigned(value)) || (t.T == UintTy && isSigned(value)) { return nil, fmt.Errorf("slice of incompatible types.") } var packed []byte for i := 0; i < value.Len(); i++ { - packed = append(packed, packNum(value.Index(i), t.T)...) + val, err := t.pack(value.Index(i).Interface()) + if err != nil { + return nil, err + } + packed = append(packed, val...) } - return packed, nil + return packBytesSlice(packed, value.Len()), nil case reflect.Bool: if value.Bool() { return common.LeftPadBytes(common.Big1.Bytes(), 32), nil |