Solana

Solana Beta is live. Try BoltRPC Solana endpoints free - start your trial now.

Ethereum RPC Methods: A Practical Guide for dApp Developers

The Ethereum JSON-RPC methods you will actually use. Covers eth_call, eth_getLogs, eth_getBalance, eth_sendRawTransaction and more with real code examples.

BoltRPC
BoltRPC Team
9 min read
Ethereum RPC Methods: A Practical Guide for dApp Developers

Ethereum RPC Methods: A Practical Guide for dApp Developers

The full Ethereum JSON-RPC specification has dozens of methods. In practice, most dApps use around 10 of them regularly. This guide focuses on the methods you will actually use, what they do, when to use each, and what to watch out for.

For the full official specification, see ethereum.org/developers/docs/apis/json-rpc.


How Ethereum RPC Methods Work

Every Ethereum node exposes a JSON-RPC API. You call it by sending a POST request with a JSON body specifying the method and parameters:

curl -X POST https://eu.endpoints.matrixed.link/rpc/ethereum?auth=YOUR_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_blockNumber",
    "params": [],
    "id": 1
  }'

In practice, you will use ethers.js, viem, or web3.py to make these calls rather than raw curl. Those libraries translate their methods into the underlying JSON-RPC calls automatically.


Reading State: The Methods You Use Most

eth_getBalance

Returns the ETH balance of an address at a given block.

// ethers.js
const balance = await provider.getBalance('0xYourAddress');
console.log(ethers.formatEther(balance)); // "1.234567890"

// Raw JSON-RPC
{
  "method": "eth_getBalance",
  "params": ["0xYourAddress", "latest"]
}

When to use: Any time you need to display or check a wallet’s ETH balance.

The block parameter: "latest" returns the current balance. Pass a specific block number (hex) to get the historical balance at that block, which requires archive access.


eth_call

Executes a read-only call to a smart contract without submitting a transaction. Does not cost gas. Returns the contract’s response.

// ethers.js — reading a contract
const contract = new ethers.Contract(contractAddress, abi, provider);
const result = await contract.balanceOf('0xSomeAddress');

// Raw JSON-RPC
{
  "method": "eth_call",
  "params": [
    {
      "to": "0xContractAddress",
      "data": "0x70a08231000000000000000000000000SomeAddress"
    },
    "latest"
  ]
}

When to use: Reading any contract state: token balances, pool prices, governance votes, NFT ownership. This is the most-called method in most dApps.

Gas-free: eth_call simulates the transaction locally on the node. It does not broadcast to the network and costs no gas.


eth_getTransactionReceipt

Returns the receipt for a completed transaction: status (success/failure), gas used, logs emitted, block number.

// ethers.js
const receipt = await provider.getTransactionReceipt(txHash);
console.log(receipt.status); // 1 = success, 0 = failure
console.log(receipt.gasUsed);
console.log(receipt.logs);   // Events emitted by the transaction

When to use: Confirming that a transaction succeeded. Checking which events were emitted. Reading return values from state-changing transactions.

Note: Returns null if the transaction has not been mined yet. Poll until you get a result, or use provider.waitForTransaction(txHash).


eth_getLogs

Queries event logs emitted by contracts matching a filter. The most powerful (and most expensive) read method.

// ethers.js — get all Transfer events from an ERC-20 contract
const filter = {
  address: tokenContractAddress,
  topics: [ethers.id("Transfer(address,address,uint256)")],
  fromBlock: 19000000,
  toBlock: 'latest'
};

const logs = await provider.getLogs(filter);

When to use: Indexing contract events. Fetching historical token transfers. Reading DeFi protocol activity. Building dashboards that need on-chain event history.

Cost note: eth_getLogs is one of the more resource-intensive RPC methods. Providers using compute unit weighting assign it a significantly higher cost multiplier than basic queries. Check your provider’s method weighting documentation before building applications that rely heavily on this method. BoltRPC pricing is straightforward — fixed monthly plans with no surprise bills.

