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