Docs
Supported ChainsTRONEthereum JSON-RPC API

eth_call - Execute Smart Contract Call

Executes a smart contract call without creating a transaction on TRON. Used for reading contract state and testing transactions.

Executes a new message call immediately without creating a transaction on the blockchain.

When to Use This Method

Use eth_call to:

  • Read Contract State - Query view/pure functions without gas costs
  • Simulate Transactions - Test transaction execution without broadcasting
  • Validate Parameters - Check if a transaction will succeed
  • Get Return Values - Retrieve data from smart contracts

Parameters

  1. Transaction Object - The transaction call object

    • from (optional): Address the transaction is sent from
    • to: Address the transaction is directed to (contract address)
    • gas (optional): Gas provided for the transaction
    • gasPrice (optional): Gas price in wei
    • value (optional): Value sent with this transaction
    • data: Hash of the method signature and encoded parameters
  2. Block Parameter - Block number, or string "latest", "earliest" or "pending"

JSON
{
  "jsonrpc": "2.0",
  "method": "eth_call",
  "params": [
    {
      "to": "0x...",
      "data": "0x..."
    },
    "latest"
  ],
  "id": 1
}

Returns

DATA - The return value of the executed contract method.

Implementation Examples

JSON-RPC endpoint format

Use https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/jsonrpc for all TRON JSON-RPC methods (eth_*, net_*, web3_*). Send POST requests with a JSON-RPC body and remember to replace YOUR_API_KEY.

Bash
# Read ERC-20 token balance
curl -X POST https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/jsonrpc \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_call",
    "params": [
      {
        "to": "0xa614f803b6fd780986a42c78ec9c7f77e6ded13c",
        "data": "0x70a08231000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045"
      },
      "latest"
    ],
    "id": 1
  }'
JavaScript
// Using ethers.js to read contract
import { ethers } from 'ethers';

const provider = new ethers.JsonRpcProvider('https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/jsonrpc');

// ERC-20 ABI for balanceOf
const abi = ['function balanceOf(address owner) view returns (uint256)'];
const contract = new ethers.Contract(contractAddress, abi, provider);

// Read balance
const balance = await contract.balanceOf(userAddress);
console.log('Token balance:', ethers.formatUnits(balance, 18));

// Raw eth_call
const data = contract.interface.encodeFunctionData('balanceOf', [userAddress]);
const result = await provider.call({
  to: contractAddress,
  data: data
});
console.log('Raw result:', result);
Python
from web3 import Web3
import json

w3 = Web3(Web3.HTTPProvider('https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/jsonrpc'))

# ERC-20 token contract
contract_address = '0xa614f803b6fd780986a42c78ec9c7f77e6ded13c'
user_address = '0xa614f803b6fd780986a42c78ec9c7f77e6ded13c'

# balanceOf method signature
data = '0x70a08231' + user_address[2:].zfill(64)

# Execute call
result = w3.eth.call({
    'to': contract_address,
    'data': data
})

balance = int(result.hex(), 16)
print(f'Token balance: {balance / 10**18}')

Example Response

JSON
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x00000000000000000000000000000000000000000000000000000000000004d2"
}

Common Use Cases

1. Read ERC-20 Token Information

JavaScript
async function getTokenInfo(tokenAddress) {
  const abi = [
    'function name() view returns (string)',
    'function symbol() view returns (string)',
    'function decimals() view returns (uint8)',
    'function totalSupply() view returns (uint256)'
  ];
  
  const contract = new ethers.Contract(tokenAddress, abi, provider);
  
  const [name, symbol, decimals, totalSupply] = await Promise.all([
    contract.name(),
    contract.symbol(),
    contract.decimals(),
    contract.totalSupply()
  ]);
  
  return {
    name,
    symbol,
    decimals,
    totalSupply: ethers.formatUnits(totalSupply, decimals)
  };
}

2. Check Allowance Before Transfer

JavaScript
async function checkAndApprove(tokenAddress, spender, amount) {
  const abi = [
    'function allowance(address owner, address spender) view returns (uint256)',
    'function approve(address spender, uint256 amount) returns (bool)'
  ];
  
  const contract = new ethers.Contract(tokenAddress, abi, provider);
  const currentAllowance = await contract.allowance(userAddress, spender);
  
  if (currentAllowance < amount) {
    console.log('Insufficient allowance, approval needed');
    // Create approval transaction
    return false;
  }
  
  return true;
}

3. Simulate Transaction Before Sending

JavaScript
async function simulateTransaction(to, data, value = '0x0') {
  try {
    const result = await provider.call({
      to,
      data,
      value,
      from: userAddress // Important for access control
    });
    
    console.log('Simulation successful:', result);
    return { success: true, result };
  } catch (error) {
    console.error('Transaction will fail:', error.message);
    return { success: false, error: error.message };
  }
}

Best Practices

  1. Always specify from for access-controlled functions
  2. Use latest block for current state
  3. Handle reverts gracefully
  4. Cache read results when appropriate
  5. Validate addresses before calling

Error Codes

CodeMessageDescription
-32600Invalid RequestMalformed request
-32602Invalid paramsInvalid method parameters
-32603Internal errorInternal JSON-RPC error
-32000Execution revertedContract execution failed
3Execution errorEVM execution error