Block range: Querying a wide block range can be slow or rejected by some providers. For large historical queries, break them into chunks (e.g., 2,000 blocks at a time) and concatenate results.

// Chunked eth_getLogs for large ranges
async function getLogsInChunks(provider, filter, chunkSize = 2000) {
  const logs = [];
  let fromBlock = filter.fromBlock;
  const toBlock = filter.toBlock === 'latest'
    ? await provider.getBlockNumber()
    : filter.toBlock;

  while (fromBlock <= toBlock) {
    const chunkEnd = Math.min(fromBlock + chunkSize - 1, toBlock);
    const chunk = await provider.getLogs({
      ...filter,
      fromBlock,
      toBlock: chunkEnd
    });
    logs.push(...chunk);
    fromBlock = chunkEnd + 1;
  }

  return logs;
}

eth_getCode

Returns the bytecode deployed at a contract address. Returns 0x for externally-owned accounts (wallets).

const code = await provider.getCode('0xContractAddress');
const isContract = code !== '0x';

When to use: Checking whether an address is a contract or a wallet before sending a transaction. Verifying that a contract is deployed.


Sending Transactions

eth_sendRawTransaction

Broadcasts a signed transaction to the network. This is the method used for all on-chain writes: token transfers, contract interactions, contract deployments.

// ethers.js handles signing and broadcasting
const signer = new ethers.Wallet(privateKey, provider);
const tx = await signer.sendTransaction({
  to: '0xRecipientAddress',
  value: ethers.parseEther('0.01')
});

const receipt = await tx.wait(); // Wait for mining

Under the hood: ethers.js signs the transaction locally, serializes it, and calls eth_sendRawTransaction with the signed bytes. Your private key never leaves your application.

Important: eth_sendRawTransaction broadcasts to the mempool. It does not guarantee inclusion. The transaction may be stuck if gas price is too low. Use eth_getTransactionReceipt or provider.waitForTransaction() to confirm.


eth_estimateGas

Estimates the gas required for a transaction before sending it.

const gasEstimate = await provider.estimateGas({
  to: contractAddress,
  data: encodedFunctionCall
});

// Add a buffer to avoid out-of-gas failures
const gasLimit = gasEstimate * 120n / 100n; // 20% buffer

When to use: Before every state-changing transaction. Setting gasLimit too low causes the transaction to fail (and still costs gas). Setting it too high wastes nothing, but users may hesitate at inflated gas estimates.


Block and Network Queries

eth_blockNumber

Returns the current block height.

const blockNumber = await provider.getBlockNumber();

When to use: Knowing the current block for relative block calculations. Confirming how many confirmations a transaction has. Polling for new blocks (though WebSocket subscriptions are more efficient).


eth_getBlockByNumber

Returns full block data: timestamp, miner/validator, transaction list, gas used.

// ethers.js
const block = await provider.getBlock('latest');
console.log(block.timestamp);     // Unix timestamp
console.log(block.transactions);  // Array of tx hashes

// With full transaction objects
const blockWithTxs = await provider.getBlock('latest', true);

When to use: Getting block timestamps for time-based logic. Fetching all transactions in a block. Calculating block-based metrics.


eth_chainId

Returns the chain ID of the connected network.

const network = await provider.getNetwork();
console.log(network.chainId); // 1n for Ethereum mainnet

When to use: Verifying you are connected to the right network before signing transactions. Essential in multi-chain applications where a wrong-chain transaction can cause real damage.


WebSocket-Only: Subscriptions

These methods are only available over WebSocket. They push data to your application as events occur, rather than requiring polling.

eth_subscribe: newHeads

Subscribe to new block headers. Fires every time a new block is produced.

const wsProvider = new ethers.WebSocketProvider(
  'wss://eu.endpoints.matrixed.link/ws/ethereum?auth=YOUR_KEY'
);

