mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
accounts/abi: added getType func to Type struct
This commit is contained in:
parent
5e45db7610
commit
b7f9ce5e45
3 changed files with 68 additions and 24 deletions
|
|
@ -23,6 +23,8 @@ import (
|
|||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
// Type enumerator
|
||||
|
|
@ -55,6 +57,7 @@ type Type struct {
|
|||
TupleRawName string // Raw struct name defined in source code, may be empty.
|
||||
TupleElems []*Type // Type information of all tuple fields
|
||||
TupleRawNames []string // Raw field name of all tuple fields
|
||||
TupelType reflect.Type
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
@ -180,7 +183,7 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
|
|||
}
|
||||
fields = append(fields, reflect.StructField{
|
||||
Name: ToCamelCase(c.Name), // reflect.StructOf will panic for any exported field.
|
||||
Type: cType.Type,
|
||||
Type: cType.getType(),
|
||||
Tag: reflect.StructTag("json:\"" + c.Name + "\""),
|
||||
})
|
||||
elems = append(elems, &cType)
|
||||
|
|
@ -191,6 +194,8 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
|
|||
}
|
||||
}
|
||||
expression += ")"
|
||||
|
||||
typ.TupelType = reflect.StructOf(fields)
|
||||
typ.Type = reflect.StructOf(fields)
|
||||
typ.TupleElems = elems
|
||||
typ.TupleRawNames = names
|
||||
|
|
@ -218,6 +223,41 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
|
|||
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.TupelType
|
||||
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
|
||||
func (t Type) String() (out string) {
|
||||
return t.stringKind
|
||||
|
|
|
|||
|
|
@ -34,32 +34,36 @@ var (
|
|||
|
||||
// ReadInteger reads the integer based on its kind and returns the appropriate value
|
||||
func ReadInteger(typ Type, b []byte) interface{} {
|
||||
switch typ.Type {
|
||||
case uint8T:
|
||||
return b[len(b)-1]
|
||||
case uint16T:
|
||||
return binary.BigEndian.Uint16(b[len(b)-2:])
|
||||
case uint32T:
|
||||
return binary.BigEndian.Uint32(b[len(b)-4:])
|
||||
case uint64T:
|
||||
return binary.BigEndian.Uint64(b[len(b)-8:])
|
||||
case int8T:
|
||||
if typ.T == UintTy {
|
||||
switch typ.Size {
|
||||
case 8:
|
||||
return b[len(b)-1]
|
||||
case 16:
|
||||
return binary.BigEndian.Uint16(b[len(b)-2:])
|
||||
case 32:
|
||||
return binary.BigEndian.Uint32(b[len(b)-4:])
|
||||
case 64:
|
||||
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])
|
||||
case int16T:
|
||||
case 16:
|
||||
return int16(binary.BigEndian.Uint16(b[len(b)-2:]))
|
||||
case int32T:
|
||||
case 32:
|
||||
return int32(binary.BigEndian.Uint32(b[len(b)-4:]))
|
||||
case int64T:
|
||||
case 64:
|
||||
return int64(binary.BigEndian.Uint64(b[len(b)-8:]))
|
||||
default:
|
||||
// the only case left for integer is int256/uint256.
|
||||
ret := new(big.Int).SetBytes(b)
|
||||
if typ.T == UintTy {
|
||||
return ret
|
||||
}
|
||||
// the only case left for integer is int256
|
||||
// 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.
|
||||
// A number is > max int256 if the bit at position 255 is set.
|
||||
ret := new(big.Int).SetBytes(b)
|
||||
if ret.Bit(255) == 1 {
|
||||
ret.Add(MaxUint256, new(big.Int).Neg(ret))
|
||||
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")
|
||||
}
|
||||
// convert
|
||||
array := reflect.New(t.Type).Elem()
|
||||
array := reflect.New(reflect.ArrayOf(t.Size, reflect.TypeOf(byte(0)))).Elem()
|
||||
|
||||
reflect.Copy(array, reflect.ValueOf(word[0:t.Size]))
|
||||
return array.Interface(), nil
|
||||
|
|
@ -127,10 +131,10 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error)
|
|||
|
||||
if t.T == SliceTy {
|
||||
// declare our slice
|
||||
refSlice = reflect.MakeSlice(t.Type, size, size)
|
||||
refSlice = reflect.MakeSlice(t.getType(), size, size)
|
||||
} else if t.T == ArrayTy {
|
||||
// declare our array
|
||||
refSlice = reflect.New(t.Type).Elem()
|
||||
refSlice = reflect.New(t.getType()).Elem()
|
||||
} else {
|
||||
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) {
|
||||
retval := reflect.New(t.Type).Elem()
|
||||
retval := reflect.New(t.getType())
|
||||
virtualArgs := 0
|
||||
for index, elem := range t.TupleElems {
|
||||
marshalledValue, err := ToGoType((index+virtualArgs)*32, *elem, output)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import (
|
|||
// TestUnpack tests the general pack/unpack tests in packing_test.go
|
||||
func TestUnpack(t *testing.T) {
|
||||
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
|
||||
def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def)
|
||||
abi, err := JSON(strings.NewReader(def))
|
||||
|
|
|
|||
Loading…
Reference in a new issue