Read the original discussion and formal description here: ethereum/EIPs#223
Main ERC-223 contracts:
- IERC223.sol: Token interface. The minimal common API ERC-223 tokens and receivers must implement in order to interact with each other.
- ERC223.sol: Token contract. Defines logic of the basic ERC-223 token. This functionality can be extended with additional functions (such as
burn()
,mint()
, ownership orapprove / transferFrom
pattern of ERC20). - Recipient interface: A dummy receiver that is intended to accept ERC-223 tokens. Use
contract MyContract is IERC223Recipient
to make contract capable of accepting ERC-223 token transactions. Contract that does not support IERC223Recipient interface can receive tokens if this contract implements a permissive fallback function (this method of token receiving is not recommended). If a contract does not implement IERC223RecipienttokenReceived
function and does not implement a permissive fallback function then this contract can not receive ERC-223 tokens.
-
ERC223Mintable.sol: Minting functinality for ERC223 tokens.
-
ERC223Burnable.sol: Burning functionality implementation for ERC223 tokens. Allows any address to burn its tokens by calling the
burn
function of the contract.
ERC-20 token standard suffers critical problems, that caused loss of approximately $3,000,000 at the moment (31 Dec, 2017). The main and the most important problem is the lack of event handling mechanism in ERC20 standard.
ERC-223 is a superset of the ERC20. It is a step forward towards economic abstraction at the application/contract level allowing the use of tokens as first class value transfer assets in smart contract development. It is also a more secure standard as it doesn't allow token transfers to contracts that do not explicitly support token receiving.
contract ERC223 {
function transfer(address to, uint value, bytes data) {
uint codeLength;
assembly {
codeLength := extcodesize(_to)
}
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
if(codeLength>0) {
// Require proper transaction handling.
ERC223Receiver receiver = ERC223Receiver(_to);
receiver.tokenReceived(msg.sender, _value, _data);
}
}
}
- Lost tokens: there are two different ways to transfer ERC20 tokens depending on is the receiver address a contract or a wallet address. You should call
transfer
to send tokens to a wallet address or callapprove
on token contract thentransferFrom
on receiver contract to send tokens to contract. Accidentally call oftransfer
function to a contract address will cause a loss of tokens inside receiver contract. - Impossibility of handling incoming token transactions / lack of event handling in ERC20: ERC20 token transaction is a call of
transfer
function inside token contract. ERC20 token contract is not notifying receiver that transaction occurs. Also there is no way to handle incoming token transactions on contract and no way to reject any non-supported tokens. - Optimization of ERC20 address-to-contract communication: You should call
approve
on token contract and then calltransferFrom
on another contract when you want to deposit your tokens into it. In fact address-to-contract transfer is a couple of two different transactions in ERC20. It also costs twice more gas compared to ERC223 transfers. In ERC223 address-to-contract transfer is a single transaction just like address-to-address transfer. - Ether transactions and token transactions behave differently: one of the goals of developing ERC223 was to make token transactions similar to Ether transactions to avoid users mistakes when transferring tokens and make interaction with token transactions easier for contract developers.
- Provides a possibility to avoid accidentally lost tokens inside contracts that are not designed to work with sent tokens.
- Allows users to send their tokens anywhere with one function
transfer
. No difference between is the receiver a contract or not. No need to learn how token contract is working for regular user to send tokens. - Allows contract developers to handle incoming token transactions.
- ERC223
transfer
to contract consumes 2 times less gas than ERC20approve
andtransferFrom
at receiver contract. - Allows to deposit tokens into contract with a single transaction. Prevents extra blockchain bloating.
- Makes token transactions similar to Ether transactions.
ERC-223 tokens are backwards compatible with ERC-20 tokens. It means that ERC-223 supports every ERC-20 functional and contracts or services working with ERC-20 tokens will work with ERC-223 tokens correctly.
ERC-223 tokens should be sent by calling transfer
function on token contract with no difference is receiver a contract or a wallet address. If the receiver is a wallet ERC-223 token transfer will be same to ERC-20 transfer. If the receiver is a contract ERC-223 token contract will try to call tokenReceived
function on receiver contract. If there is no tokenReceived
function on receiver contract transaction will fail. tokenReceived
function is analogue of fallback
function for Ether transactions. It can be used to handle incoming transactions. There is a way to attach bytes _data
to token transaction similar to _data
attached to Ether transactions. It will pass through token contract and will be handled by tokenReceived
function on receiver contract. There is also a way to call transfer
function on ERC-223 token contract with no data argument or using ERC-20 ABI with no data on transfer
function. In this case _data
will be empty bytes array.
Here is a description of the ERC-20 token standard problem that is solved by ERC-223:
ERC-20 token standard is leading to money losses for end users. The main problem is lack of possibility to handle incoming ERC-20 transactions, that were performed via transfer
function of ERC-20 token.
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 cant recognize an incoming transaction. As the result, your tokens will get stuck at the contracts balance.
How much ERC20 tokens are currently lost (31 Dec, 2017):
-
QTUM, $1,358,441 lost. watch on Etherscan
-
EOS, $1,015,131 lost. watch on Etherscan
-
GNT, $249,627 lost. watch on Etherscan
-
STORJ, $217,477 lost. watch on Etherscan
-
Tronix , $201,232 lost. watch on Etherscan
-
DGD, $151,826 lost. watch on Etherscan
-
OMG, $149,941 lost. watch on Etherscan
-
STORJ, $102,560 lost. watch on Etherscan
-
MANA, $101,967 lost. watch on Etherscan
Another disadvantages of ERC-20 that ERC-223 solves:
- Lack of
transfer
handling possibility. - Loss of tokens.
- Token-transactions should match Ethereum ideology of uniformity. When a user wants to transfer tokens, he should always call
transfer
. It doesn't matter if the user is depositing to a contract or sending to an externally owned account.
Those will allow contracts to handle incoming token transactions and prevent accidentally sent tokens from being accepted by contracts (and stuck at contract's balance).
For example decentralized exchange will no more need to require users to call approve
then call deposit
(which is internally calling transferFrom
to withdraw approved tokens). Token transaction will automatically be handled at the exchange contract.
The most important here is a call of tokenReceived
when performing a transaction to a contract.
ERC20 EIP ethereum/EIPs#20