account/abi: remove superfluous type checking (#21022)
* accounts/abi: added getType func to Type struct * accounts/abi: fixed tuple unpack * accounts/abi: removed type.Type * accounts/abi: added comment * accounts/abi: removed unused types * accounts/abi: removed superfluous declarations * accounts/abi: typo
This commit is contained in:
		
							parent
							
								
									44a3b8c04c
								
							
						
					
					
						commit
						933acf3389
					
				| @ -39,11 +39,11 @@ func formatSliceString(kind reflect.Kind, sliceSize int) string { | |||||||
| // type in t.
 | // type in t.
 | ||||||
| func sliceTypeCheck(t Type, val reflect.Value) error { | func sliceTypeCheck(t Type, val reflect.Value) error { | ||||||
| 	if val.Kind() != reflect.Slice && val.Kind() != reflect.Array { | 	if val.Kind() != reflect.Slice && val.Kind() != reflect.Array { | ||||||
| 		return typeErr(formatSliceString(t.Type.Kind(), t.Size), val.Type()) | 		return typeErr(formatSliceString(t.getType().Kind(), t.Size), val.Type()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if t.T == ArrayTy && val.Len() != t.Size { | 	if t.T == ArrayTy && val.Len() != t.Size { | ||||||
| 		return typeErr(formatSliceString(t.Elem.Type.Kind(), t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len())) | 		return typeErr(formatSliceString(t.Elem.getType().Kind(), t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len())) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if t.Elem.T == SliceTy || t.Elem.T == ArrayTy { | 	if t.Elem.T == SliceTy || t.Elem.T == ArrayTy { | ||||||
| @ -52,8 +52,8 @@ func sliceTypeCheck(t Type, val reflect.Value) error { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.Type.Kind() { | 	if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.getType().Kind() { | ||||||
| 		return typeErr(formatSliceString(t.Elem.Type.Kind(), t.Size), val.Type()) | 		return typeErr(formatSliceString(t.Elem.getType().Kind(), t.Size), val.Type()) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @ -66,10 +66,10 @@ func typeCheck(t Type, value reflect.Value) error { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Check base type validity. Element types will be checked later on.
 | 	// Check base type validity. Element types will be checked later on.
 | ||||||
| 	if t.Type.Kind() != value.Kind() { | 	if t.getType().Kind() != value.Kind() { | ||||||
| 		return typeErr(t.Type.Kind(), value.Kind()) | 		return typeErr(t.getType().Kind(), value.Kind()) | ||||||
| 	} else if t.T == FixedBytesTy && t.Size != value.Len() { | 	} else if t.T == FixedBytesTy && t.Size != value.Len() { | ||||||
| 		return typeErr(t.Type, value.Type()) | 		return typeErr(t.getType(), value.Type()) | ||||||
| 	} else { | 	} else { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -1,38 +0,0 @@ | |||||||
| // Copyright 2015 The go-ethereum Authors
 |  | ||||||
| // This file is part of the go-ethereum library.
 |  | ||||||
| //
 |  | ||||||
| // The go-ethereum library is free software: you can redistribute it and/or modify
 |  | ||||||
| // it under the terms of the GNU Lesser General Public License as published by
 |  | ||||||
| // the Free Software Foundation, either version 3 of the License, or
 |  | ||||||
| // (at your option) any later version.
 |  | ||||||
| //
 |  | ||||||
| // The go-ethereum library is distributed in the hope that it will be useful,
 |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 |  | ||||||
| // GNU Lesser General Public License for more details.
 |  | ||||||
| //
 |  | ||||||
| // You should have received a copy of the GNU Lesser General Public License
 |  | ||||||
| // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 |  | ||||||
| 
 |  | ||||||
| package abi |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"math/big" |  | ||||||
| 	"reflect" |  | ||||||
| 
 |  | ||||||
| 	"github.com/ethereum/go-ethereum/common" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	bigT      = reflect.TypeOf(&big.Int{}) |  | ||||||
| 	derefbigT = reflect.TypeOf(big.Int{}) |  | ||||||
| 	uint8T    = reflect.TypeOf(uint8(0)) |  | ||||||
| 	uint16T   = reflect.TypeOf(uint16(0)) |  | ||||||
| 	uint32T   = reflect.TypeOf(uint32(0)) |  | ||||||
| 	uint64T   = reflect.TypeOf(uint64(0)) |  | ||||||
| 	int8T     = reflect.TypeOf(int8(0)) |  | ||||||
| 	int16T    = reflect.TypeOf(int16(0)) |  | ||||||
| 	int32T    = reflect.TypeOf(int32(0)) |  | ||||||
| 	int64T    = reflect.TypeOf(int64(0)) |  | ||||||
| 	addressT  = reflect.TypeOf(common.Address{}) |  | ||||||
| ) |  | ||||||
| @ -18,6 +18,7 @@ package abi | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"math/big" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
| @ -25,7 +26,7 @@ import ( | |||||||
| // indirect recursively dereferences the value until it either gets the value
 | // indirect recursively dereferences the value until it either gets the value
 | ||||||
| // or finds a big.Int
 | // or finds a big.Int
 | ||||||
| func indirect(v reflect.Value) reflect.Value { | func indirect(v reflect.Value) reflect.Value { | ||||||
| 	if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbigT { | 	if v.Kind() == reflect.Ptr && v.Elem().Type() != reflect.TypeOf(big.Int{}) { | ||||||
| 		return indirect(v.Elem()) | 		return indirect(v.Elem()) | ||||||
| 	} | 	} | ||||||
| 	return v | 	return v | ||||||
| @ -45,26 +46,26 @@ func reflectIntType(unsigned bool, size int) reflect.Type { | |||||||
| 	if unsigned { | 	if unsigned { | ||||||
| 		switch size { | 		switch size { | ||||||
| 		case 8: | 		case 8: | ||||||
| 			return uint8T | 			return reflect.TypeOf(uint8(0)) | ||||||
| 		case 16: | 		case 16: | ||||||
| 			return uint16T | 			return reflect.TypeOf(uint16(0)) | ||||||
| 		case 32: | 		case 32: | ||||||
| 			return uint32T | 			return reflect.TypeOf(uint32(0)) | ||||||
| 		case 64: | 		case 64: | ||||||
| 			return uint64T | 			return reflect.TypeOf(uint64(0)) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	switch size { | 	switch size { | ||||||
| 	case 8: | 	case 8: | ||||||
| 		return int8T | 		return reflect.TypeOf(int8(0)) | ||||||
| 	case 16: | 	case 16: | ||||||
| 		return int16T | 		return reflect.TypeOf(int16(0)) | ||||||
| 	case 32: | 	case 32: | ||||||
| 		return int32T | 		return reflect.TypeOf(int32(0)) | ||||||
| 	case 64: | 	case 64: | ||||||
| 		return int64T | 		return reflect.TypeOf(int64(0)) | ||||||
| 	} | 	} | ||||||
| 	return bigT | 	return reflect.TypeOf(&big.Int{}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // mustArrayToBytesSlice creates a new byte slice with the exact same size as value
 | // mustArrayToBytesSlice creates a new byte slice with the exact same size as value
 | ||||||
| @ -84,7 +85,7 @@ func set(dst, src reflect.Value) error { | |||||||
| 	switch { | 	switch { | ||||||
| 	case dstType.Kind() == reflect.Interface && dst.Elem().IsValid(): | 	case dstType.Kind() == reflect.Interface && dst.Elem().IsValid(): | ||||||
| 		return set(dst.Elem(), src) | 		return set(dst.Elem(), src) | ||||||
| 	case dstType.Kind() == reflect.Ptr && dstType.Elem() != derefbigT: | 	case dstType.Kind() == reflect.Ptr && dstType.Elem() != reflect.TypeOf(big.Int{}): | ||||||
| 		return set(dst.Elem(), src) | 		return set(dst.Elem(), src) | ||||||
| 	case srcType.AssignableTo(dstType) && dst.CanSet(): | 	case srcType.AssignableTo(dstType) && dst.CanSet(): | ||||||
| 		dst.Set(src) | 		dst.Set(src) | ||||||
|  | |||||||
| @ -23,6 +23,8 @@ import ( | |||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/ethereum/go-ethereum/common" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Type enumerator
 | // Type enumerator
 | ||||||
| @ -45,16 +47,16 @@ const ( | |||||||
| // Type is the reflection of the supported argument type
 | // Type is the reflection of the supported argument type
 | ||||||
| type Type struct { | type Type struct { | ||||||
| 	Elem *Type | 	Elem *Type | ||||||
| 	Type reflect.Type |  | ||||||
| 	Size int | 	Size int | ||||||
| 	T    byte // Our own type checking
 | 	T    byte // Our own type checking
 | ||||||
| 
 | 
 | ||||||
| 	stringKind string // holds the unparsed string for deriving signatures
 | 	stringKind string // holds the unparsed string for deriving signatures
 | ||||||
| 
 | 
 | ||||||
| 	// Tuple relative fields
 | 	// Tuple relative fields
 | ||||||
| 	TupleRawName  string   // Raw struct name defined in source code, may be empty.
 | 	TupleRawName  string       // Raw struct name defined in source code, may be empty.
 | ||||||
| 	TupleElems    []*Type  // Type information of all tuple fields
 | 	TupleElems    []*Type      // Type information of all tuple fields
 | ||||||
| 	TupleRawNames []string // Raw field name of all tuple fields
 | 	TupleRawNames []string     // Raw field name of all tuple fields
 | ||||||
|  | 	TupleType     reflect.Type // Underlying struct of the tuple
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| @ -94,7 +96,6 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty | |||||||
| 			// is a slice
 | 			// is a slice
 | ||||||
| 			typ.T = SliceTy | 			typ.T = SliceTy | ||||||
| 			typ.Elem = &embeddedType | 			typ.Elem = &embeddedType | ||||||
| 			typ.Type = reflect.SliceOf(embeddedType.Type) |  | ||||||
| 			typ.stringKind = embeddedType.stringKind + sliced | 			typ.stringKind = embeddedType.stringKind + sliced | ||||||
| 		} else if len(intz) == 1 { | 		} else if len(intz) == 1 { | ||||||
| 			// is a array
 | 			// is a array
 | ||||||
| @ -104,7 +105,6 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty | |||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err) | 				return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err) | ||||||
| 			} | 			} | ||||||
| 			typ.Type = reflect.ArrayOf(typ.Size, embeddedType.Type) |  | ||||||
| 			typ.stringKind = embeddedType.stringKind + sliced | 			typ.stringKind = embeddedType.stringKind + sliced | ||||||
| 		} else { | 		} else { | ||||||
| 			return Type{}, fmt.Errorf("invalid formatting of array type") | 			return Type{}, fmt.Errorf("invalid formatting of array type") | ||||||
| @ -136,31 +136,24 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty | |||||||
| 	// varType is the parsed abi type
 | 	// varType is the parsed abi type
 | ||||||
| 	switch varType := parsedType[1]; varType { | 	switch varType := parsedType[1]; varType { | ||||||
| 	case "int": | 	case "int": | ||||||
| 		typ.Type = reflectIntType(false, varSize) |  | ||||||
| 		typ.Size = varSize | 		typ.Size = varSize | ||||||
| 		typ.T = IntTy | 		typ.T = IntTy | ||||||
| 	case "uint": | 	case "uint": | ||||||
| 		typ.Type = reflectIntType(true, varSize) |  | ||||||
| 		typ.Size = varSize | 		typ.Size = varSize | ||||||
| 		typ.T = UintTy | 		typ.T = UintTy | ||||||
| 	case "bool": | 	case "bool": | ||||||
| 		typ.T = BoolTy | 		typ.T = BoolTy | ||||||
| 		typ.Type = reflect.TypeOf(bool(false)) |  | ||||||
| 	case "address": | 	case "address": | ||||||
| 		typ.Type = addressT |  | ||||||
| 		typ.Size = 20 | 		typ.Size = 20 | ||||||
| 		typ.T = AddressTy | 		typ.T = AddressTy | ||||||
| 	case "string": | 	case "string": | ||||||
| 		typ.Type = reflect.TypeOf("") |  | ||||||
| 		typ.T = StringTy | 		typ.T = StringTy | ||||||
| 	case "bytes": | 	case "bytes": | ||||||
| 		if varSize == 0 { | 		if varSize == 0 { | ||||||
| 			typ.T = BytesTy | 			typ.T = BytesTy | ||||||
| 			typ.Type = reflect.SliceOf(reflect.TypeOf(byte(0))) |  | ||||||
| 		} else { | 		} else { | ||||||
| 			typ.T = FixedBytesTy | 			typ.T = FixedBytesTy | ||||||
| 			typ.Size = varSize | 			typ.Size = varSize | ||||||
| 			typ.Type = reflect.ArrayOf(varSize, reflect.TypeOf(byte(0))) |  | ||||||
| 		} | 		} | ||||||
| 	case "tuple": | 	case "tuple": | ||||||
| 		var ( | 		var ( | ||||||
| @ -180,7 +173,7 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty | |||||||
| 			} | 			} | ||||||
| 			fields = append(fields, reflect.StructField{ | 			fields = append(fields, reflect.StructField{ | ||||||
| 				Name: ToCamelCase(c.Name), // reflect.StructOf will panic for any exported field.
 | 				Name: ToCamelCase(c.Name), // reflect.StructOf will panic for any exported field.
 | ||||||
| 				Type: cType.Type, | 				Type: cType.getType(), | ||||||
| 				Tag:  reflect.StructTag("json:\"" + c.Name + "\""), | 				Tag:  reflect.StructTag("json:\"" + c.Name + "\""), | ||||||
| 			}) | 			}) | ||||||
| 			elems = append(elems, &cType) | 			elems = append(elems, &cType) | ||||||
| @ -191,7 +184,8 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		expression += ")" | 		expression += ")" | ||||||
| 		typ.Type = reflect.StructOf(fields) | 
 | ||||||
|  | 		typ.TupleType = reflect.StructOf(fields) | ||||||
| 		typ.TupleElems = elems | 		typ.TupleElems = elems | ||||||
| 		typ.TupleRawNames = names | 		typ.TupleRawNames = names | ||||||
| 		typ.T = TupleTy | 		typ.T = TupleTy | ||||||
| @ -210,7 +204,6 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty | |||||||
| 	case "function": | 	case "function": | ||||||
| 		typ.T = FunctionTy | 		typ.T = FunctionTy | ||||||
| 		typ.Size = 24 | 		typ.Size = 24 | ||||||
| 		typ.Type = reflect.ArrayOf(24, reflect.TypeOf(byte(0))) |  | ||||||
| 	default: | 	default: | ||||||
| 		return Type{}, fmt.Errorf("unsupported arg type: %s", t) | 		return Type{}, fmt.Errorf("unsupported arg type: %s", t) | ||||||
| 	} | 	} | ||||||
| @ -218,6 +211,41 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty | |||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (t Type) getType() reflect.Type { | ||||||
|  | 	switch t.T { | ||||||
|  | 	case IntTy: | ||||||
|  | 		return reflectIntType(false, t.Size) | ||||||
|  | 	case UintTy: | ||||||
|  | 		return reflectIntType(true, t.Size) | ||||||
|  | 	case BoolTy: | ||||||
|  | 		return reflect.TypeOf(false) | ||||||
|  | 	case StringTy: | ||||||
|  | 		return reflect.TypeOf("") | ||||||
|  | 	case SliceTy: | ||||||
|  | 		return reflect.SliceOf(t.Elem.getType()) | ||||||
|  | 	case ArrayTy: | ||||||
|  | 		return reflect.ArrayOf(t.Size, t.Elem.getType()) | ||||||
|  | 	case TupleTy: | ||||||
|  | 		return t.TupleType | ||||||
|  | 	case AddressTy: | ||||||
|  | 		return reflect.TypeOf(common.Address{}) | ||||||
|  | 	case FixedBytesTy: | ||||||
|  | 		return reflect.ArrayOf(t.Size, reflect.TypeOf(byte(0))) | ||||||
|  | 	case BytesTy: | ||||||
|  | 		return reflect.SliceOf(reflect.TypeOf(byte(0))) | ||||||
|  | 	case HashTy: | ||||||
|  | 		// hashtype currently not used
 | ||||||
|  | 		return reflect.ArrayOf(32, reflect.TypeOf(byte(0))) | ||||||
|  | 	case FixedPointTy: | ||||||
|  | 		// fixedpoint type currently not used
 | ||||||
|  | 		return reflect.ArrayOf(32, reflect.TypeOf(byte(0))) | ||||||
|  | 	case FunctionTy: | ||||||
|  | 		return reflect.ArrayOf(24, reflect.TypeOf(byte(0))) | ||||||
|  | 	default: | ||||||
|  | 		panic("Invalid type") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // String implements Stringer
 | // String implements Stringer
 | ||||||
| func (t Type) String() (out string) { | func (t Type) String() (out string) { | ||||||
| 	return t.stringKind | 	return t.stringKind | ||||||
|  | |||||||
| @ -36,58 +36,58 @@ func TestTypeRegexp(t *testing.T) { | |||||||
| 		components []ArgumentMarshaling | 		components []ArgumentMarshaling | ||||||
| 		kind       Type | 		kind       Type | ||||||
| 	}{ | 	}{ | ||||||
| 		{"bool", nil, Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}}, | 		{"bool", nil, Type{T: BoolTy, stringKind: "bool"}}, | ||||||
| 		{"bool[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]bool(nil)), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}}, | 		{"bool[]", nil, Type{T: SliceTy, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[]"}}, | ||||||
| 		{"bool[2]", nil, Type{Size: 2, T: ArrayTy, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}}, | 		{"bool[2]", nil, Type{Size: 2, T: ArrayTy, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[2]"}}, | ||||||
| 		{"bool[2][]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}}, | 		{"bool[2][]", nil, Type{T: SliceTy, Elem: &Type{T: ArrayTy, Size: 2, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}}, | ||||||
| 		{"bool[][]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}}, | 		{"bool[][]", nil, Type{T: SliceTy, Elem: &Type{T: SliceTy, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}}, | ||||||
| 		{"bool[][2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}}, | 		{"bool[][2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: SliceTy, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}}, | ||||||
| 		{"bool[2][2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}}, | 		{"bool[2][2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: ArrayTy, Size: 2, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}}, | ||||||
| 		{"bool[2][][2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][][2]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}, stringKind: "bool[2][][2]"}}, | 		{"bool[2][][2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: SliceTy, Elem: &Type{T: ArrayTy, Size: 2, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}, stringKind: "bool[2][][2]"}}, | ||||||
| 		{"bool[2][2][2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}, stringKind: "bool[2][2][2]"}}, | 		{"bool[2][2][2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: ArrayTy, Size: 2, Elem: &Type{T: ArrayTy, Size: 2, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}, stringKind: "bool[2][2][2]"}}, | ||||||
| 		{"bool[][][]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}, stringKind: "bool[][][]"}}, | 		{"bool[][][]", nil, Type{T: SliceTy, Elem: &Type{T: SliceTy, Elem: &Type{T: SliceTy, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}, stringKind: "bool[][][]"}}, | ||||||
| 		{"bool[][2][]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][2][]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}, stringKind: "bool[][2][]"}}, | 		{"bool[][2][]", nil, Type{T: SliceTy, Elem: &Type{T: ArrayTy, Size: 2, Elem: &Type{T: SliceTy, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}, stringKind: "bool[][2][]"}}, | ||||||
| 		{"int8", nil, Type{Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}}, | 		{"int8", nil, Type{Size: 8, T: IntTy, stringKind: "int8"}}, | ||||||
| 		{"int16", nil, Type{Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}}, | 		{"int16", nil, Type{Size: 16, T: IntTy, stringKind: "int16"}}, | ||||||
| 		{"int32", nil, Type{Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}}, | 		{"int32", nil, Type{Size: 32, T: IntTy, stringKind: "int32"}}, | ||||||
| 		{"int64", nil, Type{Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}}, | 		{"int64", nil, Type{Size: 64, T: IntTy, stringKind: "int64"}}, | ||||||
| 		{"int256", nil, Type{Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}}, | 		{"int256", nil, Type{Size: 256, T: IntTy, stringKind: "int256"}}, | ||||||
| 		{"int8[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]int8{}), Elem: &Type{Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[]"}}, | 		{"int8[]", nil, Type{T: SliceTy, Elem: &Type{Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[]"}}, | ||||||
| 		{"int8[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int8{}), Elem: &Type{Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[2]"}}, | 		{"int8[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[2]"}}, | ||||||
| 		{"int16[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]int16{}), Elem: &Type{Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[]"}}, | 		{"int16[]", nil, Type{T: SliceTy, Elem: &Type{Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[]"}}, | ||||||
| 		{"int16[2]", nil, Type{Size: 2, T: ArrayTy, Type: reflect.TypeOf([2]int16{}), Elem: &Type{Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[2]"}}, | 		{"int16[2]", nil, Type{Size: 2, T: ArrayTy, Elem: &Type{Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[2]"}}, | ||||||
| 		{"int32[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]int32{}), Elem: &Type{Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, | 		{"int32[]", nil, Type{T: SliceTy, Elem: &Type{Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, | ||||||
| 		{"int32[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int32{}), Elem: &Type{Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, | 		{"int32[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, | ||||||
| 		{"int64[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]int64{}), Elem: &Type{Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[]"}}, | 		{"int64[]", nil, Type{T: SliceTy, Elem: &Type{Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[]"}}, | ||||||
| 		{"int64[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int64{}), Elem: &Type{Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[2]"}}, | 		{"int64[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[2]"}}, | ||||||
| 		{"int256[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, | 		{"int256[]", nil, Type{T: SliceTy, Elem: &Type{Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, | ||||||
| 		{"int256[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]*big.Int{}), Elem: &Type{Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, | 		{"int256[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, | ||||||
| 		{"uint8", nil, Type{Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}}, | 		{"uint8", nil, Type{Size: 8, T: UintTy, stringKind: "uint8"}}, | ||||||
| 		{"uint16", nil, Type{Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}}, | 		{"uint16", nil, Type{Size: 16, T: UintTy, stringKind: "uint16"}}, | ||||||
| 		{"uint32", nil, Type{Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}}, | 		{"uint32", nil, Type{Size: 32, T: UintTy, stringKind: "uint32"}}, | ||||||
| 		{"uint64", nil, Type{Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}}, | 		{"uint64", nil, Type{Size: 64, T: UintTy, stringKind: "uint64"}}, | ||||||
| 		{"uint256", nil, Type{Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}}, | 		{"uint256", nil, Type{Size: 256, T: UintTy, stringKind: "uint256"}}, | ||||||
| 		{"uint8[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]uint8{}), Elem: &Type{Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[]"}}, | 		{"uint8[]", nil, Type{T: SliceTy, Elem: &Type{Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[]"}}, | ||||||
| 		{"uint8[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint8{}), Elem: &Type{Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[2]"}}, | 		{"uint8[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[2]"}}, | ||||||
| 		{"uint16[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]uint16{}), Elem: &Type{Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[]"}}, | 		{"uint16[]", nil, Type{T: SliceTy, Elem: &Type{Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[]"}}, | ||||||
| 		{"uint16[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint16{}), Elem: &Type{Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[2]"}}, | 		{"uint16[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[2]"}}, | ||||||
| 		{"uint32[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]uint32{}), Elem: &Type{Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, | 		{"uint32[]", nil, Type{T: SliceTy, Elem: &Type{Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, | ||||||
| 		{"uint32[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint32{}), Elem: &Type{Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, | 		{"uint32[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, | ||||||
| 		{"uint64[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]uint64{}), Elem: &Type{Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[]"}}, | 		{"uint64[]", nil, Type{T: SliceTy, Elem: &Type{Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[]"}}, | ||||||
| 		{"uint64[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint64{}), Elem: &Type{Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[2]"}}, | 		{"uint64[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[2]"}}, | ||||||
| 		{"uint256[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, | 		{"uint256[]", nil, Type{T: SliceTy, Elem: &Type{Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, | ||||||
| 		{"uint256[2]", nil, Type{T: ArrayTy, Type: reflect.TypeOf([2]*big.Int{}), Size: 2, Elem: &Type{Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, | 		{"uint256[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, | ||||||
| 		{"bytes32", nil, Type{T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}}, | 		{"bytes32", nil, Type{T: FixedBytesTy, Size: 32, stringKind: "bytes32"}}, | ||||||
| 		{"bytes[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][]byte{}), Elem: &Type{Type: reflect.TypeOf([]byte{}), T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}}, | 		{"bytes[]", nil, Type{T: SliceTy, Elem: &Type{T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}}, | ||||||
| 		{"bytes[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]byte{}), Elem: &Type{T: BytesTy, Type: reflect.TypeOf([]byte{}), stringKind: "bytes"}, stringKind: "bytes[2]"}}, | 		{"bytes[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[2]"}}, | ||||||
| 		{"bytes32[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][32]byte{}), Elem: &Type{Type: reflect.TypeOf([32]byte{}), T: FixedBytesTy, Size: 32, stringKind: "bytes32"}, stringKind: "bytes32[]"}}, | 		{"bytes32[]", nil, Type{T: SliceTy, Elem: &Type{T: FixedBytesTy, Size: 32, stringKind: "bytes32"}, stringKind: "bytes32[]"}}, | ||||||
| 		{"bytes32[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][32]byte{}), Elem: &Type{T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}, stringKind: "bytes32[2]"}}, | 		{"bytes32[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: FixedBytesTy, Size: 32, stringKind: "bytes32"}, stringKind: "bytes32[2]"}}, | ||||||
| 		{"string", nil, Type{T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}}, | 		{"string", nil, Type{T: StringTy, stringKind: "string"}}, | ||||||
| 		{"string[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]string{}), Elem: &Type{Type: reflect.TypeOf(""), T: StringTy, stringKind: "string"}, stringKind: "string[]"}}, | 		{"string[]", nil, Type{T: SliceTy, Elem: &Type{T: StringTy, stringKind: "string"}, stringKind: "string[]"}}, | ||||||
| 		{"string[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]string{}), Elem: &Type{T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}, stringKind: "string[2]"}}, | 		{"string[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: StringTy, stringKind: "string"}, stringKind: "string[2]"}}, | ||||||
| 		{"address", nil, Type{Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}}, | 		{"address", nil, Type{Size: 20, T: AddressTy, stringKind: "address"}}, | ||||||
| 		{"address[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]common.Address{}), Elem: &Type{Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, | 		{"address[]", nil, Type{T: SliceTy, Elem: &Type{Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, | ||||||
| 		{"address[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]common.Address{}), Elem: &Type{Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, | 		{"address[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, | ||||||
| 		// TODO when fixed types are implemented properly
 | 		// TODO when fixed types are implemented properly
 | ||||||
| 		// {"fixed", nil, Type{}},
 | 		// {"fixed", nil, Type{}},
 | ||||||
| 		// {"fixed128x128", nil, Type{}},
 | 		// {"fixed128x128", nil, Type{}},
 | ||||||
| @ -95,14 +95,14 @@ func TestTypeRegexp(t *testing.T) { | |||||||
| 		// {"fixed[2]", nil, Type{}},
 | 		// {"fixed[2]", nil, Type{}},
 | ||||||
| 		// {"fixed128x128[]", nil, Type{}},
 | 		// {"fixed128x128[]", nil, Type{}},
 | ||||||
| 		// {"fixed128x128[2]", nil, Type{}},
 | 		// {"fixed128x128[2]", nil, Type{}},
 | ||||||
| 		{"tuple", []ArgumentMarshaling{{Name: "a", Type: "int64"}}, Type{T: TupleTy, Type: reflect.TypeOf(struct { | 		{"tuple", []ArgumentMarshaling{{Name: "a", Type: "int64"}}, Type{T: TupleTy, TupleType: reflect.TypeOf(struct { | ||||||
| 			A int64 `json:"a"` | 			A int64 `json:"a"` | ||||||
| 		}{}), stringKind: "(int64)", | 		}{}), stringKind: "(int64)", | ||||||
| 			TupleElems: []*Type{{T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"a"}}}, | 			TupleElems: []*Type{{T: IntTy, Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"a"}}}, | ||||||
| 		{"tuple with long name", []ArgumentMarshaling{{Name: "aTypicalParamName", Type: "int64"}}, Type{T: TupleTy, Type: reflect.TypeOf(struct { | 		{"tuple with long name", []ArgumentMarshaling{{Name: "aTypicalParamName", Type: "int64"}}, Type{T: TupleTy, TupleType: reflect.TypeOf(struct { | ||||||
| 			ATypicalParamName int64 `json:"aTypicalParamName"` | 			ATypicalParamName int64 `json:"aTypicalParamName"` | ||||||
| 		}{}), stringKind: "(int64)", | 		}{}), stringKind: "(int64)", | ||||||
| 			TupleElems: []*Type{{T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"aTypicalParamName"}}}, | 			TupleElems: []*Type{{T: IntTy, Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"aTypicalParamName"}}}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, tt := range tests { | 	for _, tt := range tests { | ||||||
| @ -312,12 +312,12 @@ func TestInternalType(t *testing.T) { | |||||||
| 	internalType := "struct a.b[]" | 	internalType := "struct a.b[]" | ||||||
| 	kind := Type{ | 	kind := Type{ | ||||||
| 		T: TupleTy, | 		T: TupleTy, | ||||||
| 		Type: reflect.TypeOf(struct { | 		TupleType: reflect.TypeOf(struct { | ||||||
| 			A int64 `json:"a"` | 			A int64 `json:"a"` | ||||||
| 		}{}), | 		}{}), | ||||||
| 		stringKind:    "(int64)", | 		stringKind:    "(int64)", | ||||||
| 		TupleRawName:  "ab[]", | 		TupleRawName:  "ab[]", | ||||||
| 		TupleElems:    []*Type{{T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, | 		TupleElems:    []*Type{{T: IntTy, Size: 64, stringKind: "int64"}}, | ||||||
| 		TupleRawNames: []string{"a"}, | 		TupleRawNames: []string{"a"}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -34,32 +34,36 @@ var ( | |||||||
| 
 | 
 | ||||||
| // ReadInteger reads the integer based on its kind and returns the appropriate value
 | // ReadInteger reads the integer based on its kind and returns the appropriate value
 | ||||||
| func ReadInteger(typ Type, b []byte) interface{} { | func ReadInteger(typ Type, b []byte) interface{} { | ||||||
| 	switch typ.Type { | 	if typ.T == UintTy { | ||||||
| 	case uint8T: | 		switch typ.Size { | ||||||
| 		return b[len(b)-1] | 		case 8: | ||||||
| 	case uint16T: | 			return b[len(b)-1] | ||||||
| 		return binary.BigEndian.Uint16(b[len(b)-2:]) | 		case 16: | ||||||
| 	case uint32T: | 			return binary.BigEndian.Uint16(b[len(b)-2:]) | ||||||
| 		return binary.BigEndian.Uint32(b[len(b)-4:]) | 		case 32: | ||||||
| 	case uint64T: | 			return binary.BigEndian.Uint32(b[len(b)-4:]) | ||||||
| 		return binary.BigEndian.Uint64(b[len(b)-8:]) | 		case 64: | ||||||
| 	case int8T: | 			return binary.BigEndian.Uint64(b[len(b)-8:]) | ||||||
|  | 		default: | ||||||
|  | 			// the only case left for unsigned integer is uint256.
 | ||||||
|  | 			return new(big.Int).SetBytes(b) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	switch typ.Size { | ||||||
|  | 	case 8: | ||||||
| 		return int8(b[len(b)-1]) | 		return int8(b[len(b)-1]) | ||||||
| 	case int16T: | 	case 16: | ||||||
| 		return int16(binary.BigEndian.Uint16(b[len(b)-2:])) | 		return int16(binary.BigEndian.Uint16(b[len(b)-2:])) | ||||||
| 	case int32T: | 	case 32: | ||||||
| 		return int32(binary.BigEndian.Uint32(b[len(b)-4:])) | 		return int32(binary.BigEndian.Uint32(b[len(b)-4:])) | ||||||
| 	case int64T: | 	case 64: | ||||||
| 		return int64(binary.BigEndian.Uint64(b[len(b)-8:])) | 		return int64(binary.BigEndian.Uint64(b[len(b)-8:])) | ||||||
| 	default: | 	default: | ||||||
| 		// the only case left for integer is int256/uint256.
 | 		// the only case left for integer is int256
 | ||||||
| 		ret := new(big.Int).SetBytes(b) |  | ||||||
| 		if typ.T == UintTy { |  | ||||||
| 			return ret |  | ||||||
| 		} |  | ||||||
| 		// big.SetBytes can't tell if a number is negative or positive in itself.
 | 		// big.SetBytes can't tell if a number is negative or positive in itself.
 | ||||||
| 		// On EVM, if the returned number > max int256, it is negative.
 | 		// On EVM, if the returned number > max int256, it is negative.
 | ||||||
| 		// A number is > max int256 if the bit at position 255 is set.
 | 		// A number is > max int256 if the bit at position 255 is set.
 | ||||||
|  | 		ret := new(big.Int).SetBytes(b) | ||||||
| 		if ret.Bit(255) == 1 { | 		if ret.Bit(255) == 1 { | ||||||
| 			ret.Add(MaxUint256, new(big.Int).Neg(ret)) | 			ret.Add(MaxUint256, new(big.Int).Neg(ret)) | ||||||
| 			ret.Add(ret, common.Big1) | 			ret.Add(ret, common.Big1) | ||||||
| @ -106,7 +110,7 @@ func ReadFixedBytes(t Type, word []byte) (interface{}, error) { | |||||||
| 		return nil, fmt.Errorf("abi: invalid type in call to make fixed byte array") | 		return nil, fmt.Errorf("abi: invalid type in call to make fixed byte array") | ||||||
| 	} | 	} | ||||||
| 	// convert
 | 	// convert
 | ||||||
| 	array := reflect.New(t.Type).Elem() | 	array := reflect.New(t.getType()).Elem() | ||||||
| 
 | 
 | ||||||
| 	reflect.Copy(array, reflect.ValueOf(word[0:t.Size])) | 	reflect.Copy(array, reflect.ValueOf(word[0:t.Size])) | ||||||
| 	return array.Interface(), nil | 	return array.Interface(), nil | ||||||
| @ -127,10 +131,10 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) | |||||||
| 
 | 
 | ||||||
| 	if t.T == SliceTy { | 	if t.T == SliceTy { | ||||||
| 		// declare our slice
 | 		// declare our slice
 | ||||||
| 		refSlice = reflect.MakeSlice(t.Type, size, size) | 		refSlice = reflect.MakeSlice(t.getType(), size, size) | ||||||
| 	} else if t.T == ArrayTy { | 	} else if t.T == ArrayTy { | ||||||
| 		// declare our array
 | 		// declare our array
 | ||||||
| 		refSlice = reflect.New(t.Type).Elem() | 		refSlice = reflect.New(t.getType()).Elem() | ||||||
| 	} else { | 	} else { | ||||||
| 		return nil, fmt.Errorf("abi: invalid type in array/slice unpacking stage") | 		return nil, fmt.Errorf("abi: invalid type in array/slice unpacking stage") | ||||||
| 	} | 	} | ||||||
| @ -154,7 +158,7 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func forTupleUnpack(t Type, output []byte) (interface{}, error) { | func forTupleUnpack(t Type, output []byte) (interface{}, error) { | ||||||
| 	retval := reflect.New(t.Type).Elem() | 	retval := reflect.New(t.getType()).Elem() | ||||||
| 	virtualArgs := 0 | 	virtualArgs := 0 | ||||||
| 	for index, elem := range t.TupleElems { | 	for index, elem := range t.TupleElems { | ||||||
| 		marshalledValue, err := ToGoType((index+virtualArgs)*32, *elem, output) | 		marshalledValue, err := ToGoType((index+virtualArgs)*32, *elem, output) | ||||||
|  | |||||||
| @ -33,7 +33,7 @@ import ( | |||||||
| // TestUnpack tests the general pack/unpack tests in packing_test.go
 | // TestUnpack tests the general pack/unpack tests in packing_test.go
 | ||||||
| func TestUnpack(t *testing.T) { | func TestUnpack(t *testing.T) { | ||||||
| 	for i, test := range packUnpackTests { | 	for i, test := range packUnpackTests { | ||||||
| 		t.Run(strconv.Itoa(i), func(t *testing.T) { | 		t.Run(strconv.Itoa(i)+" "+test.def, func(t *testing.T) { | ||||||
| 			//Unpack
 | 			//Unpack
 | ||||||
| 			def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def) | 			def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def) | ||||||
| 			abi, err := JSON(strings.NewReader(def)) | 			abi, err := JSON(strings.NewReader(def)) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user