Tokens

What Are Tokens?

Tokens are digital assets that represent ownership or access to a particular service, asset, or value on a blockchain. Unlike cryptocurrencies like Bitcoin or Ether, which have their own blockchains, tokens are built on existing blockchains like Ethereum. Tokens can have various functions:

  • Currency: Used as a medium of exchange (e.g., stablecoins).

  • Governance: Represent voting power in decentralized organizations (e.g., governance tokens).

  • Access: Represent access to specific services or applications (e.g., utility tokens).

  • Assets: Represent ownership of real-world or digital assets (e.g., NFTs).

How Tokens Work on Ethereum

Tokens on Ethereum follow specific standards that define how they function, allowing for interoperability across platforms. These standards ensure that tokens behave predictably and consistently, especially when interacting with smart contracts, decentralized applications (dApps), and exchanges.

Types of Tokens: Fungible vs. Non-Fungible

  • Fungible Tokens: Interchangeable and have the same value (e.g., 1 ETH = 1 ETH). Examples include ERC-20 tokens.

  • Non-Fungible Tokens (NFTs): Unique and not interchangeable. Each token has distinct properties and value (e.g., ERC-721 tokens).

ERC Token Standards

a. ERC-20: Fungible Tokens

Overview

ERC-20 is the most commonly used token standard for creating fungible tokens on Ethereum. These tokens are interchangeable, and each unit has the same value and properties.

Key Functions in ERC-20

  • totalSupply(): Returns the total supply of tokens.

  • balanceOf(address): Returns the balance of a particular address.

  • transfer(to, value): Transfers a certain amount of tokens to another address.

  • approve(spender, value): Approves another address to spend a certain amount of tokens on behalf of the owner.

  • transferFrom(from, to, value): Transfers tokens on behalf of an address (using the approved amount).

Example Use Case

Stablecoins like USDC and DAI are built using the ERC-20 standard, allowing users to send and receive them just like they would with Ether.

Code Example:

// A simple ERC-20 token
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor(uint256 initialSupply) ERC20("MyToken", "MTK") {
        _mint(msg.sender, initialSupply);
    }
}

b. ERC-721: Non-Fungible Tokens (NFTs)

Overview

ERC-721 is a standard for creating non-fungible tokens (NFTs). Each ERC-721 token is unique and cannot be replaced with another, making it ideal for assets like digital art, collectibles, and property.

Key Functions in ERC-721

  • ownerOf(tokenId): Returns the owner of a specific NFT.

  • transferFrom(from, to, tokenId): Transfers ownership of an NFT.

  • approve(to, tokenId): Allows another address to transfer a specific token.

Example Use Case

Projects like CryptoKitties and Bored Ape Yacht Club use ERC-721 tokens to represent unique digital assets (e.g., individual kitties or apes).

Code Example:

// A simple ERC-721 NFT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract MyNFT is ERC721 {
    constructor() ERC721("MyNFT", "NFT") {}

    function mintNFT(address recipient, uint256 tokenId) public {
        _mint(recipient, tokenId);
    }
}

c. ERC-1155: Multi-Token Standard

Overview

ERC-1155 is a versatile token standard that allows for the creation of both fungible and non-fungible tokens within the same contract. This makes it ideal for gaming and applications where both types of assets are needed (e.g., in-game currency and unique items).

Key Functions in ERC-1155

  • balanceOf(address, tokenId): Returns the balance of a specific token for an address.

  • safeTransferFrom(from, to, tokenId, amount, data): Transfers tokens safely.

  • setApprovalForAll(operator, approved): Allows or revokes an operator to transfer all tokens on behalf of the owner.

Example Use Case

Games like Gods Unchained use ERC-1155 tokens to represent both in-game currency (fungible) and special items or cards (non-fungible).

Code Example:

// A simple ERC-1155 token contract
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";

contract MyMultiToken is ERC1155 {
    constructor() ERC1155("https://api.example.com/{id}.json") {}

    function mint(address account, uint256 id, uint256 amount, bytes memory data) public {
        _mint(account, id, amount, data);
    }
}

d. ERC-4626: Tokenized Vaults (Yield-bearing Tokens)

Overview

ERC-4626 is a new standard designed for tokenized vaults, specifically for DeFi protocols that issue interest-bearing tokens. This standard allows users to deposit tokens into a vault, which is then used in various yield-generating strategies (e.g., lending, staking). In return, users receive an ERC-4626 token that represents their share in the vault.

Key Functions in ERC-4626

  • deposit(amount, to): Deposits tokens into the vault and issues yield-bearing tokens in return.

  • withdraw(amount, to): Withdraws tokens from the vault by redeeming yield-bearing tokens.

  • totalAssets(): Returns the total assets held in the vault.

Example Use Case

Yearn Finance and Aave could use ERC-4626 to manage yield-bearing tokens that represent deposits in yield-generating protocols.

Code Example:

// A simplified ERC-4626 vault
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol";

contract MyVault is ERC4626 {
    constructor(ERC20 _asset) ERC4626(_asset) {}
    
    // Other vault-specific logic can be added here
}

Conclusion

Understanding the different ERC token standards is crucial to navigating the Ethereum ecosystem. Each token standard serves specific use cases, from basic fungible tokens (ERC-20) to complex multi-token standards (ERC-1155) and yield-bearing vaults (ERC-4626). By using real-world examples and code snippets, developers can better grasp the functionality and applications of these tokens.

Last updated