Ethers Contracts provides contract abstraction meta-classes that enable developers to interact with Ethereum smart contracts as native JavaScript objects. It creates runtime objects that represent on-chain contracts, allowing developers to call contract methods, handle events, and manage transactions through a clean JavaScript API.
npm install @ethersproject/contractsimport {
Contract,
ContractFactory,
// Types
Overrides,
PayableOverrides,
CallOverrides,
PopulatedTransaction,
EventFilter,
ContractFunction,
Event,
ContractReceipt,
ContractTransaction,
ContractInterface
} from "@ethersproject/contracts";
// Common dependencies for contract interaction
import { JsonRpcProvider, Provider } from "@ethersproject/providers";
import { Wallet, Signer } from "@ethersproject/wallet";
import { Interface } from "@ethersproject/abi";
import { BigNumber } from "@ethersproject/bignumber";
import { parseEther, formatEther } from "@ethersproject/units";For CommonJS:
const {
Contract,
ContractFactory,
// Types available but not needed at runtime for JS
} = require("@ethersproject/contracts");
// Common dependencies
const { JsonRpcProvider } = require("@ethersproject/providers");
const { Wallet } = require("@ethersproject/wallet");
const { parseEther, formatEther } = require("@ethersproject/units");import { Contract, ContractFactory } from "@ethersproject/contracts";
import { JsonRpcProvider } from "@ethersproject/providers";
import { Wallet } from "@ethersproject/wallet";
import { parseEther } from "@ethersproject/units";
// Connect to Ethereum
const provider = new JsonRpcProvider("https://mainnet.infura.io/v3/YOUR_KEY");
const wallet = new Wallet("YOUR_PRIVATE_KEY", provider);
// Create contract instance
const abi = [
"function balanceOf(address owner) view returns (uint256)",
"function transfer(address to, uint256 amount) returns (bool)",
"event Transfer(address indexed from, address indexed to, uint256 value)"
];
const contract = new Contract("0x...", abi, wallet);
// Call read-only function
const balance = await contract.balanceOf("0x...");
// Send transaction
const tx = await contract.transfer("0x...", parseEther("1.0"));
await tx.wait();
// Listen for events
contract.on("Transfer", (from, to, value, event) => {
console.log(`Transfer: ${from} -> ${to}: ${value}`);
});Ethers Contracts is built around several key components:
Core contract instantiation and method calling functionality. Provides the main Contract class for interacting with deployed smart contracts.
class Contract extends BaseContract {
constructor(
addressOrName: string,
contractInterface: ContractInterface,
signerOrProvider?: Signer | Provider
);
// Dynamic methods generated from ABI
readonly [key: string]: ContractFunction | any;
}
class BaseContract {
readonly address: string;
readonly interface: Interface;
readonly signer: Signer;
readonly provider: Provider;
readonly functions: { [name: string]: ContractFunction };
readonly callStatic: { [name: string]: ContractFunction };
readonly estimateGas: { [name: string]: ContractFunction<BigNumber> };
readonly populateTransaction: { [name: string]: ContractFunction<PopulatedTransaction> };
readonly filters: { [name: string]: (...args: Array<any>) => EventFilter };
}
type ContractInterface = string | ReadonlyArray<Fragment | JsonFragment | string> | Interface;
type ContractFunction<T = any> = (...args: Array<any>) => Promise<T>;Contract deployment functionality through ContractFactory. Enables deploying new contract instances and managing deployment transactions.
class ContractFactory {
constructor(
contractInterface: ContractInterface,
bytecode: BytesLike | { object: string },
signer?: Signer
);
readonly interface: Interface;
readonly bytecode: string;
readonly signer: Signer;
deploy(...args: Array<any>): Promise<Contract>;
getDeployTransaction(...args: Array<any>): TransactionRequest;
attach(address: string): Contract;
connect(signer: Signer): ContractFactory;
}Comprehensive event listening, filtering, and querying capabilities. Supports real-time event monitoring and historical event queries.
interface Event extends Log {
event?: string;
eventSignature?: string;
args?: Result;
decodeError?: Error;
decode?: (data: string, topics?: Array<string>) => any;
removeListener: () => void;
getBlock: () => Promise<Block>;
getTransaction: () => Promise<TransactionResponse>;
getTransactionReceipt: () => Promise<TransactionReceipt>;
}
type EventFilter = {
address?: string;
topics?: Array<string | Array<string>>;
};Transaction management including overrides, gas estimation, and transaction population. Provides comprehensive control over transaction parameters.
interface Overrides {
gasLimit?: BigNumberish | Promise<BigNumberish>;
gasPrice?: BigNumberish | Promise<BigNumberish>;
maxFeePerGas?: BigNumberish | Promise<BigNumberish>;
maxPriorityFeePerGas?: BigNumberish | Promise<BigNumberish>;
nonce?: BigNumberish | Promise<BigNumberish>;
type?: number;
accessList?: AccessListish;
customData?: Record<string, any>;
ccipReadEnabled?: boolean;
}
interface PayableOverrides extends Overrides {
value?: BigNumberish | Promise<BigNumberish>;
}
interface CallOverrides extends PayableOverrides {
blockTag?: BlockTag | Promise<BlockTag>;
from?: string | Promise<string>;
}
interface PopulatedTransaction {
to?: string;
from?: string;
nonce?: number;
gasLimit?: BigNumber;
gasPrice?: BigNumber;
data?: string;
value?: BigNumber;
chainId?: number;
type?: number;
accessList?: AccessList;
maxFeePerGas?: BigNumber;
maxPriorityFeePerGas?: BigNumber;
customData?: Record<string, any>;
ccipReadEnabled?: boolean;
}// Re-exported types from dependencies
import {
Interface,
Fragment,
JsonFragment,
Result
} from "@ethersproject/abi";
import {
Signer,
Provider,
TransactionRequest,
TransactionResponse,
TransactionReceipt,
Block,
BlockTag,
Log
} from "@ethersproject/abstract-provider";
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { BytesLike } from "@ethersproject/bytes";
import { AccessList, AccessListish } from "@ethersproject/transactions";
// Core contract types
interface ContractReceipt extends TransactionReceipt {
events?: Array<Event>;
}
interface ContractTransaction extends TransactionResponse {
wait(confirmations?: number): Promise<ContractReceipt>;
}
// Additional type aliases for convenience
type ContractInterface = string | ReadonlyArray<Fragment | JsonFragment | string> | Interface;
type ContractFunction<T = any> = (...args: Array<any>) => Promise<T>;