wsProvider.on('block', (blockNumber) => {
  console.log('New block:', blockNumber);
});

When to use: Real-time UIs that display the latest block. Any application that needs to react to new blocks without polling.


eth_subscribe: logs

Subscribe to contract event logs matching a filter. Fires in real time as matching events are emitted.

const filter = {
  address: uniswapPoolAddress,
  topics: [ethers.id("Swap(address,address,int256,int256,uint160,uint128,int24)")]
};

wsProvider.on(filter, (log) => {
  console.log('New swap event:', log);
});

When to use: Real-time event monitoring. Trading dashboards. Liquidation bots. Price feeds that react to on-chain swaps.


Quick Reference

MethodTypeUse Case
eth_getBalanceReadETH balance of address
eth_callReadRead contract state (gas-free)
eth_getTransactionReceiptReadConfirm transaction + get logs
eth_getLogsReadHistorical event queries
eth_getCodeReadCheck if address is a contract
eth_sendRawTransactionWriteBroadcast signed transaction
eth_estimateGasUtilityPre-estimate gas for transaction
eth_blockNumberUtilityCurrent block height
eth_getBlockByNumberUtilityBlock data + transactions
eth_chainIdUtilityVerify connected network
eth_subscribe (newHeads)WSSReal-time block notifications
eth_subscribe (logs)WSSReal-time contract event stream

One RPC Endpoint for All EVM Methods

BoltRPC supports the full Ethereum JSON-RPC method set across all 22 supported networks. Every method in this guide works on Ethereum, Arbitrum, Base, Polygon, Optimism and all other supported EVM chains. Same method names, same format, just a different endpoint URL.

Trusted by Chainlink, Tiingo, Gains Network, Enjin. Built on ISO/IEC 27001:2022 certified infrastructure via Matrixed.Link. Flat monthly plan pricing — predictable costs with no surprise bills.

Start your free 2-week trial: trial.boltrpc.io

See all supported networks: boltrpc.io/networks


FAQ

Do all EVM chains support the same RPC methods?

The core methods (eth_getBalance, eth_call, eth_sendRawTransaction, etc.) are supported on all EVM-compatible chains. Some chains add additional methods or modify response fields. Arbitrum, for example, adds arb_ prefixed methods. Base and Optimism add optimism_ methods. Always check the chain-specific documentation for anything beyond the core spec.

Why does eth_getLogs cost more with some providers?

Providers using compute unit pricing apply a multiplier to eth_getLogs because it is resource-intensive on the node. The multiplier can be large relative to simple queries — often 75× or more compared to a basic balance check. BoltRPC uses flat-rate monthly plans, so your costs remain predictable regardless of which methods you call most heavily.

What is the difference between eth_call and eth_sendRawTransaction?

eth_call executes a read-only simulation locally on the node: no gas, no state change, not broadcast to the network. eth_sendRawTransaction broadcasts a signed transaction to the network and causes a real state change. Use eth_call to read; use eth_sendRawTransaction to write.

How do I decode event logs from eth_getLogs?

Event logs are ABI-encoded. You need the contract ABI to decode them. ethers.js does this automatically when you use a Contract instance with the ABI. For raw logs, use ethers.Interface to decode:

const iface = new ethers.Interface(abi);
const decoded = iface.parseLog(log);

Can I use WebSocket for all methods, not just subscriptions?

Yes. WebSocket supports all standard JSON-RPC methods plus subscriptions. However, for request-response queries, HTTP is simpler to manage (no persistent connection, no reconnection logic). Use WebSocket when you need subscriptions; use HTTP for everything else.

Frequently asked questions

Ready to build with high-performance RPC?

Start your free trial today. No credit card required. Access 20+ networks instantly.

Disclaimer: The content in this article is for informational purposes only and does not constitute financial, legal, or technical advice. Code examples and configurations are provided as-is. Always verify information with official documentation and test thoroughly in your own environment before deploying to production.

Continue reading