@@ -18,6 +18,7 @@ package abi
18
18
19
19
import (
20
20
"bytes"
21
+ "errors"
21
22
"fmt"
22
23
"log"
23
24
"math/big"
@@ -103,6 +104,137 @@ func TestTypeCheck(t *testing.T) {
103
104
}
104
105
}
105
106
107
+ func TestSimpleMethodUnpack (t * testing.T ) {
108
+ for i , test := range []struct {
109
+ def string // definition of the **output** ABI params
110
+ marshalledOutput []byte // evm return data
111
+ expectedOut interface {} // the expected output
112
+ outVar string // the output variable (e.g. uint32, *big.Int, etc)
113
+ err error // nil or error if expected
114
+ }{
115
+ {
116
+ `[ { "type": "uint32" } ]` ,
117
+ pad ([]byte {1 }, 32 , true ),
118
+ uint32 (1 ),
119
+ "uint32" ,
120
+ nil ,
121
+ },
122
+ {
123
+ `[ { "type": "uint32" } ]` ,
124
+ pad ([]byte {1 }, 32 , true ),
125
+ nil ,
126
+ "uint16" ,
127
+ errors .New ("abi: cannot unmarshal uint32 in to uint16" ),
128
+ },
129
+ {
130
+ `[ { "type": "uint17" } ]` ,
131
+ pad ([]byte {1 }, 32 , true ),
132
+ nil ,
133
+ "uint16" ,
134
+ errors .New ("abi: cannot unmarshal *big.Int in to uint16" ),
135
+ },
136
+ {
137
+ `[ { "type": "uint17" } ]` ,
138
+ pad ([]byte {1 }, 32 , true ),
139
+ big .NewInt (1 ),
140
+ "*big.Int" ,
141
+ nil ,
142
+ },
143
+ {
144
+ `[ { "type": "address" } ]` ,
145
+ pad (pad ([]byte {1 }, 20 , false ), 32 , true ),
146
+ common.Address {1 },
147
+ "address" ,
148
+ nil ,
149
+ },
150
+ {
151
+ `[ { "type": "bytes32" } ]` ,
152
+ pad ([]byte {1 }, 32 , false ),
153
+ pad ([]byte {1 }, 32 , false ),
154
+ "bytes" ,
155
+ nil ,
156
+ },
157
+ {
158
+ `[ { "type": "bytes32" } ]` ,
159
+ pad ([]byte {1 }, 32 , false ),
160
+ pad ([]byte {1 }, 32 , false ),
161
+ "hash" ,
162
+ nil ,
163
+ },
164
+ } {
165
+ abiDefinition := fmt .Sprintf (`[{ "name" : "method", "outputs": %s}]` , test .def )
166
+ abi , err := JSON (strings .NewReader (abiDefinition ))
167
+ if err != nil {
168
+ t .Errorf ("%d failed. %v" , i , err )
169
+ continue
170
+ }
171
+
172
+ var outvar interface {}
173
+ switch test .outVar {
174
+ case "uint8" :
175
+ var v uint8
176
+ err = abi .Unpack (& v , "method" , test .marshalledOutput )
177
+ outvar = v
178
+ case "uint16" :
179
+ var v uint16
180
+ err = abi .Unpack (& v , "method" , test .marshalledOutput )
181
+ outvar = v
182
+ case "uint32" :
183
+ var v uint32
184
+ err = abi .Unpack (& v , "method" , test .marshalledOutput )
185
+ outvar = v
186
+ case "uint64" :
187
+ var v uint64
188
+ err = abi .Unpack (& v , "method" , test .marshalledOutput )
189
+ outvar = v
190
+ case "*big.Int" :
191
+ var v * big.Int
192
+ err = abi .Unpack (& v , "method" , test .marshalledOutput )
193
+ outvar = v
194
+ case "address" :
195
+ var v common.Address
196
+ err = abi .Unpack (& v , "method" , test .marshalledOutput )
197
+ outvar = v
198
+ case "bytes" :
199
+ var v []byte
200
+ err = abi .Unpack (& v , "method" , test .marshalledOutput )
201
+ outvar = v
202
+ case "hash" :
203
+ var v common.Hash
204
+ err = abi .Unpack (& v , "method" , test .marshalledOutput )
205
+ outvar = v
206
+ default :
207
+ t .Errorf ("unsupported type '%v' please add it to the switch statement in this test" , test .outVar )
208
+ continue
209
+ }
210
+
211
+ if err != nil && test .err == nil {
212
+ t .Errorf ("%d failed. Expected no err but got: %v" , i , err )
213
+ continue
214
+ }
215
+ if err == nil && test .err != nil {
216
+ t .Errorf ("%d failed. Expected err: %v but got none" , i , test .err )
217
+ continue
218
+ }
219
+ if err != nil && test .err != nil && err .Error () != test .err .Error () {
220
+ t .Errorf ("%d failed. Expected err: '%v' got err: '%v'" , i , test .err , err )
221
+ continue
222
+ }
223
+
224
+ if err == nil {
225
+ // bit of an ugly hack for hash type but I don't feel like finding a proper solution
226
+ if test .outVar == "hash" {
227
+ tmp := outvar .(common.Hash ) // without assignment it's unaddressable
228
+ outvar = tmp [:]
229
+ }
230
+
231
+ if ! reflect .DeepEqual (test .expectedOut , outvar ) {
232
+ t .Errorf ("%d failed. Output error: expected %v, got %v" , i , test .expectedOut , outvar )
233
+ }
234
+ }
235
+ }
236
+ }
237
+
106
238
func TestPack (t * testing.T ) {
107
239
for i , test := range []struct {
108
240
typ string
@@ -354,28 +486,6 @@ func TestMethodSignature(t *testing.T) {
354
486
}
355
487
}
356
488
357
- func TestOldPack (t * testing.T ) {
358
- abi , err := JSON (strings .NewReader (jsondata2 ))
359
- if err != nil {
360
- t .Error (err )
361
- t .FailNow ()
362
- }
363
-
364
- sig := crypto .Keccak256 ([]byte ("foo(uint32)" ))[:4 ]
365
- sig = append (sig , make ([]byte , 32 )... )
366
- sig [35 ] = 10
367
-
368
- packed , err := abi .Pack ("foo" , uint32 (10 ))
369
- if err != nil {
370
- t .Error (err )
371
- t .FailNow ()
372
- }
373
-
374
- if ! bytes .Equal (packed , sig ) {
375
- t .Errorf ("expected %x got %x" , sig , packed )
376
- }
377
- }
378
-
379
489
func TestMultiPack (t * testing.T ) {
380
490
abi , err := JSON (strings .NewReader (jsondata2 ))
381
491
if err != nil {
0 commit comments