1時間でQtum上に独自のERC20トークンを発行する (環境構築編)

[Qtum](https://qtum.org) のネットワーク上に[ERC20トークン](https://en.wikipedia.org/wiki/ERC20)を発行する手順をまとめます。
QtumではEthereumのコントラクトを動作させることができます。つまり、Ethereum向けに(solidityなどで)書かれたコントラクトを、Ethereum向けの(solcなどの)コンパイラでバイトコードに変換し、それをQtum上にデプロイすることができます。
そこで、ERC20のサンプルコードを使って、自分の独自トークンをQtum上に発行してみます。

Qtumの説明についてはこちらを参照
[Qtumって何？](https://qiita.com/yoshikazzz/items/4299eaf276e356b5eb2a)

本記事はこちらの非公式チュートリアル(英語)を参考にしています。
前編(環境構築編)はほぼチュートリアルの日本語訳に近いです。

[Qtum Blockchain Development Environment Setup](https://steemit.com/qtum/@cryptominder/qtum-blockchain-development-environment-setup)
[Quantum (Qtum) Blockchain Developer Tutorial - Hello World!]
(https://steemit.com/qtum/@cryptominder/quantum-qtum-blockchain-developer-tutorial-hello-world)

本記事は前編(環境構築編)です。環境構築が済んでいる方は後編へどうぞ。
[1時間でQtum上に独自のERC20トークンを発行する(コントラクト編)](https://qiita.com/TakuyaObata/items/ded8f7b5bb66aba28ea5)


#前提条件

- ここではMac環境を前提としていますが、他の環境でも概ね同様だと思われますので、ご自身の環境に合わせて読み替えて下さい。

- Qtumのテストネットワーク構築に、約200MBほどのディスク容量が必要です。

#Dockerのインストール
Qtumの開発用クライアントはDockerイメージが配布されています。　
以降の操作は全てDocker上で行います。

以下の記事などを参考にDockerをインストールします。
[Dockerインストールメモ](https://qiita.com/n-yamanaka/items/ddb18943f5e43ca5ac2e)

筆者の環境では以下のバージョンを使いました。

```
$ docker version
```
```
Client:
 Version:	17.12.0-ce
 API version:	1.35
 Go version:	go1.9.2
 Git commit:	c97c6d6
 Built:	Wed Dec 27 20:03:51 2017
 OS/Arch:	darwin/amd64

Server:
 Engine:
  Version:	17.12.0-ce
  API version:	1.35 (minimum version 1.12)
  Go version:	go1.9.2
  Git commit:	c97c6d6
  Built:	Wed Dec 27 20:12:29 2017
  OS/Arch:	linux/amd64
  Experimental:	false
```

インストールが正常にできているかどうか、以下のコマンドで確認します。

```
$ docker run hello-world
```

以下のように出力されれば正常です。

```
(前略)
Hello from Docker!
This message shows that your installation appears to be working correctly.
(後略)
```

#Dockerネットワークを作成
この後の章でQtumのノードを3つ立ててテストネットワークを構築します。
その準備として、各ノードが相互に通信するために[bridgeネットワーク](https://docs.docker.com/network/)をDocker上に作成します。

```
$ docker network create --driver bridge qtum_network
```

以下のコマンドで作成されたネットワークを確認します。

```
$ docker network ls
```

```
NETWORK ID          NAME                DRIVER              SCOPE
33be845dadba        bridge              bridge              local
2616c8e689b8        host                host                local
6724e6ca5685        none                null                local
f510fe3f0095        qtum_network        bridge              local
```

qtum_networkがbridgeというドライバで作成されていればOKです。
このネットワーク名を以降の手順で使用します。

#QtumのDockerイメージをpullする

以下のコマンドでQtumのDockerイメージを取得します。

```
$ docker pull cryptominder/qtum
```

イメージを取得できているか確認します。

```
$ docker images
```

```
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
cryptominder/qtum     latest              f5adde30c8eb        5 months ago        92.1MB
```

#Qtum Daemonのconfigファイルをダウンロード
ノードを3つ立てるにあたり、各ノードのconfigファイルが必要になります。
以下のリポジトリからサンプルを取得してきます。

https://github.com/crypt0m1nd3r/docker-qtum-config

・node1_qtumd.conf
・node2_qtumd.conf
・node3_qtumd.conf

今回は上記のconfigファイルをそのまま使います。
各ファイルには、

node1→node2
node2→node3
node3→node1

と互いのノードを接続する設定が書かれています。

また、

```
regtest=1
```

と書かれた行がありますが、これはregtestというテストモードを使うことを示しています。

これらのファイルを適当な作業用ディレクトリに配置します。
以降の作業は作業用ディレクトリ上で行います。

#Qtumノードを立てる
###node1の起動

以下のコマンドでnode1を立てます。
(カレントディレクトリが作業用ディレクトリである前提です)

```
$ docker run -d --rm --name qtumd_node1 --network=qtum_network -v ${PWD}/node1_qtumd.conf:/home/qtum/qtum.conf:ro -v ${PWD}/node1_data:/data cryptominder/qtum:latest qtumd
```

以下のようにコンテナIDが返ります。(IDは実行毎に変わります)

```
ad208bdd859ed6f61e966d40c416d0e262f861c259c27b9c23ff8b8b7b3308ce
```

デーモンが起動したか確認するには以下のコマンドを実行します。

```
$ docker ps
```

```
ad208bdd859e        cryptominder/qtum:latest   "/entrypoint.sh qtumd"   4 seconds ago       Up 3 seconds        3888-3889/tcp, 13888-13889/tcp, 23888/tcp   qtumd_node1
```

###コマンドの説明

・-vオプションでは絶対パスを記述する必要があるため、```${PWD}```を使用しています。
Windowsでは```${PWD}```を%```cd%```に読み替えて下さい。

・以下のオプションは、ホスト側のnode1_dataディレクトリをQtumイメージ内の/dataディレクトリにマウントしています。

```
-v ${PWD}/node1_data:/data
```

/dataにはノード1の各種データ(ブロックチェーン、ウォレットのキーなど)が保存されるので、このオプションによって、ノード情報を不揮発化しています。デーモンとして起動させたnode1を終了させても、次回起動時に各データが引き継がれます。


・以下のオプションは、先ほど取得したconfigファイルを　Docker上にマウントしています。

```
-v ${PWD}/node1_qtumd.conf:/home/qtum/qtum.conf:ro
```

###node2, node3の起動
同様のコマンドでnode2, node3を起動します。

```
$ docker run -d --rm --name qtumd_node2 --network=qtum_network -v ${PWD}/node2_qtumd.conf:/home/qtum/qtum.conf:ro -v ${PWD}/node2_data:/data cryptominder/qtum:latest qtumd
```

```
$ docker run -d --rm --name qtumd_node3 --network=qtum_network -v ${PWD}/node3_qtumd.conf:/home/qtum/qtum.conf:ro -v ${PWD}/node3_data:/data cryptominder/qtum:latest qtumd
```


#セットアップの確認
各ノードにコマンドを実行させるには、```qtum-cli```を使います。
このツールはRPCインタフェースを通して各ノードにコマンドを送ります。

例えばこのように使います。(getinfoコマンドを実行)

```
$ docker run -i --network container:qtumd_node1 -v ${PWD}/node1_qtumd.conf:/home/qtum/qtum.conf:ro -v ${PWD}/node1_data:/data cryptominder/qtum:latest qtum-cli getinfo
```

qtum-cliを使ったコマンドは今後頻出しますが、やや長くて不便なのでシェルスクリプトにしてしまいましょう。
以下をファイルに保存します。

```qtum-cli-node1.sh
#!/bin/sh
docker run -i --network container:qtumd_node1 -v ${PWD}/node1_qtumd.conf:/home/qtum/qtum.conf:ro -v ${PWD}/node1_data:/data cryptominder/qtum:latest qtum-cli $@
```

パーミッションを実行可能に設定しておきます。

```
chmod 755 qtum-cli-node1.sh
```

これで、```./qtum-cli-node1.sh command arg1 arg2```などとすればqtum-cliを実行できます。
同様にnode2, node3用も必要に応じて作成して下さい。

以下のコマンドを実行してノード情報を取得してみます。

```
$ ./qtum-cli-node1.sh getinfo
```

以下のような出力が得られたら成功です。

```
{
  "version": 140301,
  "protocolversion": 70016,
  "walletversion": 130000,
  "balance": 0.00000000,
  "stake": 0.00000000,
  "blocks": 0,
  "timeoffset": 0,
  "connections": 0,
  "proxy": "",
  "difficulty": {
    "proof-of-work": 4.656542373906925e-10,
    "proof-of-stake": 4.656542373906925e-10
  },
  "testnet": false,
  "moneysupply": 0,
  "keypoololdest": 1520687095,
  "keypoolsize": 100,
  "paytxfee": 0.00000000,
  "relayfee": 0.00400000,
  "errors": ""
}
```

コマンドの末尾を```qtum-cli help```とすると使えるコマンドの一覧が出力されます。

node2, node3も同様にgetinfoしてセットアップを確認します。

#ブロック生成
上記のようにセットアップが完了した時点では、ブロックは自動的に生成されていきません。
しばらく放置しても、blockは0のままになっていると思います。
この理由については[次章](#Appendix QtumのPoSについて)で述べますが、ここではブロックを手動で生成させてみます。

ここまで、regtestというテストモードで環境を構築しました。
このテストモードでは、```qtum-cli generate```を使うと手動でブロックを生成することができます。

以下のコマンドで１ブロック生成することができます。

```
$ ./qtum-cli-node1.sh generate 1
```

再度getinfoをすると、以下のように
"blocks": 1,
となり、block numberが1になります。

```

  "version": 140301,
  "protocolversion": 70016,
  "walletversion": 130000,
  "balance": 0.00000000,
  "stake": 0.00000000,
  "blocks": 1,
  "timeoffset": 0,
  "connections": 0,
  "proxy": "",
  "difficulty": {
    "proof-of-work": 4.656542373906925e-10,
    "proof-of-stake": 4.656542373906925e-10
  },
  "testnet": false,
  "moneysupply": 20000,
  "keypoololdest": 1520687095,
  "keypoolsize": 100,
  "paytxfee": 0.00000000,
  "relayfee": 0.00400000,
  "errors": ""
}
```

同様に```qtum-cli generate 2000 ```などと実行してブロックを進めておきます。
これによって、以降Stakingが行われ、自動的にブロック生成されていくようになります。
それと同時に、使用可能なQTUMトークンがウォレットに溜まっていきます。
(501以降であればstakingが開始されますが、stakingされたQTUM残高はさらに500ブロック経過後から徐々にリリースされるため、ある程度進めておいた方がQTUM残高が潤沢になります。)

大量のブロックを生成させる場合は長い時間がかかることがあるので注意して下さい。

Stakingについてはこちらを参照下さい。
[Qtum Staking 日本語解説](https://qiita.com/yoshikazzz/items/cbbfa75a85186f13ac69#%E5%82%99%E8%80%83)

以上で前編(環境構築編は)終わりです。
[後編(コントラクト編)](https://qiita.com/TakuyaObata/items/ded8f7b5bb66aba28ea5)に続きます。

#Appendix1 QtumのPoSについて
Qtumは基本的にPoSを採用していますが、最初の5000ブロックではPoWのブロックとPoSのブロックが混在した状態になっているようです。(Stakingの権利を得るためにはUTXO単位で500ブロック以上の承認が必要、つまり500ブロック以下ではStaking可能なノードが存在しないことが理由？)
5000ブロックを越えるとPoWが無効になり、PoSへ完全移行するようです。
ただし、regtestモードではPoWとPoSの制限がないとのことなので、最初からPoSだと思われます。実際、blockが500を超えるまでは自動的にブロック生成されることがありません。500を超えるとPoSによって自動的にブロックが生成されていきます。

#Appendix2 停止とリセット
Qtumノードを停止するには、以下のようにします。

```
docker stop qtumd_node1
```
　
また、qtumdのノード情報を保存したディレクトリ(node1_data etc)を削除してしまえば、次回起動時には0から再度スタートします。

#後編へ
[1時間 でQtum上に独自のERC20トークンを発行する (コントラクト編)](https://qiita.com/TakuyaObata/items/ded8f7b5bb66aba28ea5)