abi.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  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. "encoding/binary"
  19. "encoding/json"
  20. "fmt"
  21. "io"
  22. "math/big"
  23. "reflect"
  24. "strings"
  25. "github.com/ethereum/go-ethereum/common"
  26. )
  27. // The ABI holds information about a contract's context and available
  28. // invokable methods. It will allow you to type check function calls and
  29. // packs data accordingly.
  30. type ABI struct {
  31. Constructor Method
  32. Methods map[string]Method
  33. Events map[string]Event
  34. }
  35. // JSON returns a parsed ABI interface and error if it failed.
  36. func JSON(reader io.Reader) (ABI, error) {
  37. dec := json.NewDecoder(reader)
  38. var abi ABI
  39. if err := dec.Decode(&abi); err != nil {
  40. return ABI{}, err
  41. }
  42. return abi, nil
  43. }
  44. // Pack the given method name to conform the ABI. Method call's data
  45. // will consist of method_id, args0, arg1, ... argN. Method id consists
  46. // of 4 bytes and arguments are all 32 bytes.
  47. // Method ids are created from the first 4 bytes of the hash of the
  48. // methods string signature. (signature = baz(uint32,string32))
  49. func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) {
  50. // Fetch the ABI of the requested method
  51. var method Method
  52. if name == "" {
  53. method = abi.Constructor
  54. } else {
  55. m, exist := abi.Methods[name]
  56. if !exist {
  57. return nil, fmt.Errorf("method '%s' not found", name)
  58. }
  59. method = m
  60. }
  61. arguments, err := method.pack(method, args...)
  62. if err != nil {
  63. return nil, err
  64. }
  65. // Pack up the method ID too if not a constructor and return
  66. if name == "" {
  67. return arguments, nil
  68. }
  69. return append(method.Id(), arguments...), nil
  70. }
  71. // toGoSliceType parses the input and casts it to the proper slice defined by the ABI
  72. // argument in T.
  73. func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
  74. index := i * 32
  75. // The slice must, at very least be large enough for the index+32 which is exactly the size required
  76. // for the [offset in output, size of offset].
  77. if index+32 > len(output) {
  78. return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), index+32)
  79. }
  80. elem := t.Type.Elem
  81. // first we need to create a slice of the type
  82. var refSlice reflect.Value
  83. switch elem.T {
  84. case IntTy, UintTy, BoolTy:
  85. // create a new reference slice matching the element type
  86. switch t.Type.Kind {
  87. case reflect.Bool:
  88. refSlice = reflect.ValueOf([]bool(nil))
  89. case reflect.Uint8:
  90. refSlice = reflect.ValueOf([]uint8(nil))
  91. case reflect.Uint16:
  92. refSlice = reflect.ValueOf([]uint16(nil))
  93. case reflect.Uint32:
  94. refSlice = reflect.ValueOf([]uint32(nil))
  95. case reflect.Uint64:
  96. refSlice = reflect.ValueOf([]uint64(nil))
  97. case reflect.Int8:
  98. refSlice = reflect.ValueOf([]int8(nil))
  99. case reflect.Int16:
  100. refSlice = reflect.ValueOf([]int16(nil))
  101. case reflect.Int32:
  102. refSlice = reflect.ValueOf([]int32(nil))
  103. case reflect.Int64:
  104. refSlice = reflect.ValueOf([]int64(nil))
  105. default:
  106. refSlice = reflect.ValueOf([]*big.Int(nil))
  107. }
  108. case AddressTy: // address must be of slice Address
  109. refSlice = reflect.ValueOf([]common.Address(nil))
  110. case HashTy: // hash must be of slice hash
  111. refSlice = reflect.ValueOf([]common.Hash(nil))
  112. case FixedBytesTy:
  113. refSlice = reflect.ValueOf([][]byte(nil))
  114. default: // no other types are supported
  115. return nil, fmt.Errorf("abi: unsupported slice type %v", elem.T)
  116. }
  117. var slice []byte
  118. var size int
  119. var offset int
  120. if t.Type.IsSlice {
  121. // get the offset which determines the start of this array ...
  122. offset = int(binary.BigEndian.Uint64(output[index+24 : index+32]))
  123. if offset+32 > len(output) {
  124. return nil, fmt.Errorf("abi: cannot marshal in to go slice: offset %d would go over slice boundary (len=%d)", len(output), offset+32)
  125. }
  126. slice = output[offset:]
  127. // ... starting with the size of the array in elements ...
  128. size = int(binary.BigEndian.Uint64(slice[24:32]))
  129. slice = slice[32:]
  130. // ... and make sure that we've at the very least the amount of bytes
  131. // available in the buffer.
  132. if size*32 > len(slice) {
  133. return nil, fmt.Errorf("abi: cannot marshal in to go slice: insufficient size output %d require %d", len(output), offset+32+size*32)
  134. }
  135. // reslice to match the required size
  136. slice = slice[:size*32]
  137. } else if t.Type.IsArray {
  138. //get the number of elements in the array
  139. size = t.Type.SliceSize
  140. //check to make sure array size matches up
  141. if index+32*size > len(output) {
  142. return nil, fmt.Errorf("abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)", len(output), index+32*size)
  143. }
  144. //slice is there for a fixed amount of times
  145. slice = output[index : index+size*32]
  146. }
  147. for i := 0; i < size; i++ {
  148. var (
  149. inter interface{} // interface type
  150. returnOutput = slice[i*32 : i*32+32] // the return output
  151. )
  152. // set inter to the correct type (cast)
  153. switch elem.T {
  154. case IntTy, UintTy:
  155. inter = readInteger(t.Type.Kind, returnOutput)
  156. case BoolTy:
  157. inter = !allZero(returnOutput)
  158. case AddressTy:
  159. inter = common.BytesToAddress(returnOutput)
  160. case HashTy:
  161. inter = common.BytesToHash(returnOutput)
  162. case FixedBytesTy:
  163. inter = returnOutput
  164. }
  165. // append the item to our reflect slice
  166. refSlice = reflect.Append(refSlice, reflect.ValueOf(inter))
  167. }
  168. // return the interface
  169. return refSlice.Interface(), nil
  170. }
  171. func readInteger(kind reflect.Kind, b []byte) interface{} {
  172. switch kind {
  173. case reflect.Uint8:
  174. return uint8(b[len(b)-1])
  175. case reflect.Uint16:
  176. return binary.BigEndian.Uint16(b[len(b)-2:])
  177. case reflect.Uint32:
  178. return binary.BigEndian.Uint32(b[len(b)-4:])
  179. case reflect.Uint64:
  180. return binary.BigEndian.Uint64(b[len(b)-8:])
  181. case reflect.Int8:
  182. return int8(b[len(b)-1])
  183. case reflect.Int16:
  184. return int16(binary.BigEndian.Uint16(b[len(b)-2:]))
  185. case reflect.Int32:
  186. return int32(binary.BigEndian.Uint32(b[len(b)-4:]))
  187. case reflect.Int64:
  188. return int64(binary.BigEndian.Uint64(b[len(b)-8:]))
  189. default:
  190. return new(big.Int).SetBytes(b)
  191. }
  192. }
  193. func allZero(b []byte) bool {
  194. for _, byte := range b {
  195. if byte != 0 {
  196. return false
  197. }
  198. }
  199. return true
  200. }
  201. // toGoType parses the input and casts it to the proper type defined by the ABI
  202. // argument in T.
  203. func toGoType(i int, t Argument, output []byte) (interface{}, error) {
  204. // we need to treat slices differently
  205. if (t.Type.IsSlice || t.Type.IsArray) && t.Type.T != BytesTy && t.Type.T != StringTy && t.Type.T != FixedBytesTy && t.Type.T != FunctionTy {
  206. return toGoSlice(i, t, output)
  207. }
  208. index := i * 32
  209. if index+32 > len(output) {
  210. return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), index+32)
  211. }
  212. // Parse the given index output and check whether we need to read
  213. // a different offset and length based on the type (i.e. string, bytes)
  214. var returnOutput []byte
  215. switch t.Type.T {
  216. case StringTy, BytesTy: // variable arrays are written at the end of the return bytes
  217. // parse offset from which we should start reading
  218. offset := int(binary.BigEndian.Uint64(output[index+24 : index+32]))
  219. if offset+32 > len(output) {
  220. return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32)
  221. }
  222. // parse the size up until we should be reading
  223. size := int(binary.BigEndian.Uint64(output[offset+24 : offset+32]))
  224. if offset+32+size > len(output) {
  225. return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), offset+32+size)
  226. }
  227. // get the bytes for this return value
  228. returnOutput = output[offset+32 : offset+32+size]
  229. default:
  230. returnOutput = output[index : index+32]
  231. }
  232. // convert the bytes to whatever is specified by the ABI.
  233. switch t.Type.T {
  234. case IntTy, UintTy:
  235. return readInteger(t.Type.Kind, returnOutput), nil
  236. case BoolTy:
  237. return !allZero(returnOutput), nil
  238. case AddressTy:
  239. return common.BytesToAddress(returnOutput), nil
  240. case HashTy:
  241. return common.BytesToHash(returnOutput), nil
  242. case BytesTy, FixedBytesTy, FunctionTy:
  243. return returnOutput, nil
  244. case StringTy:
  245. return string(returnOutput), nil
  246. }
  247. return nil, fmt.Errorf("abi: unknown type %v", t.Type.T)
  248. }
  249. // these variable are used to determine certain types during type assertion for
  250. // assignment.
  251. var (
  252. r_interSlice = reflect.TypeOf([]interface{}{})
  253. r_hash = reflect.TypeOf(common.Hash{})
  254. r_bytes = reflect.TypeOf([]byte{})
  255. r_byte = reflect.TypeOf(byte(0))
  256. )
  257. // Unpack output in v according to the abi specification
  258. func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
  259. var method = abi.Methods[name]
  260. if len(output) == 0 {
  261. return fmt.Errorf("abi: unmarshalling empty output")
  262. }
  263. // make sure the passed value is a pointer
  264. valueOf := reflect.ValueOf(v)
  265. if reflect.Ptr != valueOf.Kind() {
  266. return fmt.Errorf("abi: Unpack(non-pointer %T)", v)
  267. }
  268. var (
  269. value = valueOf.Elem()
  270. typ = value.Type()
  271. )
  272. if len(method.Outputs) > 1 {
  273. switch value.Kind() {
  274. // struct will match named return values to the struct's field
  275. // names
  276. case reflect.Struct:
  277. for i := 0; i < len(method.Outputs); i++ {
  278. marshalledValue, err := toGoType(i, method.Outputs[i], output)
  279. if err != nil {
  280. return err
  281. }
  282. reflectValue := reflect.ValueOf(marshalledValue)
  283. for j := 0; j < typ.NumField(); j++ {
  284. field := typ.Field(j)
  285. // TODO read tags: `abi:"fieldName"`
  286. if field.Name == strings.ToUpper(method.Outputs[i].Name[:1])+method.Outputs[i].Name[1:] {
  287. if err := set(value.Field(j), reflectValue, method.Outputs[i]); err != nil {
  288. return err
  289. }
  290. }
  291. }
  292. }
  293. case reflect.Slice:
  294. if !value.Type().AssignableTo(r_interSlice) {
  295. return fmt.Errorf("abi: cannot marshal tuple in to slice %T (only []interface{} is supported)", v)
  296. }
  297. // if the slice already contains values, set those instead of the interface slice itself.
  298. if value.Len() > 0 {
  299. if len(method.Outputs) > value.Len() {
  300. return fmt.Errorf("abi: cannot marshal in to slices of unequal size (require: %v, got: %v)", len(method.Outputs), value.Len())
  301. }
  302. for i := 0; i < len(method.Outputs); i++ {
  303. marshalledValue, err := toGoType(i, method.Outputs[i], output)
  304. if err != nil {
  305. return err
  306. }
  307. reflectValue := reflect.ValueOf(marshalledValue)
  308. if err := set(value.Index(i).Elem(), reflectValue, method.Outputs[i]); err != nil {
  309. return err
  310. }
  311. }
  312. return nil
  313. }
  314. // create a new slice and start appending the unmarshalled
  315. // values to the new interface slice.
  316. z := reflect.MakeSlice(typ, 0, len(method.Outputs))
  317. for i := 0; i < len(method.Outputs); i++ {
  318. marshalledValue, err := toGoType(i, method.Outputs[i], output)
  319. if err != nil {
  320. return err
  321. }
  322. z = reflect.Append(z, reflect.ValueOf(marshalledValue))
  323. }
  324. value.Set(z)
  325. default:
  326. return fmt.Errorf("abi: cannot unmarshal tuple in to %v", typ)
  327. }
  328. } else {
  329. marshalledValue, err := toGoType(0, method.Outputs[0], output)
  330. if err != nil {
  331. return err
  332. }
  333. if err := set(value, reflect.ValueOf(marshalledValue), method.Outputs[0]); err != nil {
  334. return err
  335. }
  336. }
  337. return nil
  338. }
  339. func (abi *ABI) UnmarshalJSON(data []byte) error {
  340. var fields []struct {
  341. Type string
  342. Name string
  343. Constant bool
  344. Indexed bool
  345. Anonymous bool
  346. Inputs []Argument
  347. Outputs []Argument
  348. }
  349. if err := json.Unmarshal(data, &fields); err != nil {
  350. return err
  351. }
  352. abi.Methods = make(map[string]Method)
  353. abi.Events = make(map[string]Event)
  354. for _, field := range fields {
  355. switch field.Type {
  356. case "constructor":
  357. abi.Constructor = Method{
  358. Inputs: field.Inputs,
  359. }
  360. // empty defaults to function according to the abi spec
  361. case "function", "":
  362. abi.Methods[field.Name] = Method{
  363. Name: field.Name,
  364. Const: field.Constant,
  365. Inputs: field.Inputs,
  366. Outputs: field.Outputs,
  367. }
  368. case "event":
  369. abi.Events[field.Name] = Event{
  370. Name: field.Name,
  371. Anonymous: field.Anonymous,
  372. Inputs: field.Inputs,
  373. }
  374. }
  375. }
  376. return nil
  377. }