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