Ethereum スマートコントラクトによるinterfaceの実装

【本文】
---

Solidityを使用したスマートコントラクトのinterface実装についてのサンプルと簡単な解説となります。
トークンモデルを標準化したERC20を実装したコントラクトを見ていると、しばしばERC20をinterfaceとして実装しているケースがあり、interfaceについてある程度理解しておくことも重要です。

interfaceは他の言語と基本的な考え方は変わりませんが、誤解を招く言い方にはなりますが、Solidityでは例えばERC20と言った標準化されたルールを規定したものと捉えておくと良いです。
（もし、ルールが定まらず各人が勝手な仕様でトークンを発行すると、etherとトークン、あるいはトークン同士を交換する際に大変になる、と言った事態を避ける。）

interfaceやeventと言った詳細な説明（と言ってもinterfaceは制約事項くらいしか書かれていないが。）はsolidityの公式ドキュメントを参照することをお勧めします。

【サンプル】
---

**[test0624]**

+ test0624はtest0624Interface0624を実装する。
+ 実装時の約束事としてinterface0624で定義された関数の型を使用しなければならない。
+ interface0624で定義されたイベントを出力する為、emitを使用している。これによって、test0624で実装したcalcNumメソッドの実行ログが出力される。
+ デプロイする際は、contractのみで、interface自体はデプロイできない。

>```java:test0624.sol
pragma solidity ^0.4.24;
import './test0624Interface.sol';
//test0624Interface.solを実装
contract test0624 is test0624Interface {
    // test0624Interface.solで定義された関数（calcNum）を実装
    function calcNum(uint256 _num) public returns (bool success){
        num = num + _num;
        // test0624Interface.solで定義されたイベントを出力
        emit CalcNum(msg.sender, _num);
        return true;
    }
}
>```

**[test0624Interface]**

+ test0624Interfaceはinterfaceであり、関数の型やイベントの定義と言った最低限の実装のみ行う。なお、solidityでは、interfaceは他のinterfaceを実装することはできない。
+ interfaceを実装するcontractは、interfaceで定義された関数の型を全てその通りに実装しなければならない。
+ interfaceで定める関数は型のみなので、それを実装したcontract側で具体的な処理を記述すればよい。

>```java:test0624Interface.sol
pragma solidity ^0.4.24;
//インターフェース
contract test0624Interface {
    uint256 public num;
    //関数の型を定義
    function calcNum (uint256 _num) public returns(bool success);
    //イベント定義
    event CalcNum(address indexed _owner, uint256 _num);
}
>```

**簡単な説明（interfaceとcontractの関係）**

+ contractがinterfaceを実装する際、以下の通り、interfaceのファイルをimportし、contract名に「contract A is B(interface) { ... }」のように記述する。

>```java:
import './test0624Interface.sol';
//test0624Interface.solを実装
contract test0624 is test0624Interface {
     ...
}
>```

+ Interfaceで以下の通り関数を定義しているが、単に関数の型（関数名、引数、戻り値）だけ実装している。実際の処理内容は実装するcontract側で記述することになる。

>```java:
//関数の型を定義
function calcNum (uint256 _num) public returns(bool success);
>```

+ イベント定義は以下の通り。

>```java:
//イベント定義
event CalcNum(address indexed _owner, uint256 _num);
>```

+ interfaceを実装したcontract側では、関数をinterfaceで定義された通りのまま記述し、具体的な処理内容をメソッド内で定義している。
+ 具体的な処理は単に引数を基に加算処理するだけのもの。（処理内容自体は何でもよい。）
+ 「emit」の箇所が、interfaceで実装したイベント定義となる。
+ 最後に、戻り値を成功した場合のbool型（真偽）を返している。

>```java:
function calcNum(uint256 _num) public returns (bool success){
        num = num + _num;
        // test0624Interface.solで定義されたイベントを出力
        emit CalcNum(msg.sender, _num);
        return true;
    }
>```


【実行結果】
---

+ 今回は、Remixを使ってローカルのメモリ上で疑似デプロイする。上述の通り、デプロイするのは、contractのみ。サンプルでは、「test0624」をデプロイすることになる。
+ Remix上の「Run」タブで「Environment: JavaScript VM」を選択し、「Deploy」ボタン押下でメモリ上に疑似デプロイされる。
+ 疑似デプロイ後、「calcNum」メソッドをボタン押下で実行。
+ 実行結果は（図1）の通り。

**[図1]**
![remix0624.png](https://qiita-image-store.s3.amazonaws.com/0/167054/7884aaf3-c5b1-ade8-e6f7-b4dc4c3fe4dd.png)

+ （図2）Remix上のコンソール画面にlogsと言う項目が出力されているが、これが、Interfaceで定義したイベントを、contract側でemitによって出力した結果となる。つまり、Eventの実態はlogと言うことになる。
+ 画像では少し見え辛いが、logsの中に「topic」があり、ハッシュ値（0x4655cc4631771176f71ef2de57c20fdb8da6ca3eb57d6a7b09f8751f2fd7144d）が割り当てられていることが分かる。実は、このtopicsはinterfaceで定義した「CalcNum(address indexed _owner, uint256 _num)」をハッシュ化したものとなる。

**[図2]**
![remix0624_2.png](https://qiita-image-store.s3.amazonaws.com/0/167054/a63618c0-68b9-2388-547f-a2899af92301.png)


【まとめ】
---

interfaceを作成することで、contractを標準化することが可能になります。実際、ERC20と言ったトークン標準化に準拠したトークンモデルの多くは、しばしばinterfaceを用いて実装されていることが分かります。その意味では、interfaceは共通ルールを規定するもの、とも言えそうです。
また、interfaceを用いることで、contract側の処理内容を変更したい場合はinterfaceを実装したcontractのメソッド内で修正すればよいとか、contractの可読性を上げるのにも使用できます。



【参考文献】
---

**Solidity: Contractについて**

+  [" Solidity — Solidity 0.4.21 documentation "](http://solidity.readthedocs.io/en/v0.4.21/contracts.html)

**ERC20(EIP20)、事例含む**

+  [" ERC: Token standard #20 "](https://github.com/ethereum/EIPs/issues/20)
+  [" EIPs/EIPS/eip-20.md "](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md)
+  [" Consensys - Tokens/contracts/eip20/
 "](https://github.com/ConsenSys/Tokens/tree/master/contracts/eip20)
+  [" トークンコントラクトの仕組みとERC20トークンを用いたサービス設計の概要
 "（Gnosy - ブロックチェーンブログ）](http://blockchain.gunosy.io/entry/token-summary-and-token-contract)