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