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