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