argument.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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. "reflect"
  21. "strings"
  22. )
  23. // Argument holds the name of the argument and the corresponding type.
  24. // Types are used when packing and testing arguments.
  25. type Argument struct {
  26. Name string
  27. Type Type
  28. Indexed bool // indexed is only used by events
  29. }
  30. type Arguments []Argument
  31. // UnmarshalJSON implements json.Unmarshaler interface
  32. func (a *Argument) UnmarshalJSON(data []byte) error {
  33. var extarg struct {
  34. Name string
  35. Type string
  36. Indexed bool
  37. }
  38. err := json.Unmarshal(data, &extarg)
  39. if err != nil {
  40. return fmt.Errorf("argument json err: %v", err)
  41. }
  42. a.Type, err = NewType(extarg.Type)
  43. if err != nil {
  44. return err
  45. }
  46. a.Name = extarg.Name
  47. a.Indexed = extarg.Indexed
  48. return nil
  49. }
  50. func countNonIndexedArguments(args []Argument) int {
  51. out := 0
  52. for i := range args {
  53. if !args[i].Indexed {
  54. out++
  55. }
  56. }
  57. return out
  58. }
  59. func (a *Arguments) isTuple() bool {
  60. return a != nil && len(*a) > 1
  61. }
  62. func (a *Arguments) Unpack(v interface{}, data []byte) error {
  63. if a.isTuple() {
  64. return a.unpackTuple(v, data)
  65. }
  66. return a.unpackAtomic(v, data)
  67. }
  68. func (a *Arguments) unpackTuple(v interface{}, output []byte) error {
  69. // make sure the passed value is a pointer
  70. valueOf := reflect.ValueOf(v)
  71. if reflect.Ptr != valueOf.Kind() {
  72. return fmt.Errorf("abi: Unpack(non-pointer %T)", v)
  73. }
  74. var (
  75. value = valueOf.Elem()
  76. typ = value.Type()
  77. kind = value.Kind()
  78. )
  79. /* !TODO add this back
  80. if err := requireUnpackKind(value, typ, kind, (*a), false); err != nil {
  81. return err
  82. }
  83. */
  84. // `i` counts the nonindexed arguments.
  85. // `j` counts the number of complex types.
  86. // both `i` and `j` are used to to correctly compute `data` offset.
  87. i, j := -1, 0
  88. for _, arg := range(*a) {
  89. if arg.Indexed {
  90. // can't read, continue
  91. continue
  92. }
  93. i++
  94. marshalledValue, err := toGoType((i+j)*32, arg.Type, output)
  95. if err != nil {
  96. return err
  97. }
  98. if arg.Type.T == ArrayTy {
  99. // combined index ('i' + 'j') need to be adjusted only by size of array, thus
  100. // we need to decrement 'j' because 'i' was incremented
  101. j += arg.Type.Size - 1
  102. }
  103. reflectValue := reflect.ValueOf(marshalledValue)
  104. switch kind {
  105. case reflect.Struct:
  106. for j := 0; j < typ.NumField(); j++ {
  107. field := typ.Field(j)
  108. // TODO read tags: `abi:"fieldName"`
  109. if field.Name == strings.ToUpper(arg.Name[:1])+arg.Name[1:] {
  110. if err := set(value.Field(j), reflectValue, arg); err != nil {
  111. return err
  112. }
  113. }
  114. }
  115. case reflect.Slice, reflect.Array:
  116. if value.Len() < i {
  117. return fmt.Errorf("abi: insufficient number of arguments for unpack, want %d, got %d", len(*a), value.Len())
  118. }
  119. v := value.Index(i)
  120. if err := requireAssignable(v, reflectValue); err != nil {
  121. return err
  122. }
  123. reflectValue := reflect.ValueOf(marshalledValue)
  124. return set(v.Elem(), reflectValue, arg)
  125. default:
  126. return fmt.Errorf("abi:[2] cannot unmarshal tuple in to %v", typ)
  127. }
  128. }
  129. return nil
  130. }
  131. func (a *Arguments) unpackAtomic(v interface{}, output []byte) error {
  132. // make sure the passed value is a pointer
  133. valueOf := reflect.ValueOf(v)
  134. if reflect.Ptr != valueOf.Kind() {
  135. return fmt.Errorf("abi: Unpack(non-pointer %T)", v)
  136. }
  137. arg := (*a)[0]
  138. if arg.Indexed {
  139. return fmt.Errorf("abi: attempting to unpack indexed variable into element.")
  140. }
  141. value := valueOf.Elem()
  142. marshalledValue, err := toGoType(0, arg.Type, output)
  143. if err != nil {
  144. return err
  145. }
  146. if err := set(value, reflect.ValueOf(marshalledValue), arg); err != nil {
  147. return err
  148. }
  149. return nil
  150. }
  151. func (arguments *Arguments) Pack(args ...interface{}) ([]byte, error) {
  152. // Make sure arguments match up and pack them
  153. if arguments == nil {
  154. return nil, fmt.Errorf("arguments are nil, programmer error!")
  155. }
  156. abiArgs := *arguments
  157. if len(args) != len(abiArgs) {
  158. return nil, fmt.Errorf("argument count mismatch: %d for %d", len(args), len(abiArgs))
  159. }
  160. // variable input is the output appended at the end of packed
  161. // output. This is used for strings and bytes types input.
  162. var variableInput []byte
  163. // input offset is the bytes offset for packed output
  164. inputOffset := 0
  165. for _, abiArg := range abiArgs {
  166. if abiArg.Type.T == ArrayTy {
  167. inputOffset += (32 * abiArg.Type.Size)
  168. } else {
  169. inputOffset += 32
  170. }
  171. }
  172. var ret []byte
  173. for i, a := range args {
  174. input := abiArgs[i]
  175. // pack the input
  176. packed, err := input.Type.pack(reflect.ValueOf(a))
  177. if err != nil {
  178. return nil, err
  179. }
  180. // check for a slice type (string, bytes, slice)
  181. if input.Type.requiresLengthPrefix() {
  182. // calculate the offset
  183. offset := inputOffset + len(variableInput)
  184. // set the offset
  185. ret = append(ret, packNum(reflect.ValueOf(offset))...)
  186. // Append the packed output to the variable input. The variable input
  187. // will be appended at the end of the input.
  188. variableInput = append(variableInput, packed...)
  189. } else {
  190. // append the packed value to the input
  191. ret = append(ret, packed...)
  192. }
  193. }
  194. // append the variable input at the end of the packed input
  195. ret = append(ret, variableInput...)
  196. return ret, nil
  197. }