eth_call
Executes a new message call immediately without creating a transaction on the blockchain. Used for reading smart contract state.
When to Use This Method​
eth_call
is essential for:
- Reading Contract State - Query view/pure functions
- Simulating Transactions - Test execution without gas costs
- DeFi Integrations - Check prices, balances, allowances
- Complex Queries - Execute multi-step contract logic
Parameters​
-
Transaction Object
from
- (optional) Address executing the callto
- Contract address to callgas
- (optional) Gas limit for the callgasPrice
- (optional) Gas price in weivalue
- (optional) Value to send in weidata
- Encoded function call data
-
Block Parameter -
QUANTITY|TAG
"latest"
- Most recent block"pending"
- Pending state- Block number in hex
{
"jsonrpc": "2.0",
"method": "eth_call",
"params": [
{
"to": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"data": "0x70a08231000000000000000000000000742d35cc6634c0532925a3b844bc9e7595f0beb"
},
"latest"
],
"id": 1
}
Returns​
DATA
- The return value of the executed contract function.
Implementation Examples​
- JavaScript
- Python
import { JsonRpcProvider, Contract, Interface } from 'ethers';
const provider = new JsonRpcProvider('https://api-base-mainnet.n.dwellir.com/YOUR_API_KEY');
// ERC20 ABI for common functions
const ERC20_ABI = [
"function balanceOf(address owner) view returns (uint256)",
"function allowance(address owner, address spender) view returns (uint256)",
"function totalSupply() view returns (uint256)",
"function decimals() view returns (uint8)",
"function symbol() view returns (string)",
"function name() view returns (string)"
];
// Read ERC20 token balance
async function getTokenBalance(tokenAddress, walletAddress) {
const contract = new Contract(tokenAddress, ERC20_ABI, provider);
const balance = await contract.balanceOf(walletAddress);
const decimals = await contract.decimals();
const symbol = await contract.symbol();
return {
raw: balance.toString(),
formatted: (Number(balance) / Math.pow(10, decimals)).toFixed(4),
symbol: symbol
};
}
// Direct eth_call for custom encoding
async function directCall(to, data) {
const result = await provider.call({
to: to,
data: data
});
return result;
}
// Simulate transaction without sending
async function simulateTransaction(from, to, value, data) {
try {
const result = await provider.call({
from: from,
to: to,
value: value,
data: data,
gasLimit: 3000000 // High limit for simulation
});
return { success: true, result: result };
} catch (error) {
return { success: false, error: error.message };
}
}
from web3 import Web3
from eth_abi import encode, decode
w3 = Web3(Web3.HTTPProvider('https://api-base-mainnet.n.dwellir.com/YOUR_API_KEY'))
def call_contract_function(contract_address, function_signature, params):
"""Generic contract call function"""
# Encode function call
function_selector = w3.keccak(text=function_signature)[:4]
encoded_params = encode(params['types'], params['values'])
data = function_selector + encoded_params
# Make the call
result = w3.eth.call({
'to': contract_address,
'data': data
})
return result
def get_erc20_balance(token_address, wallet_address):
"""Get ERC20 token balance"""
# balanceOf(address) selector
function_signature = "balanceOf(address)"
function_selector = w3.keccak(text=function_signature)[:4].hex()
# Encode address parameter
encoded_address = wallet_address[2:].lower().zfill(64)
data = function_selector + encoded_address
# Make the call
result = w3.eth.call({
'to': token_address,
'data': data
})
# Decode result
balance = int(result.hex(), 16)
return balance
def batch_token_balances(token_addresses, wallet_address):
"""Get multiple token balances efficiently"""
balances = {}
for token in token_addresses:
try:
balance = get_erc20_balance(token, wallet_address)
balances[token] = balance
except Exception as e:
balances[token] = {'error': str(e)}
return balances
Common Use Cases​
1. DeFi Price Queries​
// Uniswap V3 Pool Price Query
async function getPoolPrice(poolAddress) {
const poolABI = [
"function slot0() view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked)",
"function token0() view returns (address)",
"function token1() view returns (address)"
];
const pool = new Contract(poolAddress, poolABI, provider);
const [slot0, token0, token1] = await Promise.all([
pool.slot0(),
pool.token0(),
pool.token1()
]);
// Calculate price from sqrtPriceX96
const sqrtPriceX96 = slot0.sqrtPriceX96;
const price = (Number(sqrtPriceX96) / (2 ** 96)) ** 2;
return {
token0: token0,
token1: token1,
price: price,
tick: slot0.tick
};
}
2. Multi-Contract Queries​
// Batch multiple contract calls
async function multicall(calls) {
const multicallABI = [
"function aggregate(tuple(address target, bytes callData)[] calls) view returns (uint256 blockNumber, bytes[] returnData)"
];
const multicallAddress = "0xcA11bde05977b3631167028862bE2a173976CA11"; // Base Multicall3
const multicall = new Contract(multicallAddress, multicallABI, provider);
const results = await multicall.aggregate(calls);
return results.returnData;
}
3. Access Control Checks​
// Check permissions before transaction
async function checkPermissions(contractAddress, userAddress, role) {
const accessControlABI = [
"function hasRole(bytes32 role, address account) view returns (bool)",
"function getRoleAdmin(bytes32 role) view returns (bytes32)"
];
const contract = new Contract(contractAddress, accessControlABI, provider);
const hasRole = await contract.hasRole(role, userAddress);
return hasRole;
}
Error Handling​
Error Code | Description | Solution |
---|---|---|
-32000 | Execution reverted | Check function requirements |
-32602 | Invalid parameters | Verify data encoding |
-32015 | VM execution error | Check contract logic |
async function safeCall(to, data) {
try {
const result = await provider.call({ to, data });
return { success: true, data: result };
} catch (error) {
if (error.message.includes('revert')) {
// Try to decode revert reason
const reason = error.data?.replace('0x08c379a0', '');
if (reason) {
const decoded = ethers.utils.toUtf8String('0x' + reason.slice(8));
return { success: false, error: decoded };
}
}
return { success: false, error: error.message };
}
}
Need help? Contact our support team or check the Base documentation.