type.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Copyright 2015 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package abi
  17. import (
  18. "fmt"
  19. "reflect"
  20. "regexp"
  21. "strconv"
  22. "strings"
  23. )
  24. // Type enumerator
  25. const (
  26. IntTy byte = iota
  27. UintTy
  28. BoolTy
  29. StringTy
  30. SliceTy
  31. ArrayTy
  32. AddressTy
  33. FixedBytesTy
  34. BytesTy
  35. HashTy
  36. FixedPointTy
  37. FunctionTy
  38. )
  39. // Type is the reflection of the supported argument type
  40. type Type struct {
  41. Elem *Type
  42. Kind reflect.Kind
  43. Type reflect.Type
  44. Size int
  45. T byte // Our own type checking
  46. stringKind string // holds the unparsed string for deriving signatures
  47. }
  48. var (
  49. // typeRegex parses the abi sub types
  50. typeRegex = regexp.MustCompile("([a-zA-Z]+)(([0-9]+)(x([0-9]+))?)?")
  51. )
  52. // NewType creates a new reflection type of abi type given in t.
  53. func NewType(t string) (typ Type, err error) {
  54. // check that array brackets are equal if they exist
  55. if strings.Count(t, "[") != strings.Count(t, "]") {
  56. return Type{}, fmt.Errorf("invalid arg type in abi")
  57. }
  58. typ.stringKind = t
  59. // if there are brackets, get ready to go into slice/array mode and
  60. // recursively create the type
  61. if strings.Count(t, "[") != 0 {
  62. i := strings.LastIndex(t, "[")
  63. // recursively embed the type
  64. embeddedType, err := NewType(t[:i])
  65. if err != nil {
  66. return Type{}, err
  67. }
  68. // grab the last cell and create a type from there
  69. sliced := t[i:]
  70. // grab the slice size with regexp
  71. re := regexp.MustCompile("[0-9]+")
  72. intz := re.FindAllString(sliced, -1)
  73. if len(intz) == 0 {
  74. // is a slice
  75. typ.T = SliceTy
  76. typ.Kind = reflect.Slice
  77. typ.Elem = &embeddedType
  78. typ.Type = reflect.SliceOf(embeddedType.Type)
  79. } else if len(intz) == 1 {
  80. // is a array
  81. typ.T = ArrayTy
  82. typ.Kind = reflect.Array
  83. typ.Elem = &embeddedType
  84. typ.Size, err = strconv.Atoi(intz[0])
  85. if err != nil {
  86. return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err)
  87. }
  88. typ.Type = reflect.ArrayOf(typ.Size, embeddedType.Type)
  89. } else {
  90. return Type{}, fmt.Errorf("invalid formatting of array type")
  91. }
  92. return typ, err
  93. }
  94. // parse the type and size of the abi-type.
  95. parsedType := typeRegex.FindAllStringSubmatch(t, -1)[0]
  96. // varSize is the size of the variable
  97. var varSize int
  98. if len(parsedType[3]) > 0 {
  99. var err error
  100. varSize, err = strconv.Atoi(parsedType[2])
  101. if err != nil {
  102. return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err)
  103. }
  104. } else {
  105. if parsedType[0] == "uint" || parsedType[0] == "int" {
  106. // this should fail because it means that there's something wrong with
  107. // the abi type (the compiler should always format it to the size...always)
  108. return Type{}, fmt.Errorf("unsupported arg type: %s", t)
  109. }
  110. }
  111. // varType is the parsed abi type
  112. switch varType := parsedType[1]; varType {
  113. case "int":
  114. typ.Kind, typ.Type = reflectIntKindAndType(false, varSize)
  115. typ.Size = varSize
  116. typ.T = IntTy
  117. case "uint":
  118. typ.Kind, typ.Type = reflectIntKindAndType(true, varSize)
  119. typ.Size = varSize
  120. typ.T = UintTy
  121. case "bool":
  122. typ.Kind = reflect.Bool
  123. typ.T = BoolTy
  124. typ.Type = reflect.TypeOf(bool(false))
  125. case "address":
  126. typ.Kind = reflect.Array
  127. typ.Type = addressT
  128. typ.Size = 20
  129. typ.T = AddressTy
  130. case "string":
  131. typ.Kind = reflect.String
  132. typ.Type = reflect.TypeOf("")
  133. typ.T = StringTy
  134. case "bytes":
  135. if varSize == 0 {
  136. typ.T = BytesTy
  137. typ.Kind = reflect.Slice
  138. typ.Type = reflect.SliceOf(reflect.TypeOf(byte(0)))
  139. } else {
  140. typ.T = FixedBytesTy
  141. typ.Kind = reflect.Array
  142. typ.Size = varSize
  143. typ.Type = reflect.ArrayOf(varSize, reflect.TypeOf(byte(0)))
  144. }
  145. case "function":
  146. typ.Kind = reflect.Array
  147. typ.T = FunctionTy
  148. typ.Size = 24
  149. typ.Type = reflect.ArrayOf(24, reflect.TypeOf(byte(0)))
  150. default:
  151. return Type{}, fmt.Errorf("unsupported arg type: %s", t)
  152. }
  153. return
  154. }
  155. // String implements Stringer
  156. func (t Type) String() (out string) {
  157. return t.stringKind
  158. }
  159. func (t Type) pack(v reflect.Value) ([]byte, error) {
  160. // dereference pointer first if it's a pointer
  161. v = indirect(v)
  162. if err := typeCheck(t, v); err != nil {
  163. return nil, err
  164. }
  165. if t.T == SliceTy || t.T == ArrayTy {
  166. var packed []byte
  167. for i := 0; i < v.Len(); i++ {
  168. val, err := t.Elem.pack(v.Index(i))
  169. if err != nil {
  170. return nil, err
  171. }
  172. packed = append(packed, val...)
  173. }
  174. if t.T == SliceTy {
  175. return packBytesSlice(packed, v.Len()), nil
  176. } else if t.T == ArrayTy {
  177. return packed, nil
  178. }
  179. }
  180. return packElement(t, v), nil
  181. }
  182. // requireLengthPrefix returns whether the type requires any sort of length
  183. // prefixing.
  184. func (t Type) requiresLengthPrefix() bool {
  185. return t.T == StringTy || t.T == BytesTy || t.T == SliceTy
  186. }