In Ethereum, ERCs are analogous to RFCs. It turns out that lot of the more popular EIPs (Ethereum Improvement Proposals) and ERCs are related to tokens.
This has resulted in standards that have shaped how tokens are created, managed, and traded on the Ethereum blockchain. The most popular of these standards are ERC-20, ERC-721, ERC-777, ERC-1155 and ERC-4626. Each of these standards has its own unique properties and use cases. This article will go over these standards and their use in blockchain applications, providing various examples.
ERC-20 Tokens
ERC-20 is the most widely used token standard on the Ethereum blockchain. It is used to create fungible tokens, which means any instance of the token is interchangeable with another and holds the same value. ERC-20 tokens can serve various functions such as currency, shares, or loyalty points.
EIP-20 provides specifications in regards to approving and transferring tokens from one address to another, obtaining token balances and knowing what the total supply for the tokens is, among other things.
Example
pragma solidity 0.8.4;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
// This token extends OpenZeppelin's implementation of the IERC20 interface
// but also mints 100 tokens (assuming 18 decimals) to the deployer account
contract MyERC20 is ERC20 {
constructor(string memory name, string memory symbol) ERC20(name, symbol) {
_mint(msg.sender, 100 * 10 ** uint(decimals()));
}
}
ERC-721 Tokens
ERC-721 is another widely adopted standard on the Ethereum blockchain. This one is used non-fungible tokens: unlike ERC-20, each ERC-721 token is unique and has its own value. This makes ERC-721 tokens ideal for representing assets such as real estate, collectibles, and in-game items.
EIP-721 provides specifications on things in a similar way to what EIP-20 does: token transferring and ownership, token approval and token total supply, among others. Some of these are optional, so not all implementations must have every method specified in the document.
Example
pragma solidity 0.8.4;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
// This token extends OpenZeppelin's implementation of the IERC721 interface
// and represents an imaginary asset called Crypto Capybara.
// It implements a public counter for how many mints have been executed,
// and a method which provides a string base to generate unique URIs for each individual token ID
contract MyERC721 is ERC721, Ownable {
using Counters for Counters.Counter;
Counters.Counter public mintedCounter;
constructor() ERC721("CryptoCapybara", "CCB") {}
function mint(address to, uint256 tokenId) public onlyOwner {
mintedCounter.increment();
_mint(to, tokenId);
}
function _baseURI() internal pure override returns (string memory) {
return "https://crypto-capybaras.com/nft/";
}
}
ERC-777 Tokens
ERC-777 was originally conceived as an improvement on the ERC-20 standard.
The standard was thought out to be backwards compatible with ERC-20, and to also work with hooks in order to better control what actions to take when sending or receiving fungible tokens through smart contracts. This would provide a way to react to these occurrences.
Contracts could register themselves as aware of this standard, so that tokens accidentally sent to the wrong contracts wouldn’t get locked, which has historically been an issue with ERC-20 tokens. It also aimed at approving and sending tokens in a single transaction, plus dealing with decimals in a less error-prone way.
However, despite its EIP and general documentation still available, it’s been proposed to deprecate this standard. For details on this discussion see the corresponding GitHub thread.
ERC-1155 Tokens
ERC-1155 is a relatively newer token standard on the Ethereum blockchain, which allows for the creation and handling of both fungible and non-fungible tokens in a single contract.
In a way, it aims to achieve everything that ERC-20 and ERC-721 do, but expanding on it and making it more efficient. It can save costs by managing tokens in batches (approval, transfer and balance) instead of individually. It also implements a hook for receiving tokens.
A more in-depth explanation into its motivation and rationale can be found in EIP-1155.
Example
pragma solidity 0.8.4;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
// This token extends OpenZeppelin's implementation of the IERC1155 interface
contract MyERC1155 is ERC1155 {
uint256 public constant COINS = 0;
uint256 public constant MAGIC_ARTIFACT = 1;
constructor() ERC1155("https://medieval-tokens.com/item/{id}.json") {
_mint(msg.sender, COINS, 10**18, "");
_mint(msg.sender, MAGIC_ARTIFACT, 1, "");
}
}
In this case, COINS
is taken as fungible since 10**18
units are minted when the contract is deployed. However, there’s only 1 MAGIC_ARTIFACT
, so in practical terms this means it’s non-fungible.
ERC-4626 Tokens
ERC-4626 aims at implementing a standarized API for what’s called tokenized or yield-bearing vaults. Vaults are smart contracts that take in token deposits and do something with those tokens to provide token rewards to the depositor.
These represent shares of a single underlying ERC-20 token, so it’s an extension of said standard. As its EIP explains, the creation of this standard comes from the complexities that arise from lending and borrowing platforms, as well as market aggregators.
Conclusion
ERC token standards have revolutionized the way we create and manage tokens on the blockchain. Understanding the different types of token standards and choosing the right ones for your application will be crucial in terms of correctly implementing your business logic. Finally, implementing widely adopted standards will contribute to the interoperability of your assets with the rest of the ecosystem.
Posted in Blockchain, Smart Contract, Solidity, Technologies