MyToken発行してみた(テスト環境編)

> **Note：**記事は執筆時点（2018年6月）の内容です。技術の進歩が早く、今後陳腐化する可能性もあるのでご留意ください。

# はじめに
* ERC20のオリジナルトークンを作ってみよう
* ローカル環境で作成したコントラクトをテスト環境にデプロイしよう


# 事前準備
* 以下の記事の続きとなります。まだの方は、ローカル環境でのデプロイまで実施してください。

> **MyToken発行してみた(開発環境編)**

> * https://qiita.com/ttoori-ttoori/items/ffb20fe07d3913a1891f


# 参考資料
* 以下の先生の記事を参考しながら、進めます。先生に感謝。

> **EthereumのERC20 トークンとして社内通貨(風)のものを作ってみます**

> * https://qiita.com/Yaggytter/items/9df7e35e8725c3baad82


# 作業の流れ
1. INFURAアカウントの取得
2. truffle-hdwallet-providerのインストール
3. ネットワーク設定情報の編集
4. 環境変数の設定
5. コントラクトのデプロイ
6. デプロイされたコントラクトの確認
7. EtherScanでの確認


# 【手順1】INFURAアカウントの取得
* 以下リンクより、INFURAアカウントを取得する

> **INFURA**
> * https://infura.io/

* アカウンド取得したら、accessTokenを控えておく
    * メールが届くので、メールからも確認可能

### なんでINFURAが必要なの？

> * Ethereumのノードをホスティングし、かつ、JSON-RPCやRESTfulなAPIを提供してくれているサービス

> * 自分で本番環境やテスト環境向けのノードを立てると、環境構築やデータの同期（ブロックを全てダウンロードする）など非常に大変です。便利なサービスを利用しましょう。


# 【手順2】truffle-hdwallet-providerのインストール
* シェルで以下コマンドを実行

### truffle-hdwallet-providerのインストール
```bash
# プロジェクトのホームに移動後、
# truffle-hdwallet-providerのインストール
$ npm install truffle-hdwallet-provider --save
```

> **Note：**テストネットにデプロイする際のproviderとして使用するためにインストールしておきます


# 【手順3】ネットワーク設定情報の編集
* プロジェクトフォルダ直下にある`truffle.js`をエディタで開く
* 以下のコードをコピーして貼り付け
 
### ネットワーク設定情報の編集
```js:truffle.js
var HDWalletProvider = require("truffle-hdwallet-provider");
var mnemonic = process.env.ROPSTEN_MNEMONIC;
var accessToken = process.env.INFURA_ACCESS_TOKEN;

module.exports = {
  networks: {
    ropsten: {
      provider: function() {
        return new HDWalletProvider(
          mnemonic,
          "https://ropsten.infura.io/" + accessToken
        );
      },
      network_id: 3,
      gas: 500000
    }   
  }
};
```

> **Note：**現在、Ethereumのテストネットワークは３つ（Ropsten/Kovan/Rinkeby）用意されています。
> 今回は、Ropstenテストネットワークを使用する前提で進めます。
> ちなみに、本番環境（Mainnet）にデプロイする際にはGAS（手数料）がかかるため、Ethereumが必要になります。

# 【手順4】環境変数の設定
* シェルで以下コマンドを実行

### 環境変数の設定
```bash
# 環境変数の設定(ROPSTEN_MNEMONIC)
$ export ROPSTEN_MNEMONIC="..."

# 環境変数の設定(INFURA_ACCESS_TOKEN)
$ export INFURA_ACCESS_TOKEN="..."
```

> **Note：**環境変数には以下の内容を設定します

> * ROPSTEN_MNEMONIC：Ropstenのアカウントを作成した際に保存したニーモニック（例：orange apple banana ... みたいな文字列）

> * INFURA_ACCESS_TOKEN：INFURAのアカウント取得時に控えたTOKEN（例：Y6tTgE...みたいな文字列）


### 環境変数の確認
```bash
# 環境変数の確認(ROPSTEN_MNEMONIC)
$ printenv ROPSTEN_MNEMONIC

# 環境変数の確認(INFURA_ACCESS_TOKEN)
$ printenv INFURA_ACCESS_TOKEN
```

> **Note：**環境変数は、手順2で作成した`truffle.js`内で使用されます

# 【手順5】コントラクトのデプロイ
* シェルで以下コマンドを実行

### コントラクトのデプロイ
```bash
# ropstenネットワークへのデプロイ
$ truffle migrate --network ropsten

## 実行結果（例）
Using network 'ropsten'.

Running migration: 1_initial_migration.js
  Replacing Migrations...
  ... 0x31d669c4a9fe19c46d3c840a374610abdbca562b261e35a602ec025f1be44a5b
  Migrations: 0x88ad97728b2e9116917b1c8a228c7edbc0480019
Saving successful migration to network...
  ... 0xb2a224957bf7b832c8e5738d3788ee897690be3ac9b2bb4dd34002214991be5c
Saving artifacts...
Running migration: 2_deploy_tooricoin.js
  Deploying TooriCoin...
  ... 0xd3d66c21e22dee0db01a910b3d81115af4e4e544744d7f1f45693f139f2e1be5
  TooriCoin: 0x7b6e3ca032f7140ddd85e1639a6b34de51e8fc3a
Saving successful migration to network...
  ... 0x07004adf1bfaca4bae8e4afa2cd080a47546f556a5486e9ee5809cd4b59c1c91
Saving artifacts...

```



# 【手順6】デプロイされたコントラクトの確認
* シェルで以下コマンドを実行

```bash
# truffle consoleの起動
$ truffle console --network ropsten
```

* truffleコンソールで以下コマンドを実行

