まだERC20で消滅してるの？

みなさん、仮想通貨作ってますか？
作ったことがないという方、Ethereumを使えば簡単に仮想通貨が作れてしまいます。
最近、ERC20を使って仮想通貨を作ったり、ICOのコントラクトを作ったりする記事が多くありますが、実は [Ethereum.org](https://www.ethereum.org) のチュートリアルで詳しく解説されています。Ethereumの基本機能ですからね。

- [仮想通貨を作るチュートリアル](https://www.ethereum.org/token)
- [ICOのチュートリアル](https://www.ethereum.org/crowdsale)


# 仮想通貨の仕様
仮想通貨といってもどういう機能を持ったものが仮想通貨といえるのでしょうか？
Ethereumのチュートリアルのコードでは以下のように書かれています。

```typescript:
function TokenERC20(
    uint256 initialSupply,
    string tokenName,
    string tokenSymbol
) public {
    totalSupply = initialSupply * 10 ** uint256(decimals);
    balanceOf[msg.sender] = totalSupply;
    name = tokenName;
    symbol = tokenSymbol;
}
```

ここにある ERC20 というのは仮想通貨(以下トークンと呼びます)の仕様のことです。
ERC とは Ethereum Request for Comments の略で Ethereum に関連する技術仕様の提案書のことです。
この提案が可決されると EIP(Ethereum Improvement Proposal) に追加され、正式な仕様となります。
ERC20 はトークンに関する標準インターフェースについて書かれたERCで、既に [EIP20 Standard Token](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) として追加されています。

# ERC20 の仕様
ERC20 の仕様を満たすインターフェースを以下に示します。
それぞれの関数についてはERC20を読んでもらえばわかるので省略します。

```typescript:ERC20
function name() constant returns (string name)
function symbol() constant returns (string symbol)
function decimals() constant returns (uint8 decimals)
function totalSupply() constant returns (uint256 totalSupply)
function balanceOf(address _owner) constant returns (uint256 balance)
function transfer(address _to, uint256 _value) returns (bool success)
function transferFrom(address _from, address _to, uint256 _value) returns (bool success)
function approve(address _spender, uint256 _value) returns (bool success)
function allowance(address _owner, address _spender) constant returns (uint256 remaining)
event Transfer(address indexed _from, address indexed _to, uint256 _value)
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
```

通貨として成立させるためにはトークンを転送するメソッドが必要です。
ERC20 では`transfer`と`transferFrom`がそれにあたります。
したがって、このインターフェースを満たせば仮想通貨として機能させることが可能ということです。
そして、現在この ERC20 の仕様が Ethereum の標準となっています。

# ERC20の問題
標準となっている ERC20 ですが、重大な問題を抱えています。
それは、トークンコントラクト自体にトランザクションを処理する機能がないことです。
ユーザのアドレスではなく、コントラクトアドレスにトークンを誤って送ってしまった場合でも、正常な動作として送れます。
しかし、そのトークンはもう動かすことがないので、実質消滅してしまうことになります。
この現象は多く報告されており、既に約5000万円相当のトークンがブラックホールに吸い込まれたようです。

# ERC223
この問題を解決した仕様が ERC223 です。
ERC223 の仕様を満たすインターフェースを以下に示します。

```typescript:ERC223
function name() constant returns (string name)
function symbol() constant returns (string symbol)
function decimals() constant returns (uint8 decimals)
function totalSupply() constant returns (uint256 totalSupply)
function balanceOf(address _owner) constant returns (uint256 balance)

function transfer(address _to, uint256 _value) returns (bool)
function transfer(address _to, uint _value, bytes _data) returns (bool)
function tokenFallback(address _from, uint _value, bytes _data)

event Transfer(address indexed _from, address indexed _to, uint256 indexed _value, bytes _data)
```

# ERC20 との違い
## `tokenFallback`を追加

まず、大きく違うのが`tokenFallback`が追加されたことです。
このメソッドによって、送られたトークンが正しいトークンかどうか検証し、そうでなければ送り返すということが可能となります。
これで消滅する問題を回避できます。

## `transfer` が2つある
ERC223 では自身の`transfer`と ERC20 への後方互換を持たせるために ERC20 の`transfer`が定義されています。
また、ERC223 の`transfer`ではパラメータに`data`が追加されており、トランザクションデータを持たせることが可能となっています。

## `transferFrom`, `approve`, `allowance`を削除
これらは、コントラクトに転送処理をさせるために必要なメソッドです。
ERC223 ではこの機能はトークンが持つべきではないとしています。

# ERC223 のメリット
まず、最大のメリットはユーザが誤ってトークンを失うことがなくなることです。ERC20 では間違って送ったとしてもそれが間違っていたかどうかすらわからない状態です。
また、`transferFrom`がなくなったことにより、ユーザは転送のために使うメソッドでどちらを使えば良いのか決めるときに、内部ロジックを考えなくてもすみます。
また、`transferFrom`を使うときには`approve`で許可しないといけないので、転送に 2 ステップ必要となり Gas も多くかかります。

# まとめ
ERC223 は ERC20 の問題を解決しており、後方互換性もあるので、特に理由もなければ ERC223 準拠が良いと思います。
ERC20 準拠のトークンは GOX する可能性のある危険なトークンになるのでICOしようと思っている方は注意しましょう。(トークンを作って遊ぶだけなら全然気にする必要はありません)
ERC223について文句がある方は私ではなくERCで議論してください。


# 参考
- [Ethereum Improvement Proposal](https://github.com/ethereum/EIPs)
- [ERC20 Standard Token](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md)
- [ERC223 Standard Token](https://github.com/ethereum/EIPs/issues/223)

本記事の内容は [blockchain.tokyo#3](https://blockchain-tokyo.connpass.com/event/71629/) で話したものです。