@@ -48,42 +48,6 @@ func JSON(reader io.Reader) (ABI, error) {
48
48
return abi , nil
49
49
}
50
50
51
- // tests, tests whether the given input would result in a successful
52
- // call. Checks argument list count and matches input to `input`.
53
- func (abi ABI ) pack (method Method , args ... interface {}) ([]byte , error ) {
54
- // variable input is the output appended at the end of packed
55
- // output. This is used for strings and bytes types input.
56
- var variableInput []byte
57
-
58
- var ret []byte
59
- for i , a := range args {
60
- input := method .Inputs [i ]
61
- // pack the input
62
- packed , err := input .Type .pack (a )
63
- if err != nil {
64
- return nil , fmt .Errorf ("`%s` %v" , method .Name , err )
65
- }
66
-
67
- // check for a slice type (string, bytes, slice)
68
- if input .Type .T == StringTy || input .Type .T == BytesTy || input .Type .IsSlice {
69
- // calculate the offset
70
- offset := len (method .Inputs )* 32 + len (variableInput )
71
- // set the offset
72
- ret = append (ret , packNum (reflect .ValueOf (offset ), UintTy )... )
73
- // Append the packed output to the variable input. The variable input
74
- // will be appended at the end of the input.
75
- variableInput = append (variableInput , packed ... )
76
- } else {
77
- // append the packed value to the input
78
- ret = append (ret , packed ... )
79
- }
80
- }
81
- // append the variable input at the end of the packed input
82
- ret = append (ret , variableInput ... )
83
-
84
- return ret , nil
85
- }
86
-
87
51
// Pack the given method name to conform the ABI. Method call's data
88
52
// will consist of method_id, args0, arg1, ... argN. Method id consists
89
53
// of 4 bytes and arguments are all 32 bytes.
@@ -102,11 +66,7 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) {
102
66
}
103
67
method = m
104
68
}
105
- // Make sure arguments match up and pack them
106
- if len (args ) != len (method .Inputs ) {
107
- return nil , fmt .Errorf ("argument count mismatch: %d for %d" , len (args ), len (method .Inputs ))
108
- }
109
- arguments , err := abi .pack (method , args ... )
69
+ arguments , err := method .pack (method , args ... )
110
70
if err != nil {
111
71
return nil , err
112
72
}
@@ -126,18 +86,21 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
126
86
if index + 32 > len (output ) {
127
87
return nil , fmt .Errorf ("abi: cannot marshal in to go slice: insufficient size output %d require %d" , len (output ), index + 32 )
128
88
}
89
+ elem := t .Type .Elem
129
90
130
91
// first we need to create a slice of the type
131
92
var refSlice reflect.Value
132
- switch t . Type .T {
93
+ switch elem .T {
133
94
case IntTy , UintTy , BoolTy : // int, uint, bool can all be of type big int.
134
95
refSlice = reflect .ValueOf ([]* big.Int (nil ))
135
96
case AddressTy : // address must be of slice Address
136
97
refSlice = reflect .ValueOf ([]common.Address (nil ))
137
98
case HashTy : // hash must be of slice hash
138
99
refSlice = reflect .ValueOf ([]common.Hash (nil ))
100
+ case FixedBytesTy :
101
+ refSlice = reflect .ValueOf ([]byte (nil ))
139
102
default : // no other types are supported
140
- return nil , fmt .Errorf ("abi: unsupported slice type %v" , t . Type .T )
103
+ return nil , fmt .Errorf ("abi: unsupported slice type %v" , elem .T )
141
104
}
142
105
// get the offset which determines the start of this array ...
143
106
offset := int (common .BytesToBig (output [index : index + 32 ]).Uint64 ())
@@ -164,7 +127,7 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
164
127
)
165
128
166
129
// set inter to the correct type (cast)
167
- switch t . Type .T {
130
+ switch elem .T {
168
131
case IntTy , UintTy :
169
132
inter = common .BytesToBig (returnOutput )
170
133
case BoolTy :
@@ -186,7 +149,7 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) {
186
149
// argument in T.
187
150
func toGoType (i int , t Argument , output []byte ) (interface {}, error ) {
188
151
// we need to treat slices differently
189
- if t .Type .IsSlice {
152
+ if ( t .Type .IsSlice || t . Type . IsArray ) && t . Type . T != BytesTy && t . Type . T != StringTy && t . Type . T != FixedBytesTy {
190
153
return toGoSlice (i , t , output )
191
154
}
192
155
@@ -217,12 +180,33 @@ func toGoType(i int, t Argument, output []byte) (interface{}, error) {
217
180
returnOutput = output [index : index + 32 ]
218
181
}
219
182
220
- // cast bytes to abi return type
183
+ // convert the bytes to whatever is specified by the ABI.
221
184
switch t .Type .T {
222
- case IntTy :
223
- return common .BytesToBig (returnOutput ), nil
224
- case UintTy :
225
- return common .BytesToBig (returnOutput ), nil
185
+ case IntTy , UintTy :
186
+ bigNum := common .BytesToBig (returnOutput )
187
+
188
+ // If the type is a integer convert to the integer type
189
+ // specified by the ABI.
190
+ switch t .Type .Kind {
191
+ case reflect .Uint8 :
192
+ return uint8 (bigNum .Uint64 ()), nil
193
+ case reflect .Uint16 :
194
+ return uint16 (bigNum .Uint64 ()), nil
195
+ case reflect .Uint32 :
196
+ return uint32 (bigNum .Uint64 ()), nil
197
+ case reflect .Uint64 :
198
+ return uint64 (bigNum .Uint64 ()), nil
199
+ case reflect .Int8 :
200
+ return int8 (bigNum .Int64 ()), nil
201
+ case reflect .Int16 :
202
+ return int16 (bigNum .Int64 ()), nil
203
+ case reflect .Int32 :
204
+ return int32 (bigNum .Int64 ()), nil
205
+ case reflect .Int64 :
206
+ return int64 (bigNum .Int64 ()), nil
207
+ case reflect .Ptr :
208
+ return bigNum , nil
209
+ }
226
210
case BoolTy :
227
211
return common .BytesToBig (returnOutput ).Uint64 () > 0 , nil
228
212
case AddressTy :
@@ -328,10 +312,12 @@ func set(dst, src reflect.Value, output Argument) error {
328
312
return fmt .Errorf ("abi: cannot unmarshal %v in to array of elem %v" , src .Type (), dstType .Elem ())
329
313
}
330
314
331
- if dst .Len () < output .Type .Size {
332
- return fmt .Errorf ("abi: cannot unmarshal src (len=%d) in to dst (len=%d)" , output .Type .Size , dst .Len ())
315
+ if dst .Len () < output .Type .SliceSize {
316
+ return fmt .Errorf ("abi: cannot unmarshal src (len=%d) in to dst (len=%d)" , output .Type .SliceSize , dst .Len ())
333
317
}
334
318
reflect .Copy (dst , src )
319
+ case dstType .Kind () == reflect .Interface :
320
+ dst .Set (src )
335
321
default :
336
322
return fmt .Errorf ("abi: cannot unmarshal %v in to %v" , src .Type (), dst .Type ())
337
323
}
0 commit comments