Truffle console で送金受取を行う（Truffle 5対応）

truffle console から色々コントラクトを操作したかったんだけど、ネットに転がってる情報とちょっと違っていたのでメモ。Turffle 4.xとちょっと変わったみたいです。

# 目標

コントラクトアカウントをローカル環境にデプロイし、truffleコンソール上でEOA（外部アカウント）に独自トークンを送金するのを目的とします！

Webフロントエンドの実装やテストネット、メインネットへのデプロイは今回は行いません！またそのうち‥

# コントラクトの準備

まずはコントラクトを用意しましょう！

```sh
$ npm install -g truffle # まだインストールしていなければ
$ mkdir test-contract
$ cd test-contract
$ truffle init
```

これでプロジェクトができますね！
今回は送金するので `transfer` メソッドが実装されているコントラクトであれば十分です。ただ自分で実装するのは面倒なので、OpenZeppelinを使いERC20に準拠させます。[ここ](https://qiita.com/toshiaki_takase/items/75fe140f78e03aa5f732)の素晴らしい記事を参考にサクっとやりましょう。

OpenZeppelinを導入した上でContractファイルを作っていきます。

```sh
$ npm init -y
$ npm install -E openzeppelin-solidity
$ touch contracts/TestContract.sol
```

`TestContract.sol` の中身を編集していきます。ほとんど[ここ](https://qiita.com/toshiaki_takase/items/75fe140f78e03aa5f732)のコピペです‥

``` js
pragma solidity ^0.5.0;
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";

contract TestContract is ERC20, ERC20Detailed {

    string private _name = "TestContract";
    string private _symbol = "TC";
    uint8 private _decimals = 18;

    address account = msg.sender;
    uint value = 100000000000000000000;

    constructor() ERC20Detailed( _name, _symbol, _decimals) public {
        _mint(account, value);
    }
}
```

OpenZeppelin も `２．０` からは上記のようにimportする内容が細かくなったようです。古い記事のコピペではコンパイルが通らないので注意！

# ローカル環境の準備

ローカル環境を整えていきましょう。今回はお手軽にganacheで環境構築していきます。

[公式ホームページ](https://www.trufflesuite.com/ganache) からビルド済みのものを取得するか、[自前でビルド](https://github.com/trufflesuite/ganache)します。ビルド済みのもので事足りるのですが、今回は自分でビルドしてみます。

``` bash
# 作業用ディレクトリとは異なる場所で作業すること
$ git clone https://github.com/trufflesuite/ganache.git
$ cd ganache
$ npm install
$ npm start
```

`npm start` でElectronが立ち上がります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142812/a13ae719-4e81-ef2e-f3ea-3fd6f029c018.png)

`QUICKSTART` を選ぶといくかのEOAのウォレットが生成され、ノードが立ち上がります。ここに先程のContractをデプロイしていきます。

# デプロイの準備

truffleの作業環境で今度はデプロイ用のコードを書いていきます。 `./migrations/` にはすでに `1_initial_migration.js` というファイルがあると思いますが、 `2_deploy_contract.js` というファイルを新規作成し、以下のように書いてきましょう。

``` js
var TestContract = artifacts.require("./TestContract.sol");
  
module.exports = function(deployer) {
    deployer.deploy(TestContract);
};
```

そして環境設定を行います。 プロジェクトルートの`truffle-config.js` ganacheの情報をもとに編集します。私の手元だと下記のように表示されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142812/b246ed95-594a-4c24-9c3f-9be5278e1585.png)

したがってtruffle-config.jsの `host`, `port`, `network_id` は以下のようになります。`gas` は大きすぎず小さすぎない適当な値を入力します。小さすぎるとコントラクトを実行できず、大きすぎると手持ちのEtherで足りなくなってしまうからです。


``` diff
module.exports = {
  /* 中略 */
  networks: {
+   local: {
+     host:"127.0.0.1",
+     port: 7545,
+     network_id: "5777",
+     gas: 2000000
+   }
  }
};
```

# デプロイ

そしてコンパイルとマイグレーションを行い、Contractをローカルにデプロイします。

``` sh
$ truffle compile
$ truffle migrate --network local
```

デプロイが終わるといくらgasがかかったかが表示されます。

```
Summary
=======
> Total deployments:   2
> Final cost:          0.0333941 ETH
```

# truffle console での送金

さてここでContractを送金してみましょう。以下のように入力してコンソールに入ります。

``` js
$ truffle console --network local
truffle(local)> 　# 入った
```

コンソールから出るには `.exit` と入力します。

さて、先程のContractのアドレスを調べてみましょう。

``` js
truffle(local)> TestContract.address
'0x88E2a079DaCABaB64f6901aF543f052AAf1dB66f'
```

と出力されますね。では、今回のトークンの総供給量を出してみましょう。

``` js
truffle(local)> const tc = await TestContract.at(TestContract.address).then(_ => _)
undefined
truffle(local)> tc.totalSupply().then(ts => ts.toString())
'100000000000000000000'
```

このあたりが古い記事（Truffle 4.x以前）だと同期処理になっているのを見かけます。 `Contract#at()` などはPromiseを返すようになったため、上記のように対応しましょう。

ではいよいよ送金をしてみましょう。Ganacheに表示されている適当なアドレスに送金してみます。 `dest` にGanacheに表示されているEOAのアドレスを格納します。

お好きなものを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142812/5738ada4-07dd-6a6a-acb1-528b38a56bbf.png)


``` js
truffle(local)> const dest = "0x163c07CB14603bcBb867f2e95AE2ae965d824ebd"
undefined
truffle(local)> tc.transfer(dest, 10)
{ tx:
   '0x282c11cfbeb31df6483e65cfeda8d9d40309af54627ac2cd427ab4c438ebd2c8',
  (中略）
     from: '0xfdb1c9353c4b325bb3c609bbb70a60fc26eb9c76',
     to: '0x88e2a079dacabab64f6901af543f052aaf1db66f',
     gasUsed: 51368,
  (後略）

```

トランザクションや送金先アドレス、使用したGaｓなどが表示されました。ここでは `transfer` 関数で10トークンを送っています。残高を表示してみましょう。

``` js
truffle(local)> const balance = await TestContract.at(TestContract.address).then((address) => address.balanceOf(dest))
truffle(local)> balance.toNumber()
10
```

これで指定のEOAにトークンが送金されたことがわかります。これで送金は完了です！