### コントラクトのインスタンス化
```js
// コントラクトをインスタンス化します
truffle(ropsten)> contract = TooriCoin.at("<コントラクトのアドレス>")

// 実行結果（例）
[{...}] （contractが表示される。長いので省略）

```

* コントラクトの基礎情報を確認する

### コントラクトの基礎情報確認
```js
// コントラクトの名称を表示
truffle(ropsten)> contract.name()

// 実行結果（例）
'TooriCoin'

// Tokenの総額を表示
truffle(ropsten)> contract.totalSupply()

// 実行結果（例）
BigNumber { s: 1, e: 24, c: [ 10000000000 ] }
```

* 各アカウント毎の残高を表示する

### アカウント毎の残高確認（実行前）
```js
// 送信元のアカウントの残高を表示
truffle(ropsten)> contract.balanceOf("0xF847430749C90Ee9926369e96B8EA78E2A5887c8")

// 実行結果（例）
BigNumber { s: 1, e: 24, c: [ 10000000000 ] }

// 送信先のアカウントの残高を表示
truffle(ropsten)> contract.balanceOf("0x35ad22B8E0885619F8925e96AF1ec44B6AF85e35")

// 実行結果（例）
BigNumber { s: 1, e: 0, c: [ 0 ] }
```

* 送信元のアカウントから送信先のアカウント(**0x35ad22B8E0885619F8925e96AF1ec44B6AF85e35**)に対して、メッセージとTokenを送信してみます

### メッセージとTokenの送信
```js
// メッセージとTokenを送信
truffle(ropsten)> contract.thanks("0x35ad22B8E0885619F8925e96AF1ec44B6AF85e35", "Thanks on Ropsten!")

// 実行結果（例）
{ tx:
   '0x6644060cc70437ff70983bd172b6770483a6a1f958611758b98613ff0618c237',
  receipt:
   { blockHash:
      '0x694ad2daefa6280d43c48369a133dac07f7136cc7304032bbc749b598a040d70',
     blockNumber: 3526993,
     contractAddress: null,
     cumulativeGasUsed: 215765,
     from: '0xf847430749c90ee9926369e96b8ea78e2a5887c8',
     gasUsed: 73775,
     logs: [ [Object] ],
     logsBloom:
      '0x00000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000100000000000000000000000008000000000000000000080000000000000000000000000040000000001000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000400000000000000000000000000000000000100000000000000000000000000000000',
     status: '0x1',
     to: '0x7b6e3ca032f7140ddd85e1639a6b34de51e8fc3a',
     transactionHash:
      '0x6644060cc70437ff70983bd172b6770483a6a1f958611758b98613ff0618c237',
     transactionIndex: 1 },
  logs:
   [ { address: '0x7b6e3ca032f7140ddd85e1639a6b34de51e8fc3a',
       blockNumber: 3526993,
       transactionHash:
        '0x6644060cc70437ff70983bd172b6770483a6a1f958611758b98613ff0618c237',
       transactionIndex: 1,
       blockHash:
        '0x694ad2daefa6280d43c48369a133dac07f7136cc7304032bbc749b598a040d70',
       logIndex: 2,
       removed: false,
       event: 'Transfer',
       args: [Object] } ] }
```

* メッセージ送信後の各アカウント毎の残高を表示する

### アカウント毎の残高確認（実行後）
```js
// 送信元のアカウントの残高を表示
truffle(ropsten)> contract.balanceOf("0xF847430749C90Ee9926369e96B8EA78E2A5887c8")

// 実行結果（例）
BigNumber { s: 1, e: 23, c: [ 9999000000 ] }

// 送信先のアカウントの残高を表示
truffle(ropsten)> contract.balanceOf("0x35ad22B8E0885619F8925e96AF1ec44B6AF85e35")

// 実行結果（例）
BigNumber { s: 1, e: 20, c: [ 1000000 ] }
```

* メッセージ内容を表示してみます

### メッセージ内容の表示
```js
// メッセージ内容の表示
truffle(ropsten)> contract.thanksMessage("0x35ad22B8E0885619F8925e96AF1ec44B6AF85e35")

// 実行結果（例）
'Thanks on Ropsten!'
```

> **Note：**Tokenだけでなく、メッセージもEthereum上に記録されていることが確認できます

# 【手順7】EtherScanでの確認
### EtherScanって何？

> * 本番環境（Mainnet）とテスト環境（Ropsten/Kovan/Rinkeby）のトランザクション・アドレスの情報をブラウザベースで参照できるWebサービス

* ブラウザにて以下のURLにアクセス

> **EtherScan (Ropsten)**

> * https://ropsten.etherscan.io/token/[コントラクトのアドレス]


　　
> **Note：**コントラクトのアドレスには、migrateした際に表示されたコントラクトのアドレスを設定してください。

> 今回の例では、以下のURLにアクセスする

> * https://ropsten.etherscan.io/token/0x7b6e3ca032f7140ddd85e1639a6b34de51e8fc3a


* アクセスすると以下のような画面が表示される

![etherscan-01.PNG](https://qiita-image-store.s3.amazonaws.com/0/265386/a264041b-8819-b8f9-1966-e80c5aa2833c.png)


> **Note：**ヘッダ部分に、`TooriCoin`の表示があり、デプロイしたコントラクトであることが確認できる

* `Token Transfers`タブを見ると、先程送信したメッセージとTokenのトランザクションが表示される

* `TxHash`のリンクをクリックすると、以下の画面に遷移し、トランザクションの詳細を確認できる

![etherscan-02.PNG](https://qiita-image-store.s3.amazonaws.com/0/265386/819eb987-c1bd-9cd1-6f62-c523a61c14ce.png)


# まとめ
* ローカル環境上で作成したERC20のオリジナルトークンをテストネット（Ropsten）にデプロイすることができました！