type.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  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. "errors"
  19. "fmt"
  20. "reflect"
  21. "regexp"
  22. "strconv"
  23. "strings"
  24. "github.com/ethereum/go-ethereum/common"
  25. )
  26. // Type enumerator
  27. const (
  28. IntTy byte = iota
  29. UintTy
  30. BoolTy
  31. StringTy
  32. SliceTy
  33. ArrayTy
  34. TupleTy
  35. AddressTy
  36. FixedBytesTy
  37. BytesTy
  38. HashTy
  39. FixedPointTy
  40. FunctionTy
  41. )
  42. // Type is the reflection of the supported argument type.
  43. type Type struct {
  44. Elem *Type
  45. Size int
  46. T byte // Our own type checking
  47. stringKind string // holds the unparsed string for deriving signatures
  48. // Tuple relative fields
  49. TupleRawName string // Raw struct name defined in source code, may be empty.
  50. TupleElems []*Type // Type information of all tuple fields
  51. TupleRawNames []string // Raw field name of all tuple fields
  52. TupleType reflect.Type // Underlying struct of the tuple
  53. }
  54. var (
  55. // typeRegex parses the abi sub types
  56. typeRegex = regexp.MustCompile("([a-zA-Z]+)(([0-9]+)(x([0-9]+))?)?")
  57. )
  58. // NewType creates a new reflection type of abi type given in t.
  59. func NewType(t string, internalType string, components []ArgumentMarshaling) (typ Type, err error) {
  60. // check that array brackets are equal if they exist
  61. if strings.Count(t, "[") != strings.Count(t, "]") {
  62. return Type{}, fmt.Errorf("invalid arg type in abi")
  63. }
  64. typ.stringKind = t
  65. // if there are brackets, get ready to go into slice/array mode and
  66. // recursively create the type
  67. if strings.Count(t, "[") != 0 {
  68. // Note internalType can be empty here.
  69. subInternal := internalType
  70. if i := strings.LastIndex(internalType, "["); i != -1 {
  71. subInternal = subInternal[:i]
  72. }
  73. // recursively embed the type
  74. i := strings.LastIndex(t, "[")
  75. embeddedType, err := NewType(t[:i], subInternal, components)
  76. if err != nil {
  77. return Type{}, err
  78. }
  79. // grab the last cell and create a type from there
  80. sliced := t[i:]
  81. // grab the slice size with regexp
  82. re := regexp.MustCompile("[0-9]+")
  83. intz := re.FindAllString(sliced, -1)
  84. if len(intz) == 0 {
  85. // is a slice
  86. typ.T = SliceTy
  87. typ.Elem = &embeddedType
  88. typ.stringKind = embeddedType.stringKind + sliced
  89. } else if len(intz) == 1 {
  90. // is an array
  91. typ.T = ArrayTy
  92. typ.Elem = &embeddedType
  93. typ.Size, err = strconv.Atoi(intz[0])
  94. if err != nil {
  95. return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err)
  96. }
  97. typ.stringKind = embeddedType.stringKind + sliced
  98. } else {
  99. return Type{}, fmt.Errorf("invalid formatting of array type")
  100. }
  101. return typ, err
  102. }
  103. // parse the type and size of the abi-type.
  104. matches := typeRegex.FindAllStringSubmatch(t, -1)
  105. if len(matches) == 0 {
  106. return Type{}, fmt.Errorf("invalid type '%v'", t)
  107. }
  108. parsedType := matches[0]
  109. // varSize is the size of the variable
  110. var varSize int
  111. if len(parsedType[3]) > 0 {
  112. var err error
  113. varSize, err = strconv.Atoi(parsedType[2])
  114. if err != nil {
  115. return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err)
  116. }
  117. } else {
  118. if parsedType[0] == "uint" || parsedType[0] == "int" {
  119. // this should fail because it means that there's something wrong with
  120. // the abi type (the compiler should always format it to the size...always)
  121. return Type{}, fmt.Errorf("unsupported arg type: %s", t)
  122. }
  123. }
  124. // varType is the parsed abi type
  125. switch varType := parsedType[1]; varType {
  126. case "int":
  127. typ.Size = varSize
  128. typ.T = IntTy
  129. case "uint":
  130. typ.Size = varSize
  131. typ.T = UintTy
  132. case "bool":
  133. typ.T = BoolTy
  134. case "address":
  135. typ.Size = 20
  136. typ.T = AddressTy
  137. case "string":
  138. typ.T = StringTy
  139. case "bytes":
  140. if varSize == 0 {
  141. typ.T = BytesTy
  142. } else {
  143. typ.T = FixedBytesTy
  144. typ.Size = varSize
  145. }
  146. case "tuple":
  147. var (
  148. fields []reflect.StructField
  149. elems []*Type
  150. names []string
  151. expression string // canonical parameter expression
  152. )
  153. expression += "("
  154. overloadedNames := make(map[string]string)
  155. for idx, c := range components {
  156. cType, err := NewType(c.Type, c.InternalType, c.Components)
  157. if err != nil {
  158. return Type{}, err
  159. }
  160. fieldName, err := overloadedArgName(c.Name, overloadedNames)
  161. if err != nil {
  162. return Type{}, err
  163. }
  164. overloadedNames[fieldName] = fieldName
  165. fields = append(fields, reflect.StructField{
  166. Name: fieldName, // reflect.StructOf will panic for any exported field.
  167. Type: cType.GetType(),
  168. Tag: reflect.StructTag("json:\"" + c.Name + "\""),
  169. })
  170. elems = append(elems, &cType)
  171. names = append(names, c.Name)
  172. expression += cType.stringKind
  173. if idx != len(components)-1 {
  174. expression += ","
  175. }
  176. }
  177. expression += ")"
  178. typ.TupleType = reflect.StructOf(fields)
  179. typ.TupleElems = elems
  180. typ.TupleRawNames = names
  181. typ.T = TupleTy
  182. typ.stringKind = expression
  183. const structPrefix = "struct "
  184. // After solidity 0.5.10, a new field of abi "internalType"
  185. // is introduced. From that we can obtain the struct name
  186. // user defined in the source code.
  187. if internalType != "" && strings.HasPrefix(internalType, structPrefix) {
  188. // Foo.Bar type definition is not allowed in golang,
  189. // convert the format to FooBar
  190. typ.TupleRawName = strings.Replace(internalType[len(structPrefix):], ".", "", -1)
  191. }
  192. case "function":
  193. typ.T = FunctionTy
  194. typ.Size = 24
  195. default:
  196. return Type{}, fmt.Errorf("unsupported arg type: %s", t)
  197. }
  198. return
  199. }
  200. // GetType returns the reflection type of the ABI type.
  201. func (t Type) GetType() reflect.Type {
  202. switch t.T {
  203. case IntTy:
  204. return reflectIntType(false, t.Size)
  205. case UintTy:
  206. return reflectIntType(true, t.Size)
  207. case BoolTy:
  208. return reflect.TypeOf(false)
  209. case StringTy:
  210. return reflect.TypeOf("")
  211. case SliceTy:
  212. return reflect.SliceOf(t.Elem.GetType())
  213. case ArrayTy:
  214. return reflect.ArrayOf(t.Size, t.Elem.GetType())
  215. case TupleTy:
  216. return t.TupleType
  217. case AddressTy:
  218. return reflect.TypeOf(common.Address{})
  219. case FixedBytesTy:
  220. return reflect.ArrayOf(t.Size, reflect.TypeOf(byte(0)))
  221. case BytesTy:
  222. return reflect.SliceOf(reflect.TypeOf(byte(0)))
  223. case HashTy:
  224. // hashtype currently not used
  225. return reflect.ArrayOf(32, reflect.TypeOf(byte(0)))
  226. case FixedPointTy:
  227. // fixedpoint type currently not used
  228. return reflect.ArrayOf(32, reflect.TypeOf(byte(0)))
  229. case FunctionTy:
  230. return reflect.ArrayOf(24, reflect.TypeOf(byte(0)))
  231. default:
  232. panic("Invalid type")
  233. }
  234. }
  235. func overloadedArgName(rawName string, names map[string]string) (string, error) {
  236. fieldName := ToCamelCase(rawName)
  237. if fieldName == "" {
  238. return "", errors.New("abi: purely anonymous or underscored field is not supported")
  239. }
  240. // Handle overloaded fieldNames
  241. _, ok := names[fieldName]
  242. for idx := 0; ok; idx++ {
  243. fieldName = fmt.Sprintf("%s%d", ToCamelCase(rawName), idx)
  244. _, ok = names[fieldName]
  245. }
  246. return fieldName, nil
  247. }
  248. // String implements Stringer.
  249. func (t Type) String() (out string) {
  250. return t.stringKind
  251. }
  252. func (t Type) pack(v reflect.Value) ([]byte, error) {
  253. // dereference pointer first if it's a pointer
  254. v = indirect(v)
  255. if err := typeCheck(t, v); err != nil {
  256. return nil, err
  257. }
  258. switch t.T {
  259. case SliceTy, ArrayTy:
  260. var ret []byte
  261. if t.requiresLengthPrefix() {
  262. // append length
  263. ret = append(ret, packNum(reflect.ValueOf(v.Len()))...)
  264. }
  265. // calculate offset if any
  266. offset := 0
  267. offsetReq := isDynamicType(*t.Elem)
  268. if offsetReq {
  269. offset = getTypeSize(*t.Elem) * v.Len()
  270. }
  271. var tail []byte
  272. for i := 0; i < v.Len(); i++ {
  273. val, err := t.Elem.pack(v.Index(i))
  274. if err != nil {
  275. return nil, err
  276. }
  277. if !offsetReq {
  278. ret = append(ret, val...)
  279. continue
  280. }
  281. ret = append(ret, packNum(reflect.ValueOf(offset))...)
  282. offset += len(val)
  283. tail = append(tail, val...)
  284. }
  285. return append(ret, tail...), nil
  286. case TupleTy:
  287. // (T1,...,Tk) for k >= 0 and any types T1, …, Tk
  288. // enc(X) = head(X(1)) ... head(X(k)) tail(X(1)) ... tail(X(k))
  289. // where X = (X(1), ..., X(k)) and head and tail are defined for Ti being a static
  290. // type as
  291. // head(X(i)) = enc(X(i)) and tail(X(i)) = "" (the empty string)
  292. // and as
  293. // head(X(i)) = enc(len(head(X(1)) ... head(X(k)) tail(X(1)) ... tail(X(i-1))))
  294. // tail(X(i)) = enc(X(i))
  295. // otherwise, i.e. if Ti is a dynamic type.
  296. fieldmap, err := mapArgNamesToStructFields(t.TupleRawNames, v)
  297. if err != nil {
  298. return nil, err
  299. }
  300. // Calculate prefix occupied size.
  301. offset := 0
  302. for _, elem := range t.TupleElems {
  303. offset += getTypeSize(*elem)
  304. }
  305. var ret, tail []byte
  306. for i, elem := range t.TupleElems {
  307. field := v.FieldByName(fieldmap[t.TupleRawNames[i]])
  308. if !field.IsValid() {
  309. return nil, fmt.Errorf("field %s for tuple not found in the given struct", t.TupleRawNames[i])
  310. }
  311. val, err := elem.pack(field)
  312. if err != nil {
  313. return nil, err
  314. }
  315. if isDynamicType(*elem) {
  316. ret = append(ret, packNum(reflect.ValueOf(offset))...)
  317. tail = append(tail, val...)
  318. offset += len(val)
  319. } else {
  320. ret = append(ret, val...)
  321. }
  322. }
  323. return append(ret, tail...), nil
  324. default:
  325. return packElement(t, v)
  326. }
  327. }
  328. // requireLengthPrefix returns whether the type requires any sort of length
  329. // prefixing.
  330. func (t Type) requiresLengthPrefix() bool {
  331. return t.T == StringTy || t.T == BytesTy || t.T == SliceTy
  332. }
  333. // isDynamicType returns true if the type is dynamic.
  334. // The following types are called “dynamic”:
  335. // * bytes
  336. // * string
  337. // * T[] for any T
  338. // * T[k] for any dynamic T and any k >= 0
  339. // * (T1,...,Tk) if Ti is dynamic for some 1 <= i <= k
  340. func isDynamicType(t Type) bool {
  341. if t.T == TupleTy {
  342. for _, elem := range t.TupleElems {
  343. if isDynamicType(*elem) {
  344. return true
  345. }
  346. }
  347. return false
  348. }
  349. return t.T == StringTy || t.T == BytesTy || t.T == SliceTy || (t.T == ArrayTy && isDynamicType(*t.Elem))
  350. }
  351. // getTypeSize returns the size that this type needs to occupy.
  352. // We distinguish static and dynamic types. Static types are encoded in-place
  353. // and dynamic types are encoded at a separately allocated location after the
  354. // current block.
  355. // So for a static variable, the size returned represents the size that the
  356. // variable actually occupies.
  357. // For a dynamic variable, the returned size is fixed 32 bytes, which is used
  358. // to store the location reference for actual value storage.
  359. func getTypeSize(t Type) int {
  360. if t.T == ArrayTy && !isDynamicType(*t.Elem) {
  361. // Recursively calculate type size if it is a nested array
  362. if t.Elem.T == ArrayTy || t.Elem.T == TupleTy {
  363. return t.Size * getTypeSize(*t.Elem)
  364. }
  365. return t.Size * 32
  366. } else if t.T == TupleTy && !isDynamicType(t) {
  367. total := 0
  368. for _, elem := range t.TupleElems {
  369. total += getTypeSize(*elem)
  370. }
  371. return total
  372. }
  373. return 32
  374. }