eth_call | Avalanche

Recipes
🤑
Simulate a buy swap on Uniswap using Web3.js
Open Recipe

Avalanche API method that enables instant execution of a new message call without requiring the creation of a transaction on the blockchain. This can be useful for testing and debugging by simulating transfers or smart contract transactions and retrieving data from the blockchain.

📘

Disclaimer

The interactive example on this page uses eth_call to call the poolLength method from Trader Joe: Master Chef Joe V2 smart contract on Avalanche. It returns how many liquidity pools are available on the Trader Joe exchange.

👍

Get you own node endpoint today

Start for free and get your app to production levels immediately. No credit card required.

You can sign up with your GitHub, X, Google, or Microsoft account.

Parameters

  • object — the transaction call object:

    • from — (optional) the string of the address used to send the transaction.
    • to — the string of the address to which the transaction is directed, a wallet, or a smart contract.
    • gas — (optional) the maximum amount of gas that can be used by the transaction.
    • gasprice — (optional) the amount of gas price the sender is willing to pay for each gas unit in Wei.
    • value — (optional) the value sent with this transaction, encoded as hexadecimal.
    • data — (optional) additional data to be sent with the call, usually used to invoke functions from smart contracts as a string of the hash of the method signature and encoded parameters. See the Ethereum Contract ABI.
  • quantity or tag — the integer of a block encoded as hexadecimal or the string with:

    • latest — the most recent block in the blockchain and the current state of the blockchain at the most recent block

    • earliest — the earliest available or genesis block

    • pending — the pending state and transactions block. The current state of transactions that have been broadcast to the network but have not yet been included in a block.

      📘

      See the default block parameter.

Response

  • data — the result of executing the specified call on the Ethereum Virtual Machine (EVM), encoded as a hexadecimal string.

eth_call code examples

The following code snippets provide a clear demonstration of how to simulate a standard AVAX transfer between two accounts. Note that when using eth_call to simulate a transfer or a smart contract transaction, the sender account must have a sufficient balance to cover the associated gas fee.

const Web3 = require("web3");
const NODE_URL = "CHAINSTACK_NODE_URL";
const web3 = new Web3(NODE_URL);

async function simulateTransfer() {
    try {
        // Define the accounts to transfer between
        const fromAddress = "0xAd80f9fcc2a315aBB6007F6fd6cCEC74C1168b9a";
        const toAddress = "0x19e7e376e7c213b7e7e7e46cc70a5dd086daff2a";

        // Define the value to transfer (converted to Wei)
        const value = web3.utils.toWei("100", "ether");

        // Build transaction object
        const transactionObject = {
            from: fromAddress,
            to: toAddress,
            gas: 21000, // 21000 is the standard for a regular tranfer
            value: value,
            data: ""
        }

        // Use eth_call to simulate the transfer on the latest block
        const result = await web3.eth.call({
            transactionObject
        }, "latest");

        console.log(`Transaction hash: ${result}`);
    } catch (error) {
        console.error(`Error: ${error.message}`);
    }
}

simulateTransfer();
const ethers = require('ethers');
const NODE_URL = "CHAINSTACK_NODE_URL";
const provider = new ethers.providers.JsonRpcProvider(NODE_URL);

const simulateTransfer = async () => {
  try {    
    // Define the accounts to transfer between
    const fromAddress = "0xCd19A5475983D85bdb77991FA886105743a9CbE9";
    const toAddress = "0x19e7e376e7c213b7e7e7e46cc70a5dd086daff2a";

    // Define the value to transfer
    const value = ethers.parseEther("1");

    // Build transaction object
    const transactionObject = {
        from: fromAddress,
        to: toAddress,
        gasLimit: ethers.toQuantity(21000),
        value: value
    }

    // Use eth_call to simulate the transfer on the latest block
    const result = await provider.call(transactionObject);
    console.log(`Result: ${result}`);

  } catch (error) {
    console.error(`Error: ${error.message}`);

  }
}

simulateTransfer();
from web3 import Web3  
node_url = "CHAINSTACK_NODE_URL"

web3 = Web3(Web3.HTTPProvider(node_url)) 

# Define the accounts to transfer between
from_address = web3.to_checksum_address('0xAd80f9fcc2a315aBB6007F6fd6cCEC74C1168b9a')
to_address = web3.to_checksum_address('0x19e7e376e7c213b7e7e7e46cc70a5dd086daff2a')

# Define the value to transfer (in Ether)
value = web3.to_wei(1, 'ether')

# Build the transaction object
transaction = {
    'from': from_address,
    'to': to_address,
    'gas': 21000,  # 21000 is the standard for a regular transfer
    'value': value,
    'data': '',
}

# Use eth_call to simulate the transfer
result = web3.eth.call(transaction, 'latest')
print(result)

Executing this code will produce a return value of 0x, indicating a successful transaction. This implies that the transaction will be executed without any errors when the code is used to send the transaction.

Use case

A common use case for eth_call is calling smart contract functions. For example, interact with an ERC-20 token smart contract deployed on the Avalanche network and retrieve the balance of a specific account.

The following code uses the web3.js library to call the balanceOf function of the AAVE token smart contract on the Avalanche network.

const Web3 = require("web3");
const NODE_URL = "CHAINSTACK_NODE_URL";
const web3 = new Web3(NODE_URL);

// Contract address and ABI for the token
const CONTRACT_ADDRESS = "0x63a72806098Bd3D9520cC43356dD78afe5D386D9";
const ABI = [
  {
    "constant": true,
    "inputs": [
      {
        "name": "_owner",
        "type": "address"
      }
    ],
    "name": "balanceOf",
    "outputs": [
      {
        "name": "balance",
        "type": "uint256"
      }
    ],
    "payable": false,
    "stateMutability": "view",
    "type": "function"
  }
];

// Asynchronously fetches the balance of an account for the given address
async function getAccountBalance(address) {
  try {
    // Create a new contract instance
    const contract = new web3.eth.Contract(ABI, CONTRACT_ADDRESS);

    // Call the balanceOf function to retrieve the account balance in wei using eth_call
    const balanceInWei = await contract.methods.balanceOf(address).call();

    // Convert the balance from wei to ethers
    const balanceInEth = web3.utils.fromWei(balanceInWei, "ether");

    // Log the account balance in ethers to the console
    console.log(`The account balance for address ${address} is: ${balanceInEth} AAVE`);
    
  } catch (error) {
    console.error("Error occurred while fetching account balance:", error);
  }
}

// Call the getAccountBalance function with a sample account address
getAccountBalance("0x78bbcab7902f14fb84563aea2b8ae3f7d5c8c5c4");

The getAccountBalance function is called with the address of the account whose balance we want to retrieve. This function creates a new contract instance, calls the balanceOf function of the smart contract with the provided address, and retrieves the account balance in Wei. The balance is then converted to the ethers unit using the fromWei function of the web3.utils object.

Finally, the account balance is printed to the console for easy viewing.

Try the eth_call RPC method yourself

Language
Click Try It! to start a request and see the response here!