スマートコントラクトのセキュリティを楽しく学ぶ"Capture the Ether"


![Screenshot from 2018-09-26 22-33-48.png](https://qiita-image-store.s3.amazonaws.com/0/253754/26a4d79c-5726-6351-bf44-e5fe594e4987.png)

# 概要
Ethereumを始めとして、スマートコントラクトを作成できる環境がどんどん整いつつ有るように感じる最近です。
ですが手軽にできるようになってきたからこそ、忘れてはいけないのがセキュリティ対策ですね。
この記事では、スマートコントラクトのセキュリティをゲーム形式で楽しく学べる[**"Capture the Ether"**](https://capturetheether.com)の紹介をさせていただきます。

# スマートコントラクトのセキュリティ
## スマートコントラクトのセキュリティの重要性
皆様ご存知の通りだと思いますが、ざっくりおさらいさせていただきます。

- 一度リリース（＝デプロイ）したら**修正がとても難しい**
- 修正どころか、**強制停止も難しい**
- しかし、**扱えるお金は非常に大きい**

こういった特性から、**リリース前にセキュリティ対策がきちんと出来ているかをチェックすることが非常に重要**なのです。

## ならどうやって対策すればいいの？
とはいえども、まだまだ新しい分野のため、セキュリティの専門家はごくわずか。
専門の書籍も少なく、情報も増えては来ていますが、中々ハードルは高い印象です。

そこで、参加した勉強会で紹介していただいた、簡単に楽しくスマートコントラクトを学べる[**"Capture the Ether"**](https://capturetheether.com)が割と良さそうだったので共有させていただきます。

# Capture the Ether とは
## 公式より
公式の説明をざっくり意訳させていただきます（訳が怪しいのはお許しください）。
### Capture the Ether って？
>Capture the Etherはセキュリティを学ぶために、Ethereum のスマートコントラクトをハッキングするゲームだ。
>楽しみながら勉強できるよ！
>このゲームはスマートコントラクトに関するブログ、[Program the Blockchain](https://programtheblockchain.com/)の管理人でも有る[@smarx](https://twitter.com/smarx)の提供だ。

### ルールは？どうやったら勝ち？
>ゲームは、いろいろなカテゴリの一連の課題で構成されているよ。各課題をクリアするごとにポイントを獲得できる。より難しいものほど、多くのポイントがゲットできるようになっているんだ！

>さて、各課題は、isComplete関数（または、public state変数）が用意されたスマートコントラクトの形式で用意されている。君の目的は、**isComplete関数の返り値がtrueになるようにスマートコントラクトをハックすることだ！**

>課題をクリアしてポイントを集めるとどうなるか？リーダーボードに君の名前が載ることになるだろう！

### 何から始めたらいい？
>[*warmup（準備運動）*](https://capturetheether.com/challenges/warmup)は君が必要になるであろうツールの紹介のためのカテゴリだ。でも、もし君が最新のEthereumのスマートコントラクトを開発しようと考えているならば、最初に[Program the Blockchain](https://programtheblockchain.com/)と、そのバックグラウンドに目を通しておいてほしい。

>またもし、ツールや知識が不足していると感じるなら、[リソースページ](https://capturetheether.com/resources)をチェックするか、[ヘルプ](https://www.reddit.com/r/capturetheether)を利用してほしい。

## つまり？
**脆弱性の有るスマートコントラクトを実際にハッキングする経験**を通して、バッドプラクティスを知り、セキュリティ対策を学ぶことができるゲームです。

ポイントを稼いでリーダーボード上位を目指せ！

もしSolidityの文法を学んだことがないなら、先に[CryptoZombies](https://cryptozombies.io/jp/)がおすすめです。

# 実際に挑戦してみよう
## 準備するもの
公式でも推奨の環境は有るのですが、私が個人的に使用している環境を紹介します。

- [Remix](https://remix.ethereum.org/)
    - SolidityのWebIDE。これで開発からデプロイまで。
    - 紹介ページは[ココらへん](http://www.atmarkit.co.jp/ait/articles/1711/27/news009.html)を参照のこと。
- [MetaMask](https://metamask.io/)
    - Chrome/Firefox用のウォレット管理プラグイン。
    - 実行にはEthereumのテストネットを使用するので、MetaMaskがあると便利。
    - 紹介ページは[ココらへん](https://coiner-blog.com/dapps/metamask-summary)を参照のこと。
- RopstenのEthereum残高
    - 実行時に少なからずEtherが必要。準備しておきます。
    - ※テストネットのものなので無料で用意できます。
    - [ココらへん](https://qiita.com/tmikada/items/cdc5a3871f655cb7b67d)を参考に5~10Etherを用意しておくと安心。

## 進め方
ここではWarmupの課題を２つ、実際の進め方を解説して、基本的な課題の進め方を説明したいと思います。
![Screenshot from 2018-09-26 23-14-32.png](https://qiita-image-store.s3.amazonaws.com/0/253754/9da43bba-57cd-0724-d488-7a6a841ad44f.png)
まずはトップの**【LET'S PLAY >】**から。

![Screenshot from 2018-09-26 23-17-06.png](https://qiita-image-store.s3.amazonaws.com/0/253754/c8cef24c-344d-6f0e-e358-cfc27a43777b.png)
この上から2つを実行していきます。

### Deploy a contract
公式を意訳しつつ画像等で補足します。

>このチャレンジをコンプリートするための手順は以下のとおり。
>
1. MetaMaskをインストールしよう
2. RopStenテストネットワークに切り替えよう
3. RopStenのテスト用Etherを手に入れよう。"buy"ボタンを押すと、テスト用Etherを配布している*faucet*のページに飛ぶはずだ。

（ここまでは上の【準備するもの】を参考にしていただければ。）

>ここまで出来たら、左の赤いボタンを押して、チャレンジコントラクトをデプロイしよう。
![Screenshot from 2018-09-26 23-27-47.png](https://qiita-image-store.s3.amazonaws.com/0/253754/ae50b481-8253-afdd-6887-adc0c25448fb.png)



クリックすると、MetaMaskが実行されるので、【Submit】を選択。
![Screenshot from 2018-09-26 23-29-04.png](https://qiita-image-store.s3.amazonaws.com/0/253754/65c926ef-697b-4710-1d83-04ff6b9f29b4.png)


>今回は、デプロイしたコントラクトに対して何もする必要はない。デプロイが終わったら、左のボタンが変わるから、"Check Solution"ボタンを押せば完了だ！

デプロイが終わると以下のような画面に。
【Check Solution】を押す。
![Screenshot from 2018-09-26 23-29-52.png](https://qiita-image-store.s3.amazonaws.com/0/253754/0bb45d1f-2664-d035-f72f-2c39f9556564.png)

クリックすると、またMetaMaskが実行されるので、【Submit】を選択。
![Screenshot from 2018-09-26 23-29-04.png](https://qiita-image-store.s3.amazonaws.com/0/253754/65c926ef-697b-4710-1d83-04ff6b9f29b4.png)

最終的に完了するとこうなる。
![Screenshot from 2018-09-26 23-26-41.png](https://qiita-image-store.s3.amazonaws.com/0/253754/892bba81-fd05-3cbf-3943-38299da1bdd6.png)

これで終了。MetaMaskのトランザクションが実際に取り込まれるまでにやや時間がかかることには注意。

### Call me
同じく。

>このチャレンジをコンプリオートするためには、たった一つの関数を呼び出すだけでいい。

>"Begin Challenge"ボタンで、以下のコントラクトがデプロイされる。

>```
>pragma solidity ^0.4.21;
>
>contract CallMeChallenge {
>    bool public isComplete = false;
>
>    function callme() public {
>        isComplete = true;
>    }
>}
>```

>callme()関数を呼び出せたら、"Check Solution"ボタンをクリックしてくれ。

…とは言われてもどういうこと？という感じかもしれないので進め方を以下に解説。

**（１）まずは"Begin Challenge"を押します。MetaMaskでの実行も忘れずに。これによって、先のコードがRopSten上にデプロイされます（画像は使いまわし）。**
![Screenshot from 2018-09-26 23-27-47.png](https://qiita-image-store.s3.amazonaws.com/0/253754/11bda556-ea4a-c9f8-684b-2d89cd767fc8.png)
![Screenshot from 2018-09-26 23-29-04.png](https://qiita-image-store.s3.amazonaws.com/0/253754/107ded18-76e6-d390-d645-ef3e73967f33.png)

**（２）デプロイが完了すると、コントラクトのアドレスが表示されるので、それをメモ帳などにコピーしておきます（画像は使いまわし）。**
![Screenshot from 2018-09-26 23-37-05.png](https://qiita-image-store.s3.amazonaws.com/0/253754/0fad99a1-e80f-36c4-0513-00eb2361e40f.png)

**（３）Remixに移動して、先のコントラクトのコードを全部貼り付け、【Start to Compile】を押します**
![Screenshot from 2018-09-26 23-36-23.png](https://qiita-image-store.s3.amazonaws.com/0/253754/8aa151a3-6448-ccec-b439-d3f975ab8623.png)
![Screenshot from 2018-09-26 23-51-53.png](https://qiita-image-store.s3.amazonaws.com/0/253754/d4c66c57-7679-f8e8-1e5b-96c5bdb6ab20.png)

下の方に緑背景で「CallMeChallenge」が出ればOK。

**（４）【Run】タブを選択して、【Environment】を"Injected Web3"にする**
![Screenshot from 2018-09-26 23-53-55.png](https://qiita-image-store.s3.amazonaws.com/0/253754/4f7d291b-8451-7496-112f-71d61762a5a1.png)

**（５）先ほどコピーしておいたコントラクトアドレスを【At Address】に貼り付けて、【At Address】をクリック**
![Screenshot from 2018-09-26 23-52-29.png](https://qiita-image-store.s3.amazonaws.com/0/253754/076e3b66-6398-af28-97a3-8693cb63f02e.png)
）

**（６）これで、先にデプロイしておいたコントラクトが操作できるようになったので、【callme】ボタンを押して、callme()メソッドを呼び出す(※この時、MetaMaskの処理がまた必要）**

![Screenshot from 2018-09-26 23-53-11.png](https://qiita-image-store.s3.amazonaws.com/0/253754/12c0a6cc-10f3-9077-39b4-732938a7e3b1.png)

**（７）これでコンプリート条件を満たしたので、【CheckSolution】をクリック(画像は使いまわし）**
![Screenshot from 2018-09-26 23-29-52.png](https://qiita-image-store.s3.amazonaws.com/0/253754/0c21047d-09b2-5ac6-7143-391fd9254197.png)

これで完了です。

# まとめ
今回解説したのはチュートリアルでしたが、同様に勧めていくことでスマートコントラクトのセキュリティについて学んでいくことが出来ます。基本的な流れは「デプロイ→ハック（今回解説した、メソッドの実行と同じような形で行えるはず）→コンプリート」です。

バッドプラクティスと、それに対する攻撃方法を知ることは、防御方法を知る近道だと思います。手を動かしてそれを学べるこのサービスは中々有用ではないでしょうか。

また、逆にベストプラクティスを学びたいなら[Zeppelin](https://github.com/OpenZeppelin/openzeppelin-solidity)あたりが有名所でしょうか。
もしおすすめがあればコメントいただけると嬉しいです。