CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-web3-eth

Web3 module to interact with the Ethereum blockchain and smart contracts.

67

0.98x
Overview
Eval results
Files

smart-contract-interaction.mddocs/

Smart Contract Interaction

The smart contract interaction functionality provides methods to execute contract calls, estimate gas consumption, create access lists, and interact with smart contracts without state changes.

Contract Calls

call

Executes a read-only call to a smart contract method without creating a transaction on the blockchain.

call(transaction?: TransactionCall, blockNumber?: BlockNumberOrTag, returnFormat?: DataFormat): Promise<Bytes>;

Parameters:

  • transaction: Transaction call object with contract address, method data, and parameters
  • blockNumber: Block number or tag to execute call against (defaults to "latest")
  • returnFormat: Output format configuration

Usage Example:

// Simple contract call - get total supply of an ERC20 token
const totalSupplyCall = {
  to: "0x1234567890123456789012345678901234567890", // token contract address
  data: "0x18160ddd" // totalSupply() method selector
};

const result = await eth.call(totalSupplyCall);
console.log("Total supply (raw):", result);

// Contract call with parameters - get balance of specific address
import { encodeFunctionCall } from "web3-eth-abi";

const balanceOfCall = {
  to: "0x1234567890123456789012345678901234567890",
  data: encodeFunctionCall({
    name: "balanceOf",
    type: "function",
    inputs: [{ name: "owner", type: "address" }]
  }, ["0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E"])
};

const balance = await eth.call(balanceOfCall);
console.log("Token balance:", balance);

// Historical state query
const historicalBalance = await eth.call(balanceOfCall, 15000000);

Gas Estimation

estimateGas

Estimates the amount of gas required to execute a transaction or contract call.

estimateGas(transaction?: TransactionCall, blockNumber?: BlockNumberOrTag, returnFormat?: DataFormat): Promise<Numbers>;

Usage Example:

// Estimate gas for token transfer
const transferGasEstimate = await eth.estimateGas({
  from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
  to: "0x1234567890123456789012345678901234567890", // token contract
  data: encodeFunctionCall({
    name: "transfer",
    type: "function", 
    inputs: [
      { name: "to", type: "address" },
      { name: "amount", type: "uint256" }
    ]
  }, [
    "0x8ba1f109551bD432803012645Hac136c1c1b6c5E", // recipient
    "1000000000000000000" // 1 token (assuming 18 decimals)
  ])
});

console.log(`Estimated gas for transfer: ${transferGasEstimate}`);

// Estimate gas for contract deployment
const deploymentGasEstimate = await eth.estimateGas({
  from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
  data: "0x608060405234801561001057600080fd5b50..." // contract bytecode
});

console.log(`Estimated gas for deployment: ${deploymentGasEstimate}`);

// Add buffer to gas estimate (common practice)
const gasWithBuffer = Math.floor(Number(transferGasEstimate) * 1.2); // 20% buffer

EIP-2930 Access Lists

createAccessList

Generates an access list for EIP-2930 transactions to reduce gas costs by pre-declaring storage access.

createAccessList(transaction?: TransactionForAccessList, blockNumber?: BlockNumberOrTag, returnFormat?: DataFormat): Promise<AccessListResult>;

Usage Example:

// Create access list for token transfer
const accessListResult = await eth.createAccessList({
  from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
  to: "0x1234567890123456789012345678901234567890",
  data: encodeFunctionCall({
    name: "transfer",
    type: "function",
    inputs: [
      { name: "to", type: "address" },
      { name: "amount", type: "uint256" }
    ]
  }, [
    "0x8ba1f109551bD432803012645Hac136c1c1b6c5E",
    "1000000000000000000"
  ])
});

console.log("Access list:", accessListResult.accessList);
console.log("Gas used with access list:", accessListResult.gasUsed);

// Use access list in transaction to save gas
const receipt = await eth.sendTransaction({
  from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
  to: "0x1234567890123456789012345678901234567890",
  data: encodeFunctionCall(/* ... */),
  accessList: accessListResult.accessList,
  type: 1 // EIP-2930 transaction type
});

Contract Interaction Patterns

ERC20 Token Interactions

// Common ERC20 interactions
class ERC20Helper {
  constructor(private eth: Web3Eth, private tokenAddress: Address) {}

