github.com/amazechain/amc@v0.1.3/internal/avm/abi/unpack_test.go (about) 1 // Copyright 2023 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain 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 AmazeChain 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 AmazeChain 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/amazechain/amc/internal/avm/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 }