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