  async totalSupply(): Promise<string> {
    const result = await this.eth.call({
      to: this.tokenAddress,
      data: "0x18160ddd" // totalSupply()
    });
    return result;
  }

  async balanceOf(owner: Address): Promise<string> {
    const result = await this.eth.call({
      to: this.tokenAddress,
      data: encodeFunctionCall({
        name: "balanceOf",
        type: "function",
        inputs: [{ name: "owner", type: "address" }]
      }, [owner])
    });
    return result;
  }

  async estimateTransfer(from: Address, to: Address, amount: string): Promise<number> {
    const gasEstimate = await this.eth.estimateGas({
      from,
      to: this.tokenAddress,
      data: encodeFunctionCall({
        name: "transfer", 
        type: "function",
        inputs: [
          { name: "to", type: "address" },
          { name: "amount", type: "uint256" }
        ]
      }, [to, amount])
    });
    return Number(gasEstimate);
  }
}

Contract State Queries

// Query multiple contract states efficiently
async function getContractStates(contractAddress: Address) {
  // Prepare multiple calls
  const calls = [
    { to: contractAddress, data: "0x18160ddd" }, // totalSupply()
    { to: contractAddress, data: "0x313ce567" }, // decimals()
    { to: contractAddress, data: "0x95d89b41" }, // symbol()
    { to: contractAddress, data: "0x06fdde03" }  // name()
  ];

  // Execute all calls in parallel
  const results = await Promise.all(
    calls.map(call => eth.call(call))
  );

  return {
    totalSupply: results[0],
    decimals: results[1], 
    symbol: results[2],
    name: results[3]
  };
}

View Function Helpers

// Helper for common view function patterns
async function callViewFunction(
  contractAddress: Address,
  functionAbi: any,
  params: any[] = [],
  blockNumber?: BlockNumberOrTag
) {
  const data = encodeFunctionCall(functionAbi, params);
  
  return await eth.call({
    to: contractAddress,
    data
  }, blockNumber);
}

// Usage example
const ownerResult = await callViewFunction(
  "0x1234567890123456789012345678901234567890",
  {
    name: "owner",
    type: "function",
    inputs: [],
    outputs: [{ name: "", type: "address" }]
  }
);

Error Handling

// Handle contract call errors
async function safeContractCall(transaction: TransactionCall) {
  try {
    const result = await eth.call(transaction);
    return { success: true, data: result };
  } catch (error) {
    // Check if it's a revert with reason
    if (error.message.includes("execution reverted")) {
      return { 
        success: false, 
        error: "Contract execution reverted",
        details: error.message 
      };
    }
    
    // Other errors (invalid address, network issues, etc.)
    return { 
      success: false, 
      error: "Call failed", 
      details: error.message 
    };
  }
}

Core Types

interface TransactionCall {
  from?: Address;
  to: Address;
  gas?: Numbers;
  gasPrice?: Numbers;
  maxFeePerGas?: Numbers;
  maxPriorityFeePerGas?: Numbers;
  value?: Numbers;
  data?: Bytes;
  type?: Numbers;
  accessList?: AccessList;
}

interface TransactionForAccessList {
  from?: Address;
  to?: Address;
  gas?: Numbers;
  gasPrice?: Numbers;
  maxFeePerGas?: Numbers;
  maxPriorityFeePerGas?: Numbers;
  value?: Numbers;
  data?: Bytes;
}

interface AccessList {
  address: Address;
  storageKeys: HexString32Bytes[];
}

interface AccessListResult {
  accessList: AccessList[];
  gasUsed: HexString;
}

type Address = HexString20Bytes;
type Numbers = HexString | number | bigint;
type Bytes = HexString;
type BlockNumberOrTag = Numbers | "latest" | "earliest" | "pending" | "safe" | "finalized";

interface DataFormat {
  number: NumberFormat;
  bytes: BytesFormat;
}

Install with Tessl CLI

npx tessl i tessl/npm-web3-eth

docs

account-operations.md

blockchain-state.md

cryptographic-operations.md

event-monitoring.md

gas-fee-management.md

index.md

network-information.md

smart-contract-interaction.md

transaction-management.md

transaction-utilities.md

tile.json