1. Introduction
Ethers.js is a lightweight JavaScript library for interacting with the Ethereum blockchain. It provides:
- A unified way to connect to Ethereum nodes.
- Tools for creating and managing wallets.
- A simple API for calling smart contracts.
- Built-in utilities for handling blockchain-specific data formats (e.g.,
BigNumber
, hex strings, hashes).
Compared to alternatives like web3.js, Ethers.js is designed to be:
- Smaller (tree-shakeable, modular).
- Safer (immutability, strict typing).
- Developer-friendly (clean API surface).
2. Setup
Install via npm (or yarn/pnpm):
npm install ethers
import { ethers } from "ethers";
const { ethers } = require("ethers");
async function main() {
const provider = ethers.getDefaultProvider();
const blockNumber = await provider.getBlockNumber();
console.log("Latest block:", blockNumber);
}
main();
- Providers – Connecting to Ethereum
A Provider is your connection to the Ethereum network. Think of it as a “read-only API”.
JSON-RPC Provider
const provider = new ethers.JsonRpcProvider("http://localhost:8545");
Infura
const provider = new ethers.InfuraProvider("mainnet", process.env.INFURA_API_KEY);
Alchemy
const provider = new ethers.AlchemyProvider("sepolia", process.env.ALCHEMY_API_KEY);
Etherscan (read-only)
const provider = new ethers.EtherscanProvider("mainnet", process.env.ETHERSCAN_API_KEY);
Browser Provider (MetaMask)
const provider = new ethers.BrowserProvider(window.ethereum);
await provider.send("eth_requestAccounts", []);
Recap:
Provider = blockchain connection.
Use RPC for local, Infura/Alchemy for production, MetaMask for browser.
- Wallets – Managing Keys
A Wallet represents an Ethereum account (private key + address).
Create a Random Wallet
const wallet = ethers.Wallet.createRandom();
console.log("Address:", wallet.address);
console.log("Mnemonic:", wallet.mnemonic.phrase);
Import from Private Key
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY);
Import from Mnemonic
const wallet = ethers.Wallet.fromPhrase("test test test ...");
Connect Wallet to Provider
const provider = new ethers.JsonRpcProvider("https://rpc.sepolia.org");
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
Sign a Message
const signature = await wallet.signMessage("Hello Ethereum");
console.log("Signature:", signature);
Send a Transaction
const tx = await wallet.sendTransaction({
to: "0xabc123...def",
value: ethers.parseEther("0.01")
});
console.log("Transaction hash:", tx.hash);
⚡ Recap:
Wallet = identity + signer.
Always connect wallet → provider before sending transactions.
- Contracts – Interacting with Smart Contracts
A Contract object allows you to call functions defined in a smart contract.
Define a Contract
const abi = [
"function balanceOf(address) view returns (uint)",
"function transfer(address, uint) returns (bool)"
];
const tokenAddress = "0xYourTokenAddress";
const contract = new ethers.Contract(tokenAddress, abi, provider);
Read Data
const balance = await contract.balanceOf("0xabc123...");
console.log("Balance:", ethers.formatUnits(balance, 18));
Write Data (with Signer)
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
const contractWithSigner = contract.connect(signer);
const tx = await contractWithSigner.transfer("0xdef456...", ethers.parseUnits("1", 18));
await tx.wait();
console.log("Transfer confirmed:", tx.hash);
Listen to Events
contract.on("Transfer", (from, to, value) => {
console.log(`Transfer: ${value} tokens from ${from} to ${to}`);
});
Recap:
Contract = interface + ABI + address.
Use provider for read calls, wallet signer for transactions.
- Utilities – Everyday Helpers
Unit Conversion
const value = ethers.parseEther("1.0");
console.log(value.toString());
console.log(ethers.formatEther(value));
BigNumber Math
const a = ethers.parseUnits("1000", 18);
const b = ethers.parseUnits("250", 18);
console.log(a.add(b).toString());
Hashing
const hash = ethers.keccak256(ethers.toUtf8Bytes("hello"));
console.log("Hash:", hash);
Address Helpers
console.log(ethers.isAddress("0xabc123..."));
console.log(ethers.getAddress("0xabc123..."));
⚡ Recap: Utilities handle ETH units, big numbers, hashes, addresses.
- Advanced Topics
Gas Estimation & Overrides
const gas = await contract.estimateGas.transfer("0xdef...", ethers.parseUnits("1", 18));
const tx = await contractWithSigner.transfer("0xdef...", ethers.parseUnits("1", 18), {
gasLimit: gas * 2n
});
Event Filters
const filter = contract.filters.Transfer(null, "0xdef...");
const events = await contract.queryFilter(filter, -1000, "latest");
console.log(events);
Security Tips
Never hardcode private keys.
Use BrowserProvider for frontend dApps.
Validate user inputs.
- Quick Recap (Cheat Sheet)
Provider = connect (JsonRpcProvider, InfuraProvider, BrowserProvider).
Wallet = manage keys + sign transactions.
Contract = interact with ABI.
Utilities = conversions, hashes, addresses.
Advanced = gas, filters, security.
Top comments (0)