In the ever-evolving landscape of blockchain technology, tokens have emerged as a crucial building block, powering a wide range of applications and driving innovation. To ensure compatibility and interoperability, various token standards have been established, laying down a common framework for token creation and interaction. Among these, ERC standards stand out as the most prominent, particularly in the Ethereum ecosystem.
What are ERC Standards?
ERC stands for Ethereum Request for Comments, a process initiated by the Ethereum community to propose and evaluate technical standards for Ethereum blockchain-based tokens. These standards serve as blueprints, defining the functionalities and behaviors of specific types of tokens. By adhering to these standards, developers can create tokens that seamlessly integrate with existing Ethereum-based applications and protocols.
Types of ERC Standards
The ERC ecosystem encompasses a diverse range of standards, each tailored to a distinct type of token. Here are some of the most prominent ERC standards:
- ERC-20: This standard governs fungible tokens, which are interchangeable and have identical value. Examples of ERC-20 tokens include Basic Attention Token (BAT), Chainlink (LINK), and Tether USD (USDT).
- ERC-721: This standard defines non-fungible tokens (NFTs), which are unique and indivisible assets. NFTs can represent digital collectibles, artwork, in-game items, or any other unique asset.
- ERC-777: This standard builds upon ERC-20, enhancing its functionality and reducing transaction overhead. It introduces features like token approvals and enables users to reject incoming tokens from blacklisted addresses.
- ERC-1155: This standard expands upon ERC-20 and ERC-721 by allowing the creation and management of both fungible and non-fungible tokens within a single smart contract. This offers efficiency and simplifies token interactions.
Each token standard has its own interface that defines the operation or functionality of the token, so if we want to integrate the token into our application then we need to implement that interface. There are several reasons why ERC-token standards should implement interfaces:
1. Standardized Token Behavior: Implementing interfaces ensures that tokens adhere to a common set of rules and behaviors, making them more predictable and easier to integrate with other applications. This standardization also facilitates interoperability, allowing tokens to be used seamlessly across various platforms and protocols.
2. Enhanced Interoperability: By conforming to well-defined interfaces, ERC-tokens can be more easily integrated with existing infrastructure and protocols, such as wallets, exchanges, and marketplaces. This interoperability reduces friction and encourages wider adoption of tokens across the ecosystem.
3. Improved Developer Experience: Developers can rely on standardized interfaces to quickly and easily understand and interact with ERC-tokens, regardless of their specific implementation. This simplifies development and reduces the learning curve for new users, making it easier to build applications that utilize ERC-tokens.
4. Reduced Risk of Errors: Implementing interfaces promotes consistency and reduces the likelihood of errors in token interactions. This not only improves the overall user experience but also enhances the security of token-based applications.
5. Community-Driven Standards: ERC-token standards are developed and maintained by a vibrant community of developers and enthusiasts. This collaborative approach ensures that the standards evolve in a way that meets the needs of the ecosystem and reflects the latest advancements in blockchain technology.
ERC-20
pragma solidity ^0.8.0;
interface ERC20 {
function totalSupply() public view returns (uint256);
function balanceOf(address account) public view returns (uint256);
function allowance(address owner, address spender) public view returns (uint256);
function transfer(address recipient, uint256 amount) public returns (bool);
function approve(address spender, uint256 amount) public returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool);
}
- totalSupply(): Returns the total number of tokens in circulation.
- balanceOf(address account): Returns the balance of tokens held by the specified account.
- allowance(address owner, address spender): Returns the amount of tokens that the spender is approved to transfer from the owner’s account.
- transfer(address recipient, uint256 amount): Transfers the specified amount of tokens from the caller’s account to the recipient’s account.
- approve(address spender, uint256 amount): Approves the specified spender to transfer up to the specified amount of tokens from the caller’s account.
- transferFrom(address sender, address recipient, uint256 amount): Transfers the specified amount of tokens from the specified sender’s account to the recipient’s account, and requires sender’s approval.
ERC-721
pragma solidity ^0.8.0;
interface ERC721 {
event Transfer(address indexed from, address indexed to, uint256 tokenId);
event Approval(address indexed owner, address indexed approved, uint256 tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) public view returns (uint256);
function ownerOf(uint256 tokenId) public view returns (address);
function exists(uint256 tokenId) public view returns (bool);
function mint(address owner, uint256 tokenId) public;
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
function safeTransferFrom(address from, address to, uint256 tokenId) public;
function transferFrom(address from, address to, uint256 tokenId) public;
function approve(address spender, uint256 tokenId) public;
function setApprovalForAll(address operator, bool approved) public;
function isApprovedForAll(address owner, address operator) public view returns (bool);
function getApproved(uint256 tokenId) public view returns (address);
}
- balanceOf(address owner): Returns the number of tokens owned by the specified owner.
- ownerOf(uint256 tokenId): Returns the address of the owner of the specified token ID.
- exists(uint256 tokenId): Returns true if the specified token ID exists, and false otherwise.
- mint(address owner, uint256 tokenId): Creates a new token and assigns it to the specified owner.
- safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data): Transfers the specified token from the specified from address to the to address, and can include additional data in the data parameter.
- safeTransferFrom(address from, address to, uint256 tokenId): Transfers the specified token from the specified from address to the to address, and requires from’s approval.
- transferFrom(address from, address to, uint256 tokenId): Transfers the specified token from the specified from address to the to address.
- approve(address spender, uint256 tokenId): Approves the specified spender to transfer the specified token ID from the caller’s account.
- setApprovalForAll(address operator, bool approved): Sets the specified operator as an authorized operator for the caller’s account, allowing them to transfer all of the caller’s tokens without requiring the caller’s approval for each transfer.
- isApprovedForAll(address owner, address operator): Returns true if the specified operator is an authorized operator for the specified owner’s account, and false otherwise.
- getApproved(uint256 tokenId): Returns the address of the authorized spender for the specified token ID.
ERC-777
pragma solidity ^0.8.0;
interface ERC777 {
event Mint(address owner, uint256 id);
event Transfer(address indexed from, address indexed to, uint256 id, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 id, uint256 amount);
event Burn(address owner, uint256 id, uint256 amount);
event SetApprovalForAll(address indexed owner, address indexed spender, bool approved);
function balanceOf(address owner) external view returns (uint256);
function ownerOf(uint256 id) external view returns (address);
function safeTransfer(address to, uint256 id, uint256 amount, bytes memory data) external;
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes memory data) external;
function transfer(address to, uint256 id, uint256 amount) external;
function approve(address spender, uint256 id, uint256 amount) external;
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address owner, address spender) external view returns (bool);
function getApproved(uint256 id) external view returns (address);
}
- Mint(address owner, uint256 id): Event emitted when a new token is minted for the specified owner.
- Transfer(address indexed from, address indexed to, uint256 id, uint256 amount): Event emitted when a token is transferred from one address to another.
- Approval(address indexed owner, addressindexed spender, uint256 id, uint256 amount): Event emitted when a spender is approved to transfer up to the specified amount of tokens from the owner’s account.
- Burn(address owner, uint256 id, uint256 amount): Event emitted when a token is burned (removed from circulation).
- SetApprovalForAll(address indexed owner, address indexed spender, bool approved): Event emitted when the approval status for a spender is updated.
- balanceOf(address owner): Returns the balance of tokens held by the specified account.
- ownerOf(uint256 id): Returns the address of the owner of the specified token ID.
- safeTransfer(address to, uint256 id, uint256 amount, bytes memory data): Transfers the specified amount of tokens from the specified sender’s account to the recipient’s account, and can include additional data in the data parameter.
- safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes memory data): Transfers the specified amount of tokens from the specified sender’s account to the recipient’s account, and requires sender’s approval, and can include additional data in the data parameter.
- transfer(address to, uint256 id, uint256 amount): This method is a simplified version of the transferFrom method that does not require sender’s approval. This is because the caller is assumed to be the owner of the tokens.
ERC-1155
pragma solidity ^0.8.0;
interface ERC1155 {
event Transfer(address indexed operator, address indexed from, address indexed to, uint256[] tokenIds, uint256[] amounts);
event Approval(address indexed owner, address indexed spender, uint256[] tokenIds, uint256[] amounts);
event SetApprovalForAll(address indexed owner, address indexed spender, bool approved);
// Functions to mint new tokens or burn existing ones
function mint(address to, uint256[] tokenIds, uint256[] amounts) external;
function burn(address from, uint256[] tokenIds, uint256[] amounts) external;
// Functions to transfer tokens from one address to another
function safeTransferFrom(address from, address to, uint256[] tokenIds, uint256[] amounts, bytes memory data) external;
function transferFrom(address from, address to, uint256[] tokenIds, uint256[] amounts) external;
// Functions to approve or revoke another address's ability to transfer tokens
function approve(address spender, uint256[] tokenIds, uint256[] amounts) external;
function setApprovalForAll(address operator, bool approved) external;
// Functions to check an address's balance or allowance
function balanceOf(address owner, uint256 tokenId) external view returns (uint256);
function balanceOfBatch(address[] owners, uint256[] tokenIds) external view returns (uint256[] balances);
function isApprovedForAll(address owner, address spender) external view returns (bool);
function allowance(address owner, address spender, uint256 tokenId) external view returns (uint256);
function allowanceBatch(address owner, address spender, uint256[] tokenIds) external view returns (uint256[] allowances);
}
- Transfer (address indexed operator, address indexed from, address indexed to, uint256[] tokenIds, uint256[] amounts): This event is emitted whenever tokens are transferred from one address to another. It provides information about the addresses involved, the token IDs of the transferred tokens, and the amounts of each token transferred.
- Approval (address indexed owner, address indexed spender, uint256[] tokenIds, uint256[] amounts): This event is emitted whenever a spender is granted approval to transfer tokens on behalf of another address (the owner). It provides information about the addresses involved, the token IDs of the approved tokens, and the amounts of each token approved.
- SetApprovalForAll (address indexed owner, address indexed spender, bool approved): This event is emitted whenever an address sets the allowance for another address (the spender) to manage its tokens. The approved parameter indicates whether the spender is allowed to transfer all of the owner’s tokens or only specific token IDs.
- Minting and Burning Tokens
- The ERC-1155 interface provides methods for minting and burning tokens:
- mint(address to, uint256[] tokenIds, uint256[] amounts): This function mints new tokens and assigns them to the specified to address. The tokenIds parameter specifies the token IDs of the minted tokens, and the amounts parameter specifies the number of each token to mint.
- burn(address from, uint256[] tokenIds, uint256[] amounts): This function burns existing tokens, removing them from circulation. The from parameter specifies the address that owns the tokens to be burned, the tokenIds parameter specifies the token IDs of the tokens to be burned, and the amounts parameter specifies the number of each token to burn.
- Safe Transfers and Approvals
- The ERC-1155 interface provides methods for safer transfers and approvals:
- safeTransferFrom(address from, address to, uint256[] tokenIds, uint256[] amounts, bytes memory data): This function transfers tokens from one address to another in a safer manner. It allows for additional data to be included in the data parameter, and it requires the sender’s approval for each token transfer.
- transferFrom(address from, address to, uint256[] tokenIds, uint256[] amounts): This function transfers tokens from one address to another, but it does not require the sender’s approval. This method is typically used when the caller is the owner of the tokens and does not need to request permission from another user.
- approve(address spender, uint256[] tokenIds, uint256[] amounts): This function approves another address (the spender) to transfer specific tokens on behalf of the calling address. The tokenIds parameter specifies the token IDs of the approved tokens, and the amounts parameter specifies the maximum amount of each token that the spender is allowed to transfer.
- setApprovalForAll(address operator, bool approved): This function sets the global allowance for another address (the operator) to manage all of the calling address’s tokens. When approved is true, the operator can transfer any of the calling address’s tokens without explicit approval.
Examples of ERC Standard Applications
ERC standards have enabled the creation of a vast array of applications, including:
- Decentralized Finance (DeFi): ERC-20 tokens power a wide range of DeFi applications, such as stablecoins, lending and borrowing protocols, and decentralized exchanges.
- Non-Fungible Token (NFT) Marketplaces: ERC-721 and ERC-1155 tokens have revolutionized the NFT ecosystem, enabling the creation and sale of unique digital assets.
- Gaming and Entertainment: ERC standards are integrated into games and entertainment platforms, enabling the creation of in-game currencies, collectibles, and other interactive assets.
- Supply Chain Management: ERC standards can be used to track the movement of goods and materials, providing transparency and efficiency in supply chains.
Conclusion
ERC standards have played a pivotal role in shaping the blockchain ecosystem, providing a standardized approach to token creation and interaction. Their widespread adoption has fostered interoperability and facilitated the development of innovative applications across various industries. As blockchain technology continues to evolve, ERC standards are likely to remain a cornerstone of tokenization and decentralized applications.
Originally posted in https://www.inclinedweb.com/2023/12/17/decoding-erc-standards-a-comprehensive-guide-to-token-standards/
Decoding ERC Standards: A Comprehensive Guide to Token Standards was originally published in The Dark Side on Medium, where people are continuing the conversation by highlighting and responding to this story.