Skip to content
This repository has been archived by the owner on Oct 4, 2019. It is now read-only.

Current implementation of ECIP1021 doesn't match ERC223 token standard. #60

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
110 changes: 78 additions & 32 deletions ECIPs/ECIP-1021.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@
Resolution: https://github.com/Dexaran/ERC23-tokens

EIP #223 on Ethereum project: https://github.com/ethereum/EIPs/issues/223

## Abstract

The following describes standard functions a token contract and contract working with specified token can implement to prevent accidentally sends of tokens to contracts and make token transactions behave like ether transactions.

## Motivation

Two problems of ERC20 that ERC23 will solve:
1. When you are sending tokens receiver will never know that transaction appears. Addresses don't care about it while contracts my need to handle transactions.
2. Tokens could be sent to another contract address where would not be accessible anymore.
Problems of ERC20 that ERC223 will solve:
1. Impossibility of handling incoming transactions in receiver contract.
2. Tokens could be sent to contract that is not designed to work with tokens without handling and potentially could be lost. At least $72000 are lost at the moment. This problem is described [here](https://www.reddit.com/r/ethereum/comments/60ql37/attention_be_careful_using_ethereum_tokens/).
3. Token-transactions should match Ethereum ideology of uniformity. When a user needs to transfer his funds, he must always perform `transfer`. Doesn't matter is user depositing in contract or sending to an externally owned account.

Those will allow dapps and wallets to handle incoming token transactions and prevent accidentally sent tokens from being accepted by contracts.
Those will allow contracts to handle incoming token transactions and prevent accidentally sent tokens from being accepted by contracts.
For example decentralized exchange will no more need to force users to call `approve` at token contract then call `deposit` that is calling `transferFrom` taking allowed tokens. Token transaction will automatically be handled inside the exchange contract.

The most important here are, `transferToContract` and `fallbackToken`.
The most important here is a call of `tokenFallback` when performing a transaction to a contract.

## Specification

Expand All @@ -32,45 +33,90 @@ Contracts that work with tokens

## Methods

NOTE: An important point is that contract developers should handle `fallbackToken` like fallback for ether transactions if they wish their contracts to work with specified tokens.
NOTE: An important point is that contract developers must implement `tokenFallback` if they want their contracts to work with the specified tokens.

## Token contract methods
isContract
If the receiver does not implement the `tokenFallback` function, consider the contract is not designed to work with tokens, then the transaction must fail and no tokens will be transferred. An analogy with an Ether transaction that is failing when trying to send Ether to a contract that did not implement `function() payable`.

`function isContract(address _addr) private returns (bool is_contract)`
private function that assembles `extcodesize(_addr)` and returns `true` if code size is greater than 0. It's needed to choose which function to use `transferToAddress` or `transferToContract` depending on is the reveiver a contract or not.

transferToContract
#### totalSupply

`function transferToContract(address _to, uint _value) private returns (bool success)`
private function that transfers tokens from `msg.sender` to `_to` then trying to call `fallbackToken(msg.sender, _value)` at `_to`.
```js
function totalSupply() constant returns (uint256 totalSupply)
```
Get the total token supply

transferToAddress
#### name

function transferToAddress(address _to, uint _value) private returns (bool success)
private function similar to base ERC20 `transfer`
```js
function name() constant returns (string _name)
```
Get the name of token

transfer
#### symbol

`function transfer(address _to, uint _value) returns (bool success)`
function that is always called when someone wants to transfer tokens. Calls `transferToAddress` or `transferToContract` depending on is the reveiver an address or a contract.
```js
function symbol() constant returns (string _symbol)
```
Get the symbol of token

## Contract to work with tokens
#### decimals

```js
function decimals() constant returns (uint8 _decimals)
```
Get decimals of token

#### balanceOf

```js
function balanceOf(address _owner) constant returns (uint256 balance)
```
Get the account balance of another account with address _owner


#### transfer(address, uint, bytes)

```js
function transfer(address _to, uint _value, bytes _data) returns (bool success)
```
function that is always called when someone wants to transfer tokens.
This function must transfer tokens and invoke the function `tokenFallback (address, uint256, bytes)` in `_to`, if _to is a contract. If the `tokenFallback` function is not implemented in ` _to` (receiver contract), then the transaction must fail and the transfer of tokens should not occur.
If `_to` is an externally owned address, then the transaction must be sent without trying to execute ` tokenFallback` in `_to`.
`_data` can be attached to this token transaction and it will stay in blockchain forever (requires more gas). `_data` can be empty.

supportedTokens
NOTE: The recommended way to check whether the `_to` is a contract or an address is to assemble the code of ` _to`. If there is no code in `_to`, then this is an externally owned address, otherwise it's a contract.

`mapping (address => bool) supportedTokens;`
Mapping of addresses of token contracts that are supported.
IMPORTANT: Token fallback function that will be called at receiver contract must be named `tokenFallback` and take parameters` address`, `uint256`,` bytes`. This function must have `0xc0ee0b8a` [signature](https://www.4byte.directory/signatures/?bytes4_signature=0xc0ee0b8a).

addToken

`function addToken(address _token)`
Allows a token contract address to work with.
#### transfer(address, uint)

```js
function transfer(address _to, uint _value) returns (bool success)
```
Needed due to backwards compatibility reasons because of ERC20 transfer function doesn't have `bytes` parameter. This function must transfer tokens and invoke the function `tokenFallback(address, uint256, bytes)` in `_to`, if _to is a contract. If the `tokenFallback` function is not implemented in ` _to` (receiver contract), then the transaction must fail and the transfer of tokens should not occur.

IMPORTANT: Token fallback function that will be called at receiver contract must be named `tokenFallback` and take parameters` address`, `uint256`,` bytes`. This function must have `0xc0ee0b8a` [signature](https://www.4byte.directory/signatures/?bytes4_signature=0xc0ee0b8a).

## Events

#### Transfer

```js
event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes _data)
```
Triggered when tokens are transferred.

## Contract to work with tokens

```js
function tokenFallback(address _from, uint _value, bytes _data)
```
A function to handle token transfers that is called from token contract when token holder is sending tokens. `_from` is a token sender, `_value` is amount of incoming tokens and `_data` is attached data similar to data in Ether transactions. Works like fallback function for Ether transactions and returns nothing.

removeToken
NOTE: `msg.sender` will be a token-contract inside the `tokenFallback` function. It may be important to filter which tokens are sent (by token-contract address). The token sender (the person who initiated the token transaction) will be `_from` inside the` tokenFallback` function.

`function removeToken(address _token)`
Makes a given token contract address no more allowed to work with.
IMPORTANT: This function must be named `tokenFallback` and take parameters` address`, `uint256`,` bytes` to match the [function signature](https://www.4byte.directory/signatures/?bytes4_signature=0xc0ee0b8a) `0xc0ee0b8a`.

`function fallbackToken(address _from, uint _value)`
A function to handle token transfers that is called from token contract when token holder is sending tokens. `_from` is a token holder and `_value` is amount of incoming tokens. Works like fallback function for Ether transactions.
## Recommended implementation
This is highly recommended implementation of ERC 223 token: https://github.com/Dexaran/ERC23-tokens/tree/Recommended