Skip to content

10. Web2 to Web3: ERC-20, ERC-721 & IPFS

A “standard” on Ethereum is an agreed-upon set of functions that a contract exposes so that wallets, exchanges, and other contracts can interact with it without custom code. This lesson covers the two you will meet everywhere — ERC-20 (fungible tokens) and ERC-721 (non-fungible tokens / NFTs) — and IPFS, the storage layer NFT metadata typically lives on. The practical message is: you rarely write these from scratch, you extend audited implementations.

  • What a token actually is — not a coin in a wallet, but a contract that keeps a ledger. An ERC-20 is a mapping(address => uint256) of balances plus standard functions to move them. “Owning a token” means the contract’s mapping credits your address.
  • ERC-20 (fungible) — every unit is interchangeable, like currency. The standard defines transfer, approve, transferFrom, balanceOf, totalSupply, and the Transfer / Approval events. Because every ERC-20 shares this interface, any wallet or DEX can handle a token it has never seen before.
  • approve / transferFrom — the two-step pattern that lets a contract move your tokens on your behalf (you approve a spender, it later calls transferFrom). This is what makes DEXs and vending contracts possible — and, done carelessly, a common source of risk.
  • ERC-721 (non-fungible) — each token has a unique tokenId and an individual owner. The standard tracks ownerOf(tokenId) and per-token transfers. Used for anything where items are distinct: art, memberships, deeds.
  • tokenURI and metadata — an ERC-721 doesn’t store the image or attributes onchain (that would be enormous and expensive). It stores a tokenURI that points to a JSON metadata file, which in turn points to the image.
  • IPFS — a content-addressed storage network: a file’s address (its CID) is a hash of its contents, so the link can’t silently change what it serves. This is why NFT metadata is pinned to IPFS rather than a normal URL that an owner could swap out.
  • OpenZeppelin — the community’s audited, reusable implementations of these standards. You import and extend ERC20 or ERC721 and add only your specifics, rather than re-implementing (and re-bugging) the standard.
  • Believing the NFT image is “on the blockchain.” Usually only a pointer is onchain; the metadata and image live on IPFS (or, riskily, a plain server that can go away).
  • Using a mutable http:// URL for metadata, which lets the content behind an NFT change or vanish. Content-addressed IPFS avoids this.
  • Writing your own ERC-20/721 from scratch for production. Reach for OpenZeppelin; the audited version has already handled the edge cases.
  • Misunderstanding approve — granting an unlimited allowance to an untrusted contract is a real way funds get drained.
  • What makes an ERC-20 “fungible” and an ERC-721 “non-fungible,” in terms of what the contract stores?
  • Where does an NFT’s image actually live, and what part is onchain?
  • Why is content-addressed IPFS storage safer for metadata than a normal web URL?

There are two ways to understand tokens: read a minimal implementation to see what a standard actually requires, then use a battle-tested library to ship one safely. Do both.

See what’s under the hood — Solidity by Example

  • ERC20 — a complete fungible-token contract in ~60 lines: balanceOf, transfer, approve, transferFrom, and the Transfer / Approval events.
  • ERC721 — the non-fungible equivalent, with per-token ownership and approvals.
  • ERC1155 — one contract holding many token types, fungible and non-fungible together.

Ship it safely — OpenZeppelin Contracts

Real projects almost never hand-write these. They inherit from OpenZeppelin, whose implementations are widely audited and reused. Rolling your own token invites the exact bugs these libraries have already fixed.

  • ERC20 — inherit ERC20, set name/symbol in the constructor, and call _mint. Add only the extensions you need: ERC20Burnable, ERC20Pausable, ERC20Capped, ERC20Permit (gasless approvals, EIP-2612), or ERC20Votes.
  • ERC721 — base ERC721 plus extensions like ERC721URIStorage (per-token metadata URI — this is where your IPFS tokenURI goes), ERC721Enumerable, and ERC721Pausable.
  • Access control — gate mint / pause with Ownable (single owner, onlyOwner) or AccessControl (named roles like MINTER_ROLE, used via onlyRole).
  • UtilitiesSafeERC20 for calling tokens that don’t return a bool, plus ReentrancyGuard and Pausable.
  • Contracts Wizard — an interactive tool that generates a correct OpenZeppelin token from checkboxes. Great for seeing how the pieces fit; still read what it produces.

Sources: Solidity by Example (Cyfrin) and the OpenZeppelin Contracts docs. Storing tokenURI metadata on IPFS is covered in the notes above.

Module 2: Solidity & Token Standards.