github.com/iotexproject/iotex-core@v1.14.1-rc1/api/web3server_integrity_test.go (about) 1 // Copyright (c) 2022 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package api 7 8 import ( 9 "context" 10 "crypto/ecdsa" 11 "encoding/hex" 12 "encoding/json" 13 "fmt" 14 "math/big" 15 "net/http" 16 "net/http/httptest" 17 "strings" 18 "testing" 19 20 "github.com/ethereum/go-ethereum/common" 21 "github.com/ethereum/go-ethereum/core/types" 22 "github.com/iotexproject/go-pkgs/util" 23 "github.com/iotexproject/iotex-address/address" 24 "github.com/iotexproject/iotex-proto/golang/iotextypes" 25 "github.com/stretchr/testify/require" 26 27 "github.com/iotexproject/iotex-core/action" 28 "github.com/iotexproject/iotex-core/actpool" 29 "github.com/iotexproject/iotex-core/blockchain" 30 "github.com/iotexproject/iotex-core/blockchain/blockdao" 31 "github.com/iotexproject/iotex-core/test/identityset" 32 "github.com/iotexproject/iotex-core/testutil" 33 ) 34 35 const ( 36 _evmNetworkID uint32 = 1 37 ) 38 39 func TestWeb3ServerIntegrity(t *testing.T) { 40 svr, bc, dao, actPool, cleanIndexFile := setupTestServer() 41 web3svr := svr.httpSvr 42 defer cleanIndexFile() 43 ctx := context.Background() 44 web3svr.Start(ctx) 45 defer web3svr.Stop(ctx) 46 handler := newHTTPHandler(NewWeb3Handler(svr.core, "", _defaultBatchRequestLimit)) 47 48 // send request 49 t.Run("eth_gasPrice", func(t *testing.T) { 50 gasPrice(t, handler) 51 }) 52 53 t.Run("eth_chainId", func(t *testing.T) { 54 chainID(t, handler) 55 }) 56 57 t.Run("eth_blockNumber", func(t *testing.T) { 58 blockNumber(t, handler) 59 }) 60 61 t.Run("eth_getBlockByNumber", func(t *testing.T) { 62 getBlockByNumber(t, handler) 63 }) 64 65 t.Run("eth_getBalance", func(t *testing.T) { 66 getBalance(t, handler) 67 }) 68 69 t.Run("eth_getTransactionCount", func(t *testing.T) { 70 getTransactionCount(t, handler) 71 }) 72 73 t.Run("eth_call", func(t *testing.T) { 74 ethCall(t, handler) 75 }) 76 77 t.Run("web3_clientVersion", func(t *testing.T) { 78 getNodeInfo(t, handler) 79 }) 80 81 t.Run("eth_getBlockTransactionCountByHash", func(t *testing.T) { 82 getBlockTransactionCountByHash(t, handler, bc) 83 }) 84 85 t.Run("eth_getBlockByHash", func(t *testing.T) { 86 getBlockByHash(t, handler, bc) 87 }) 88 89 t.Run("eth_getTransactionByHash", func(t *testing.T) { 90 getTransactionByHash(t, handler) 91 }) 92 93 t.Run("eth_getLogs", func(t *testing.T) { 94 getLogs(t, handler) 95 }) 96 97 t.Run("eth_getTransactionReceipt", func(t *testing.T) { 98 getTransactionReceipt(t, handler) 99 }) 100 101 t.Run("eth_getBlockTransactionCountByNumber", func(t *testing.T) { 102 getBlockTransactionCountByNumber(t, handler) 103 }) 104 105 t.Run("eth_getTransactionByBlockHashAndIndex", func(t *testing.T) { 106 getTransactionByBlockHashAndIndex(t, handler, bc) 107 }) 108 109 t.Run("eth_getTransactionByBlockNumberAndIndex", func(t *testing.T) { 110 getTransactionByBlockNumberAndIndex(t, handler) 111 }) 112 113 t.Run("eth_newFilter", func(t *testing.T) { 114 newfilter(t, handler) 115 }) 116 117 t.Run("eth_newBlockFilter", func(t *testing.T) { 118 newBlockFilter(t, handler) 119 }) 120 121 t.Run("eth_getFilterChanges", func(t *testing.T) { 122 getFilterChanges(t, handler) 123 }) 124 125 t.Run("eth_getFilterLogs", func(t *testing.T) { 126 getFilterLogs(t, handler) 127 }) 128 129 t.Run("net_version", func(t *testing.T) { 130 getNetworkID(t, handler) 131 }) 132 133 t.Run("eth_accounts", func(t *testing.T) { 134 ethAccounts(t, handler) 135 }) 136 137 t.Run("web3Staking", func(t *testing.T) { 138 web3Staking(t, handler) 139 }) 140 141 t.Run("eth_sendRawTransaction", func(t *testing.T) { 142 sendRawTransaction(t, handler) 143 }) 144 145 t.Run("eth_estimateGas", func(t *testing.T) { 146 estimateGas(t, handler, bc, dao, actPool) 147 }) 148 149 t.Run("eth_getCode", func(t *testing.T) { 150 getCode(t, handler, bc, dao, actPool) 151 }) 152 153 t.Run("eth_getStorageAt", func(t *testing.T) { 154 getStorageAt(t, handler, bc, dao, actPool) 155 }) 156 } 157 158 func setupTestServer() (*ServerV2, blockchain.Blockchain, blockdao.BlockDAO, actpool.ActPool, func()) { 159 cfg := newConfig() 160 cfg.chain.EVMNetworkID = _evmNetworkID 161 cfg.api.HTTPPort = testutil.RandomPort() 162 svr, bc, dao, _, _, actPool, bfIndexFile, _ := createServerV2(cfg, false) 163 return svr, bc, dao, actPool, func() { 164 testutil.CleanupPath(bfIndexFile) 165 } 166 } 167 168 func serveTestHTTP(require *require.Assertions, handler *hTTPHandler, method string, param string) interface{} { 169 req, _ := http.NewRequest(http.MethodPost, "http://url.com", 170 strings.NewReader(fmt.Sprintf(`[{"jsonrpc":"2.0","method":"%s","params":%s,"id":1}]`, method, param))) 171 resp := httptest.NewRecorder() 172 173 handler.ServeHTTP(resp, req) 174 175 var vals []struct { 176 Jsonrpc string `json:"jsonrpc"` 177 ID int `json:"id"` 178 Result interface{} `json:"result"` 179 } 180 err := json.NewDecoder(resp.Body).Decode(&vals) 181 require.NoError(err) 182 require.NotEmpty(vals) 183 return vals[0].Result 184 } 185 186 func gasPrice(t *testing.T, handler *hTTPHandler) { 187 require := require.New(t) 188 result := serveTestHTTP(require, handler, "eth_gasPrice", "[]") 189 actual, ok := result.(string) 190 require.True(ok) 191 require.Equal(uint64ToHex(1000000000000), actual) 192 } 193 194 func chainID(t *testing.T, handler *hTTPHandler) { 195 require := require.New(t) 196 result := serveTestHTTP(require, handler, "eth_chainId", "[]") 197 actual, ok := result.(string) 198 require.True(ok) 199 require.Equal(uint64ToHex(1), actual) 200 require.Equal(uint64ToHex(uint64(_evmNetworkID)), actual) 201 } 202 203 func blockNumber(t *testing.T, handler *hTTPHandler) { 204 require := require.New(t) 205 result := serveTestHTTP(require, handler, "eth_blockNumber", "[]") 206 actual, ok := result.(string) 207 require.True(ok) 208 require.Equal(uint64ToHex(4), actual) 209 } 210 211 func getBlockByNumber(t *testing.T, handler *hTTPHandler) { 212 require := require.New(t) 213 for _, test := range []struct { 214 params string 215 expected int 216 }{ 217 {`["1", true]`, 2}, 218 {`["1", false]`, 2}, 219 {`["10", false]`, 0}, 220 } { 221 result := serveTestHTTP(require, handler, "eth_getBlockByNumber", test.params) 222 if test.expected == 0 { 223 require.Nil(result) 224 } else { 225 actual, ok := result.(map[string]interface{})["transactions"] 226 require.True(ok) 227 require.Equal(test.expected, len(actual.([]interface{}))) 228 } 229 } 230 } 231 232 func getBalance(t *testing.T, handler *hTTPHandler) { 233 require := require.New(t) 234 result := serveTestHTTP(require, handler, "eth_getBalance", `["0xDa7e12Ef57c236a06117c5e0d04a228e7181CF36", 1]`) 235 ans, ok := new(big.Int).SetString("9999999999999999999999999991", 10) 236 require.True(ok) 237 actual, ok := result.(string) 238 require.True(ok) 239 ans, ok = new(big.Int).SetString("9999999999999999999999999991", 10) 240 require.True(ok) 241 require.Equal("0x"+fmt.Sprintf("%x", ans), actual) 242 } 243 244 func getTransactionCount(t *testing.T, handler *hTTPHandler) { 245 require := require.New(t) 246 for _, test := range []struct { 247 params string 248 expected int 249 }{ 250 {`["0xDa7e12Ef57c236a06117c5e0d04a228e7181CF36", "0x1"]`, 2}, 251 {`["0xDa7e12Ef57c236a06117c5e0d04a228e7181CF36", "pending"]`, 2}, 252 } { 253 result := serveTestHTTP(require, handler, "eth_getTransactionCount", test.params) 254 actual, ok := result.(string) 255 require.True(ok) 256 require.Equal(uint64ToHex(uint64(test.expected)), actual) 257 } 258 } 259 260 func ethCall(t *testing.T, handler *hTTPHandler) { 261 require := require.New(t) 262 for _, test := range []struct { 263 params string 264 expected int 265 }{ 266 { 267 `[{ 268 "from": "", 269 "to": "0x7c13866F9253DEf79e20034eDD011e1d69E67fe5", 270 "gas": "0x4e20", 271 "gasPrice": "0xe8d4a51000", 272 "value": "0x1", 273 "data": "0x1" 274 }, 275 1]`, 276 1, 277 }, 278 { 279 `[{ 280 "from": "", 281 "to": "0xb1f8e55c7f64d203c1400b9d8555d050f94adf39", 282 "gas": "0x4e20", 283 "gasPrice": "0xe8d4a51000", 284 "value": "0x1", 285 "data": "0x1" 286 }, 287 1]`, 288 0, 289 }, 290 } { 291 result := serveTestHTTP(require, handler, "eth_call", test.params) 292 if test.expected == 0 { 293 require.Nil(result) 294 continue 295 } 296 actual, ok := result.(string) 297 require.True(ok) 298 require.Equal("0x", actual) 299 } 300 } 301 302 func getNodeInfo(t *testing.T, handler *hTTPHandler) { 303 require := require.New(t) 304 result := serveTestHTTP(require, handler, "web3_clientVersion", "[]") 305 actual, ok := result.(string) 306 require.True(ok) 307 require.Equal("NoBuildInfo/NoBuildInfo", actual) 308 } 309 310 func getBlockTransactionCountByHash(t *testing.T, handler *hTTPHandler, bc blockchain.Blockchain) { 311 require := require.New(t) 312 header, err := bc.BlockHeaderByHeight(1) 313 require.NoError(err) 314 blkHash := header.HashBlock() 315 result := serveTestHTTP(require, handler, "eth_getBlockTransactionCountByHash", 316 fmt.Sprintf(`["0x%s", 1]`, hex.EncodeToString(blkHash[:]))) 317 actual, ok := result.(string) 318 require.True(ok) 319 require.Equal(uint64ToHex(2), actual) 320 } 321 322 func getBlockByHash(t *testing.T, handler *hTTPHandler, bc blockchain.Blockchain) { 323 require := require.New(t) 324 header, err := bc.BlockHeaderByHeight(1) 325 require.NoError(err) 326 blkHash := header.HashBlock() 327 328 for _, test := range []struct { 329 params string 330 expected int 331 }{ 332 {fmt.Sprintf(`["0x%s", false]`, hex.EncodeToString(blkHash[:])), 1}, 333 {`["0xa2e8e0c9cafbe93f2b7f7c9d32534bc6fde95f2185e5f2aaa6bf7ebdf1a6610a", false]`, 0}, 334 } { 335 result := serveTestHTTP(require, handler, "eth_getBlockByHash", test.params) 336 if test.expected == 0 { 337 require.Nil(result) 338 continue 339 } 340 hash, ok := result.(map[string]interface{})["hash"] 341 require.True(ok) 342 require.Equal("0x"+hex.EncodeToString(blkHash[:]), hash) 343 transactions, ok := result.(map[string]interface{})["transactions"] 344 require.True(ok) 345 require.Equal(2, len(transactions.([]interface{}))) 346 } 347 } 348 349 func getTransactionByHash(t *testing.T, handler *hTTPHandler) { 350 require := require.New(t) 351 for _, test := range []struct { 352 params string 353 expected int 354 }{ 355 {fmt.Sprintf(`["0x%s", false]`, hex.EncodeToString(_transferHash1[:])), 1}, 356 {`["0x58df1e9cb0572fea48e8ce9d9b787ae557c304657d01890f4fc5ea88a1f44c3e", false]`, 0}, 357 } { 358 result := serveTestHTTP(require, handler, "eth_getTransactionByHash", test.params) 359 if test.expected == 0 { 360 require.Nil(result) 361 continue 362 } 363 hash, ok := result.(map[string]interface{})["hash"] 364 require.True(ok) 365 require.Equal("0x"+hex.EncodeToString(_transferHash1[:]), hash) 366 } 367 } 368 369 func getLogs(t *testing.T, handler *hTTPHandler) { 370 require := require.New(t) 371 for _, test := range []struct { 372 params string 373 expected int 374 }{ 375 { 376 `[{"fromBlock":"0x1"}]`, 377 4, // if deployed contract, +1 378 }, 379 { 380 // empty log 381 `[{"address":"0x8ce313ab12bf7aed8136ab36c623ff98c8eaad34"}]`, 382 0, 383 }, 384 } { 385 result := serveTestHTTP(require, handler, "eth_getLogs", test.params) 386 ret, ok := result.([]interface{}) 387 require.True(ok) 388 require.Equal(test.expected, len(ret)) 389 } 390 } 391 392 func getTransactionReceipt(t *testing.T, handler *hTTPHandler) { 393 require := require.New(t) 394 for _, test := range []struct { 395 params string 396 expected int 397 }{ 398 {fmt.Sprintf(`["0x%s", false]`, hex.EncodeToString(_transferHash1[:])), 1}, 399 {`["0x58df1e9cb0572fea48e8ce9d9b787ae557c304657d01890f4fc5ea88a1f44c3e", false]`, 0}, 400 } { 401 result := serveTestHTTP(require, handler, "eth_getTransactionReceipt", test.params) 402 if test.expected == 0 { 403 require.Nil(result) 404 continue 405 } 406 transactionHash, ok := result.(map[string]interface{})["transactionHash"] 407 require.True(ok) 408 require.Equal("0x"+hex.EncodeToString(_transferHash1[:]), transactionHash) 409 fromAddr, _ := ioAddrToEthAddr(identityset.Address(27).String()) 410 toAddr, _ := ioAddrToEthAddr(identityset.Address(30).String()) 411 from, ok := result.(map[string]interface{})["from"] 412 require.True(ok) 413 to, ok := result.(map[string]interface{})["to"] 414 require.True(ok) 415 require.Equal(strings.ToLower(fromAddr), from) 416 require.Equal(toAddr, to) 417 contractAddress, ok := result.(map[string]interface{})["contractAddress"] 418 require.True(ok) 419 require.Nil(nil, contractAddress) 420 gasUsed, ok := result.(map[string]interface{})["gasUsed"] 421 require.True(ok) 422 require.Equal(uint64ToHex(10000), gasUsed) 423 blockNumber, ok := result.(map[string]interface{})["blockNumber"] 424 require.True(ok) 425 require.Equal(uint64ToHex(1), blockNumber) 426 } 427 } 428 429 func getBlockTransactionCountByNumber(t *testing.T, handler *hTTPHandler) { 430 require := require.New(t) 431 result := serveTestHTTP(require, handler, "eth_getBlockTransactionCountByNumber", `["0x1"]`) 432 actual, ok := result.(string) 433 require.True(ok) 434 require.Equal(uint64ToHex(2), actual) 435 } 436 437 func getTransactionByBlockHashAndIndex(t *testing.T, handler *hTTPHandler, bc blockchain.Blockchain) { 438 require := require.New(t) 439 header, err := bc.BlockHeaderByHeight(1) 440 require.NoError(err) 441 blkHash := header.HashBlock() 442 443 for _, test := range []struct { 444 params string 445 expected int 446 }{ 447 {fmt.Sprintf(`["0x%s", "0x0"]`, hex.EncodeToString(blkHash[:])), 1}, 448 {fmt.Sprintf(`["0x%s", "0x10"]`, hex.EncodeToString(blkHash[:])), 0}, 449 {`["0xa2e8e0c9cafbe93f2b7f7c9d32534bc6fde95f2185e5f2aaa6bf7ebdf1a6610a", "0x0"]`, 0}, 450 } { 451 result := serveTestHTTP(require, handler, "eth_getTransactionByBlockHashAndIndex", test.params) 452 if test.expected == 0 { 453 require.Nil(result) 454 continue 455 } 456 hash, ok := result.(map[string]interface{})["hash"] 457 require.True(ok) 458 require.Equal("0x"+hex.EncodeToString(_transferHash1[:]), hash) 459 fromAddr, _ := ioAddrToEthAddr(identityset.Address(27).String()) 460 toAddr, _ := ioAddrToEthAddr(identityset.Address(30).String()) 461 from, ok := result.(map[string]interface{})["from"] 462 require.True(ok) 463 to, ok := result.(map[string]interface{})["to"] 464 require.True(ok) 465 require.Equal(strings.ToLower(fromAddr), from) 466 require.Equal(toAddr, to) 467 468 gas, ok := result.(map[string]interface{})["gas"] 469 require.True(ok) 470 require.Equal(uint64ToHex(20000), gas) 471 gasPrice, ok := result.(map[string]interface{})["gasPrice"] 472 require.True(ok) 473 require.Equal(uint64ToHex(0), gasPrice) 474 } 475 } 476 477 func getTransactionByBlockNumberAndIndex(t *testing.T, handler *hTTPHandler) { 478 require := require.New(t) 479 for _, test := range []struct { 480 params string 481 expected int 482 }{ 483 {`["0x1", "0x0"]`, 1}, 484 {`["0x1", "0x10"]`, 0}, 485 {`["0x10", "0x0"]`, 0}, 486 } { 487 result := serveTestHTTP(require, handler, "eth_getTransactionByBlockNumberAndIndex", test.params) 488 if test.expected == 0 { 489 require.Nil(result) 490 continue 491 } 492 hash, ok := result.(map[string]interface{})["hash"] 493 require.True(ok) 494 require.Equal("0x"+hex.EncodeToString(_transferHash1[:]), hash) 495 fromAddr, _ := ioAddrToEthAddr(identityset.Address(27).String()) 496 toAddr, _ := ioAddrToEthAddr(identityset.Address(30).String()) 497 from, ok := result.(map[string]interface{})["from"] 498 require.True(ok) 499 to, ok := result.(map[string]interface{})["to"] 500 require.True(ok) 501 require.Equal(strings.ToLower(fromAddr), from) 502 require.Equal(toAddr, to) 503 504 gas, ok := result.(map[string]interface{})["gas"] 505 require.True(ok) 506 require.Equal(uint64ToHex(20000), gas) 507 gasPrice, ok := result.(map[string]interface{})["gasPrice"] 508 require.True(ok) 509 require.Equal(uint64ToHex(0), gasPrice) 510 } 511 } 512 513 func newfilter(t *testing.T, handler *hTTPHandler) { 514 require := require.New(t) 515 result := serveTestHTTP(require, handler, "eth_newFilter", `[{"fromBlock":"0x1"}]`) 516 actual, ok := result.(string) 517 require.True(ok) 518 require.Equal("0xe10f7dd489b75a36de8e246eb974827fe86a02ed19d9b475a1600cf4f935feff", actual) 519 } 520 521 func newBlockFilter(t *testing.T, handler *hTTPHandler) { 522 require := require.New(t) 523 result := serveTestHTTP(require, handler, "eth_newBlockFilter", "[]") 524 actual, ok := result.(string) 525 require.True(ok) 526 require.Equal("0x71371f8dbaefc4c96d2534163a1b461951c88520cd32bc03b5bfdfe7340bc187", actual) 527 } 528 529 func getFilterChanges(t *testing.T, handler *hTTPHandler) { 530 require := require.New(t) 531 532 result := serveTestHTTP(require, handler, "eth_newFilter", `[{"fromBlock":"0x1"}]`) 533 actual, ok := result.(string) 534 require.True(ok) 535 result1 := serveTestHTTP(require, handler, "eth_getFilterChanges", fmt.Sprintf(`["%s"]`, actual)) 536 actual1, ok := result1.([]interface{}) 537 require.True(ok) 538 require.Len(actual1, 4) 539 // request again after last rolling 540 result1 = serveTestHTTP(require, handler, "eth_getFilterChanges", fmt.Sprintf(`["%s"]`, actual)) 541 actual1, ok = result1.([]interface{}) 542 require.True(ok) 543 require.Len(actual1, 0) 544 545 result = serveTestHTTP(require, handler, "eth_newBlockFilter", `[]`) 546 actual, ok = result.(string) 547 require.True(ok) 548 result1 = serveTestHTTP(require, handler, "eth_getFilterChanges", fmt.Sprintf(`["%s"]`, actual)) 549 actual1, ok = result1.([]interface{}) 550 require.True(ok) 551 require.Len(actual1, 1) 552 // request again after last rolling 553 result1 = serveTestHTTP(require, handler, "eth_getFilterChanges", fmt.Sprintf(`["%s"]`, actual)) 554 actual1, ok = result1.([]interface{}) 555 require.True(ok) 556 require.Len(actual1, 0) 557 } 558 559 func getFilterLogs(t *testing.T, handler *hTTPHandler) { 560 require := require.New(t) 561 result := serveTestHTTP(require, handler, "eth_newFilter", `[{"fromBlock":"0x1"}]`) 562 actual, ok := result.(string) 563 require.True(ok) 564 565 result1 := serveTestHTTP(require, handler, "eth_getFilterLogs", fmt.Sprintf(`["%s"]`, actual)) 566 actual1, ok := result1.([]interface{}) 567 require.True(ok) 568 require.Equal(4, len(actual1)) 569 } 570 571 func getNetworkID(t *testing.T, handler *hTTPHandler) { 572 require := require.New(t) 573 result := serveTestHTTP(require, handler, "net_version", "[]") 574 actual, ok := result.(string) 575 require.True(ok) 576 require.Equal(fmt.Sprintf("%d", _evmNetworkID), actual) 577 } 578 579 func ethAccounts(t *testing.T, handler *hTTPHandler) { 580 require := require.New(t) 581 result := serveTestHTTP(require, handler, "eth_accounts", "[]") 582 actual, ok := result.([]interface{}) 583 require.True(ok) 584 require.Equal(0, len(actual)) 585 } 586 587 func web3Staking(t *testing.T, handler *hTTPHandler) { 588 require := require.New(t) 589 ecdsaPvk, ok := identityset.PrivateKey(28).EcdsaPrivateKey().(*ecdsa.PrivateKey) 590 require.True(ok) 591 toAddr, err := ioAddrToEthAddr(address.StakingProtocolAddr) 592 require.NoError(err) 593 594 type stakeData struct { 595 actType string 596 data []byte 597 } 598 var testDatas []stakeData 599 600 // encode stake data 601 act1, err := action.NewCreateStake(1, "test", "100", 7, false, []byte{}, 1000000, big.NewInt(0)) 602 require.NoError(err) 603 data, err := act1.EncodeABIBinary() 604 require.NoError(err) 605 testDatas = append(testDatas, stakeData{"createStake", data}) 606 607 act2, err := action.NewDepositToStake(2, 7, "100", []byte{}, 1000000, big.NewInt(0)) 608 require.NoError(err) 609 data2, err := act2.EncodeABIBinary() 610 require.NoError(err) 611 testDatas = append(testDatas, stakeData{"depositToStake", data2}) 612 613 act3, err := action.NewChangeCandidate(3, "test", 7, []byte{}, 1000000, big.NewInt(0)) 614 require.NoError(err) 615 data3, err := act3.EncodeABIBinary() 616 require.NoError(err) 617 testDatas = append(testDatas, stakeData{"changeCandidate", data3}) 618 619 act4, err := action.NewUnstake(4, 7, []byte{}, 1000000, big.NewInt(0)) 620 require.NoError(err) 621 data4, err := act4.EncodeABIBinary() 622 require.NoError(err) 623 testDatas = append(testDatas, stakeData{"unstake", data4}) 624 625 act5, err := action.NewWithdrawStake(5, 7, []byte{}, 1000000, big.NewInt(0)) 626 require.NoError(err) 627 data5, err := act5.EncodeABIBinary() 628 require.NoError(err) 629 testDatas = append(testDatas, stakeData{"withdrawStake", data5}) 630 631 act6, err := action.NewRestake(6, 7, 7, false, []byte{}, 1000000, big.NewInt(0)) 632 require.NoError(err) 633 data6, err := act6.EncodeABIBinary() 634 require.NoError(err) 635 testDatas = append(testDatas, stakeData{"restake", data6}) 636 637 act7, err := action.NewTransferStake(7, "io1xpq62aw85uqzrccg9y5hnryv8ld2nkpycc3gza", 7, []byte{}, 1000000, big.NewInt(0)) 638 require.NoError(err) 639 data7, err := act7.EncodeABIBinary() 640 require.NoError(err) 641 testDatas = append(testDatas, stakeData{"transferStake", data7}) 642 643 act8, err := action.NewCandidateRegister( 644 8, 645 "test", 646 "io1xpq62aw85uqzrccg9y5hnryv8ld2nkpycc3gza", 647 "io1xpq62aw85uqzrccg9y5hnryv8ld2nkpycc3gza", 648 "io1xpq62aw85uqzrccg9y5hnryv8ld2nkpycc3gza", 649 "100", 650 7, 651 false, 652 []byte{}, 653 1000000, 654 big.NewInt(0)) 655 require.NoError(err) 656 data8, err := act8.EncodeABIBinary() 657 require.NoError(err) 658 testDatas = append(testDatas, stakeData{"candidateRegister", data8}) 659 660 act9, err := action.NewCandidateUpdate( 661 9, 662 "test", 663 "io1xpq62aw85uqzrccg9y5hnryv8ld2nkpycc3gza", 664 "io1xpq62aw85uqzrccg9y5hnryv8ld2nkpycc3gza", 665 1000000, 666 big.NewInt(0)) 667 require.NoError(err) 668 data9, err := act9.EncodeABIBinary() 669 require.NoError(err) 670 testDatas = append(testDatas, stakeData{"candidateUpdate", data9}) 671 672 for i, test := range testDatas { 673 // estimate gas 674 result := serveTestHTTP(require, handler, "eth_estimateGas", 675 fmt.Sprintf(`[{ 676 "from": "%s", 677 "to": "%s", 678 "gas": "0x0", 679 "gasPrice": "0x0", 680 "value": "0x0", 681 "data": "%s"}, 682 1]`, identityset.Address(28).Hex(), toAddr, hex.EncodeToString(test.data))) 683 actual, ok := result.(string) 684 require.True(ok) 685 gasLimit, err := hexStringToNumber(actual) 686 require.NoError(err) 687 688 // create tx 689 to := common.HexToAddress(toAddr) 690 rawTx := types.NewTx(&types.LegacyTx{ 691 Nonce: uint64(9 + i), 692 GasPrice: big.NewInt(0), 693 Gas: gasLimit, 694 To: &to, 695 Value: big.NewInt(0), 696 Data: test.data, 697 }) 698 signer, err := action.NewEthSigner(iotextypes.Encoding_ETHEREUM_EIP155, _evmNetworkID) 699 require.NoError(err) 700 tx, err := types.SignTx(rawTx, signer, ecdsaPvk) 701 require.NoError(err) 702 BinaryData, err := tx.MarshalBinary() 703 require.NoError(err) 704 705 // send tx 706 result = serveTestHTTP(require, handler, "eth_sendRawTransaction", fmt.Sprintf(`["%s"]`, hex.EncodeToString(BinaryData))) 707 ret, ok := result.(string) 708 require.True(ok) 709 require.Equal(tx.Hash().Hex(), ret) 710 } 711 } 712 713 func sendRawTransaction(t *testing.T, handler *hTTPHandler) { 714 require := require.New(t) 715 rawData := "0xf8600180830186a09412745fec82b585f239c01090882eb40702c32b04808025a0b0e1aab5b64d744ae01fc9f1c3e9919844a799e90c23129d611f7efe6aec8a29a0195e28d22d9b280e00d501ff63525bb76f5c87b8646c89d5d9c5485edcb1b498" 716 tx, err := action.DecodeEtherTx(rawData) 717 require.NoError(err) 718 result := serveTestHTTP(require, handler, "eth_sendRawTransaction", fmt.Sprintf(`["%s"]`, rawData)) 719 actual, ok := result.(string) 720 require.True(ok) 721 require.Equal(tx.Hash().Hex(), actual) 722 } 723 724 func estimateGas(t *testing.T, handler *hTTPHandler, bc blockchain.Blockchain, dao blockdao.BlockDAO, actPool actpool.ActPool) { 725 require := require.New(t) 726 727 // deploy a contract 728 contractCode := "608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b6100556004803603810190610050919061009d565b610075565b005b61005f61007f565b60405161006c91906100d9565b60405180910390f35b8060008190555050565b60008054905090565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220c86a8c4dd175f55f5732b75b721d714ceb38a835b87c6cf37cf28c790813e19064736f6c63430008070033" 729 contract, _ := deployContractV2(bc, dao, actPool, identityset.PrivateKey(13), 1, bc.TipHeight(), contractCode) 730 731 fromAddr, _ := ioAddrToEthAddr(identityset.Address(0).String()) 732 toAddr, _ := ioAddrToEthAddr(identityset.Address(28).String()) 733 contractAddr, _ := ioAddrToEthAddr(contract) 734 735 for _, test := range []struct { 736 params string 737 expected uint64 738 }{ 739 { 740 fmt.Sprintf(`[{ 741 "from": "%s", 742 "to": "%s", 743 "gas": "0x0", 744 "gasPrice": "0x0", 745 "value": "0x0", 746 "data": "0x1123123c"}, 747 1]`, fromAddr, toAddr), 748 21000, 749 }, 750 { 751 fmt.Sprintf(`[{ 752 "from": "%s", 753 "to": "%s", 754 "gas": "0x0", 755 "gasPrice": "0x0", 756 "value": "0x0", 757 "data": "344933be000000000000000000000000000000000000000000000000000be497a92e9f3300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000f8be4046fd89199906ca348bcd3822c4b250e246000000000000000000000000000000000000000000000000000000006173a15400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a00744882684c3e4747faefd68d283ea44099d030000000000000000000000000258866edaf84d6081df17660357ab20a07d0c80"}, 758 1]`, fromAddr, toAddr), 759 36000, 760 }, 761 { 762 fmt.Sprintf(`[{ 763 "from": "%s", 764 "to": "%s", 765 "gas": "0x0", 766 "gasPrice": "0x0", 767 "value": "0x0", 768 "data": "0x6d4ce63c"}, 769 1]`, fromAddr, contractAddr), 770 21000, 771 }, 772 } { 773 result := serveTestHTTP(require, handler, "eth_estimateGas", test.params) 774 actual, ok := result.(string) 775 require.True(ok) 776 require.Equal(uint64ToHex(test.expected), actual) 777 } 778 } 779 780 func getCode(t *testing.T, handler *hTTPHandler, bc blockchain.Blockchain, dao blockdao.BlockDAO, actPool actpool.ActPool) { 781 require := require.New(t) 782 // deploy a contract 783 contractCode := "608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b6100556004803603810190610050919061009d565b610075565b005b61005f61007f565b60405161006c91906100d9565b60405180910390f35b8060008190555050565b60008054905090565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220c86a8c4dd175f55f5732b75b721d714ceb38a835b87c6cf37cf28c790813e19064736f6c63430008070033" 784 contract, _ := deployContractV2(bc, dao, actPool, identityset.PrivateKey(13), 2, bc.TipHeight(), contractCode) 785 contractAddr, _ := ioAddrToEthAddr(contract) 786 787 result := serveTestHTTP(require, handler, "eth_getCode", fmt.Sprintf(`["%s", "0x1"]`, contractAddr)) 788 actual, ok := result.(string) 789 require.True(ok) 790 require.Contains(contractCode, util.Remove0xPrefix(actual)) 791 } 792 793 func getStorageAt(t *testing.T, handler *hTTPHandler, bc blockchain.Blockchain, dao blockdao.BlockDAO, actPool actpool.ActPool) { 794 require := require.New(t) 795 // deploy a contract 796 contractCode := "608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b6100556004803603810190610050919061009d565b610075565b005b61005f61007f565b60405161006c91906100d9565b60405180910390f35b8060008190555050565b60008054905090565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220c86a8c4dd175f55f5732b75b721d714ceb38a835b87c6cf37cf28c790813e19064736f6c63430008070033" 797 contract, _ := deployContractV2(bc, dao, actPool, identityset.PrivateKey(13), 3, bc.TipHeight(), contractCode) 798 contractAddr, _ := ioAddrToEthAddr(contract) 799 800 for _, test := range []struct { 801 params string 802 expected int 803 }{ 804 {fmt.Sprintf(`["%s", "0x0"]`, contractAddr), 1}, 805 {`[1]`, 0}, 806 {`["TEST", "TEST"]`, 0}, 807 } { 808 result := serveTestHTTP(require, handler, "eth_getStorageAt", test.params) 809 if test.expected == 0 { 810 require.Nil(result) 811 continue 812 } 813 actual, ok := result.(string) 814 require.True(ok) 815 // the value of any contract at pos0 is be "0x0000000000000000000000000000000000000000000000000000000000000000" 816 require.Equal("0x0000000000000000000000000000000000000000000000000000000000000000", actual) 817 } 818 }