CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-web3-eth-contract

Web3 module to interact with Ethereum smart contracts with TypeScript type safety

Pending
Overview
Eval results
Files

method-execution.mddocs/

Method Execution

Contract method calls for both read-only operations and state-changing transactions with full TypeScript type safety based on contract ABI.

Capabilities

Method Object Types

Different method object interfaces depending on the contract method's state mutability.

/**
 * Interface for non-payable contract methods (view, pure, nonpayable)
 */
interface NonPayableMethodObject<Inputs = unknown[], Outputs = unknown[]> {
  /** The arguments passed to this method */
  arguments: Inputs;
  
  /**
   * Call a method and execute its smart contract method in the EVM without sending any transaction
   * Note: calling cannot alter the smart contract state
   * @param options - The options used for calling
   * @returns Promise that resolves to the method return values
   */
  call(options?: NonPayableCallOptions): Promise<Outputs>;
  
  /**
   * Estimate the gas required for this method
   * @param options - The options used for gas estimation
   * @returns Promise that resolves to estimated gas amount
   */
  estimateGas(options?: NonPayableCallOptions): Promise<number>;
  
  /**
   * Create an access list for this method call
   * @param options - The options used for access list creation
   * @returns Promise that resolves to access list result
   */
  createAccessList(options?: NonPayableCallOptions): Promise<AccessListResult>;
  
  /**
   * Encode the ABI for this method including function signature and parameters
   * @returns The encoded ABI byte code to send via a transaction or call
   */
  encodeABI(): string;
  
  /**
   * Decode raw result of method call into readable values
   * @param data - The data to decode
   * @returns The decoded data
   */
  decodeData(data: HexString): Inputs;
  
  /**
   * Populate transaction object for this method call
   * @param options - Transaction options
   * @param contractOptions - Contract default options
   * @returns Transaction call object
   */
  populateTransaction(options?: NonPayableCallOptions, contractOptions?: ContractOptions): TransactionCall;
}

/**
 * Interface for payable contract methods 
 */
interface PayableMethodObject<Inputs = unknown[], Outputs = unknown[]> 
  extends NonPayableMethodObject<Inputs, Outputs> {
  
  /**
   * Send a transaction to execute this method and change contract state
   * @param options - The options used for sending the transaction
   * @returns PromiEvent that resolves to transaction receipt with events
   */
  send(options?: PayableCallOptions): Web3PromiEvent<TransactionReceipt, SendTransactionEvents>;
}

Method Access

Access contract methods through the dynamically generated methods property.

class Contract<Abi extends ContractAbi> {
  /** Dynamically generated methods based on contract ABI */
  readonly methods: ContractMethodsInterface<Abi>;
}

type ContractMethodsInterface<Abi extends ContractAbi> = {
  [MethodAbi in FilterAbis<Abi, AbiFunctionFragment & { type: 'function' }> as MethodAbi['name']]: ContractBoundMethod<MethodAbi>;
} & {
  /** Allow access by method signature for overloaded methods */
  [key: string]: ContractBoundMethod<any>;
};

type ContractBoundMethod<Abi extends AbiFunctionFragment> = (
  ...args: ContractMethodInputParameters<Abi['inputs']>
) => Abi['stateMutability'] extends 'payable' | 'pure'
  ? PayableMethodObject<ContractMethodInputParameters<Abi['inputs']>, ContractMethodOutputParameters<Abi['outputs']>>
  : NonPayableMethodObject<ContractMethodInputParameters<Abi['inputs']>, ContractMethodOutputParameters<Abi['outputs']>>;

Call Options

Options for method calls and transactions.

// From web3-types
interface NonPayableCallOptions {
  from?: Address;
  gas?: Numbers;
  gasPrice?: Numbers;
  maxFeePerGas?: Numbers;
  maxPriorityFeePerGas?: Numbers;
  nonce?: Numbers; 
  block?: BlockNumberOrTag;
}

interface PayableCallOptions extends NonPayableCallOptions {
  value?: Numbers;
}

type NonPayableTxOptions = NonPayableCallOptions;
type PayableTxOptions = PayableCallOptions;

Usage Examples

Read-Only Method Calls

import { Contract } from "web3-eth-contract";

const abi = [
  {
    inputs: [],
    name: "getValue",
    outputs: [{ name: "", type: "uint256" }],
    stateMutability: "view",
    type: "function"
  },
  {
    inputs: [{ name: "account", type: "address" }],
    name: "balanceOf", 
    outputs: [{ name: "", type: "uint256" }],
    stateMutability: "view",
    type: "function"
  }
] as const;

const contract = new Contract(abi, contractAddress);

// Simple call without options
const value = await contract.methods.getValue().call();
console.log("Current value:", value);

