summaryrefslogtreecommitdiff
path: root/data/abi/abi_type.go
diff options
context:
space:
mode:
Diffstat (limited to 'data/abi/abi_type.go')
-rw-r--r--data/abi/abi_type.go122
1 files changed, 45 insertions, 77 deletions
diff --git a/data/abi/abi_type.go b/data/abi/abi_type.go
index 65e3dfc6a..eb93f9eea 100644
--- a/data/abi/abi_type.go
+++ b/data/abi/abi_type.go
@@ -84,15 +84,15 @@ type Type struct {
func (t Type) String() string {
switch t.abiTypeID {
case Uint:
- return "uint" + strconv.Itoa(int(t.bitSize))
+ return fmt.Sprintf("uint%d", t.bitSize)
case Byte:
return "byte"
case Ufixed:
- return "ufixed" + strconv.Itoa(int(t.bitSize)) + "x" + strconv.Itoa(int(t.precision))
+ return fmt.Sprintf("ufixed%dx%d", t.bitSize, t.precision)
case Bool:
return "bool"
case ArrayStatic:
- return t.childTypes[0].String() + "[" + strconv.Itoa(int(t.staticLength)) + "]"
+ return fmt.Sprintf("%s[%d]", t.childTypes[0].String(), t.staticLength)
case Address:
return "address"
case ArrayDynamic:
@@ -110,31 +110,19 @@ func (t Type) String() string {
}
}
-var staticArrayRegexp *regexp.Regexp = nil
-var ufixedRegexp *regexp.Regexp = nil
+var staticArrayRegexp = regexp.MustCompile(`^([a-z\d\[\](),]+)\[([1-9][\d]*)]$`)
+var ufixedRegexp = regexp.MustCompile(`^ufixed([1-9][\d]*)x([1-9][\d]*)$`)
-func init() {
- var err error
- // Note that we allow only decimal static array length
- staticArrayRegexp, err = regexp.Compile(`^([a-z\d\[\](),]+)\[([1-9][\d]*)]$`)
- if err != nil {
- panic(err.Error())
- }
- ufixedRegexp, err = regexp.Compile(`^ufixed([1-9][\d]*)x([1-9][\d]*)$`)
- if err != nil {
- panic(err.Error())
- }
-}
-
-// TypeFromString de-serialize ABI type from a string following ABI encoding.
-func TypeFromString(str string) (Type, error) {
+// TypeOf parses an ABI type string.
+// For example: `TypeOf("(uint64,byte[])")`
+func TypeOf(str string) (Type, error) {
switch {
case strings.HasSuffix(str, "[]"):
- arrayArgType, err := TypeFromString(str[:len(str)-2])
+ arrayArgType, err := TypeOf(str[:len(str)-2])
if err != nil {
return Type{}, err
}
- return MakeDynamicArrayType(arrayArgType), nil
+ return makeDynamicArrayType(arrayArgType), nil
case strings.HasSuffix(str, "]"):
stringMatches := staticArrayRegexp.FindStringSubmatch(str)
// match the string itself, array element type, then array length
@@ -149,19 +137,19 @@ func TypeFromString(str string) (Type, error) {
return Type{}, err
}
// parse the array element type
- arrayType, err := TypeFromString(stringMatches[1])
+ arrayType, err := TypeOf(stringMatches[1])
if err != nil {
return Type{}, err
}
- return MakeStaticArrayType(arrayType, uint16(arrayLength)), nil
+ return makeStaticArrayType(arrayType, uint16(arrayLength)), nil
case strings.HasPrefix(str, "uint"):
typeSize, err := strconv.ParseUint(str[4:], 10, 16)
if err != nil {
return Type{}, fmt.Errorf("ill formed uint type: %s", str)
}
- return MakeUintType(uint16(typeSize))
+ return makeUintType(int(typeSize))
case str == "byte":
- return MakeByteType(), nil
+ return byteType, nil
case strings.HasPrefix(str, "ufixed"):
stringMatches := ufixedRegexp.FindStringSubmatch(str)
// match string itself, then type-bitSize, and type-precision
@@ -177,13 +165,13 @@ func TypeFromString(str string) (Type, error) {
if err != nil {
return Type{}, err
}
- return MakeUfixedType(uint16(ufixedSize), uint16(ufixedPrecision))
+ return makeUfixedType(int(ufixedSize), int(ufixedPrecision))
case str == "bool":
- return MakeBoolType(), nil
+ return boolType, nil
case str == "address":
- return MakeAddressType(), nil
+ return addressType, nil
case str == "string":
- return MakeStringType(), nil
+ return stringType, nil
case len(str) >= 2 && str[0] == '(' && str[len(str)-1] == ')':
tupleContent, err := parseTupleContent(str[1 : len(str)-1])
if err != nil {
@@ -191,7 +179,7 @@ func TypeFromString(str string) (Type, error) {
}
tupleTypes := make([]Type, len(tupleContent))
for i := 0; i < len(tupleContent); i++ {
- ti, err := TypeFromString(tupleContent[i])
+ ti, err := TypeOf(tupleContent[i])
if err != nil {
return Type{}, err
}
@@ -284,29 +272,36 @@ func parseTupleContent(str string) ([]string, error) {
return tupleStrSegs, nil
}
-// MakeUintType makes `Uint` ABI type by taking a type bitSize argument.
+// makeUintType makes `Uint` ABI type by taking a type bitSize argument.
// The range of type bitSize is [8, 512] and type bitSize % 8 == 0.
-func MakeUintType(typeSize uint16) (Type, error) {
+func makeUintType(typeSize int) (Type, error) {
if typeSize%8 != 0 || typeSize < 8 || typeSize > 512 {
return Type{}, fmt.Errorf("unsupported uint type bitSize: %d", typeSize)
}
return Type{
abiTypeID: Uint,
- bitSize: typeSize,
+ bitSize: uint16(typeSize),
}, nil
}
-// MakeByteType makes `Byte` ABI type.
-func MakeByteType() Type {
- return Type{
- abiTypeID: Byte,
- }
-}
+var (
+ // byteType is ABI type constant for byte
+ byteType = Type{abiTypeID: Byte}
-// MakeUfixedType makes `UFixed` ABI type by taking type bitSize and type precision as arguments.
+ // boolType is ABI type constant for bool
+ boolType = Type{abiTypeID: Bool}
+
+ // addressType is ABI type constant for address
+ addressType = Type{abiTypeID: Address}
+
+ // stringType is ABI type constant for string
+ stringType = Type{abiTypeID: String}
+)
+
+// makeUfixedType makes `UFixed` ABI type by taking type bitSize and type precision as arguments.
// The range of type bitSize is [8, 512] and type bitSize % 8 == 0.
// The range of type precision is [1, 160].
-func MakeUfixedType(typeSize uint16, typePrecision uint16) (Type, error) {
+func makeUfixedType(typeSize int, typePrecision int) (Type, error) {
if typeSize%8 != 0 || typeSize < 8 || typeSize > 512 {
return Type{}, fmt.Errorf("unsupported ufixed type bitSize: %d", typeSize)
}
@@ -315,21 +310,14 @@ func MakeUfixedType(typeSize uint16, typePrecision uint16) (Type, error) {
}
return Type{
abiTypeID: Ufixed,
- bitSize: typeSize,
- precision: typePrecision,
+ bitSize: uint16(typeSize),
+ precision: uint16(typePrecision),
}, nil
}
-// MakeBoolType makes `Bool` ABI type.
-func MakeBoolType() Type {
- return Type{
- abiTypeID: Bool,
- }
-}
-
-// MakeStaticArrayType makes static length array ABI type by taking
+// makeStaticArrayType makes static length array ABI type by taking
// array element type and array length as arguments.
-func MakeStaticArrayType(argumentType Type, arrayLength uint16) Type {
+func makeStaticArrayType(argumentType Type, arrayLength uint16) Type {
return Type{
abiTypeID: ArrayStatic,
childTypes: []Type{argumentType},
@@ -337,28 +325,14 @@ func MakeStaticArrayType(argumentType Type, arrayLength uint16) Type {
}
}
-// MakeAddressType makes `Address` ABI type.
-func MakeAddressType() Type {
- return Type{
- abiTypeID: Address,
- }
-}
-
-// MakeDynamicArrayType makes dynamic length array by taking array element type as argument.
-func MakeDynamicArrayType(argumentType Type) Type {
+// makeDynamicArrayType makes dynamic length array by taking array element type as argument.
+func makeDynamicArrayType(argumentType Type) Type {
return Type{
abiTypeID: ArrayDynamic,
childTypes: []Type{argumentType},
}
}
-// MakeStringType makes `String` ABI type.
-func MakeStringType() Type {
- return Type{
- abiTypeID: String,
- }
-}
-
// MakeTupleType makes tuple ABI type by taking an array of tuple element types as argument.
func MakeTupleType(argumentTypes []Type) (Type, error) {
if len(argumentTypes) >= math.MaxUint16 {
@@ -451,10 +425,7 @@ func (t Type) ByteLen() (int, error) {
return singleBoolSize, nil
case ArrayStatic:
if t.childTypes[0].abiTypeID == Bool {
- byteLen := int(t.staticLength) / 8
- if t.staticLength%8 != 0 {
- byteLen++
- }
+ byteLen := int(t.staticLength+7) / 8
return byteLen, nil
}
elemByteLen, err := t.childTypes[0].ByteLen()
@@ -472,10 +443,7 @@ func (t Type) ByteLen() (int, error) {
i += after
// get number of bool
boolNum := after + 1
- size += boolNum / 8
- if boolNum%8 != 0 {
- size++
- }
+ size += (boolNum + 7) / 8
} else {
childByteSize, err := t.childTypes[i].ByteLen()
if err != nil {