Solidityコードをデバッグする

この記事は [Altplus Advent Calendar 2017](https://qiita.com/advent-calendar/2017/altplus) の5日目のエントリです。

こんにちわ、Xamarin人材です。
最近思い出作りにSolidityを書き始めたので、開発環境の使い方のメモです。

# Solidityとは
Ethereum上で動作させるスマートコントラクトを記述するための言語です。
jsっぽい？けど静的型付き言語。
Soliity言語で書いたコントラクトは、以下の手順を踏むことでEthereumネットワークにデプロイされ、他者が使用できる状態になります。

1. コーディング
2. コンパイル
3. デプロイ

手順1〜2はテキストエディタとターミナルでもさほど問題ありませんが、3のデプロイ作業がなかなかに面倒です。手作業であたたかみのあるデプロイも人生には大事なのかもしれませんが、そういうところを楽させてくれるのが、[Remix](https://github.com/ethereum/browser-solidity)です。

# Remix(browser-solidity)を使う
[Remix](https://github.com/ethereum/browser-solidity)は、もともとbrowser-solidtyと呼ばれていたものです。名前の通り、ブラウザ上で動作するSolidityのIDEです。github上からダウンロードすればローカルでも動かせます。

## エディタ
なかなか高機能なエディタで、auto compileなんかも走らせることができます。なのでコンパイルエラーなんかがあれば常時アラートしてくれます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/46184/003ad86e-2d9e-7f7a-e65e-8b2d70ef79a3.png)

## ContractのDebugもできる
私はなかなか脳内デバッガーの精度が低く、ステップ実行してコードの動きを確認したくなることが多々あります。Remixであれば、それも可能です。

コントラクトの中身はあまり本筋と関係ありませんが、今回はこのようなコントラクトを書いてみました。
Postで気になるあの人に向けたメッセージをブロックチェーン上に刻むことができ、Readで自分宛のメッセージを読むことができます。

```solidity:sample.sol
pragma solidity ^0.4.0;

contract SampleContract {
    address public owner;
    mapping(address => string) public messages;

    // コンストラクタ
    function SampleContract() public {
        owner = msg.sender;
    }

    // 任意のアドレスに向けたメッセージを記す。
    function Post(address dest, string message) public {
        messages[dest] = message;
    }
    
    // メッセージを読む。何も存在しなければabort
    function Read() public constant returns (string message) {
        bytes memory strMem = bytes(messages[msg.sender]);
        require(strMem.length > 0);
        return messages[msg.sender];
    }
}
```

### デバッグ手順
#### 1. EnvironmentをJavaScript VMに変更

[Run]タブにて、[Environment]を[JavaScript VM]とします。
他のEnvironmentを選択しているとデバッグできませんのでご注意。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/46184/cdfe83d5-da1b-0ef1-e02e-aca4ec0fe397.png)


#### 2. コントラクトのデプロイ

おなじく[Run]タブ内でデプロイしたいコントラクトを選択し、[Create]ボタンを押せばデプロイ完了です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/46184/f83a58b7-969c-a5e2-4307-b680aeb1a411.png)


#### 3. コントラクトの実行
Remix上でデプロイしたコントラクトが一覧表示されていますので、こちらから任意のfunctionを選んで実行します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/46184/1c31084b-8473-9e3a-01c2-6397584c9823.png)

#### 4. デバッグ

エディタ下部のコンソールに次のようにコントラクトの実行結果が表示されていますので、右側の[Debug]をクリックします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/46184/9cfeddf0-811f-528b-157e-40609cc6e8ee.png)

すると、右側のタブは自動的に[Debugger]に切り替わり、デバッグ対象のfunctionのエントリポイントで自動的に一時停止します。実行済みのコントラクトを再生してデバッグするようなイメージですね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/46184/22942fad-f41a-e186-74cc-c46438496233.png)

あとは、表示されているボタンを使ってステップイン、ステップオーバー、ブレークポイントまで飛ばす・・・といった、一般的なデバッガで可能な操作を行うことができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/46184/d9ed7bf1-00a5-474c-8746-5d3bfdb066e4.png)

ローカル変数の中身も表示可能。
Watchみたいなのはない・・・のかな？

# おわりに
以上、Solidityコードをババっと書いてちゃちゃっとデバッグする方法でした。PCのメモリ上にデプロイされているだけなのであまり面白みはありませんが、Solidityでどんなことができるのか、というのを知るには良いのではないかと思います。

きちんとコントラクトのデバッグができたら、Ethereumネットワークにデプロイして遊んでみましょう。（まずはプライベートネットから！）

# 参考
[Ethereum入門](https://book.ethereum-jp.net/)
[Remix](https://github.com/ethereum/browser-solidity)