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