github.com/ethereum/go-ethereum@v1.16.1/accounts/abi/unpack_test.go (about) 1 // Copyright 2017 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 17 package abi 18 19 import ( 20 "bytes" 21 "encoding/hex" 22 "fmt" 23 "math" 24 "math/big" 25 "reflect" 26 "strconv" 27 "strings" 28 "testing" 29 30 "github.com/ethereum/go-ethereum/common" 31 "github.com/stretchr/testify/require" 32 ) 33 34 func BenchmarkUnpack(b *testing.B) { 35 testCases := []struct { 36 def string 37 packed string 38 }{ 39 { 40 def: `[{"type": "uint32"}]`, 41 packed: "0000000000000000000000000000000000000000000000000000000000000001", 42 }, 43 { 44 def: `[{"type": "uint32[]"}]`, 45 packed: "0000000000000000000000000000000000000000000000000000000000000020" + 46 "0000000000000000000000000000000000000000000000000000000000000002" + 47 "0000000000000000000000000000000000000000000000000000000000000001" + 48 "0000000000000000000000000000000000000000000000000000000000000002", 49 }, 50 } 51 for i, test := range testCases { 52 b.Run(strconv.Itoa(i), func(b *testing.B) { 53 def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def) 54 abi, err := JSON(strings.NewReader(def)) 55 if err != nil { 56 b.Fatalf("invalid ABI definition %s: %v", def, err) 57 } 58 encb, err := hex.DecodeString(test.packed) 59 if err != nil { 60 b.Fatalf("invalid hex %s: %v", test.packed, err) 61 } 62 63 b.ResetTimer() 64 65 var result any 66 for range b.N { 67 result, _ = abi.Unpack("method", encb) 68 } 69 _ = result 70 }) 71 } 72 } 73 74 // TestUnpack tests the general pack/unpack tests in packing_test.go 75 func TestUnpack(t *testing.T) { 76 t.Parallel() 77 for i, test := range packUnpackTests { 78 t.Run(strconv.Itoa(i)+" "+test.def, func(t *testing.T) { 79 //Unpack 80 def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def) 81 abi, err := JSON(strings.NewReader(def)) 82 if err != nil { 83 t.Fatalf("invalid ABI definition %s: %v", def, err) 84 } 85 encb, err := hex.DecodeString(test.packed) 86 if err != nil { 87 t.Fatalf("invalid hex %s: %v", test.packed, err) 88 } 89 out, err := abi.Unpack("method", encb) 90 if err != nil { 91 t.Errorf("test %d (%v) failed: %v", i, test.def, err) 92 return 93 } 94 if !reflect.DeepEqual(test.unpacked, ConvertType(out[0], test.unpacked)) { 95 t.Errorf("test %d (%v) failed: expected %v, got %v", i, test.def, test.unpacked, out[0]) 96 } 97 }) 98 } 99 } 100 101 type unpackTest struct { 102 def string // ABI definition JSON 103 enc string // evm return data 104 want interface{} // the expected output 105 err string // empty or error if expected 106 } 107 108 func (test unpackTest) checkError(err error) error { 109 if err != nil { 110 if len(test.err) == 0 { 111 return fmt.Errorf("expected no err but got: %v", err) 112 } else if err.Error() != test.err { 113 return fmt.Errorf("expected err: '%v' got err: %q", test.err, err) 114 } 115 } else if len(test.err) > 0 { 116 return fmt.Errorf("expected err: %v but got none", test.err) 117 } 118 return nil 119 } 120 121 var unpackTests = []unpackTest{ 122 // Bools 123 { 124 def: `[{ "type": "bool" }]`, 125 enc: "0000000000000000000000000000000000000000000000000001000000000001", 126 want: false, 127 err: "abi: improperly encoded boolean value", 128 }, 129 { 130 def: `[{ "type": "bool" }]`, 131 enc: "0000000000000000000000000000000000000000000000000000000000000003", 132 want: false, 133 err: "abi: improperly encoded boolean value", 134 }, 135 // Integers 136 { 137 def: `[{"type": "uint32"}]`, 138 enc: "0000000000000000000000000000000000000000000000000000000000000001", 139 want: uint16(0), 140 err: "abi: cannot unmarshal uint32 in to uint16", 141 }, 142 { 143 def: `[{"type": "uint17"}]`, 144 enc: "0000000000000000000000000000000000000000000000000000000000000001", 145 want: uint16(0), 146 err: "abi: cannot unmarshal *big.Int in to uint16", 147 }, 148 { 149 def: `[{"type": "int32"}]`, 150 enc: "0000000000000000000000000000000000000000000000000000000000000001", 151 want: int16(0), 152 err: "abi: cannot unmarshal int32 in to int16", 153 }, 154 { 155 def: `[{"type": "int17"}]`, 156 enc: "0000000000000000000000000000000000000000000000000000000000000001", 157 want: int16(0), 158 err: "abi: cannot unmarshal *big.Int in to int16", 159 }, 160 { 161 def: `[{"type": "bytes"}]`, 162 enc: "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000", 163 want: [32]byte{1}, 164 }, 165 { 166 def: `[{"type": "bytes32"}]`, 167 enc: "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000", 168 want: []byte(nil), 169 err: "abi: cannot unmarshal [32]uint8 in to []uint8", 170 }, 171 { 172 def: `[{"name":"___","type":"int256"}]`, 173 enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", 174 want: struct { 175 IntOne *big.Int 176 Intone *big.Int 177 }{IntOne: big.NewInt(1)}, 178 }, 179 { 180 def: `[{"name":"int_one","type":"int256"},{"name":"IntOne","type":"int256"}]`, 181 enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", 182 want: struct { 183 Int1 *big.Int 184 Int2 *big.Int 185 }{}, 186 err: "abi: multiple outputs mapping to the same struct field 'IntOne'", 187 }, 188 { 189 def: `[{"name":"int","type":"int256"},{"name":"Int","type":"int256"}]`, 190 enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", 191 want: struct { 192 Int1 *big.Int 193 Int2 *big.Int 194 }{}, 195 err: "abi: multiple outputs mapping to the same struct field 'Int'", 196 }, 197 { 198 def: `[{"name":"int","type":"int256"},{"name":"_int","type":"int256"}]`, 199 enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", 200 want: struct { 201 Int1 *big.Int 202 Int2 *big.Int 203 }{}, 204 err: "abi: multiple outputs mapping to the same struct field 'Int'", 205 }, 206 { 207 def: `[{"name":"Int","type":"int256"},{"name":"_int","type":"int256"}]`, 208 enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", 209 want: struct { 210 Int1 *big.Int 211 Int2 *big.Int 212 }{}, 213 err: "abi: multiple outputs mapping to the same struct field 'Int'", 214 }, 215 { 216 def: `[{"name":"Int","type":"int256"},{"name":"_","type":"int256"}]`, 217 enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", 218 want: struct { 219 Int1 *big.Int 220 Int2 *big.Int 221 }{}, 222 err: "abi: purely underscored output cannot unpack to struct", 223 }, 224 // Make sure only the first argument is consumed 225 { 226 def: `[{"name":"int_one","type":"int256"}]`, 227 enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", 228 want: struct { 229 IntOne *big.Int 230 }{big.NewInt(1)}, 231 }, 232 { 233 def: `[{"name":"int__one","type":"int256"}]`, 234 enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", 235 want: struct { 236 IntOne *big.Int 237 }{big.NewInt(1)}, 238 }, 239 { 240 def: `[{"name":"int_one_","type":"int256"}]`, 241 enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", 242 want: struct { 243 IntOne *big.Int 244 }{big.NewInt(1)}, 245 }, 246 { 247 def: `[{"type":"bool"}]`, 248 enc: "", 249 want: false, 250 err: "abi: attempting to unmarshal an empty string while arguments are expected", 251 }, 252 { 253 def: `[{"type":"bytes32","indexed":true},{"type":"uint256","indexed":false}]`, 254 enc: "", 255 want: false, 256 err: "abi: attempting to unmarshal an empty string while arguments are expected", 257 }, 258 { 259 def: `[{"type":"bool","indexed":true},{"type":"uint64","indexed":true}]`, 260 enc: "", 261 want: false, 262 }, 263 } 264 265 // TestLocalUnpackTests runs test specially designed only for unpacking. 266 // All test cases that can be used to test packing and unpacking should move to packing_test.go 267 func TestLocalUnpackTests(t *testing.T) { 268 t.Parallel() 269 for i, test := range unpackTests { 270 t.Run(strconv.Itoa(i), func(t *testing.T) { 271 //Unpack 272 def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def) 273 abi, err := JSON(strings.NewReader(def)) 274 if err != nil { 275 t.Fatalf("invalid ABI definition %s: %v", def, err) 276 } 277 encb, err := hex.DecodeString(test.enc) 278 if err != nil { 279 t.Fatalf("invalid hex %s: %v", test.enc, err) 280 } 281 outptr := reflect.New(reflect.TypeOf(test.want)) 282 err = abi.UnpackIntoInterface(outptr.Interface(), "method", encb) 283 if err := test.checkError(err); err != nil { 284 t.Errorf("test %d (%v) failed: %v", i, test.def, err) 285 return 286 } 287 out := outptr.Elem().Interface() 288 if !reflect.DeepEqual(test.want, out) { 289 t.Errorf("test %d (%v) failed: expected %v, got %v", i, test.def, test.want, out) 290 } 291 }) 292 } 293 } 294 295 func TestUnpackIntoInterfaceSetDynamicArrayOutput(t *testing.T) { 296 t.Parallel() 297 abi, err := JSON(strings.NewReader(`[{"constant":true,"inputs":[],"name":"testDynamicFixedBytes15","outputs":[{"name":"","type":"bytes15[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"testDynamicFixedBytes32","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"}]`)) 298 if err != nil { 299 t.Fatal(err) 300 } 301 302 var ( 303 marshalledReturn32 = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000230783132333435363738393000000000000000000000000000000000000000003078303938373635343332310000000000000000000000000000000000000000") 304 marshalledReturn15 = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000230783031323334350000000000000000000000000000000000000000000000003078393837363534000000000000000000000000000000000000000000000000") 305 306 out32 [][32]byte 307 out15 [][15]byte 308 ) 309 310 // test 32 311 err = abi.UnpackIntoInterface(&out32, "testDynamicFixedBytes32", marshalledReturn32) 312 if err != nil { 313 t.Fatal(err) 314 } 315 if len(out32) != 2 { 316 t.Fatalf("expected array with 2 values, got %d", len(out32)) 317 } 318 expected := common.Hex2Bytes("3078313233343536373839300000000000000000000000000000000000000000") 319 if !bytes.Equal(out32[0][:], expected) { 320 t.Errorf("expected %x, got %x\n", expected, out32[0]) 321 } 322 expected = common.Hex2Bytes("3078303938373635343332310000000000000000000000000000000000000000") 323 if !bytes.Equal(out32[1][:], expected) { 324 t.Errorf("expected %x, got %x\n", expected, out32[1]) 325 } 326 327 // test 15 328 err = abi.UnpackIntoInterface(&out15, "testDynamicFixedBytes32", marshalledReturn15) 329 if err != nil { 330 t.Fatal(err) 331 } 332 if len(out15) != 2 { 333 t.Fatalf("expected array with 2 values, got %d", len(out15)) 334 } 335 expected = common.Hex2Bytes("307830313233343500000000000000") 336 if !bytes.Equal(out15[0][:], expected) { 337 t.Errorf("expected %x, got %x\n", expected, out15[0]) 338 } 339 expected = common.Hex2Bytes("307839383736353400000000000000") 340 if !bytes.Equal(out15[1][:], expected) { 341 t.Errorf("expected %x, got %x\n", expected, out15[1]) 342 } 343 } 344 345 type methodMultiOutput struct { 346 Int *big.Int 347 String string 348 } 349 350 func methodMultiReturn(require *require.Assertions) (ABI, []byte, methodMultiOutput) { 351 const definition = `[ 352 { "name" : "multi", "type": "function", "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]` 353 var expected = methodMultiOutput{big.NewInt(1), "hello"} 354 355 abi, err := JSON(strings.NewReader(definition)) 356 require.NoError(err) 357 // using buff to make the code readable 358 buff := new(bytes.Buffer) 359 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) 360 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040")) 361 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000005")) 362 buff.Write(common.RightPadBytes([]byte(expected.String), 32)) 363 return abi, buff.Bytes(), expected 364 } 365 366 func TestMethodMultiReturn(t *testing.T) { 367 t.Parallel() 368 type reversed struct { 369 String string 370 Int *big.Int 371 } 372 373 newInterfaceSlice := func(len int) interface{} { 374 slice := make([]interface{}, len) 375 return &slice 376 } 377 378 abi, data, expected := methodMultiReturn(require.New(t)) 379 bigint := new(big.Int) 380 var testCases = []struct { 381 dest interface{} 382 expected interface{} 383 error string 384 name string 385 }{{ 386 &methodMultiOutput{}, 387 &expected, 388 "", 389 "Can unpack into structure", 390 }, { 391 &reversed{}, 392 &reversed{expected.String, expected.Int}, 393 "", 394 "Can unpack into reversed structure", 395 }, { 396 &[]interface{}{&bigint, new(string)}, 397 &[]interface{}{&expected.Int, &expected.String}, 398 "", 399 "Can unpack into a slice", 400 }, { 401 &[]interface{}{&bigint, ""}, 402 &[]interface{}{&expected.Int, expected.String}, 403 "", 404 "Can unpack into a slice without indirection", 405 }, { 406 &[2]interface{}{&bigint, new(string)}, 407 &[2]interface{}{&expected.Int, &expected.String}, 408 "", 409 "Can unpack into an array", 410 }, { 411 &[2]interface{}{}, 412 &[2]interface{}{expected.Int, expected.String}, 413 "", 414 "Can unpack into interface array", 415 }, { 416 newInterfaceSlice(2), 417 &[]interface{}{expected.Int, expected.String}, 418 "", 419 "Can unpack into interface slice", 420 }, { 421 &[]interface{}{new(int), new(int)}, 422 &[]interface{}{&expected.Int, &expected.String}, 423 "abi: cannot unmarshal *big.Int in to int", 424 "Can not unpack into a slice with wrong types", 425 }, { 426 &[]interface{}{new(int)}, 427 &[]interface{}{}, 428 "abi: insufficient number of arguments for unpack, want 2, got 1", 429 "Can not unpack into a slice with wrong types", 430 }} 431 for _, tc := range testCases { 432 t.Run(tc.name, func(t *testing.T) { 433 require := require.New(t) 434 err := abi.UnpackIntoInterface(tc.dest, "multi", data) 435 if tc.error == "" { 436 require.Nil(err, "Should be able to unpack method outputs.") 437 require.Equal(tc.expected, tc.dest) 438 } else { 439 require.EqualError(err, tc.error) 440 } 441 }) 442 } 443 } 444 445 func TestMultiReturnWithArray(t *testing.T) { 446 t.Parallel() 447 const definition = `[{"name" : "multi", "type": "function", "outputs": [{"type": "uint64[3]"}, {"type": "uint64"}]}]` 448 abi, err := JSON(strings.NewReader(definition)) 449 if err != nil { 450 t.Fatal(err) 451 } 452 buff := new(bytes.Buffer) 453 buff.Write(common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000009")) 454 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000008")) 455 456 ret1, ret1Exp := new([3]uint64), [3]uint64{9, 9, 9} 457 ret2, ret2Exp := new(uint64), uint64(8) 458 if err := abi.UnpackIntoInterface(&[]interface{}{ret1, ret2}, "multi", buff.Bytes()); err != nil { 459 t.Fatal(err) 460 } 461 if !reflect.DeepEqual(*ret1, ret1Exp) { 462 t.Error("array result", *ret1, "!= Expected", ret1Exp) 463 } 464 if *ret2 != ret2Exp { 465 t.Error("int result", *ret2, "!= Expected", ret2Exp) 466 } 467 } 468 469 func TestMultiReturnWithStringArray(t *testing.T) { 470 t.Parallel() 471 const definition = `[{"name" : "multi", "type": "function", "outputs": [{"name": "","type": "uint256[3]"},{"name": "","type": "address"},{"name": "","type": "string[2]"},{"name": "","type": "bool"}]}]` 472 abi, err := JSON(strings.NewReader(definition)) 473 if err != nil { 474 t.Fatal(err) 475 } 476 buff := new(bytes.Buffer) 477 buff.Write(common.Hex2Bytes("000000000000000000000000000000000000000000000000000000005c1b78ea0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000001a055690d9db80000000000000000000000000000ab1257528b3782fb40d7ed5f72e624b744dffb2f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001048656c6c6f2c20457468657265756d2100000000000000000000000000000000")) 478 temp, _ := new(big.Int).SetString("30000000000000000000", 10) 479 ret1, ret1Exp := new([3]*big.Int), [3]*big.Int{big.NewInt(1545304298), big.NewInt(6), temp} 480 ret2, ret2Exp := new(common.Address), common.HexToAddress("ab1257528b3782fb40d7ed5f72e624b744dffb2f") 481 ret3, ret3Exp := new([2]string), [2]string{"Ethereum", "Hello, Ethereum!"} 482 ret4, ret4Exp := new(bool), false 483 if err := abi.UnpackIntoInterface(&[]interface{}{ret1, ret2, ret3, ret4}, "multi", buff.Bytes()); err != nil { 484 t.Fatal(err) 485 } 486 if !reflect.DeepEqual(*ret1, ret1Exp) { 487 t.Error("big.Int array result", *ret1, "!= Expected", ret1Exp) 488 } 489 if !reflect.DeepEqual(*ret2, ret2Exp) { 490 t.Error("address result", *ret2, "!= Expected", ret2Exp) 491 } 492 if !reflect.DeepEqual(*ret3, ret3Exp) { 493 t.Error("string array result", *ret3, "!= Expected", ret3Exp) 494 } 495 if !reflect.DeepEqual(*ret4, ret4Exp) { 496 t.Error("bool result", *ret4, "!= Expected", ret4Exp) 497 } 498 } 499 500 func TestMultiReturnWithStringSlice(t *testing.T) { 501 t.Parallel() 502 const definition = `[{"name" : "multi", "type": "function", "outputs": [{"name": "","type": "string[]"},{"name": "","type": "uint256[]"}]}]` 503 abi, err := JSON(strings.NewReader(definition)) 504 if err != nil { 505 t.Fatal(err) 506 } 507 buff := new(bytes.Buffer) 508 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040")) // output[0] offset 509 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000120")) // output[1] offset 510 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // output[0] length 511 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040")) // output[0][0] offset 512 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000080")) // output[0][1] offset 513 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000008")) // output[0][0] length 514 buff.Write(common.Hex2Bytes("657468657265756d000000000000000000000000000000000000000000000000")) // output[0][0] value 515 buff.Write(common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000b")) // output[0][1] length 516 buff.Write(common.Hex2Bytes("676f2d657468657265756d000000000000000000000000000000000000000000")) // output[0][1] value 517 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // output[1] length 518 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000064")) // output[1][0] value 519 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000065")) // output[1][1] value 520 ret1, ret1Exp := new([]string), []string{"ethereum", "go-ethereum"} 521 ret2, ret2Exp := new([]*big.Int), []*big.Int{big.NewInt(100), big.NewInt(101)} 522 if err := abi.UnpackIntoInterface(&[]interface{}{ret1, ret2}, "multi", buff.Bytes()); err != nil { 523 t.Fatal(err) 524 } 525 if !reflect.DeepEqual(*ret1, ret1Exp) { 526 t.Error("string slice result", *ret1, "!= Expected", ret1Exp) 527 } 528 if !reflect.DeepEqual(*ret2, ret2Exp) { 529 t.Error("uint256 slice result", *ret2, "!= Expected", ret2Exp) 530 } 531 } 532 533 func TestMultiReturnWithDeeplyNestedArray(t *testing.T) { 534 t.Parallel() 535 // Similar to TestMultiReturnWithArray, but with a special case in mind: 536 // values of nested static arrays count towards the size as well, and any element following 537 // after such nested array argument should be read with the correct offset, 538 // so that it does not read content from the previous array argument. 539 const definition = `[{"name" : "multi", "type": "function", "outputs": [{"type": "uint64[3][2][4]"}, {"type": "uint64"}]}]` 540 abi, err := JSON(strings.NewReader(definition)) 541 if err != nil { 542 t.Fatal(err) 543 } 544 buff := new(bytes.Buffer) 545 // construct the test array, each 3 char element is joined with 61 '0' chars, 546 // to from the ((3 + 61) * 0.5) = 32 byte elements in the array. 547 buff.Write(common.Hex2Bytes(strings.Join([]string{ 548 "", //empty, to apply the 61-char separator to the first element as well. 549 "111", "112", "113", "121", "122", "123", 550 "211", "212", "213", "221", "222", "223", 551 "311", "312", "313", "321", "322", "323", 552 "411", "412", "413", "421", "422", "423", 553 }, "0000000000000000000000000000000000000000000000000000000000000"))) 554 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000009876")) 555 556 ret1, ret1Exp := new([4][2][3]uint64), [4][2][3]uint64{ 557 {{0x111, 0x112, 0x113}, {0x121, 0x122, 0x123}}, 558 {{0x211, 0x212, 0x213}, {0x221, 0x222, 0x223}}, 559 {{0x311, 0x312, 0x313}, {0x321, 0x322, 0x323}}, 560 {{0x411, 0x412, 0x413}, {0x421, 0x422, 0x423}}, 561 } 562 ret2, ret2Exp := new(uint64), uint64(0x9876) 563 if err := abi.UnpackIntoInterface(&[]interface{}{ret1, ret2}, "multi", buff.Bytes()); err != nil { 564 t.Fatal(err) 565 } 566 if !reflect.DeepEqual(*ret1, ret1Exp) { 567 t.Error("array result", *ret1, "!= Expected", ret1Exp) 568 } 569 if *ret2 != ret2Exp { 570 t.Error("int result", *ret2, "!= Expected", ret2Exp) 571 } 572 } 573 574 func TestUnmarshal(t *testing.T) { 575 t.Parallel() 576 const definition = `[ 577 { "name" : "int", "type": "function", "outputs": [ { "type": "uint256" } ] }, 578 { "name" : "bool", "type": "function", "outputs": [ { "type": "bool" } ] }, 579 { "name" : "bytes", "type": "function", "outputs": [ { "type": "bytes" } ] }, 580 { "name" : "fixed", "type": "function", "outputs": [ { "type": "bytes32" } ] }, 581 { "name" : "multi", "type": "function", "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] }, 582 { "name" : "intArraySingle", "type": "function", "outputs": [ { "type": "uint256[3]" } ] }, 583 { "name" : "addressSliceSingle", "type": "function", "outputs": [ { "type": "address[]" } ] }, 584 { "name" : "addressSliceDouble", "type": "function", "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] }, 585 { "name" : "mixedBytes", "type": "function", "stateMutability" : "view", "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]` 586 587 abi, err := JSON(strings.NewReader(definition)) 588 if err != nil { 589 t.Fatal(err) 590 } 591 buff := new(bytes.Buffer) 592 593 // marshall mixed bytes (mixedBytes) 594 p0, p0Exp := []byte{}, common.Hex2Bytes("01020000000000000000") 595 p1, p1Exp := [32]byte{}, common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000ddeeff") 596 mixedBytes := []interface{}{&p0, &p1} 597 598 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040")) 599 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000ddeeff")) 600 buff.Write(common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000a")) 601 buff.Write(common.Hex2Bytes("0102000000000000000000000000000000000000000000000000000000000000")) 602 603 err = abi.UnpackIntoInterface(&mixedBytes, "mixedBytes", buff.Bytes()) 604 if err != nil { 605 t.Error(err) 606 } else { 607 if !bytes.Equal(p0, p0Exp) { 608 t.Errorf("unexpected value unpacked: want %x, got %x", p0Exp, p0) 609 } 610 611 if !bytes.Equal(p1[:], p1Exp) { 612 t.Errorf("unexpected value unpacked: want %x, got %x", p1Exp, p1) 613 } 614 } 615 616 // marshal int 617 var Int *big.Int 618 err = abi.UnpackIntoInterface(&Int, "int", common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) 619 if err != nil { 620 t.Error(err) 621 } 622 623 if Int == nil || Int.Cmp(big.NewInt(1)) != 0 { 624 t.Error("expected Int to be 1 got", Int) 625 } 626 627 // marshal bool 628 var Bool bool 629 err = abi.UnpackIntoInterface(&Bool, "bool", common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) 630 if err != nil { 631 t.Error(err) 632 } 633 634 if !Bool { 635 t.Error("expected Bool to be true") 636 } 637 638 // marshal dynamic bytes max length 32 639 buff.Reset() 640 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020")) 641 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020")) 642 bytesOut := common.RightPadBytes([]byte("hello"), 32) 643 buff.Write(bytesOut) 644 645 var Bytes []byte 646 err = abi.UnpackIntoInterface(&Bytes, "bytes", buff.Bytes()) 647 if err != nil { 648 t.Error(err) 649 } 650 651 if !bytes.Equal(Bytes, bytesOut) { 652 t.Errorf("expected %x got %x", bytesOut, Bytes) 653 } 654 655 // marshall dynamic bytes max length 64 656 buff.Reset() 657 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020")) 658 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040")) 659 bytesOut = common.RightPadBytes([]byte("hello"), 64) 660 buff.Write(bytesOut) 661 662 err = abi.UnpackIntoInterface(&Bytes, "bytes", buff.Bytes()) 663 if err != nil { 664 t.Error(err) 665 } 666 667 if !bytes.Equal(Bytes, bytesOut) { 668 t.Errorf("expected %x got %x", bytesOut, Bytes) 669 } 670 671 // marshall dynamic bytes max length 64 672 buff.Reset() 673 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020")) 674 buff.Write(common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000003f")) 675 bytesOut = common.RightPadBytes([]byte("hello"), 64) 676 buff.Write(bytesOut) 677 678 err = abi.UnpackIntoInterface(&Bytes, "bytes", buff.Bytes()) 679 if err != nil { 680 t.Error(err) 681 } 682 683 if !bytes.Equal(Bytes, bytesOut[:len(bytesOut)-1]) { 684 t.Errorf("expected %x got %x", bytesOut[:len(bytesOut)-1], Bytes) 685 } 686 687 // marshal dynamic bytes output empty 688 err = abi.UnpackIntoInterface(&Bytes, "bytes", nil) 689 if err == nil { 690 t.Error("expected error") 691 } 692 693 // marshal dynamic bytes length 5 694 buff.Reset() 695 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020")) 696 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000005")) 697 buff.Write(common.RightPadBytes([]byte("hello"), 32)) 698 699 err = abi.UnpackIntoInterface(&Bytes, "bytes", buff.Bytes()) 700 if err != nil { 701 t.Error(err) 702 } 703 704 if !bytes.Equal(Bytes, []byte("hello")) { 705 t.Errorf("expected %x got %x", bytesOut, Bytes) 706 } 707 708 // marshal dynamic bytes length 5 709 buff.Reset() 710 buff.Write(common.RightPadBytes([]byte("hello"), 32)) 711 712 var hash common.Hash 713 err = abi.UnpackIntoInterface(&hash, "fixed", buff.Bytes()) 714 if err != nil { 715 t.Error(err) 716 } 717 718 helloHash := common.BytesToHash(common.RightPadBytes([]byte("hello"), 32)) 719 if hash != helloHash { 720 t.Errorf("Expected %x to equal %x", hash, helloHash) 721 } 722 723 // marshal error 724 buff.Reset() 725 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020")) 726 err = abi.UnpackIntoInterface(&Bytes, "bytes", buff.Bytes()) 727 if err == nil { 728 t.Error("expected error") 729 } 730 731 err = abi.UnpackIntoInterface(&Bytes, "multi", make([]byte, 64)) 732 if err == nil { 733 t.Error("expected error") 734 } 735 736 buff.Reset() 737 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) 738 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) 739 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000003")) 740 // marshal int array 741 var intArray [3]*big.Int 742 err = abi.UnpackIntoInterface(&intArray, "intArraySingle", buff.Bytes()) 743 if err != nil { 744 t.Error(err) 745 } 746 var testAgainstIntArray [3]*big.Int 747 testAgainstIntArray[0] = big.NewInt(1) 748 testAgainstIntArray[1] = big.NewInt(2) 749 testAgainstIntArray[2] = big.NewInt(3) 750 751 for i, Int := range intArray { 752 if Int.Cmp(testAgainstIntArray[i]) != 0 { 753 t.Errorf("expected %v, got %v", testAgainstIntArray[i], Int) 754 } 755 } 756 // marshal address slice 757 buff.Reset() 758 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020")) // offset 759 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // size 760 buff.Write(common.Hex2Bytes("0000000000000000000000000100000000000000000000000000000000000000")) 761 762 var outAddr []common.Address 763 err = abi.UnpackIntoInterface(&outAddr, "addressSliceSingle", buff.Bytes()) 764 if err != nil { 765 t.Fatal("didn't expect error:", err) 766 } 767 768 if len(outAddr) != 1 { 769 t.Fatal("expected 1 item, got", len(outAddr)) 770 } 771 772 if outAddr[0] != (common.Address{1}) { 773 t.Errorf("expected %x, got %x", common.Address{1}, outAddr[0]) 774 } 775 776 // marshal multiple address slice 777 buff.Reset() 778 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040")) // offset 779 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000080")) // offset 780 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // size 781 buff.Write(common.Hex2Bytes("0000000000000000000000000100000000000000000000000000000000000000")) 782 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // size 783 buff.Write(common.Hex2Bytes("0000000000000000000000000200000000000000000000000000000000000000")) 784 buff.Write(common.Hex2Bytes("0000000000000000000000000300000000000000000000000000000000000000")) 785 786 var outAddrStruct struct { 787 A []common.Address 788 B []common.Address 789 } 790 err = abi.UnpackIntoInterface(&outAddrStruct, "addressSliceDouble", buff.Bytes()) 791 if err != nil { 792 t.Fatal("didn't expect error:", err) 793 } 794 795 if len(outAddrStruct.A) != 1 { 796 t.Fatal("expected 1 item, got", len(outAddrStruct.A)) 797 } 798 799 if outAddrStruct.A[0] != (common.Address{1}) { 800 t.Errorf("expected %x, got %x", common.Address{1}, outAddrStruct.A[0]) 801 } 802 803 if len(outAddrStruct.B) != 2 { 804 t.Fatal("expected 1 item, got", len(outAddrStruct.B)) 805 } 806 807 if outAddrStruct.B[0] != (common.Address{2}) { 808 t.Errorf("expected %x, got %x", common.Address{2}, outAddrStruct.B[0]) 809 } 810 if outAddrStruct.B[1] != (common.Address{3}) { 811 t.Errorf("expected %x, got %x", common.Address{3}, outAddrStruct.B[1]) 812 } 813 814 // marshal invalid address slice 815 buff.Reset() 816 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000100")) 817 818 err = abi.UnpackIntoInterface(&outAddr, "addressSliceSingle", buff.Bytes()) 819 if err == nil { 820 t.Fatal("expected error:", err) 821 } 822 } 823 824 func TestUnpackTuple(t *testing.T) { 825 t.Parallel() 826 const simpleTuple = `[{"name":"tuple","type":"function","outputs":[{"type":"tuple","name":"ret","components":[{"type":"int256","name":"a"},{"type":"int256","name":"b"}]}]}]` 827 abi, err := JSON(strings.NewReader(simpleTuple)) 828 if err != nil { 829 t.Fatal(err) 830 } 831 buff := new(bytes.Buffer) 832 833 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // ret[a] = 1 834 buff.Write(common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) // ret[b] = -1 835 836 // If the result is single tuple, use struct as return value container directly. 837 type v struct { 838 A *big.Int 839 B *big.Int 840 } 841 type r struct { 842 Result v 843 } 844 var ret0 = new(r) 845 err = abi.UnpackIntoInterface(ret0, "tuple", buff.Bytes()) 846 847 if err != nil { 848 t.Error(err) 849 } else { 850 if ret0.Result.A.Cmp(big.NewInt(1)) != 0 { 851 t.Errorf("unexpected value unpacked: want %x, got %x", 1, ret0.Result.A) 852 } 853 if ret0.Result.B.Cmp(big.NewInt(-1)) != 0 { 854 t.Errorf("unexpected value unpacked: want %x, got %x", -1, ret0.Result.B) 855 } 856 } 857 858 // Test nested tuple 859 const nestedTuple = `[{"name":"tuple","type":"function","outputs":[ 860 {"type":"tuple","name":"s","components":[{"type":"uint256","name":"a"},{"type":"uint256[]","name":"b"},{"type":"tuple[]","name":"c","components":[{"name":"x", "type":"uint256"},{"name":"y","type":"uint256"}]}]}, 861 {"type":"tuple","name":"t","components":[{"name":"x", "type":"uint256"},{"name":"y","type":"uint256"}]}, 862 {"type":"uint256","name":"a"} 863 ]}]` 864 865 abi, err = JSON(strings.NewReader(nestedTuple)) 866 if err != nil { 867 t.Fatal(err) 868 } 869 buff.Reset() 870 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000080")) // s offset 871 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")) // t.X = 0 872 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // t.Y = 1 873 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // a = 1 874 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // s.A = 1 875 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000060")) // s.B offset 876 buff.Write(common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000c0")) // s.C offset 877 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // s.B length 878 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // s.B[0] = 1 879 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // s.B[0] = 2 880 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // s.C length 881 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // s.C[0].X 882 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // s.C[0].Y 883 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // s.C[1].X 884 buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // s.C[1].Y 885 886 type T struct { 887 X *big.Int `abi:"x"` 888 Z *big.Int `abi:"y"` // Test whether the abi tag works. 889 } 890 891 type S struct { 892 A *big.Int 893 B []*big.Int 894 C []T 895 } 896 897 type Ret struct { 898 FieldS S `abi:"s"` 899 FieldT T `abi:"t"` 900 A *big.Int 901 } 902 var ret Ret 903 var expected = Ret{ 904 FieldS: S{ 905 A: big.NewInt(1), 906 B: []*big.Int{big.NewInt(1), big.NewInt(2)}, 907 C: []T{ 908 {big.NewInt(1), big.NewInt(2)}, 909 {big.NewInt(2), big.NewInt(1)}, 910 }, 911 }, 912 FieldT: T{ 913 big.NewInt(0), big.NewInt(1), 914 }, 915 A: big.NewInt(1), 916 } 917 918 err = abi.UnpackIntoInterface(&ret, "tuple", buff.Bytes()) 919 if err != nil { 920 t.Error(err) 921 } 922 if reflect.DeepEqual(ret, expected) { 923 t.Error("unexpected unpack value") 924 } 925 } 926 927 func TestOOMMaliciousInput(t *testing.T) { 928 t.Parallel() 929 oomTests := []unpackTest{ 930 { 931 def: `[{"type": "uint8[]"}]`, 932 enc: "0000000000000000000000000000000000000000000000000000000000000020" + // offset 933 "0000000000000000000000000000000000000000000000000000000000000003" + // num elems 934 "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1 935 "0000000000000000000000000000000000000000000000000000000000000002", // elem 2 936 }, 937 { // Length larger than 64 bits 938 def: `[{"type": "uint8[]"}]`, 939 enc: "0000000000000000000000000000000000000000000000000000000000000020" + // offset 940 "00ffffffffffffffffffffffffffffffffffffffffffffff0000000000000002" + // num elems 941 "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1 942 "0000000000000000000000000000000000000000000000000000000000000002", // elem 2 943 }, 944 { // Offset very large (over 64 bits) 945 def: `[{"type": "uint8[]"}]`, 946 enc: "00ffffffffffffffffffffffffffffffffffffffffffffff0000000000000020" + // offset 947 "0000000000000000000000000000000000000000000000000000000000000002" + // num elems 948 "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1 949 "0000000000000000000000000000000000000000000000000000000000000002", // elem 2 950 }, 951 { // Offset very large (below 64 bits) 952 def: `[{"type": "uint8[]"}]`, 953 enc: "0000000000000000000000000000000000000000000000007ffffffffff00020" + // offset 954 "0000000000000000000000000000000000000000000000000000000000000002" + // num elems 955 "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1 956 "0000000000000000000000000000000000000000000000000000000000000002", // elem 2 957 }, 958 { // Offset negative (as 64 bit) 959 def: `[{"type": "uint8[]"}]`, 960 enc: "000000000000000000000000000000000000000000000000f000000000000020" + // offset 961 "0000000000000000000000000000000000000000000000000000000000000002" + // num elems 962 "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1 963 "0000000000000000000000000000000000000000000000000000000000000002", // elem 2 964 }, 965 966 { // Negative length 967 def: `[{"type": "uint8[]"}]`, 968 enc: "0000000000000000000000000000000000000000000000000000000000000020" + // offset 969 "000000000000000000000000000000000000000000000000f000000000000002" + // num elems 970 "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1 971 "0000000000000000000000000000000000000000000000000000000000000002", // elem 2 972 }, 973 { // Very large length 974 def: `[{"type": "uint8[]"}]`, 975 enc: "0000000000000000000000000000000000000000000000000000000000000020" + // offset 976 "0000000000000000000000000000000000000000000000007fffffffff000002" + // num elems 977 "0000000000000000000000000000000000000000000000000000000000000001" + // elem 1 978 "0000000000000000000000000000000000000000000000000000000000000002", // elem 2 979 }, 980 } 981 for i, test := range oomTests { 982 def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def) 983 abi, err := JSON(strings.NewReader(def)) 984 if err != nil { 985 t.Fatalf("invalid ABI definition %s: %v", def, err) 986 } 987 encb, err := hex.DecodeString(test.enc) 988 if err != nil { 989 t.Fatalf("invalid hex: %s", test.enc) 990 } 991 _, err = abi.Methods["method"].Outputs.UnpackValues(encb) 992 if err == nil { 993 t.Fatalf("Expected error on malicious input, test %d", i) 994 } 995 } 996 } 997 998 func TestPackAndUnpackIncompatibleNumber(t *testing.T) { 999 t.Parallel() 1000 var encodeABI Arguments 1001 uint256Ty, err := NewType("uint256", "", nil) 1002 if err != nil { 1003 panic(err) 1004 } 1005 encodeABI = Arguments{ 1006 {Type: uint256Ty}, 1007 } 1008 1009 maxU64, ok := new(big.Int).SetString(strconv.FormatUint(math.MaxUint64, 10), 10) 1010 if !ok { 1011 panic("bug") 1012 } 1013 maxU64Plus1 := new(big.Int).Add(maxU64, big.NewInt(1)) 1014 cases := []struct { 1015 decodeType string 1016 inputValue *big.Int 1017 unpackErr error 1018 packErr error 1019 expectValue interface{} 1020 }{ 1021 { 1022 decodeType: "uint8", 1023 inputValue: big.NewInt(math.MaxUint8 + 1), 1024 unpackErr: errBadUint8, 1025 }, 1026 { 1027 decodeType: "uint8", 1028 inputValue: big.NewInt(math.MaxUint8), 1029 unpackErr: nil, 1030 expectValue: uint8(math.MaxUint8), 1031 }, 1032 { 1033 decodeType: "uint16", 1034 inputValue: big.NewInt(math.MaxUint16 + 1), 1035 unpackErr: errBadUint16, 1036 }, 1037 { 1038 decodeType: "uint16", 1039 inputValue: big.NewInt(math.MaxUint16), 1040 unpackErr: nil, 1041 expectValue: uint16(math.MaxUint16), 1042 }, 1043 { 1044 decodeType: "uint32", 1045 inputValue: big.NewInt(math.MaxUint32 + 1), 1046 unpackErr: errBadUint32, 1047 }, 1048 { 1049 decodeType: "uint32", 1050 inputValue: big.NewInt(math.MaxUint32), 1051 unpackErr: nil, 1052 expectValue: uint32(math.MaxUint32), 1053 }, 1054 { 1055 decodeType: "uint64", 1056 inputValue: maxU64Plus1, 1057 unpackErr: errBadUint64, 1058 }, 1059 { 1060 decodeType: "uint64", 1061 inputValue: maxU64, 1062 unpackErr: nil, 1063 expectValue: uint64(math.MaxUint64), 1064 }, 1065 { 1066 decodeType: "uint256", 1067 inputValue: maxU64Plus1, 1068 unpackErr: nil, 1069 expectValue: maxU64Plus1, 1070 }, 1071 { 1072 decodeType: "int8", 1073 inputValue: big.NewInt(math.MaxInt8 + 1), 1074 unpackErr: errBadInt8, 1075 }, 1076 { 1077 inputValue: big.NewInt(math.MinInt8 - 1), 1078 packErr: errInvalidSign, 1079 }, 1080 { 1081 decodeType: "int8", 1082 inputValue: big.NewInt(math.MaxInt8), 1083 unpackErr: nil, 1084 expectValue: int8(math.MaxInt8), 1085 }, 1086 { 1087 decodeType: "int16", 1088 inputValue: big.NewInt(math.MaxInt16 + 1), 1089 unpackErr: errBadInt16, 1090 }, 1091 { 1092 inputValue: big.NewInt(math.MinInt16 - 1), 1093 packErr: errInvalidSign, 1094 }, 1095 { 1096 decodeType: "int16", 1097 inputValue: big.NewInt(math.MaxInt16), 1098 unpackErr: nil, 1099 expectValue: int16(math.MaxInt16), 1100 }, 1101 { 1102 decodeType: "int32", 1103 inputValue: big.NewInt(math.MaxInt32 + 1), 1104 unpackErr: errBadInt32, 1105 }, 1106 { 1107 inputValue: big.NewInt(math.MinInt32 - 1), 1108 packErr: errInvalidSign, 1109 }, 1110 { 1111 decodeType: "int32", 1112 inputValue: big.NewInt(math.MaxInt32), 1113 unpackErr: nil, 1114 expectValue: int32(math.MaxInt32), 1115 }, 1116 { 1117 decodeType: "int64", 1118 inputValue: new(big.Int).Add(big.NewInt(math.MaxInt64), big.NewInt(1)), 1119 unpackErr: errBadInt64, 1120 }, 1121 { 1122 inputValue: new(big.Int).Sub(big.NewInt(math.MinInt64), big.NewInt(1)), 1123 packErr: errInvalidSign, 1124 }, 1125 { 1126 decodeType: "int64", 1127 inputValue: big.NewInt(math.MaxInt64), 1128 unpackErr: nil, 1129 expectValue: int64(math.MaxInt64), 1130 }, 1131 } 1132 for i, testCase := range cases { 1133 packed, err := encodeABI.Pack(testCase.inputValue) 1134 if testCase.packErr != nil { 1135 if err == nil { 1136 t.Fatalf("expected packing of testcase input value to fail") 1137 } 1138 if err != testCase.packErr { 1139 t.Fatalf("expected error '%v', got '%v'", testCase.packErr, err) 1140 } 1141 continue 1142 } 1143 if err != nil && err != testCase.packErr { 1144 panic(fmt.Errorf("unexpected error packing test-case input: %v", err)) 1145 } 1146 ty, err := NewType(testCase.decodeType, "", nil) 1147 if err != nil { 1148 panic(err) 1149 } 1150 decodeABI := Arguments{ 1151 {Type: ty}, 1152 } 1153 decoded, err := decodeABI.Unpack(packed) 1154 if err != testCase.unpackErr { 1155 t.Fatalf("Expected error %v, actual error %v. case %d", testCase.unpackErr, err, i) 1156 } 1157 if err != nil { 1158 continue 1159 } 1160 if !reflect.DeepEqual(decoded[0], testCase.expectValue) { 1161 t.Fatalf("Expected value %v, actual value %v", testCase.expectValue, decoded[0]) 1162 } 1163 } 1164 }