Roadmap › Blockchain & Web3 Fundamentals › Module: Building dApps
Lessons in this course (15)

12. JavaScript: reading and writing with ethers.js v6

Intermediate★ Must knowLesson 12 of 15
js
import { BrowserProvider, Contract, formatUnits, parseUnits } from "ethers";

const ERC20_ABI = [
  "function balanceOf(address) view returns (uint256)",
  "function decimals() view returns (uint8)",
  "function transfer(address to, uint256 amount) returns (bool)",
  "event Transfer(address indexed from, address indexed to, uint256 value)",
];

const provider = new BrowserProvider(window.ethereum);          // MetaMask (EIP-1193)
await provider.send("eth_requestAccounts", []);
const signer = await provider.getSigner();
const token = new Contract("0xTokenAddress", ERC20_ABI, signer);

const decimals = await token.decimals();
const balance = await token.balanceOf(await signer.getAddress());
console.log(formatUnits(balance, decimals));                    // e.g. "125.5"

const tx = await token.transfer("0xRecipient", parseUnits("10", decimals));   // wallet pops up to sign
const receipt = await tx.wait(1);                               // wait for 1 confirmation
console.log(receipt.status === 1 ? "success" : "reverted");

token.on("Transfer", (from, to, value) => console.log(from, to, formatUnits(value, decimals)));

Token amounts are integers in the smallest unit (uint256) — always use parseUnits/formatUnits (BigInt), never floating point. In React apps, wagmi + viem + a connector UI (RainbowKit, ConnectKit, Reown AppKit) is the common stack.