Using the Ethereum JSON-RPC API with Amazon Managed Blockchain
This topic provides a listing of Ethereum JSON-RPC methods that Managed Blockchain supports, followed by code examples that implement JSON-RPC API calls from clients using either WebSockets or HTTP.
You use the Ethereum JSON-RPC API from a client to query smart contract data and submit transactions to an Ethereum node in Managed Blockchain. The client uses either an HTTP or WebSockets endpoint hosted by the Ethereum node in Managed Blockchain to connect and send the API calls. You can get the node endpoints using the node details page in the Managed Blockchain console. For more information, see Viewing node details.
Ethereum on Managed Blockchain only supports the eth_sendRawTransaction
method, which requires that you create and sign the transaction before sending it to the node. Managed Blockchain does not have any way to sign transactions similar to an Ethereum wallet application.
All Ethereum JSON-RPC API calls to an Ethereum node on Managed Blockchain are authenticated using the Signature Version 4 signing process. This means that only authorized IAM principals in the AWS account that created the node can interact with it using the API. AWS credentials (an access key ID and secret access key) must be provided with the call. IAM policies do not apply to API calls and can not be used to allow or deny Ethereum API access to a node. IAM permissions policies only apply to operations related to node creation, deletion, and management.
Supported JSON-RPC methods
Ethereum on Managed Blockchain supports the following Ethereum JSON-RPC API methods. Methods not listed are not supported. JSON-RPC batch requests are also not supported. Each supported API call has a brief description of its utility. Unique considerations for using the JSON-RPC method with an Ethereum node in Managed Blockchain are indicated where applicable.
WebSockets calls have a 512 KB payload limit. Some calls may exceed this limit and cause a "message response is too large" error. Use HTTP for these requests instead of WebSockets. HTTP requests have a 6 MB payload limit. Responses that exceed the HTTP also result in a "message response is too large" error.
The block identifier parameter
Some methods have an extra block identifier parameter. The following options are possible values for this parameter:
-
A hexadecimal string value that represents an integer block number.
-
"earliest"
– String for the genesis block. -
"latest"
– String for the latest mined block. -
"pending"
– String for the pending state transactions.
Method | Description | Considerations |
---|---|---|
debug_traceBlock |
Returns the full stack trace of all invoked opcodes of all transactions that were included in the block provided as a parameter in RLP format. | Debug responses can get larger than allowed by the AMB API Gateway.
You can mitigate this by passing compression headers. Both headers |
debug_traceBlockByHash |
Returns the full stack trace of all transactions that were included in a specified block, by its hash. | |
debug_traceBlockByNumber |
Returns the full stack trace of all transactions that were included in the specified block number. | |
debug_traceTransaction |
Attempts to returns all traces of given transaction. | |
eth_blockNumber |
Returns the number of the most recent block. | |
eth_call |
Immediately executes a new message call without creating a transaction on the blockchain. | eth_call consumes 0 gas, but has a gas parameter for messages that require it. |
eth_chainId | Returns an integer value for the currently configured Chain Id value introduced in EIP-155None if no Chain Id is available. |
|
eth_createAccessList | This method creates an EIP2930accessList
based on a given Transaction . The accessList contains all storage slots and addresses
read and written by the transaction, except for the sender account and the precompiles. This method uses the
same transaction call object and blockNumberOrTag object as eth_call . |
An accessList can be used to unstuck contracts that became inaccessible due to gas cost
increases. |
eth_estimateGas |
Estimates and returns the gas required for a transaction without adding the transaction to the blockchain. | |
eth_feeHistory | Returns a collection of historical gas information. | |
eth_gasPrice |
Returns the current price per gas in Wei. | |
eth_getBalance |
Returns the balance of an account for the specified account address and block identifier. | |
eth_getBlockByHash |
Returns information about the block specified using the block hash. | |
eth_getBlockByNumber |
Returns information about the block specified using the block number. | |
eth_getBlockTransactionCountByHash |
Returns the number of transactions in the block specified using the block hash. | |
eth_getBlockTransactionCountByNumber |
Returns the number of transactions in the block specified using the block number. | |
eth_getCode |
Returns the code at the specified account address and block identifier. | |
eth_getFilterChanges |
Polls the specified filter ID, retuning an array of logs that occurred since the last poll. | Filters are ephemeral. If Managed Blockchain needs to manage or maintain node instances for availability and performance, and an instance is replaced, filters may be deleted. We recommend that you write your application code to handle the occasional deletion of filters. |
eth_getFilterLogs |
Returns an array of all logs for the specified filter ID. | Filters are ephemeral. If Managed Blockchain needs to manage or maintain node instances for availability and performance, and an instance is replaced, filters may be deleted. We recommend that you write your application code to handle the occasional deletion of filters. |
eth_getLogs |
Returns an array of all logs for a specified filter object. | Filters are ephemeral. If Managed Blockchain needs to manage or maintain node instances for availability and performance, and an instance is replaced, filters may be deleted. We recommend that you write your application code to handle the occasional deletion of filters. |
eth_getProof | Experimental – Returns the account and storage values of the specified account, including the Merkle proof. | |
eth_getStorageAt |
Returns the value of the specified storage position for the specified account address and block identifier. | |
eth_getTransactionByBlockHashAndIndex |
Returns information about a transaction using the specified block hash and transaction index position. | |
eth_getTransactionByBlockNumberAndIndex |
Returns information about a transaction using the specified block number and transaction index position. | |
eth_getTransactionByHash |
Returns information about the transaction with the specified transaction hash. | |
eth_getTransactionCount |
Returns the number of transactions sent from the specified address and block identifier. | |
eth_getTransactionReceipt |
Returns the receipt of the transaction using the specified transaction hash. | |
eth_getUncleByBlockHashAndIndex |
Returns information about the uncle block specified using the block hash and uncle index position. | |
eth_getUncleByBlockNumberAndIndex |
Returns information about the uncle block specified using the block number and uncle index position. | |
eth_getUncleCountByBlockHash |
Returns the number of counts in the uncle specified using the uncle hash. | |
eth_getUncleCountByBlockNumber |
Returns the number of counts in the uncle specified using the uncle number. | |
eth_getWork |
Returns the hash of the current block, the seedHash, and the boundary condition (also called the "target") to be met. | |
eth_maxPriorityFeePerGas | Returns the fee per gas that is an estimate of how much you can pay as a priority fee, or "tip", to get a transaction included in the current block. | Generally you will use the value returned from this method to set the maxFeePerGas
in the subsequent transaction that you are submitting. |
eth_newBlockFilter |
Creates a filter in the node to notify when a new block arrives. Use <code>eth_getFilterChanges</code> to check for state changes. | |
eth_newFilter |
Creates a filter object with the specified filter options (such as from block, to block, contract address, or topics). | |
eth_newPendingTransactionFilter |
Creates a filter in the node to notify when new pending transactions arrive. Use <code>eth_getFilterChanges</code> to check for state changes. | |
eth_protocolVersion |
Returns the current Ethereum protocol version. | |
eth_sendRawTransaction |
Creates a new message call transaction or a contract creation for signed transactions. | Managed Blockchain supports raw transactions only. You must create and
sign transactions before sending them. For more information, see How
to create raw transactions in Ethereum |
eth_subscribe |
Experimental for publication subscription – Creates a subscription for specified events and returns a subscription ID. | Available only when using WebSockets. Subscriptions are coupled to each connection. When the connection closes, the subscription is removed. |
eth_syncing |
Returns an object with sync status data or false when not
syncing. |
|
eth_uninstallFilter |
Uninstalls the filter with the specified filter ID. | |
eth_unsubscribe |
Experimental for publication subscription – Cancels the subscription with the specified subscription ID. | |
net_listening |
Returns true if the client is actively listening for network
connections. |
|
net_peerCount |
Returns the number of peers currently connected to the client. | |
net_version |
Returns the current network ID. | |
txpool_inspect |
Lists a textual summary of all transactions currently pending inclusion in the next blocks, and those that are queued (being scheduled for future execution only). | |
txpool_status |
Provides a count of all transactions currently pending inclusion in the next blocks, and those that are queued (being scheduled for future execution only). | |
web3_clientVersion |
Returns the current client version. | |
web3_sha3 |
Returns Keccak-256 (not the standardized SHA3-256) of the given data. |
Examples – making Ethereum API calls to an Ethereum node in Amazon Managed Blockchain
The following examples demonstrate ways to make Ethereum API calls to an Ethereum node on Amazon Managed Blockchain.
Topics
The Signature Version 4 signing process requires credentials associated with an AWS account. Some examples in this section export these sensitive credentials to the shell environment of the client. Only use these examples on a client running in a trusted context. Do not use these examples in an untrusted context, such as in a web browser or mobile app. Client credentials should never be embedded in user-facing applications. To expose an Ethereum node on Managed Blockchain to anonymous users visiting from trusted web domains, you can set up a separate endpoint in Amazon API Gateway backed by a Lambda function that forwards requests to your node using the proper IAM credentials.
Endpoint format for WebSockets and HTTP
An Ethereum node created using Ethereum on Managed Blockchain hosts one endpoint for WebSockets connections and another for HTTP connections. These endpoints conform to the following patterns.
The node ID is case-sensitive and must be lowercase where indicated, or a signature mismatch error occurs.
WebSockets endpoint format
wss://
my-node-id-lowercase
.wss.ethereum.managedblockchain.us-east-1
.amazonaws.com/
For example, wss://nd-6eaj5va43jggnpxouzp7y47e4y.wss.ethereum.managedblockchain.us-east-1.amazonaws.com/
HTTP endpoint format
https://
my-node-id-lowercase
.ethereum.managedblockchain.us-east-1
.amazonaws.com/
For example, https://nd-6eaj5va43jggnpxouzp7y47e4y.ethereum.managedblockchain.us-east-1.amazonaws.com/
Using web3.js
Web3.js
Both HTTP and WebSockets connection types rely on a local connection provider library to open the Signature Version 4 authenticated connection to the Ethereum node. You install the provider for the connection locally by copying the source code to a file on your client. You then reference the library files in the script that makes the Ethereum API call.
Prerequisites
Running the example scripts requires the following prerequisites. Prerequisites for both HTTP and WebSockets connections are included.
-
You must have node version manager (nvm) and Node.js installed on your machine. If you are using an Amazon EC2 instance as your Ethereum client, see Tutorial: Setting Up Node.js on an Amazon EC2 Instance for more information.
Type
node --version
and verify that you are using Node version 14 or later. If necessary, you can use thenvm install 14
command followed by thenvm use 14
command to install version 14.Use node package manager (npm) to install the
aws-sdk
,web3
, andxhr2
packages as shown in the following examples.npm install aws-sdk
npm install web3
npm install xhr2
The example scripts use ES modules. To enable ECMAScript (ES) module support, add the
"type": "module"
line to yourpackage.json
file. The example that follows shows the contents of a simplepackage.json
file.{ "type": "module", "dependencies": { "aws-sdk": "^2.809.0", "web3": "^1.3.0", "xhr2": "^0.2.0" } }
-
The environment variables
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
must contain credentials associated with the same AWS account that created the node. The environment variablesAMB_HTTP_ENDPOINT
andAMB_WS_ENDPOINT
must contain your Ethereum node's HTTP and WebSockets endpoints respectively.Export these variables as strings on your client as shown in the examples that follow. Replace the values with appropriate values from your IAM user account.
export AWS_ACCESS_KEY_ID="
AKIAIOSFODNN7EXAMPLE
"export AWS_SECRET_ACCESS_KEY="
wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
"export AMB_HTTP_ENDPOINT="https://
nd-6eaj5va43jggnpxouzp7y47e4y
.ethereum.managedblockchain.us-east-1.amazonaws.com/"export AMB_WS_ENDPOINT="wss://
nd-6eaj5va43jggnpxouzp7y47e4y
.wss.ethereum.managedblockchain.us-east-1.amazonaws.com/"
To make an Ethereum API call using web3.js over HTTP to your Ethereum node on Managed Blockchain
Copy the contents of the example that follows, and then use your preferred text editor to save it to a file named
aws-http-provider.js
on your client machine in the same directory where you run your script.Contents of aws-http-provider.js
///////////////////////////////////////////////////// // Authored by Carl Youngblood // Senior Blockchain Solutions Architect, AWS // Adapted from web3 npm package v1.3.0 // licensed under GNU Lesser General Public License // https://github.com/ethereum/web3.js ///////////////////////////////////////////////////// import AWS from 'aws-sdk'; import HttpProvider from 'web3-providers-http'; import XHR2 from 'xhr2'; export default class AWSHttpProvider extends HttpProvider { send(payload, callback) { const self = this; const request = new XHR2(); // eslint-disable-line request.timeout = self.timeout; request.open('POST', self.host, true); request.setRequestHeader('Content-Type', 'application/json'); request.onreadystatechange = () => { if (request.readyState === 4 && request.timeout !== 1) { let result = request.responseText; // eslint-disable-line let error = null; // eslint-disable-line try { result = JSON.parse(result); } catch (jsonError) { let message; if (!!result && !!result.error && !!result.error.message) { message = `[aws-ethjs-provider-http] ${result.error.message}`; } else { message = `[aws-ethjs-provider-http] Invalid JSON RPC response from host provider ${self.host}: ` + `${JSON.stringify(result, null, 2)}`; } error = new Error(message); } callback(error, result); } }; request.ontimeout = () => { callback(`[aws-ethjs-provider-http] CONNECTION TIMEOUT: http request timeout after ${self.timeout} ` + `ms. (i.e. your connect has timed out for whatever reason, check your provider).`, null); }; try { const strPayload = JSON.stringify(payload); const region = process.env.AWS_DEFAULT_REGION || 'us-east-1'; const credentials = new AWS.EnvironmentCredentials('AWS'); const endpoint = new AWS.Endpoint(self.host); const req = new AWS.HttpRequest(endpoint, region); req.method = request._method; req.body = strPayload; req.headers['host'] = request._url.host; const signer = new AWS.Signers.V4(req, 'managedblockchain'); signer.addAuthorization(credentials, new Date()); request.setRequestHeader('Authorization', req.headers['Authorization']); request.setRequestHeader('X-Amz-Date', req.headers['X-Amz-Date']); request.send(strPayload); } catch (error) { callback(`[aws-ethjs-provider-http] CONNECTION ERROR: Couldn't connect to node '${self.host}': ` + `${JSON.stringify(error, null, 2)}`, null); } } }
Copy the contents of the example that follows, and then use a text editor of your choosing to save it to a file named
web3-example-http.js
in the same directory where you saved the provider from the previous step. The example script runs the
Ethereum method. You can modify the script to include other methods and their parameters.getNodeInfo
Contents of web3-example-http.js
import Web3 from 'web3'; import AWSHttpProvider from './aws-http-provider.js'; const endpoint = process.env.AMB_HTTP_ENDPOINT const web3 = new Web3(new AWSHttpProvider(endpoint)); web3.eth.
getNodeInfo()
.then(console.log);Run the script to call the Ethereum API method over HTTP on your Ethereum node.
node web3-example-http.js
You should see output similar to the following.
Geth/v1.9.24-stable-cc05b050/linux-amd64/go1.15.5
To make an Ethereum API call using web3.js over WebSockets to your Ethereum node on Managed Blockchain
Copy the contents of the example that follows, and then use a text editor of your choosing to save it to a file named
aws-websocket-provider.js
in the same directory on your client where you run your script.Contents of aws-websocket-provider.js
///////////////////////////////////////////////////// // Authored by Carl Youngblood // Senior Blockchain Solutions Architect, AWS // Adapted from web3 npm package v1.3.0 // licensed under GNU Lesser General Public License // https://github.com/ethereum/web3.js ///////////////////////////////////////////////////// import AWS from 'aws-sdk'; import WebsocketProvider from 'web3-providers-ws'; import pkg from 'websocket'; const { w3cwebsocket } = pkg; const Ws = w3cwebsocket; export default class AWSWebsocketProvider extends WebsocketProvider { connect() { const region = process.env.AWS_DEFAULT_REGION || 'us-east-1'; const credentials = new AWS.EnvironmentCredentials('AWS'); const host = new URL(this.url).hostname; const endpoint = new AWS.Endpoint(`https://${host}/`); const req = new AWS.HttpRequest(endpoint, region); req.method = 'GET'; req.body = ''; req.headers['host'] = host; const signer = new AWS.Signers.V4(req, 'managedblockchain'); signer.addAuthorization(credentials, new Date()); const headers = { 'Authorization': req.headers['Authorization'], 'X-Amz-Date': req.headers['X-Amz-Date'], ...this.headers } this.connection = new Ws(this.url, this.protocol, undefined, headers, this.requestOptions, this.clientConfig); this._addSocketListeners(); } }
Copy the contents of the following, and then use a text editor of your choosing to save it to a file named
web3-example-ws.js
in the same directory where you saved the provider from the previous step. The example script runs the
Ethereum method and then closes the connection. You can modify the script to include other methods and their parameters.getNodeInfo
Contents of web3-example-ws.js
import Web3 from 'web3'; import AWSWebsocketProvider from "./aws-websocket-provider.js"; const endpoint = process.env.AMB_WS_ENDPOINT const web3 = new Web3(new AWSWebsocketProvider(endpoint)); web3.eth.
getNodeInfo()
.then(console.log).then(() => { web3.currentProvider.connection.close(); });Run the script to call the Ethereum API method over WebSockets on your Ethereum node.
node web3-example-ws.js
You should see output similar to the example that follows.
Geth/v1.9.24-stable-cc05b050/linux-amd64/go1.15.5
Using the AWS SDK for JavaScript with WebSockets
The example that follows uses a JavaScript file for Node.js to open a WebSockets connection to the Ethereum node endpoint in Managed Blockchain, and then send an Ethereum JSON-RPC API call.
Running the example script requires the following:
You must have Node.js installed on your machine. If you are using an Amazon EC2 instance, see Tutorial: Setting Up Node.js on an Amazon EC2 Instance.
You must use the Node package manager (npm) to install the AWS SDK for JavaScript, websocket-client, and ws packages as shown in the example commands that follow. The script uses classes from these packages.
npm install websocket-client
npm install ws
npm install aws-sdk
The environment variables
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
must contain credentials associated with the same account that created the node.
If you added the "type": "module"
line in your package.json
, which is necessary for the previous web3 example, the script that follows will fail with the error require is not defined
. Modify package.json
to remove or comment out this line before running the script.
To make an Ethereum API call over WebSockets to your Ethereum node on Managed Blockchain
Copy the contents of the script that follows and save it to a file on your machine, for example,
ws-ethereum-example.js
. Use a text editor to replace
with the ID of a node in your account, such asmy-node-id-lowercase
nd-6eaj5va43jggnpxouzp7y47e4y
, and replaceus-east-1
with the AWS Region in which you created your node.The example calls the Ethereum JSON-RPC method
eth_subscribe
along with thenewHeads
parameter. You can replace this method and its parameters with any method listed in Supported JSON-RPC methods.Contents of ws-ethereum-example.js
const AWS = require('aws-sdk'); const WebSocket = require('ws') const region = 'us-east-1'; const host = '
my-node-id-lowercase
.wss.ethereum.managedblockchain.us-east-1
.amazonaws.com'; const payload = { jsonrpc: '2.0', method: 'eth_subscribe
', params: ["newHeads"
], id: 67 } const credentials = new AWS.EnvironmentCredentials('AWS'); const endpoint = new AWS.Endpoint(`https://${host}`); const request = new AWS.HttpRequest(endpoint, region); request.method = 'GET'; request.body = ''; request.headers['host'] = host; const signer = new AWS.Signers.V4(request, 'managedblockchain'); signer.addAuthorization(credentials, new Date()); const ws = new WebSocket(`wss://${host}`, {headers: request.headers}); ws.onopen = async () => { ws.send(JSON.stringify(payload)); console.log('Sent request'); } ws.onerror = (error) => { console.error(`WebSocket error: ${error.message}`) } ws.onmessage = (e) => { console.log(e.data) }Run the script to call the Ethereum API method over WebSockets on your Ethereum node.
node ws-ethereum-example.js
The
eth_subscribe
method with thenewHeads
parameter generates a notification each time a new header is appended to the chain. You should see output similar to the example that follows, with additional subsequent responses. The WebSockets connection remains open and additional notifications appear until you cancel the command.sent request {"id":67,"jsonrpc":"2.0","result":"0xabcd123456789efg0h123ijk45l6m7n8"}
Using awscurl to make JSON-RPC calls over HTTP
The example that follows uses awscurl
Replace
with the ID of a node in your account such as my-node-id-lowercase
nd-6eaj5va43jggnpxouzp7y47e4y
. The example calls the web3_clientVersion
method, which takes an empty parameter block. You can replace this method and its parameters with any method listed in Supported JSON-RPC methods.
awscurl --service managedblockchain \ -X POST -d '{"jsonrpc": "2.0", "method": "web3_clientVersion", "params": [], "id": 67}' \ https://
my-node-id-lowercase
.ethereum.managedblockchain.us-east-1.amazonaws.com
The command returns output similar to the following.
{"jsonrpc":"2.0","id":67,"result":"Geth/v1.9.22-stable-c71a7e26/linux-amd64/go1.15.5"}