For the past few months, I’ve been working on a blockchain-based backend.
Coming from a traditional backend background, I found it a bit strange connecting Python to the blockchain. One of my earliest hurdles was understanding how to actually “talk” to the blockchain.
That’s when I discovered RPCs - Remote Procedure Calls and how they power everything behind the scenes in Web3.
Here’s what I learned.
🔍 What Is an RPC?
RPC stands for Remote Procedure Call.
It’s not just a Web3 concept; it’s been around in distributed systems for a long time.
In simple terms:
RPC lets a program execute a function in another program on a different server as if it were local.
A Simple Example
Imagine you have a function like this in your local code:
def MyPage(name: str, count: int):
When you call it:
data = MyPage("my", 1)
Your program jumps to that specific function and executes it directly.
Now imagine
def MyPage(name: str, count: int):
doesn’t exist in your codebase at all—instead, it lives on another server entirely.
RPC makes it so that calling
MyPage("my", 1)
sends the request over the network, runs the function on the remote server, and sends back the result, while hiding all the networking complexity from you.
⚙️ How It Works (Under the Hood)
When you make an RPC call:
- The client calls the client's stub
- The client stub marshals the parameters (converts them to a format that can be transmitted over the network, like binary)
- The marshalled data is sent to the remote server.
- The server unmarshals the parameters back to their original format.
- The server executes the function with those parameters
- The server marshals the result and sends it back.
- The client stub unmarshals the result and returns it to your program.
Note: Marshalling is the process of converting data into a format suitable for transmission, while unmarshalling is the reverse process.
🔗 RPC in Blockchain Networks
In web3, RPC specifically JSON-RPC, is used to communicate with blockchain network nodes and execute commands.
JSON-RPC encodes basic RPC functionality in JSON format, making it easier to communicate across different servers and programming languages.
Every JSON-RPC request consists of four key components:
- Version: "jsonrpc" - specifies the RPC version (typically "2.0")
- Method: "method" - the name of the function you're calling
- Parameters: "params" - the arguments for the method
- Unique Identifier: "id" - tracks the request/response pair
Here are some practical examples:
Example 1: Reading Blockchain Data
To check the current block number on Ethereum:
Request:
{
"jsonrpc": "2.0",
"method": "eth_blockNumber",
"params": [], // No parameters needed for this method
"id": 1 // A unique ID for this request
}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x1312d00" // Hexadecimal for 20,000,000 in decimal
}
Example 2: Sending Ether (State-Changing Transaction)
NOTE: Unlike read operations, sending a transaction that modifies the blockchain state is a two-step process:
- Client-Side (Off-chain): You construct the transaction details (from, to, value, gas, nonce, etc.), then sign this transaction using the sender's private key.
- Node-Side (On-chain): You send this signed raw transaction to the Ethereum node using eth_sendRawTransaction. The node validates the signature, includes it in a block, and broadcasts it to the network.
JSON-RPC Request (after signing off-chain):
{
"jsonrpc": "2.0",
"method": "eth_sendRawTransaction",
"params": [
"0xf86c808..."
// This very long hex string is the RLP-encoded, signed raw transaction
],
"id": 4
}
JSON-RPC Response (Success):
{
"jsonrpc": "2.0",
"id": 4,
"result": "0x53b496732f..." // The transaction hash
}
The result here is the transaction hash. You can then use another RPC method (eth_getTransactionReceipt) with this hash to check the transaction outcome.
Implementation Options
To send JSON-RPC requests to blockchain networks, you have two main approaches:
1. RPC Providers
RPC providers offer hosted blockchain nodes with exposed RPC endpoints. Popular options include:
Infura
Alchemy (which I use)
QuickNode
Etherscan API
Polygon, Arbitrum, and other network-specific providers
Pros: Convenient, scalable, maintained infrastructure, high uptime
Cons: Requires subscription, rate limits, ongoing costs, less control
2. Self-Hosted Nodes
You can run your blockchain node (like Hyperledger Besu for Ethereum) and connect directly to its RPC endpoint.
Pros: Full control, no rate limits, no ongoing subscription costs
Cons: Requires maintenance, storage, bandwidth, and technical expertise.
🤯 My Early Struggles
Initially, I was doing it all manually:
- Constructing JSON-RPC payloads by hand
- Sending them using requests in Python
- Decoding hexadecimal responses
- Handling edge cases and errors myself
essentially performing all the stub activities by hand.
Here's what that looked like:
import requests
import json
# Manual RPC call - the hard way
def get_block_number_manual():
payload = {
"jsonrpc": "2.0",
"method": "eth_blockNumber",
"params": [],
"id": 1
}
response = requests.post(
"https://polygon-amoy.g.alchemy.com/v2/API_KEY",
data=json.dumps(payload),
headers={'content-type': 'application/json'}
)
result = response.json()
# Convert hex to decimal manually
block_number = int(result['result'], 16)
return block_number
This approach was error-prone and tedious. Then I discovered the web3.py client library, which transformed my development experience:
from web3 import Web3
# Using web3.py - the easy way
w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_API_KEY'))
block_number = w3.eth.block_number # That's it!
The web3.py library acts as the client stub, handling all the complexity: error handling, encoding/decoding, connection management, and more.
Key Takeaways
- Understanding RPC in blockchain development opened up a whole new world for me. The key insights:
- RPC makes remote function calls feel local.
- JSON-RPC is the standard for blockchain communication
- Use established libraries like web3.py instead of manual implementation.
- RPC providers for convenience, self-hosted nodes for control
The transition from traditional backend development to blockchain becomes much smoother once you grasp these RPC fundamentals.
For a deeper dive into RPC in distributed systems, check out Understanding RPC in Distributed Systems by Christopher R. Wirz.
Hey everyone! We’re launching an exclusive token airdrop for all verified Dev.to authors. Claim your rewards here to see if you qualify (limited supply — act fast). – Admin