仮想通貨初心者がSolidity + Reactのローカル環境を構築してみた

# はじめに

こんにちは。仮想通貨を全く使ったことがないまま、ブロックチェーン上のDApp開発にチャレンジするという無謀な取り組みをしています。
事前にCrypt Zombiesというイーサリアム上でゲームを開発しながらSolidityを学ぶコースを受けました。その後ローカル環境を構築しようとTruffle Boxesからいい感じのBoxを使ってみたのですが、デモを動かせるようになるまでにかなり躓いたので、備忘録として本記事を書きました。

同じ箇所で躓いた人向けに、手順とエラー文を載せています。お急ぎの方は「手順まとめ」だけ読んでください。

## 用語
ここまで学習して掴んだ雰囲気で、ざっくりと説明しています。ちゃんとした定義からは外れている部分もあります。詳しく知りたい場合はググってください。
- イーサリアム
仮想通貨の一種であり、ブロックチェーンのプラットフォームです。こちらの「メインネット」にデプロイすると、DAppを一般公開できます。また、「テストネット」というテスト環境も複数あるようです。メインネットで処理を行うと、ガス代と呼ばれる手数料が発生します。
- DApp
イーサリアム上で動くアプリ
- Solidity
イーサリアム上で動かすDAppの開発言語
- Truffle
Solidityのフレームワーク
- Ganache
ローカル環境にブロックチェーンを構築してくれるツール
- MetaMask
仮想通貨の口座。ガス代を支払ったりするのに使います。

## 前提
- Windows11
- WSL2 v1.2.5.0
- Ubuntu 22.04.1
- Node v18.14.0
- npm v9.3.1
- Truffle v5.8.4
- Ganache v7.8.0
- Solidity v0.5.16
- Web3.js v1.8.2
- MetaMask Chrome拡張機能 v10.29.0

# 環境構築の手順

:::note warn
以前Reactのアプリを開発したことがあるので、node.js等はインストール済でした。他にもnpmやReact関係のエラーがあるかもしれませんが、本記事では扱っていません。
:::

## 1. `Truffle Boxes`から`React Truffle Box`を選ぶ
[Truffle Boxes](https://trufflesuite.com/boxes/)には手軽にSolidityの環境構築できるBoxが公開されています。今回は[React Truffle Box](https://trufflesuite.com/boxes/react/)を選びました。

## 2. `React Truffle Box`のInstallationに従うも画面が表示されない
新しいプロジェクトのフォルダを作成し、Truffleをインストールし、Boxを開けます。
```bash
プロジェクトルート$ npm install -g truffle
プロジェクトルート$ truffle unbox react
```
devサーバを起動します。
```bash
プロジェクトルート$ cd client
プロジェクトルート/client$ npm start
```
ターミナルになにやらエラーが表示されています。
```bash
Module not found: Error: Can't resolve '../../contracts/SimpleStorage.json' in 'プロジェクトルート/client/src/contexts/EthContext'
```

## 3. ターミナルのエラーを解消
Crypt Zombiesをやっていたおかげでピンときました。
コンパイルして、マイグレーションファイルを作成します。
```bash
プロジェクトルート/client$ cd ../truffle/
プロジェクトルート/truffle$ truffle compile
```
そしてもう一度devサーバを起動します。
```bash
プロジェクトルート$ cd ../client
プロジェクトルート/client$ npm start
```
ターミナルにURLが表示されるので、ブラウザで開いてみます。
…何も表示されません:disappointed_relieved:
```bash
<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost:8080/
```
## 4. ブラウザのコンソールに出たエラーに対処
ブランクの画面を開発ツールで確認します。
コンソールに次のようなエラーがでていました。
```
web3.min.js:2 WebSocket connection to 'ws://localhost:8545/' failed: 
```
このポート番号をググったところMetaMaskというサービスのようです。
ここで[React Truffle BoxのIssue](https://github.com/truffle-box/react-box/issues/199)を確認してみました。やはりMetaMaskをインストールしなければならないようです。

:::note info
ここではMetaMaskをインストールする必要はありません。
画面は表示されませんが、このまま読み進めてください。
:::
ちょうどChromeを使っていたので、Chromeの拡張機能でインストールし、ウォレットを作成してみました。

## 5. 表示された画面のPreparationに従うもデモが表示されない
ようやく画面のコンポーネントが表示されるようになりました。
Ganacheをインストールし、起動します。
```bash
プロジェクトルート/truffle$ npm install -g ganache
プロジェクトルート/truffle$ ganache
```
ここで画面には
> From the list of generated private keys, import the first one to MetaMask.

と書かれていますが、よく分からず無視しました。後で分かります。

Ganacheは起動したままで、別のターミナルを開いてGanacheにデプロイします。
```bash
プロジェクトルート/truffle$ truffle migrate --network development
```
ターミナルにエラーが出ました。
```
Error: You must specify a network_id in your 'development' configuration in order to use this network.
```

## 6. `truffle-config.js`でネットワーク設定をしようとする
ここでもCrypto Zombiesのおかげでピンときました。
`プロジェクトルート/truffle/truffle-config.js`のファイルを開きます。
言われた通り、`development`のコメントを外します。
[![Image from Gyazo](https://i.gyazo.com/cf594c5e85773687a138a8d7316d0d19.png)](https://gyazo.com/cf594c5e85773687a138a8d7316d0d19)

それでもまだエラーは出たままです。
`truffle-config.js`のコメントを読んでみたところ、MetaMaskのウォレットのニーモニックを登録しないといけないようです。
## 7. Truffle Dashboardを使う
更にコメントを読み進めると、`.env`を作らずともTruffle Dashboardというサービスで管理できるようです。
今どきキーボードのタイピング内容もハッキングされてるかもしれず、おいそれとパスコードを打ちたくないので、こちらを使います。

[Truffle Dashboard](https://trufflesuite.com/docs/truffle/how-to/use-the-truffle-dashboard/)のドキュメントを参考に、Truffle Dashboardを開きます。
```bash
プロジェクトルート$ truffle dashboard
```
すると、ブラウザでダッシュボードが起動します。

:::note warn
デフォルトのブラウザがChromeでない場合は、Chromeで開きなおしてください。
:::
ダッシュボードの左下の「Click To Connect」をクリックすると、MetaMaskが反応するので、画面の指示に従って操作します。

:::note
ここでもMetaMaskの部分は読み飛ばしてください。
:::
## 8. 依然としてデモは表示されないので、MetaMaskのネットワーク設定をする
まだデモは表示されません。
そう、MetaMaskのウォレットを作ったときに、イーサリアムのメインネットに作成していたのです:sob:

:::note
お待たせしました。
MetaMaskをインストールしてください。
:::

ウォレットの作成は、「アカウントのインポート」から行います。
Ganacheを起動したときに秘密鍵が10個ほど生成されています。
それらの先頭のものを設定します。
[![Image from Gyazo](https://i.gyazo.com/e57b384c588fe21b866d661ef8b20706.png)](https://gyazo.com/e57b384c588fe21b866d661ef8b20706)

また、ネットワークには`localhost`を選択します。
一覧に出てこない場合は「ネットワークを手動で追加」します。
チェーンIDもGanache起動時に表示されています。
[![Image from Gyazo](https://i.gyazo.com/7195d9139cda6a81b8707c6196c3f0e7.png)](https://gyazo.com/7195d9139cda6a81b8707c6196c3f0e7)

Truffle Dashboardで、「Click To Connect」をクリックし、MetaMaskの指示に従ってウォレットを設定します。

## 9. デモは表示されたが、writeのガス代が払えない

今度は最初にMetaMaskをインストールした時に作ったアカウントに紐付いてしまい、残高が0ETHなのでガス代が払えず、エラーになってしまいました。
前章でGanacheの秘密鍵からウォレットを作成していれば、このエラーは出ません。

すでに誤ったアカウントを設定してしまっている場合、ダッシュボードでDisconnectしてもまた同じアカウントに接続するだけです。
アカウントを変えるには、MetaMaskから設定します。アカウントを開いて「接続済みのサイト」を開きます。
「接続解除」リンクで接続を切り、再度ダッシュボードから接続します。

## 10. 成功！
ついに、デモを動かすことができました。
[![Image from Gyazo](https://i.gyazo.com/29dfcf9cec8640eb2275f38ba3a41a5d.png)](https://gyazo.com/29dfcf9cec8640eb2275f38ba3a41a5d)

Ganacheはテスト環境なので、トランザクションのガス代はかかりません。
デプロイ時にはガス代を取られました。
ただし、Ganache起動時に1000ETH用意してくれるので、実際にお金がかかったわけではありません。

# 手順まとめ
1. プロジェクトのフォルダを作成する。  
2. TruffleとGanacheをインストールする。 
   ```bash
   プロジェクトルート$ npm install -g truffle ganache
   ```
3. ボックスを開く。  
   ```bash
   プロジェクトルート$ truffle unbox react
   ```
4. Ganacheを起動する。
   ```bash
   プロジェクトルート$ cd ../truffle/
   プロジェクトルート/truffle$ ganache
   ```
5. MetaMaskをインストールする。
Ganache起動時に表示されたPrivate Keys(0)でアカウントをインポートし、
ローカルホストのネットワークにGanache起動時に表示されたChain Idを設定する。

6. `プロジェクトルート/truffle/truffle-config.js`のファイルを開き、`development`のコメントを外す。
6. デプロイする。  
   ```bash
   プロジェクトルート/truffle$ truffle migrate --network development
   ```
8. Truffle Dashboardを開く。 
   ```bash
   プロジェクトルート$ truffle dashboard
   ```
9. ダッシュボード画面の左下にある「Click To Connect」から、MetaMaskのウォレットに紐づける。
9. devサーバを起動する。
   ```bash
   プロジェクトルート$ cd client
   プロジェクトルート/client$ npm start
   ```
11. `http://localhost:8080/`をブラウザで開き、「See it in action」でデモを実行する。

# 最後に
イーサリアムではデータを変更するようなトランザクションにはガス代がかかりますが、Loomを使うとガス代がかからないそうです。私はゲームを作りたいだけなので、Loomにデプロイしようと思っています。

# 参考文献
[Truffle Boxes](https://trufflesuite.com/boxes/)
[React Truffle Box](https://trufflesuite.com/boxes/react/)
[React Truffle BoxのIssue](https://github.com/truffle-box/react-box/issues/199)
[Truffle Dashboard](https://trufflesuite.com/docs/truffle/how-to/use-the-truffle-dashboard/)
[簡単！MetaMaskとGanacheを連動させる為の3ステップ](https://metaverse-info.tech/development/use-ganache-with-metamask/)