abi.go 12 KB

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