// Call with specific options
const balance = await contract.methods.balanceOf("0x1234...").call({
  from: "0xabcd...",
  block: "latest"
});
console.log("Balance:", balance);

// Multi-return method
const abi2 = [{
  inputs: [],
  name: "getInfo",
  outputs: [
    { name: "name", type: "string" },
    { name: "value", type: "uint256" }
  ],
  stateMutability: "view",
  type: "function"
}] as const;

const contract2 = new Contract(abi2, contractAddress);
const result = await contract2.methods.getInfo().call();
// result.name and result.value are properly typed
console.log("Name:", result.name, "Value:", result.value);
// Also accessible by index: result[0], result[1]

State-Changing Transactions

const abi = [
  {
    inputs: [{ name: "newValue", type: "uint256" }],
    name: "setValue",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function"
  },
  {
    inputs: [
      { name: "to", type: "address" },
      { name: "amount", type: "uint256" }
    ],
    name: "transfer",
    outputs: [{ name: "", type: "bool" }],
    stateMutability: "nonpayable", 
    type: "function"
  }
] as const;

const contract = new Contract(abi, contractAddress);

// Simple transaction
const receipt = await contract.methods.setValue(42).send({
  from: "0x1234567890123456789012345678901234567890",
  gas: 100000,
  gasPrice: "20000000000"
});

console.log("Transaction hash:", receipt.transactionHash);
console.log("Gas used:", receipt.gasUsed);

// Transaction with event monitoring
const promiEvent = contract.methods.transfer("0xabcd...", 1000).send({
  from: "0x1234...",
  gas: 50000
});

promiEvent
  .on('transactionHash', (hash) => {
    console.log("Transaction sent:", hash);
  })
  .on('receipt', (receipt) => {
    console.log("Transaction confirmed:", receipt);
  })
  .on('error', (error) => {
    console.error("Transaction failed:", error);
  });

const receipt = await promiEvent;

Payable Methods

const abi = [{
  inputs: [],
  name: "deposit",
  outputs: [],
  stateMutability: "payable",
  type: "function"
}] as const;

const contract = new Contract(abi, contractAddress);

// Send ether with the transaction
const receipt = await contract.methods.deposit().send({
  from: "0x1234...",
  value: web3.utils.toWei("1", "ether"), // Send 1 ETH
  gas: 100000
});

Gas Estimation

// Estimate gas before sending transaction
const gasEstimate = await contract.methods.setValue(42).estimateGas({
  from: "0x1234567890123456789012345678901234567890"
});

console.log("Estimated gas:", gasEstimate);

// Use estimated gas with buffer
const receipt = await contract.methods.setValue(42).send({
  from: "0x1234567890123456789012345678901234567890",
  gas: Math.floor(gasEstimate * 1.2) // Add 20% buffer
});

Access List Creation

// Create access list for EIP-2930 transactions
const accessList = await contract.methods.setValue(42).createAccessList({
  from: "0x1234567890123456789012345678901234567890"
});

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

// Use access list in transaction
const receipt = await contract.methods.setValue(42).send({
  from: "0x1234567890123456789012345678901234567890",
  accessList: accessList.accessList,
  type: 1 // EIP-2930 transaction type
});

Overloaded Methods

// For overloaded methods, access by signature
const abi = [
  {
    inputs: [{ name: "value", type: "uint256" }],
    name: "set",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function"
  },
  {
    inputs: [
      { name: "key", type: "string" },
      { name: "value", type: "uint256" }
    ],
    name: "set",
    outputs: [],
    stateMutability: "nonpayable", 
    type: "function"
  }
] as const;

const contract = new Contract(abi, contractAddress);

// Access by method signature for overloaded methods
await contract.methods["set(uint256)"](42).send({ from: account });
await contract.methods["set(string,uint256)"]("key", 42).send({ from: account });

// Or by index if there are naming conflicts
await contract.methods.set(42).send({ from: account }); // First definition

Return Types

// Transaction receipt type
interface TransactionReceipt {
  transactionHash: string;
  transactionIndex: number;
  blockHash: string;
  blockNumber: number;
  from: string;
  to: string;
  gasUsed: number;
  cumulativeGasUsed: number;
  logs: EventLog[];
  status: boolean;
  // ... other receipt fields
}

// PromiEvent for transaction sending
type ContractMethodSend = Web3PromiEvent<
  FormatType<TransactionReceipt, DataFormat>,
  SendTransactionEvents<DataFormat>
>;

// Access list result
interface AccessListResult {
  accessList: AccessList;
  gasUsed: string;
}

Install with Tessl CLI

npx tessl i tessl/npm-web3-eth-contract

docs

contract-deployment.md

contract-management.md

encoding-utilities.md

event-handling.md

index.md

method-execution.md

tile.json