ERC 20, ERC 223, ERC 827 and ERC 721
Ethereum based tokens which can be bought, sold, or traded, have become the backbone of Ethereum ecosystem, innovative companies use them as internal currencies within their ecosystem. Some are listed on exchanges and act like shares of the company and some become collectables, as in the game of CryptoKitties. But still people aspiring to join the crypto race, are troubled by questions like these:
- Which type of Token best suits my idea?
- How many types of token standards are circulating in the Ethereum community?
- What are the advantages and disadvantages of various ERC token standards?
- How different token standards work?
If these questions linger in your mind too, or otherwise you’re just a scholar aiming to expand your knowledge, here is a technical introduction to various ERC standards popular in the Ethereum community. But, do you know what is ERC?
KEEP IN MIND BEFORE YOU PROCEED: The code present in this blog is solely for educational purposes and not written in its entirety. Please do not implement it in production applications!
First, what is ERC?
ERC stands for Ethereum Request for Comment. Every open source community needs a proposal request-approval system to accept revolutionary changes put forward by its users and improve itself. ERCs serve this purpose for Ethereum, they include some technical guidelines elaborating suggestions about development of the Ethereum network.
Development is a step by step process
Developers of the Ethereum community propose new standards for the Ethereum platform, by submitting an Ethereum Improvement Proposal (EIP). This includes protocol specifications and contract standards. Once that EIP is approved by a committee and finalised, it becomes an ERC.
The finalised EIPs give the Ethereum developers a set of implementable standards. This allows Smart Contracts to be built with these standards, which a common interface can access.
After this part of the blog I’m going to make some assumptions, while explaining token anatomy concepts, if you don’t, you should skip the anatomy part for each token standard, they will be as follows:
- Reader should have basic knowledge of Solidity’s syntax. Or at least you should be a developer who could relate to it.
- You are able to refer to a subject explained in a previous section of this blog and relate it to the current subject to further your understanding.
- You know about standard zeppelin contracts, if you don’t you should be able to browse the following github handle to understand my references.
ERC 20 is the most well-known among all the standards present within the entire crypto community, and most tokens issued on top of the Ethereum platform use it. Helping developers to accurately predict how new tokens will function within the larger Ethereum system.
The impact that ERC 20 therefore has on developers is massive, as projects do not need to be redone each time a new token is released. Rather, they are designed to be compatible with new tokens, provided those tokens adhere to the rules. Developers of new tokens have by-and-large observed the ERC 20 rules, meaning that most of the tokens released through Ethereum based ICOs are ERC 20 compliant.
ERC 20 Anatomy
Here’s a basic interface describing function and event signatures of ERC20 contracts, which is followed by the explanation of each function:
Public function totalSupply, is accessible to all, and it displays the number of tokens in circulation. Since, it is labelled with a view modifier, calling it won’t consume any gas. So you can know about the total tokens in supply for any ERC 20 based token, for free. Zeppelin implements this logic by updating the value of internal variable totalSupply_ every time new tokens are minted. Its value can be accessed as follows:
Function balanceOf is another public function with view modifier making it accessible to all and gas free. It takes in an ethereum addresses and returns the number of tokens allocated to that address. Zeppelin maintains an internal mapping for this purpose, as follows:
Function transfer is different from the above two functions because it will consume gas, since it will result in a state change within the Ethereum Smart contracts. It is used to transfer tokens from one address to another, when called by respective token holders. _to address is the recipient of the tokens of value amount, in the following representation taken from Zeppelin:
allowance, approve and transferFrom
Lastly, functions allowance, approve and transferFrom offer some advanced functionalities and are used to authorise some other Ethereum address to utilise your tokens on your behalf. This other Ethereum address could be a smart contract designed to handle tokens or just another account. Following is the implementation by Zeppelin solidity, incorporating the required logic for these functions:
- Function approve is used by a token owner, to allow some spender to use a particular value of his tokens on his behalf.
- Similarly, allowance can be used to check spender’s allowance for a particular owner
- And transferFrom can be finally used by spender to transfer allowed number of tokens.
What was the problem with ERC 20?
Now that you have gone through the basic functionalities of ERC 20, we can start discussing it flaws and the different requirements which resulted in various flavours of token standards present in the Ethereum driven market.
To be true, there were many. Not that ERC 20 has many flaws, but it is the most basic standard for tokens, and to solve specific problems, many upgrades were needed. Here we will first discuss various improvements suggested by ERC223.
ERC223 is built on top of ERC20 and is backwards compatible, meaning it incorporates all the functions mentioned above in ERC 20 section, it solves the following problems:
Problem of lost tokens
It happens during the transfer of ERC 20 tokens to a contract. When people mistakenly use the instructions for sending tokens to a wallet and send them to a smart contract which is not designed to handle it, their tokens get stuck in the smart contract. What’s worse? Since, the contract was not designed to handle these tokens, these tokens will be stuck there forever.
Here is an explanation of the problem from ERC 223 official github page:
If you send 100 ETH to a contract that is not intended to work with Ether, then it will reject a transaction and nothing bad will happen. If you will send 100 ERC 20 tokens to a contract that is not intended to work with ERC 20 tokens, then it will not reject tokens because it cannot recognise an incoming transaction. As the result, your tokens will get stuck at the contracts balance.
How much ERC20 tokens are currently lost (27 Dec, 2017):
1. QTUM, $1,204,273 lost. watch on Etherscan
2. EOS, $1,015,131 lost. watch on Etherscan
3. GNT, $249,627 lost. watch on Etherscan
4. STORJ, $217,477 lost. watch on Etherscan
5. Tronix , $201,232 lost. watch on Etherscan
6. DGD, $151,826 lost. watch on Etherscan
7. OMG, $149,941 lost. watch on Etherscan
8. STORJ, $102,560 lost. watch on Etherscan
NOTE: These are only 8 token contracts that I know. Each Ethereum contract is a potential token trap for ERC 20 tokens, thus, there are much more losses than I showed at this example.
Reducing energy consumption
The transfer of ERC223 tokens to a contract is a one step process rather than two steps process (for ERC20), and this means two times less gas and no extra blockchain bloating.
Anatomy of ERC 223
After understanding the problems solved by ERC 223, let’s look into a simple implementation to understand how it works:
Standard ERC223ReceivingContract must have a function tokenFallback , the sample interface would be like this:
Functions totalSupply and balanceOf have been discussed in ERC 20 the change comes in implementation of the new transfer function.
In the above code, our new transfer function takes in an extra parameter compared to the one mentioned in ERC 20, i.e. _data. It is used by assembly to retrieve the size of the code on target address, for a contract address codeLength will be greater than zero and tokenFallback function will be invoked for it. The token transfer will fail if the recipient is a contract but does not implement the tokenFallback function or the fallback function to receive funds.
In short, ERC223 checks for bytecode length of the address tokens are being transferred to, and if it is a contract, it looks for a function with the signature of tokenFallback, hence solving the problem of tokens stuck in contracts.
ERC 827 is a standard which rivals ERC 223, it can be used to solve the same problems solved by ERC 223, moreover it offers flexibility to transfer data along with tokens to smart contracts and execute them. This means it can be used to solve specific problems other than tokens getting stuck in smart contracts. In recent times ERC 827 seems to be winning against ERC 223 as it has been included by zeppelin in its open source contracts, while ERC 223 is still not present in the tokens provided by them. The motivation stated in ERC 827 ERC/EIP is as follows:
This extension of the ERC20 interface allows any tokens on Ethereum to be re-used by other applications: from wallets to decentralized exchanges. The ERC20 token standard is widely accepted but it only allows the transfer of value, ethereum users are available to transfer value and data on transactions, with these extension of the ERC20 token standard they will be able to do the same with ERC20 tokens.
To understand the usage of ERC 827 token let’s think of a hypothetical shopping cart on a merchants website.
Shopping cart on a merchants website
This cart has items waiting to be bought stored in it. But it cannot proceed to checkout unless user has the required number of tokens. When someone transfers tokens to the owner of the cart, some data is passed with the cart, which calls another function present within a contract which checks whether the cart owner has enough balance and proceeds to checkout for the items saved in cart accordingly.
Anatomy of ERC 827
A sample implementation of the ERC 827 contracts implemented by Zeppelin is as follows:
The ERC827 contract here inherits the standard ERC20 contract. Hence becoming backwards compatible it updates the signature and logic behind only three functions of the ERC 20 contracts- approve, transfer and transferFrom. We will discuss them in detail one by one:
It allows to approve the transfer of value and execute a call with the data sent during the approve function call.
Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender’s allowance to 0 and set the desired value afterwards:
It transfers tokens to a specified address and executes a call with the sent data on the same transaction. It will return true if the call function is executed successfully.
Like transfer function it also transfers tokens from one address to another and make a contract call on the same transaction. But this can be used in coordination with approve function and execute different logic while approving and transferring tokens.
ERC 721 presents a totally different concept from ERC 223 and ERC 827. To understand it properly readers must grasp the concept of fungible and non-fungible items.
Difference between fungible and non fungible?
An item can be considered fungible if it can be exchanged with another item of same type. This means the value of two fungible items is same in everyone’s eyes and they’re interchangeable. Consider a 100 Rs bill.
Fungible 100 Rs
This 100 Rs is interchangeable with another 100 Rs bill with a different reference number. So, it is fungible.
Non-fungible Healey Westland
Non fungible comes from the word “not interchangeable”. Lets try to understand this with a Healey Westland, one of the rare collectable cars. The value of two different Healey Westland may vary on their age and conditions. They may vary from collector to collector. This makes Healey Westland a non-fungible item.
ERC 721 based Cryptokittes
Now, we’re ready to understand the usage of ERC 721, which portrays the concept of non-fungible tokens. You cannot differentiate between two ERC 20 based tokens, they’re one and the same for you, but ERC 721 proposes a concept by which token holders will be able to differentiate between the tokens they hold. One famous example is CryptoKitties, it is a game in which players can buy, sell, trade, and breed digital cats. Each cat is unique in some way and this uniqueness makes the CryptoKitties extremely collectable, as someone could take interest in the characteristics of several kittens and wish to own them.
However, there are various other cases too, when non-fungibility of tokens tokens, can prove to be an asset. For instance, tokens can be used to represent real estate objects, intellectual property rights, etc… And each token might have some different parameters added to it. Or they can be used to represent items on a merchant’s website where an Adidas shoe will be different from a Nike shoe. Even different shoes within the same brand can be represented in a similar fashion.
Adidas vs Nike
ERC 721 Anatomy
Now we know why we need ERC 721 tokens so lets understand how they work. Here is an interface of ERC 721 followed by Zeppelin, followed by the explanation of functions mentioned in the interface, as implemented by zeppelin.
In the following snippet ownedTokens represents the list of token IDs owned by a particular address. And balanceOf function returns the number of tokens owned by a particular address.
Mapping tokenOwner takes in tokenId and returns the owner of that ID, but since it’s visibility is private, ownerOf function is used to make the value of this mapping available publicly. It also includes a check against zero addresses before returning the value.
This transfer function takes in the new owner’s address as _to parameter and _tokenId of the token being transferred, also note that it can only be called by the owner of token. It must include the logic to check whether the transfer clears approval check, required for a transfer. Then comes the logic to remove token’s possession from current owner and add it to the list of tokens owned by new owner.
Approves another address to claim for the ownership of the given token ID, this is another function restricted by a modifier onlyOwnerOf, which means only a token owner can access this function for a particular token. Variable tokenApprovals is a mapping from token ID to approved addresses. Similar to the transfer function discussed above approve too, takes in _to (the new token owner’s address) and _tokenId as input parameters. It checks new owner must not be the same as previous owner of the token then if any one of the addresses among _to and previously approved address passes the address(0) check, it updates the tokenApprovals mapping and fires an event named Approval.
Function approvedFor has been explained in the previous section, function isApprovedFor returns a Boolean value depending upon the response of condition approvedFor(_tokenId) == _owner. Function takeOwnership takes in _tokenId and applies the same check on message sender, if he passes the check logic similar to the transfer function is applied to claim the ownership of given _tokenID.
Ah, this must have been a pretty intense read. So, congratulations on reaching the end. Now you should be having some basic knowledge of the popular token standards circulating within the Ethereum community.
For those who need to choose a particular Token standard for their application, please keep in mind that at the time of this writing most of the standards explained in this blog, i.e. ERC 223, ERC 721 and ERC 827 are still not accepted officially and may undergo revisions.
Latest posts by Techracers (see all)
- Techracers signed an MoU with IET, DAVV, Indore: Will Offer Strategic Guidance and Technical Resources - October 2, 2018
- Hyperledger Fabric Cluster with Kubernetes - September 18, 2018
- ERC20 Tokens on HyperLedger - September 15, 2018