diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index b756e92..9879ff6 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -4,6 +4,7 @@ * EVM Template Guides ** xref:guides/contract_migration.adoc[Contract Migration] ** xref:guides/predeployed_contracts.adoc[Predeployed Contracts] +** xref:guides/rpc_differences.adoc[RPC Differences] * Runtimes ** xref:runtimes/generic.adoc[Generic Runtime] * Runtime Descriptions diff --git a/docs/modules/ROOT/pages/guides/rpc_differences.adoc b/docs/modules/ROOT/pages/guides/rpc_differences.adoc new file mode 100644 index 0000000..e47efda --- /dev/null +++ b/docs/modules/ROOT/pages/guides/rpc_differences.adoc @@ -0,0 +1,14 @@ +:source-highlighter: highlight.js +:highlightjs-languages: rust +:github-icon: pass:[] + += RPC Differences + +The EVM in a Substrate node has almost the same RPC calls common to all nodes. But some of them are not applicable for Frontier. + +These are the calls that behave differently than would be expected by regular Ethereum nodes: + +* `eth_sign` / `eth_signTransaction` -- these methods do not exist in the Frontier and this template because it, unlike Ethereum nodes, does not hold any keys. +* `eth_syncing` -- it can have additional fields `warp_chunks_amount` and `warp_chunks_processed` that describe warp syncing process. + +Other calls comply to the same scheme as Ethereum nodes provide. \ No newline at end of file diff --git a/evm-template/rpc-testing/EVM Testing.postman_collection.json b/evm-template/rpc-testing/EVM Testing.postman_collection.json new file mode 100644 index 0000000..bac5610 --- /dev/null +++ b/evm-template/rpc-testing/EVM Testing.postman_collection.json @@ -0,0 +1,1510 @@ +{ + "info": { + "_postman_id": "97fdf1db-7705-4f01-a6c9-f88ae5b86239", + "name": "EVM Testing", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "35114398" + }, + "item": [ + { + "name": "eth_blockNumber", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_blockNumber\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " let result = parseInt(jsonData.result);", + " pm.expect(result).to.gte(0);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_blockNumber\",\n \"params\": [],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_syncing", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_syncing\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " pm.expect(jsonData.result).to.not.eq(false);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_syncing\",\n \"params\": [],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_coinbase", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_coinbase\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " pm.expect(jsonData.result.slice(0,2)).to.eq(\"0x\");", + " pm.expect(jsonData.result.length).to.eq(42)", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_coinbase\",\n \"params\": [],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_chainId", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_chainId\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " let result = parseInt(jsonData.result);", + " pm.expect(result == pm.collectionVariables.get(\"chain_id\")).to.eq(true);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_chainId\",\n \"params\": [],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_gasPrice", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_gasPrice\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " let result = parseInt(jsonData.result);", + " pm.expect(result).to.greaterThan(0);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_gasPrice\",\n \"params\": [],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_accounts", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_accounts\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " // Frontier does not store any accounts in EVM", + " pm.expect(jsonData.result.length).to.eq(0);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_accounts\",\n \"params\": [],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getBalance", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getBalance\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " let result = parseInt(jsonData.result);", + " pm.expect(result == pm.collectionVariables.get(\"alice_balance\")).to.eql(true);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getBalance\",\n \"params\": [\"{{alice_addr}}\", \"latest\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getStorageAt", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getStorageAt\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.variables.get(\"request_id\")).to.eql(true);", + " let result = parseInt(jsonData.result);", + " pm.expect(result).to.eq(1234);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getStorageAt\",\n \"params\": [\"{{test_contract}}\", \"0x0\", \"latest\"], // TODO: fix contract\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getTransactionCount", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getTransactionCount\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " let result = parseInt(jsonData.result);", + " pm.expect(result == pm.collectionVariables.get(\"alice_tx_count\")).to.eq(true);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getTransactionCount\",\n \"params\": [\"{{alice_addr}}\", \"latest\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getBlockTransactionCountByHash", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getBlockTransactionCountByHash\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " let result = parseInt(jsonData.result);", + " pm.expect(result == pm.collectionVariables.get(\"block_tx_count\")).to.eq(true);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getBlockTransactionCountByHash\",\n \"params\": [\"{{block_hash}}\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getBlockTransactionCountByNumber", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getBlockTransactionCountByNumber\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " let result = parseInt(jsonData.result);", + " pm.expect(result == pm.collectionVariables.get(\"block_tx_count\")).to.eq(true);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getBlockTransactionCountByNumber\",\n \"params\": [\"{{block_number}}\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getCode", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getCode\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " pm.expect(jsonData.result).to.eq(pm.collectionVariables.get(\"contract_code\"));", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getCode\",\n \"params\": [\"{{test_contract}}\", \"latest\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_call", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_call\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id).to.eql(pm.variables.get(\"request_id\"));", + " let result = parseInt(jsonData.result);", + " pm.expect(result).to.eq(1234);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_call\",\n \"params\": [ {\n \"to\": \"{{test_contract}}\",\n \"data\": \"0x6d4ce63c\"\n }, \"latest\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_estimateGas", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getBlockTransactionCountByNumber\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id).to.eql(pm.variables.get(\"request_id\"));", + " let result = parseInt(jsonData.result);", + " pm.expect(result).to.gt(0);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_estimateGas\",\n \"params\": [{\"from\":\"0x8D97689C9818892B700e27F316cc3E41e17fBeb9\",\"to\":\"0xd3CdA913deB6f67967B99D67aCDFa1712C293601\",\"value\":\"0x186a0\"}],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getBlockByHash", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getBlockByHash\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " pm.expect(jsonData.result.hash).to.eq(pm.collectionVariables.get(\"block_hash\"));", + " pm.expect(jsonData.result.number).to.eq(pm.collectionVariables.get(\"block_number\"));", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getBlockByHash\",\n \"params\": [\"{{block_hash}}\", false],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getBlockByNumber", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getBlockByNumber\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " pm.expect(jsonData.result.hash).to.eq(pm.collectionVariables.get(\"block_hash\"));", + " pm.expect(jsonData.result.number).to.eq(pm.collectionVariables.get(\"block_number\"));", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getBlockByNumber\",\n \"params\": [\"{{block_number}}\", false],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getTransactionByHash", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getTransactionByHash\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " pm.expect(jsonData.result.blockHash).to.eq(pm.collectionVariables.get(\"tx_block_hash\"));", + " pm.expect(parseInt(jsonData.result.blockNumber) == pm.collectionVariables.get(\"tx_block_number\")).to.eq(true);", + " pm.expect(jsonData.result.from).to.eq(pm.collectionVariables.get(\"tx_from\"));", + " pm.expect(jsonData.result.transactionIndex).to.eq(pm.collectionVariables.get(\"tx_index\"));", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getTransactionByHash\",\n \"params\": [\"{{tx_hash}}\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getTransactionByBlockHashAndIndex", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getTransactionByBlockHashAndIndex\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " pm.expect(jsonData.result.blockHash).to.eq(pm.collectionVariables.get(\"tx_block_hash\"));", + " pm.expect(parseInt(jsonData.result.blockNumber) == pm.collectionVariables.get(\"tx_block_number\")).to.eq(true);", + " pm.expect(jsonData.result.from).to.eq(pm.collectionVariables.get(\"tx_from\"));", + " pm.expect(jsonData.result.transactionIndex).to.eq(pm.collectionVariables.get(\"tx_index\"));", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getTransactionByBlockHashAndIndex\",\n \"params\": [\"{{tx_block_hash}}\", \"{{tx_index}}\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getTransactionByBlockNumberAndIndex", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getTransactionByBlockNumberAndIndex\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " pm.expect(jsonData.result.blockHash).to.eq(pm.collectionVariables.get(\"tx_block_hash\"));", + " pm.expect(parseInt(jsonData.result.blockNumber) == pm.collectionVariables.get(\"tx_block_number\")).to.eq(true);", + " pm.expect(jsonData.result.from).to.eq(pm.collectionVariables.get(\"tx_from\"));", + " pm.expect(jsonData.result.transactionIndex).to.eq(pm.collectionVariables.get(\"tx_index\"));", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getTransactionByBlockNumberAndIndex\",\n \"params\": [\"{{tx_block_number}}\", \"{{tx_index}}\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getTransactionReceipt", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getTransactionReceipt\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " pm.expect(jsonData.result.blockHash).to.eq(pm.collectionVariables.get(\"tx_block_hash\"));", + " pm.expect(parseInt(jsonData.result.blockNumber) == pm.collectionVariables.get(\"tx_block_number\")).to.eq(true);", + " pm.expect(jsonData.result.from).to.eq(pm.collectionVariables.get(\"tx_from\"));", + " pm.expect(jsonData.result.transactionIndex).to.eq(pm.collectionVariables.get(\"tx_index\"));", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getTransactionReceipt\",\n \"params\": [\"{{tx_hash}}\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_newFilter", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_newFilter\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " let filter_id = parseInt(jsonData.result);", + " pm.expect(filter_id).to.greaterThan(0);", + " pm.collectionVariables.set(\"filter_id\", jsonData.result);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_newFilter\",\n \"params\": [{\n \"fromBlock\": \"latest\",\n \"topics\": [\n \"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\"\n ]\n }],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_newBlockFilter", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_newBlockFilter\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " let filter_id = parseInt(jsonData.result);", + " pm.expect(filter_id).to.greaterThan(0);", + " pm.collectionVariables.set(\"block_filter_id\", jsonData.result);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_newBlockFilter\",\n \"params\": [],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_newPendingTransactionFilter", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_newPendingTransactionFilter\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " let filter_id = parseInt(jsonData.result);", + " pm.expect(filter_id).to.greaterThan(0);", + " pm.collectionVariables.set(\"pending_filter_id\", jsonData.result);", + "", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_newPendingTransactionFilter\",\n \"params\": [],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_uninstallFilter", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_uninstallFilter\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " pm.expect(jsonData.result).to.eq(true);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_uninstallFilter\",\n \"params\": [\"{{pending_filter_id}}\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getFilterChanges", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getFilterChanges\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " pm.expect(jsonData.result.length).to.greaterThan(0);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getFilterChanges\",\n \"params\": [\"0x2\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getFilterLogs", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getFilterLogs\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + " pm.expect(jsonData.result.length).to.eq(0);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getFilterLogs\",\n \"params\": [\"{{filter_id}}\"],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + }, + { + "name": "eth_getLogs", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"test eth_getLogs\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.id == pm.collectionVariables.get(\"request_id\")).to.eql(true);", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "let req_id = pm.collectionVariables.get(\"request_id\");", + "pm.collectionVariables.set(\"request_id\", parseInt(req_id)+1);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"jsonrpc\": \"2.0\",\n \"method\": \"eth_getLogs\",\n \"params\": [{\"fromBlock\": \"0x1\"}],\n \"id\": {{request_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}", + "host": [ + "{{url}}" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "key": "url", + "value": "", + "type": "string" + }, + { + "key": "request_id", + "value": "1", + "type": "string" + }, + { + "key": "chain_id", + "value": "", + "type": "string" + }, + { + "key": "alice_addr", + "value": "", + "type": "string" + }, + { + "key": "alice_balance", + "value": "", + "type": "string" + }, + { + "key": "test_contract", + "value": "", + "type": "string" + }, + { + "key": "contract_code", + "value": "", + "type": "string" + }, + { + "key": "alice_tx_count", + "value": "", + "type": "string" + }, + { + "key": "block_hash", + "value": "", + "type": "string" + }, + { + "key": "block_number", + "value": "", + "type": "string" + }, + { + "key": "block_tx_count", + "value": "", + "type": "string" + }, + { + "key": "tx_hash", + "value": "", + "type": "string" + }, + { + "key": "tx_block_number", + "value": "", + "type": "string" + }, + { + "key": "tx_block_hash", + "value": "", + "type": "string" + }, + { + "key": "tx_from", + "value": "", + "type": "string" + }, + { + "key": "tx_index", + "value": "", + "type": "string" + }, + { + "key": "filter_id", + "value": "", + "type": "string" + }, + { + "key": "block_filter_id", + "value": "", + "type": "string" + }, + { + "key": "pending_filter_id", + "value": "" + } + ] +} \ No newline at end of file diff --git a/evm-template/rpc-testing/README.md b/evm-template/rpc-testing/README.md new file mode 100644 index 0000000..5d5608b --- /dev/null +++ b/evm-template/rpc-testing/README.md @@ -0,0 +1,19 @@ +## RPC Testing Toolkit + +This is a Postman collection to test your the RPC deployment of you smart contract. To use it you should prepare your environment and test toolkit for testing: + +* Open the collection in Postman, and open the variables in it. +* Fill the `url` with HTTP RPC url and `chain_id` with your chain's chain id. +* Obtain three funded accounts. You may provide them through the chainspec. + * Put first address to the `alice_addr` variable and their balance to the `alice_balance`. + * Make a transfer transaction from the second address to any address. + * Put its hash to the `tx_hash` variable + * Put the block number of this transaction to `tx_block_number` and `block_number`. Put the number of transactions in this block (highly likely it will be 1) to the `block_tx_count`. + * Put the hash of the block with this transaction to `tx_block_hash` and `block_hash`. + * Put the index of the transaction in the block to `tx_index`. Highly likely it will be 0. + * Put the address you have sent the transaction from to `tx_from` variable. + * Take a third address and deploy the smart contract `TestContract.sol` from it. + * Put the address of the deployed contract to the `test_contract` variable. + * Put the code from the compiled contract to the `contract_code` variable. It can be found in a resulting JSON file under `deployedBytecode` key. + +When you complete these preparation steps, run the requests from the collection. If some of them are not passing, run them as a single request and see what the request have returned to debug it. \ No newline at end of file diff --git a/evm-template/rpc-testing/TestContract.sol b/evm-template/rpc-testing/TestContract.sol new file mode 100644 index 0000000..ceedff9 --- /dev/null +++ b/evm-template/rpc-testing/TestContract.sol @@ -0,0 +1,13 @@ +contract Storage { + uint pos0; + + constructor() { + pos0 = 1234; + } + + // You can read from a state variable without sending a transaction. + function get() public view returns (uint) { + return pos0; + } +} +