DEV Community

Loading Blocks
Loading Blocks

Posted on

Ethers.js Developer Guide – Practical

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();


Enter fullscreen mode Exit fullscreen mode
  1. 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");
Enter fullscreen mode Exit fullscreen mode

Infura

const provider = new ethers.InfuraProvider("mainnet", process.env.INFURA_API_KEY);
Enter fullscreen mode Exit fullscreen mode

Alchemy

const provider = new ethers.AlchemyProvider("sepolia", process.env.ALCHEMY_API_KEY);
Enter fullscreen mode Exit fullscreen mode

Etherscan (read-only)

const provider = new ethers.EtherscanProvider("mainnet", process.env.ETHERSCAN_API_KEY);
Enter fullscreen mode Exit fullscreen mode

Browser Provider (MetaMask)

const provider = new ethers.BrowserProvider(window.ethereum);
await provider.send("eth_requestAccounts", []);
Enter fullscreen mode Exit fullscreen mode

Recap:

Provider = blockchain connection.

Use RPC for local, Infura/Alchemy for production, MetaMask for browser.

  1. 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);
Enter fullscreen mode Exit fullscreen mode

Import from Private Key

const wallet = new ethers.Wallet(process.env.PRIVATE_KEY);
Enter fullscreen mode Exit fullscreen mode

Import from Mnemonic

const wallet = ethers.Wallet.fromPhrase("test test test ...");
Enter fullscreen mode Exit fullscreen mode

Connect Wallet to Provider

const provider = new ethers.JsonRpcProvider("https://rpc.sepolia.org");
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
Enter fullscreen mode Exit fullscreen mode

Sign a Message

const signature = await wallet.signMessage("Hello Ethereum");
console.log("Signature:", signature);
Enter fullscreen mode Exit fullscreen mode

Send a Transaction

const tx = await wallet.sendTransaction({
  to: "0xabc123...def",
  value: ethers.parseEther("0.01")
});
console.log("Transaction hash:", tx.hash);
Enter fullscreen mode Exit fullscreen mode

⚡ Recap:

Wallet = identity + signer.

Always connect wallet → provider before sending transactions.

  1. 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);

Enter fullscreen mode Exit fullscreen mode

Read Data

const balance = await contract.balanceOf("0xabc123...");
console.log("Balance:", ethers.formatUnits(balance, 18));
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

Listen to Events

contract.on("Transfer", (from, to, value) => {
  console.log(`Transfer: ${value} tokens from ${from} to ${to}`);
});
Enter fullscreen mode Exit fullscreen mode

Recap:

Contract = interface + ABI + address.

Use provider for read calls, wallet signer for transactions.

  1. Utilities – Everyday Helpers

Unit Conversion

const value = ethers.parseEther("1.0");
console.log(value.toString());
console.log(ethers.formatEther(value));
Enter fullscreen mode Exit fullscreen mode

BigNumber Math

const a = ethers.parseUnits("1000", 18);
const b = ethers.parseUnits("250", 18);
console.log(a.add(b).toString());
Enter fullscreen mode Exit fullscreen mode

Hashing

const hash = ethers.keccak256(ethers.toUtf8Bytes("hello"));
console.log("Hash:", hash);
Enter fullscreen mode Exit fullscreen mode

Address Helpers

console.log(ethers.isAddress("0xabc123...")); 
console.log(ethers.getAddress("0xabc123..."));

Enter fullscreen mode Exit fullscreen mode

⚡ Recap: Utilities handle ETH units, big numbers, hashes, addresses.

  1. 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
});
Enter fullscreen mode Exit fullscreen mode

Event Filters

const filter = contract.filters.Transfer(null, "0xdef...");
const events = await contract.queryFilter(filter, -1000, "latest");
console.log(events);

Enter fullscreen mode Exit fullscreen mode

Security Tips

Never hardcode private keys.

Use BrowserProvider for frontend dApps.

Validate user inputs.

  1. 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)