Skip to content

Token Standards Explained — ERC-20, ERC-721, ERC-1155

DodaTech 2 min read

In this tutorial, you'll learn about Token Standards Explained. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

What You'll Learn

Understand Ethereum token standards — ERC-20 (fungible), ERC-721 (non-fungible), and ERC-1155 (multi-token) — and how to implement each.

Why It Matters

Token standards make Ethereum interoperable. Any wallet, exchange, or DApp can work with any token that follows the standard.

Real-World Use

USDC is an ERC-20 stablecoin, CryptoPunks are ERC-721 NFTs, and games use ERC-1155 to manage items and currency in one contract.

What is a Token Standard?

A token standard is a set of required functions and events that a smart contract must implement to be compatible with wallets and exchanges.

Wallet (MetaMask)
  ↓
Expects any ERC-20 to implement:
  transfer(), balanceOf(), approve()
  ↓
Works with USDC, UNI, DAI, LINK...

ERC-20 — Fungible Tokens

All tokens are identical and interchangeable:

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

Key properties: Divisible (18 decimals), interchangeable, uniform.

Use cases: Currencies (USDC), governance tokens (UNI), staking tokens.

// Simple ERC-20
contract MyToken is ERC20 {
    constructor() ERC20("MyToken", "MTK") {
        _mint(msg.sender, 1_000_000 * 10**18);
    }
}

ERC-721 — Non-Fungible Tokens

Each token is unique:

interface IERC721 {
    function balanceOf(address owner) external view returns (uint256);
    function ownerOf(uint256 tokenId) external view returns (address);
    function transferFrom(address from, address to, uint256 tokenId) external;
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) external;
}

Key properties: Unique IDs, indivisible, metadata per token.

Use cases: Art, collectibles, domain names, deeds.

contract MyNFT is ERC721 {
    uint256 public nextTokenId;

    constructor() ERC721("My NFT", "MNFT") {}

    function mint(address to) public returns (uint256) {
        uint256 tokenId = nextTokenId;
        _safeMint(to, tokenId);
        nextTokenId++;
        return tokenId;
    }
}

ERC-1155 — Multi-Token Standard

Batch multiple token types in one contract:

interface IERC1155 {
    function balanceOf(address account, uint256 id) external view returns (uint256);
    function balanceOfBatch(address[] memory accounts, uint256[] memory ids) external view returns (uint256[] memory);
    function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes memory data) external;
    function safeBatchTransferFrom(address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) external;
}

Key properties: Batch operations, both fungible and non-fungible tokens in one contract.

Use cases: Gaming (gold coins + swords), semi-fungible (event tickets).

Comparison

Feature ERC-20 ERC-721 ERC-1155
Token type Fungible Non-fungible Both
Transfers Amount Token ID Amount + ID
Batch No No Yes
Gas for 100 transfers 100 txs 100 txs 1 tx
Metadata No Per token Per token type
Example USDC BAYC OpenSea Shared

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro