Web3.0検証(3)-分散型アプリをTruffleで作ってみる

##### [前回] [Web3.0検証(2)-分散型アプリのアーキテクチャ](https://qiita.com/mingchun_zhao/items/00ade4202335ec7288af)

## はじめに

前回はWeb3.0の分散型アプリ(DApp)のアーキテクチャを確認しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/bb66d392-4f51-69e2-ca35-688492faa180.png)

ブロックチェーン技術を利用するため、新しい構成要素(Signer, Provider, Contract)が登場していました。

補足情報として、上記アーキテクチャ図では、[Ethereum(イーサリアム)](https://ethereum.org/ja/)をブロックチェーンのプラットフォームとして載せています。その他にも、[Polygon](https://polygon.technology/), [Solana](https://solana.com/ja)などがブロックチェーンのプラットフォームを提供しているようです(違いは今後検証予定です)。

## とにかくDAppを作ってみる

Signerによる署名認証、ブロックチェーンによるトランザクション(取引)、など新しい技術をもう少し深掘りしたい気持ちではありますが、イメージを掴むためとりあえずアプリ作ってみることに。

### DAppのチュートリアル

イーサリアムDAppチュートリアルの[ブログ](https://www.moesif.com/blog/blockchain/ethereum/Tutorial-for-building-Ethereum-Dapp-with-Integrated-Error-Monitoring/)を参考にしました。

[Truffle](https://trufflesuite.com/)フレームワークを使っていました。その理由を含め要点です:

- Truffleを使うと、DAppのUI作成にJavaScriptフレームワークであるReactを利用できる
    - SPA(Single Page App)作成にReactを使えるのはうれしい
- スマートコントラクト(Smart Contract)の設計が大事
    - スマートコントラクトとは、イーサリアム仮想マシン(EVM)上で実行されるブロックチェーン専用のプログラム
    - スマートコントラクトの定義は、[Solidity](https://solidity.readthedocs.io/en/v0.4.21/)と呼ばれる言語を用いる(イーサリアムの場合) 
    - スマートコントラクトの実行タイミングは、ブロックチェーンのトランザクション(取引)などがトリガーとなる
    - スマートコントラクトは、あらかじめ設定したルールに従って、一連の処理を自動実行する
    - スマートコントラクトの計算ロジックが複雑になるにつれ、ガス代(取引手数料)が高価になる
- Truffleを使うと、ローカルに開発・テスト環境を構築できる
    - イーサリアムのプラットフォームもテスト環境を提供してくれるようですが、開発はやはりローカル環境が便利でしょうか

## 早速DApp作成スタートです

### 環境

- CPU: Intel(R) Core(TM) 3.30GHz(4コア8スレッド)
- メモリ: 16 GB 
- Windows 10
- Visual Studio Code
- Node.js

## 作成手順

コマンドプロンプトでプロジェクトディレクトへ移動し、下記手順実行します。

### まず、Truffleフレームワークをインストール

- windows-build-toolsのインストール

```shell
npm install -g windows-build-tools

```
※ -gオプションにより、他のプロジェクトでもwindows-build-toolsを使用可能に

少し時間がかかり、以下表示されたらインストール完了です。

```
[##################] / reify:ajv: timing reifyNode:node_modules/windows-build-tools Completed in xxxms 
```

Ctrl+Cで終了します。

- Truffleフレームワークのインストール

```shell
npm install -g truffle
```

### つぎ、React Truffle Boxをインストールします

[React Truffle Box](https://trufflesuite.com/boxes/react/index.html)には、Reactアプリからスマートコントラクトを使用するために必要なものがすべて含まれているようです。

```shell
truffle.cmd unbox react
```

以下のように聞かれますが、Yを入れ、Enterします。

```
? Proceed anyway? 
```

少し時間がかかり、以下表示されたらインストール完了です。

```
Unbox successful, sweet!
```

#### プロジェクトのディレクトリ構成

以下のディレクトリ構成でファイル作成されました。

- src: Reactコード
- contracts: solidity言語で書かれたスマートコントラクト
- migrations: スマートコントラクトをイーサリアムネットワークにデプロイするためのスクリプト
- public: Reactアプリの一番最初に実行されるエントリポイントindex.html

### Truffleのdevelopコマンドを実行します

developコマンドは、ローカルにブロックチェーンの開発環境を作ってくれるようです。あと、コマンドラインからコントラクトの操作コマンドが実行できるようです、すごい!

```shell
truffle.cmd develop
```

すると、まず、イーサリアムノードのエミュレータが http://127.0.0.1:8545 に立ち上がりました。

```
Truffle Develop started at http://127.0.0.1:8545/
```

同時に、テストアカウントを10個作成してくれました(それぞれ100ETH(イーサ)含む。ETHはイーサリアムで使用する暗号資産となるイーサ(ether)の単位)

```
Accounts:
(0) 0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(1) 0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
... ...
(9) 0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Private Keys:
(0) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(1) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
... ...
(9) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Mnemonic: unusual print crouch route explain mystery tumble easily puzzle fiction swallow appear

⚠️  Important ⚠️  : This mnemonic was created for you by Truffle. It is not secure.
Ensure you do not use it on production blockchains, or else you risk losing funds.
```

実行終わったら、Truffle開発用のコマンドラインプロンプトが表示されます。

```
truffle(develop)> 
```

### スマートコントラクトをコンパイルします

Truffleコマンドプロンプトから、compileコマンドを実行します。

```shell
truffle(develop)> compile

Compiling your contracts...
===========================
> Compiling .\contracts\Migrations.sol
> Compiling .\contracts\SimpleStorage.sol
> Artifacts written to C:\study\web3\client\src\contracts
> Compiled successfully using:
   - solc: 0.5.16+commit.9c3226ce.Emscripten.clang
```

すると、solidityで書いたコントラクトがJSONアーティファクトにコンパイルされます(src\contractsディレクトリ)。
JSONファイルに、イーサリアム仮想マシン(Ethereum Virtual Machine=EVM)で実行されるバイトコードが含まれていました。

```json:SimpleStorage.json
{
  "contractName": "SimpleStorage",
  "abi": [
    {
      "constant": false,
      "inputs": [
        {
          "internalType": "uint256",
          "name": "x",
          "type": "uint256"
        }
      ],
      "name": "set",
      "outputs": [],
      "payable": false,
      "stateMutability": "nonpayable",
      "type": "function"
    },
    ... ...
  ],
  ... ...
  "bytecode": "0x608060405234801561001057600080fd5b5060c68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806360fe47b11460375780636d4ce63c146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050607e565b005b60686088565b6040518082815260200191505060405180910390f35b8060008190555050565b6000805490509056fea265627a7a72315820bce74ee723df40b6640564a6b934e56593692decf508b41377cfd818aba79e5464736f6c63430005100032",
  ... ...
}
```

### コントラクトをデプロイします

Truffleコマンドプロンプトから、migrateコマンドを実行します。
これで、コンパイルされたコントラクトが、イーサリアムネットワークのエミュレータにデプロイされるようです(truffle-config.jsを修正することで、実際のイーサリアムネットワークにもデプロイ可能とのこと、早くやってみたいー)

```shell
truffle(develop)> migrate
```

完了したら、以下表示されます。

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

### アプリを起動します

DAppが作成できたので、起動します。
別のWindowsコマンドプロンプトから(Truffleコマンドプロンプトではなく)、
プロジェクトディレクトリに移動し、以下実行します。

```shell
npm run start
```

すると、アプリ起動し、ブラウザから確認できました。やったー。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/b6077d8c-94dc-16b7-964a-4a66bf43f8f7.png)

## おわりに

ローカルに開発環境を構築し、シンプルなWeb3.0分散型アプリ(DApp)を作成・実行できました。
ローカル環境ですので、スマートコントラクトのコンパイルなど開発関連の検証しかできませんでした。
実際、イーサリアムのプラットフォームでSignerの署名認証なども検証してみたいですね。
お楽しみに。

##### [次回] [Web3.0検証(4)-分散型アプリをRemixで作ってみる](https://qiita.com/mingchun_zhao/items/145bd2c74001c287b17f)