The New ERC223 Token Standard

In this article, we will compare Ethereum Request for Comments #223 (the new ERC223 token standard) to the popular ERC20 token standard and discuss its motivation and advantages (Kin is an ERC20 token).

TLDR: ERC20 should be retired, and it’s better to use the new ERC223 token standard when implementing new tokens. Long live the new ERC223 token standard!

ERC20 Token Standard: An Oldie, but a Goldie

The ERC20 token standard, which was already formalized as Ethereum Improvement Protocol #20 (EIP20), defines a common list of rules for all Ethereum tokens to follow. This ensures common interfaces/methods and provides best practices. For example, an exchange or a smart contract (or an exchange that is a smart contract, such as EtherDelta) would only need to implement the integration logic once and later reuse the same code and functionality when listing ERC20 tokens. This is because all tokens respond to the same interface.

At the moment, there are about 100,000 ERC20 compatible token smart contracts deployed to the public Ethereum main-net, hundreds of which belong to ongoing projects and teams. For example, here are the top 10 tokens, according to the number of performed operations/transactions so far:

Top 10 ERC 20 tokens

At the time of writing, the Kin token has had about 43,946 transactions, which ranks it somewhere around thirtieth (and we expect its transaction rate to increase much more once the alpha is released).

ERC20 Interfaces

In order to comply with the ERC20 standard, the token developer needs to implement the following interfaces:

name (optional)

Returns the name of the token (e.g., "Kin").

symbol (optional)

Returns the symbol of the token (e.g., "KIN").

decimals (optional)

Returns the uint8 number of decimals the token uses (e.g., 18 means to divide the token amount by 10^18 (1000000000000000000) to get its user representation).


Returns the total token supply.

balanceOf(address _owner)

Returns the account balance of another account with the address _owner.

transfer(address _to, uint256 _value)

Transfers _value amount of tokens to address _to and must fire the transfer event. The function should revert if the _from account balance does not have enough tokens to spend.

A token contract which creates new tokens should trigger a transfer event with the _from address set to 0x0when tokens are created.

Transfers of zero value must be treated as normal transfers and fire the transfer event.

transferFrom(address _from, address _to, uint256 _value)

Transfers _value amount of tokens from the address _from to the address _to, and must fire the transfer event (see below).

The transferFrom method is used for a withdrawal workflow, allowing contracts to transfer tokens on your behalf. For example, this can be used to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. The function should revert unless the _from account has deliberately authorized the sender of the message via some mechanism.

Transfers of zero value must be treated as normal transfers and fire the transfer event.

approve(address _spender, uint256 _value)

Allows _spender to withdraw from your account multiple times, up to the _value amount. If this function is called again it overwrites the current allowance with _value.

To prevent attack vectors like the one described here and discussed here, clients should make sure to create user interfaces in a way that sets the allowance first to 0 before setting it to another value for the same spender.

allowance(address _owner, address _spender)

Returns the amount which the_spender is still allowed to withdraw from the _owner.


Transfer(address indexed _from, address indexed _to, uint256 _value)

Must trigger when tokens are transferred, including zero-value transfers.

Approval(address indexed _owner, address indexed _spender, uint256 _value)

Must trigger on any successful call to approve(address _spender, uint256 _value).

ERC223: So What’s All the Fuss About?

ERC223 is a new token standard that was proposed a couple of months ago and in the process of formalizing into an official EIP (Ethereum Improvement Protocol).

It’s important to remember that ERC223 tokens are backwards compatible with ERC20 tokens. It means that ERC223 supports every ERC20 function and contract or service working with ERC20 tokens, and will work with ERC223 tokens correctly.

After accustoming ourselves with the interfaces and the behaviors of an ERC20 token, let’s see some of its imperfections and how can they be resolved.

Accidental transfer of tokens to an unaware contract

There are two different ways to transfer ERC20 tokens depending on whether you intend to send the tokens directly or delegate the transfer to another smart contract. You can either call transfer to send tokens to a wallet address or call approve, and then trigger transferFrom from the receiver contract, in order for it to be aware of the transfer and handle it accordingly.

But what happens when you transfer your tokens to a contract address that is unaware or doesn’t expect these tokens (e.g., by simply mistyping your intended address)? Unfortunately, your tokens are going to be lost forever.

There are already a number of tokens held by token contracts that didn’t expect any tokens transfers (and the list is only growing). These tokens will not be accessible as there is no function to withdraw them from the contract.

For example:

  • 310,067 GNT are stuck in Golem contract (currently worth of $64,857).
  • 242 REP are stuck in Augur contract (currently worth of $4,723).
  • 814 DGD are stuck in Digix DAO contract (currently worth if $56,724).
  • 14,506 1ST are stuck in FirstBlood contract (currently worth of $4,689).
  • 30 MLN are stuck in Melonport contract (currently worth of $2,027).

So how does the ERC223 token standard addresses this issue?

ERC223 allows users to send their tokens to either wallet or contract with the same transfer function, thereby eliminating the potential for confusion and lost tokens. It proposes a new transfer method in order to accomplish it:

transfer(address, uint, bytes)

function transfer(address _to, uint _value, bytes _data) returns (bool success)

This function must transfer tokens and invoke the function tokenFallback (address, uint256, bytes) in _to, if _to is a contract.

The token fallback function, which will be called at the receiver contract, must be named tokenFallback and take the parameters:(address, uint256, bytes). It’s an analogue of the fallback function for ETH transactions and should be used to handle incoming transactions.

Inability of handling incoming token transactions

By sending ERC20 tokens using the transfer function, the token contract is not notifying the receiver that a transaction had occurred. The tokens are just simply credited to the address of the receiver. In addition to that, there is no way to handle incoming token transactions on contracts and no way to reject or handle any non-supported tokens.

In addition to preventing tokens getting lost, the new transfer method will also allow the smart contract to actively handle sent tokens (e.g., an exchange smart contract can react to a token transfer by crediting the token balance of the user).

Token Transfer Uniformity

An ERC20 token transaction between a regular/non-contract address and contract are two different transactions: You should call approve on the token contract and then call transferFrom on the other contract when you want to deposit your tokens into it.

ERC223 simplifies this requirement and allows using the same transfer function. ERC223 tokens can be sent by calling transfer function on the token contract with no difference if the receiver is a contract or a wallet address, since there is a new way to notify the receive contract of the transfer.

If the receiver is a a regular/non-contract address, an ERC223 token transfer will be the same as an ERC20 transfer. On the other hand, if the receiver is a contract, then the ERC223 token contract will try to call tokenFallback function on receiver contract. If there is no tokenFallback function on receiver contract, the transaction will fail.

For example, a decentralized exchange will no longer need to force users to call approve at the token contract, then call deposit to call transferFrom and take allowed tokens. The token transaction will automatically be handled inside the exchange contract, via the tokenFallback function.

But wait, there’s more!

ERC223 transfer to contract consumes half as much gas as an ERC20 approve and transferFrom at receiver contract.

In Conclusion

The new ERC223 token standard introduces improvements and capabilities, addressing some of the most significant ERC20 pain points, especially when interacting with other smart contracts.

Even though we may not be able to keep Kin on the public Ethereum blockchain because of issues with scalability, I truly wish it was possible to upgrade our current ERC20 token smart contract to an ERC223 token standard and benefit from the new features. But alas, contract upgrades aren’t supported.

We hope that you’ve enjoyed this article and found it useful. Please join our community on Reddit or Telegram, and let us know if there are other topics you’d like us to write about.

Like what you read? Give Leonid Beder a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.