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"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Type enumerator
|
// Type enumerator
|
||||||
|
|
@ -55,6 +57,7 @@ type Type struct {
|
||||||
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
|
||||||
|
TupelType reflect.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -180,7 +183,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,6 +194,8 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expression += ")"
|
expression += ")"
|
||||||
|
|
||||||
|
typ.TupelType = reflect.StructOf(fields)
|
||||||
typ.Type = reflect.StructOf(fields)
|
typ.Type = reflect.StructOf(fields)
|
||||||
typ.TupleElems = elems
|
typ.TupleElems = elems
|
||||||
typ.TupleRawNames = names
|
typ.TupleRawNames = names
|
||||||
|
|
@ -218,6 +223,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.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
|
// String implements Stringer
|
||||||
func (t Type) String() (out string) {
|
func (t Type) String() (out string) {
|
||||||
return t.stringKind
|
return t.stringKind
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
case 8:
|
||||||
return b[len(b)-1]
|
return b[len(b)-1]
|
||||||
case uint16T:
|
case 16:
|
||||||
return binary.BigEndian.Uint16(b[len(b)-2:])
|
return binary.BigEndian.Uint16(b[len(b)-2:])
|
||||||
case uint32T:
|
case 32:
|
||||||
return binary.BigEndian.Uint32(b[len(b)-4:])
|
return binary.BigEndian.Uint32(b[len(b)-4:])
|
||||||
case uint64T:
|
case 64:
|
||||||
return binary.BigEndian.Uint64(b[len(b)-8:])
|
return binary.BigEndian.Uint64(b[len(b)-8:])
|
||||||
case int8T:
|
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(reflect.ArrayOf(t.Size, reflect.TypeOf(byte(0)))).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())
|
||||||
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 a new issue