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": "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
"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-avalanche-mainnet-archive.n.dwellir.com/YOUR_API_KEY/ext/bc/C/rpc');
// 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-avalanche-mainnet-archive.n.dwellir.com/YOUR_API_KEY/ext/bc/C/rpc'))
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
// Trader Joe Pool Price Query (Avalanche native DEX)
async function getPoolPrice(poolAddress) {
const poolABI = [
"function getReserves() view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast)",
"function token0() view returns (address)",
"function token1() view returns (address)"
];
const pool = new Contract(poolAddress, poolABI, provider);
const [reserves, token0, token1] = await Promise.all([
pool.getReserves(),
pool.token0(),
pool.token1()
]);
// Calculate price ratio
const price = Number(reserves.reserve1) / Number(reserves.reserve0);
return {
token0: token0,
token1: token1,
price: price,
reserve0: reserves.reserve0.toString(),
reserve1: reserves.reserve1.toString()
};
}
2. Multi-Contract Queries
// Batch multiple contract calls using Avalanche Multicall
async function multicall(calls) {
const multicallABI = [
"function aggregate(tuple(address target, bytes callData)[] calls) view returns (uint256 blockNumber, bytes[] returnData)"
];
const multicallAddress = "0xcA11bde05977b3631167028862bE2a173976CA11"; // Multicall3 on Avalanche
const multicall = new Contract(multicallAddress, multicallABI, provider);
const results = await multicall.aggregate(calls);
return results.returnData;
}
3. AVAX Balance and Token Queries
// Check both AVAX and token balances
async function getWalletBalances(walletAddress, tokenAddresses) {
// Get native AVAX balance
const avaxBalance = await provider.getBalance(walletAddress);
// Get token balances
const tokenBalances = [];
for (const tokenAddr of tokenAddresses) {
try {
const token = new Contract(tokenAddr, ERC20_ABI, provider);
const [balance, symbol, decimals] = await Promise.all([
token.balanceOf(walletAddress),
token.symbol(),
token.decimals()
]);
tokenBalances.push({
address: tokenAddr,
symbol: symbol,
balance: balance.toString(),
formatted: (Number(balance) / Math.pow(10, decimals)).toFixed(4)
});
} catch (error) {
console.error(`Error fetching token ${tokenAddr}:`, error);
}
}
return {
avax: {
balance: avaxBalance.toString(),
formatted: formatEther(avaxBalance)
},
tokens: tokenBalances
};
}
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 Avalanche documentation.