ブロックチェーン開発によるローカル環境構築体験

この記事は[NTTコムウェア AdventCalendar 2023](https://qiita.com/advent-calendar/2023/nttcomware) 25日目の記事です。

# はじめに
NTTコムウェアの管です！
最新技術に熱心で、システム設計から開発・運用までの経験を持つ、６年目のアプリ開発エンジニアです。現在、Web3.0技術検証ワーキンググループのリーダーを務めています。

# 記事向け対象
本記事は、ブロックチェーンに興味を持つエンジニアや、ブロックチェーンの勉強中の方を対象としています。

# きっかけ
[Pythonでプライベートブロックチェーンネットワークを作ってみた](https://qiita.com/comware_guan/items/aef6d29b9f6a52056c03)という記事では、ブロックチェーンネットワークの構築方法が手動で行われていましたが、手動では素早く開発することができません。そのため、迅速に構築できるツールはありませんかと考え、[<font color="#38d9d9"> **TRUFFLE** </font>](https://trufflesuite.com/docs/truffle/)と[<font color="#FFCC33"> **Ganache** </font>](https://trufflesuite.com/docs/ganache/)というWeb3.0開発ツールを使用してローカル環境を構築しました。さらに、よく使っている[<font color="#FFD700"> **Hardhat** </font>](https://hardhat.org/docs)と[<font color="#0099FF"> **Remix IDE** </font>](https://remix-project.org/)を使用して、[<font color="#FFCC33"> **Ganache** </font>](https://trufflesuite.com/docs/ganache/)と接続してみました。
今回は上記の環境を整えた体験を共有させていただきます。

# TRUFFLEとは
TRUFFLEは、Ethereumのスマートコントラクト開発をサポートするフレームワークです。TRUFFLEを使用すると、スマートコントラクトの開発、テスト、デプロイが簡素化されます。

https://trufflesuite.com/docs/truffle/

## TRUFFLE 主な機能
- スマートコントラクトの作成
    - Solidityなどのスマートコントラクト言語を使用して、スマートコントラクトを作成することができます。また、スマートコントラクトのテンプレートも提供されており、効率的な開発を支援します。
- テストの自動化
    - JavaScriptを使用してスマートコントラクトのテストを作成できます。これにより、スマートコントラクトの機能や安全性を確認するためのテストを自動化できます。
- デプロイメント
    - 開発、テスト、本番などの異なる環境に対応しています。デプロイメントファイルを設定することで、異なるネットワークにスマートコントラクトをデプロイすることができます。
- モジュールとライブラリのサポート
    - モジュールやライブラリを使用してスマートコントラクトを構築することができます。これにより、再利用可能なコードの作成や、効率的かつ保守しやすいスマートコントラクトの開発が可能になります。
- ブロックチェーンのエミュレーション
    - Ganacheと呼ばれるブロックチェーンエミュレータを提供しています。Ganacheを使用することで、開発中にローカルでブロックチェーンをエミュレートし、スマートコントラクトをテストすることができます。

# Ganacheとは
Ganacheは、Ethereumの開発者向けのブロックチェーンエミュレータです。Ganacheを使用すると、ローカル環境で独自のプライベートなEthereumネットワークを作成し、スマートコントラクトの開発やテストを行うことができます。

https://trufflesuite.com/ganache/

## Ganache UI説明
Ganacheの起動画面から「QUICKSTART」をクリックすると、以下の画面が表示され、ローカルブロックネットワークが立ち上がることがわかりました。

![Ganache1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/4bd6f0b7-b895-8f52-99df-45582ff888f3.png)

# Hardhatとは
Hardhatは、Ethereumのスマートコントラクト開発を支援する開発ツールです。Hardhatを使用すると、スマートコントラクトのコンパイル、テスト、デプロイを簡単に行うことができます。

https://hardhat.org/docs

## Hardhat 主な機能

- スマートコントラクトのコンパイル
    - Solidityなどのスマートコントラクト言語を使用して、スマートコントラクトをコンパイルすることができます。コンパイルされたスマートコントラクトは、Ethereumブロックチェーン上で実行されます。
- ローカル開発環境の提供
    - 開発者がローカルでスマートコントラクトを開発するための環境を提供します。開発者は、Hardhatが提供するローカルノードを使用して、スマートコントラクトのテストやデバッグを行うことができます。
- テストフレームワークの統合
    - スマートコントラクトのテストを簡単に作成できるテストフレームワークとの統合をサポートしています。開発者は、テストを作成してスマートコントラクトの機能や安全性を確認することができます。
- スクリプトの実行
    - JavaScriptやTypeScriptなどのスクリプトを実行することができます。開発者は、スクリプトを使用してスマートコントラクトのデプロイや他のタスクを自動化することができます。
- メインネットワークとの統合
    - 実際のEthereumメインネットワークとの統合もサポートしています。開発者は、Hardhatを使用してスマートコントラクトをメインネットワークにデプロイし、実際のトランザクションを行うことができます。


# Remix IDEとは
ブラウザのウォレットと接続することで、テストネットワークにコントラクトをデプロイすることができます。簡単にUIでスマートコントラクトのテストを実施することができます。
また、OnlineIDEを使用する際には、GitHubと連携してリソースの管理が簡単です。

https://remix-project.org/

# 検証バージョン
- npm: v9.6.6
- Truffle v5.11.5 (core: 5.11.5)
- Ganache v7.9.1
- Solidity v0.5.16 (solc-js)
- Node v18.12.1
- Web3.js v1.10.0
- hardhat v2.18.1

# TRUFFLEとGanacheの環境設定について
ローカル構築イメージは以下の通りです。

![TRUFFLEとGanache (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/313c37fa-f24c-5382-c0ea-17602d196629.png)

### TRUFFLEとGanacheインストール

#### TRUFFLEインストール

~~~bash
npm install -g truffle ganache
~~~

#### Ganache UIインストール
オープンソースなので、自由にインストールすることができます。
https://github.com/trufflesuite/ganache-ui/releases

### TRUFFLEプロジェクト準備

#### プロジェクト作成

~~~bash
truffle init
~~~

↑↑↑のコメントで、以下のプロジェクトが自動的に生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/85f59129-778e-3efd-60bf-605284059d34.png)

#### コントラクトファイル作成

~~~bash
$ truffle create contract CryptoCurrency
~~~

↑↑↑のコメントは、以下の<font color="Green">CryptoCurrency.sol</font>を自動的に生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/cf0cc0a1-9352-4c6a-d9b2-8eccdf22a355.png)

#### デプロイ用jsファイル作成

~~~bash
$ truffle create migration deploy_crypto_currency
~~~
↑↑↑のコメントは、以下の<font color="Green">xxxx_deploy_crypto_currency.js</font>を自動的に生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/39c5dc77-71c1-023b-fe66-4ba062ac8875.png)

#### <font color="Green">truffle-config.js</font>編集

Ganacheのネットワークにデプロイできるように、以下のようにネットワークを設定します。

~~~javascript
  networks: {
    local: {
      host: "127.0.0.1",     // Localhost (default: none)
      port: 7545,            // Standard Ethereum port (default: none)
      network_id: "5777",       // Any network (default: none)
    },
  },
~~~
:::note
複数のネットワークを設定できるため、ローカルからテストネットワークにデプロイすることができます。
:::


また、スマートコントラクトのバージョンと合わせて、コンパイルバージョンを指定します。
今回は[0.8.0]を使用して作成したため、以下のように書きました。

~~~sol
pragma solidity ^0.8.0;
~~~

~~~javascript
compilers: {
    solc: {
      version: "0.8.0",      // Fetch exact version from solc-bin (default: truffle's version)
    }
  },
~~~

<details><summary> 操作ログ</summary>

~~~bash
$ truffle init

Starting init...
================

> Copying project files to C:\XXXXX\ganachetest

Init successful, sweet!

Try our scaffold commands to get started:
  $ truffle create contract YourContractName # scaffold a contract
  $ truffle create test YourTestName         # scaffold a test

http://trufflesuite.com/docs
~~~

</details>


### Ganache準備
|                           ![Ganache起動画面][Ganache1]                           |                                  ![Ganache QUICKSTART][Ganache2]                                   |
| :----------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------: |
| Ganache起動画面 | （左）QUICKSTARTボタンをクリックすると、一時的にローカルブロックネットワークが立ち上がります |

[Ganache1]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/fafe5478-d447-eb9a-c76b-0dadfb613233.png (Ganache起動画面)

[Ganache2]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/5b9c9233-d6fb-8631-c3df-fcf52b445c30.png (Ganache QUICKSTART)

### TRUFFLEとGanacheの接続
|                           ![Ganacheにプロジェクトにインポートする][Ganache3]                           |                                  ![TRUFFLEプロジェクト][Ganache4]                                   |
| :----------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------: |
| [CONTRACTS]タグから、Ganacheにプロジェクトにインポートする画面に遷移します | truffle-config.jsファイルをインストールします |

[Ganache3]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/7710cbc0-f23a-f047-0314-fdf4a7b2ecd1.png (Ganacheにプロジェクトにインポートする)

[Ganache4]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/5651ede1-49e7-d26d-edf3-ea8246754b42.png (TRUFFLEプロジェクト)

インポートした後、以下のようにプロジェクト情報を表示しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/642f7da3-2d03-6b8c-5591-9ae6dc4d2a9c.png)

また、スマートコントラクトをコンパイルしていないので、何も表示していませんね。

### 動作確認

コンパイルしてみます。

~~~bash
$ truffle compile

Compiling your contracts...
===========================
> Compiling .\contracts\CryptoCurrency.sol
> Artifacts written to C:\XXXXX\ganachetest\build\contracts
> Compiled successfully using:
   - solc: 0.8.0+commit.c7dfd78e.Emscripten.clang
~~~

お～、Ganache側で、スマートコントラクトは識別されましたが、デプロイされていないことがわかりました。

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/97d9db9a-75c4-3435-ffaf-2adadfb3c7f3.png)


デプロイしますよ～～

~~~bash
$ truffle deploy network --local

Compiling your contracts...
===========================
> Compiling .\contracts\CryptoCurrency.sol
> Artifacts written to C:\XXXXX\ganachetest\build\contracts
> Compiled successfully using:
   - solc: 0.8.0+commit.c7dfd78e.Emscripten.clang


Starting migrations...
======================
> Network name:    'ganache'
> Network id:      5777
> Block gas limit: 6721975 (0x6691b7)


1702346541_deploy_crypto_currency.js
====================================

   Deploying 'CryptoCurrency'
   --------------------------
   > transaction hash:    0x3e27ed73bd1ed7583930205942723a1d33d02703246d2903faaf6c761a1d445b
   > Blocks: 0            Seconds: 0
   > contract address:    0xcf567AE388bc76Ee6c7C71fbbF7FB190D1bDAf40
   > block number:        1
   > block timestamp:     1702349903
   > account:             0x9156D210fb055439C8fdEa9CDBAEB60b7f84d68E
   > balance:             99.99863788375
   > gas used:            403590 (0x62886)
   > gas price:           3.375 gwei
   > value sent:          0 ETH
   > total cost:          0.00136211625 ETH

   > Saving artifacts
   -------------------------------------
   > Total cost:       0.00136211625 ETH

Summary
=======
> Total deployments:   1
> Final cost:          0.00136211625 ETH

~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/d3d6b864-10a7-dbab-63c8-b50990f12545.png)

ローカルブロックチェーンにデプロイできたことを検証しました。

# HardhatとGanacheの環境設定について
以下はローカル構築イメージです。

![Hardhat (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/7e8e25aa-489c-c9af-24a0-4dd9faa23acc.png)


### Hardhatプロジェクト作成

~~~bash
$ npm init --yes
Wrote to C:\XXXXX\hardhattest\package.json:

{
  "name": "hardhattest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
~~~
以下は作成した結果です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/6673a855-03c3-80ad-25a4-5643f851b4c6.png)

#### Hardhatインストール
~~~bash
$ npm install --save-dev hardhat

added 311 packages, and audited 312 packages in 47s

69 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
~~~
パッケージのバージョン管理ファイルを作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/5150897b-36ec-c66f-fe3a-37b3641f0a21.png)

<details><summary>他のパッケージインストール</summary>

~~~bash
$ npm i @openzeppelin/contracts @nomicfoundation/hardhat-toolbox dotenv

added 259 packages, changed 2 packages, and audited 571 packages in 28s

93 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

~~~

</details>

### Hardhatプロジェクト立ち上げ

~~~bash
$ npx hardhat init
888    888                      888 888               888
888    888                      888 888               888
888    888                      888 888               888
8888888888  8888b.  888d888 .d88888 88888b.   8888b.  888888
888    888     "88b 888P"  d88" 888 888 "88b     "88b 888
888    888 .d888888 888    888  888 888  888 .d888888 888
888    888 888  888 888    Y88b 888 888  888 888  888 Y88b.
888    888 "Y888888 888     "Y88888 888  888 "Y888888  "Y888

Welcome to Hardhat v2.19.2

√ What do you want to do? · Create a JavaScript project
√ Hardhat project root: · C:\XXXX\hardhattest
√ Do you want to add a .gitignore? (Y/n) · n

You need to install these dependencies to run the sample project:
  npm install --save-dev "hardhat@^2.19.2" "@nomicfoundation/hardhat-toolbox@^4.0.0"

Project created

See the README.md file for some example tasks you can run

Give Hardhat a star on Github if you're enjoying it!

     https://github.com/NomicFoundation/hardhat

~~~

↑↑↑のコメントで、以下のようにディレクトリを拡張しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/19a6f130-9c03-0b0e-c74d-baa90ff2fb83.png)

### MetaMaskの設定
以下の手順でネットワークを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/aadf5ad8-2075-7bf4-377f-840adeb71452.png)

:::note warn
警告
チェーンIDを注意してください
:::

また、デプロイウォレット追加しなければなりません。
今回はローカル立ち上げたブロックチェーンネットワークを利用するため、MetaMaskにGanache側のアカウントをインポートしました。

|                           ![Metamaskアカウントインポート][Metamask]                           |                                  <img width="1250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/a31d84ec-cd2b-c0d3-913e-6e6dc3e453a5.png">                                  |
| :----------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------: |
| 右側のアカウントを使用して、100 ETHをインポートできました。 | 「0xBD1104ffaF5d522B9BaDB3c33bAA8C55DD6836C5BALANCE」の残高を確認してください |

[Metamask]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/0743017e-6062-68cd-4ab2-a947044482ef.png (Metamaskアカウントインポート)

[Ganache5]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/a31d84ec-cd2b-c0d3-913e-6e6dc3e453a5.png (インポートウォレット)


### Hardhatネットワーク設定
[<font color="#FFD700"> **hardhat.config.js** </font>]に、以下のようにネットワークを設定しました。

~~~bash
  networks: {
    ganache: {
      url: "http://127.0.0.1:7545",
      chainId: 1337,
      accounts: ['0xbcd312f2cffad9f96ba3f7e4fd7752cb8e854b578e1a071527385168bb50f5e0']
    }
  }
~~~

:::note warn
警告
accountsの値はウォレットのプライベートキーです。
:::

### 動作確認
上記のプロジェクトをデプロイしてみました。

~~~bash
$ npx hardhat compile
Compiled 2 Solidity files successfully (evm target: paris).
$ npx hardhat run scripts/deploy_crpyto.js --network ganache
CryptoCurrencyStore deployed to: 0xB4B7E9AC1432c333457b97f5E71575900c69af2C
~~~

<font color="#FFCC33"> **Ganache** </font>のスマートコントラクトが作成済みであることを確認しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/56cc3149-a7e0-609d-2bc6-d861f1d2957a.png)

ただし、プロジェクト全体のスマートコントラクトが表示されないため、HardhatとGanacheを使用したプロジェクト管理は不便であることがわかりました。

![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/9efacac0-95e3-491a-0335-9b6bc849a03b.png)


# RemixとGanacheの環境設定について

### Remixのネットワーク設定

|                           ![RemixでGanache選択する][Remix network]                           |                                  ![Providerを改めて設定する][Ganache6]                                   |
| :----------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------: |
| デプロイUIからDev-Ganache Providerを選択します | Ganache JSON-RPCのポートを修正します |

[Remix network]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/af591a18-512b-cd88-8f59-450a47d4c1ca.png (RemixでGanache選択する)

[Ganache6]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/2987b1b2-b980-a40f-3404-a46f3890bd9b.png (Providerを改めて設定する)

接続できた場合、Ganache側生成されたアカウントを取得できます。
|                           ![Remix側のアカウント][Remix側のアカウント]                           |                           ![Ganacheの生成アカウントリスト][Ganache7]                                   |
| :----------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------: |
| 左のGanacheウォレットのインポートされました | 右と一致していることを確認できます |

[Remix側のアカウント]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/4a57f54d-63a5-85da-e772-8a1a1641fc42.png (Remix側のアカウント)

[Ganache7]: https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/31c37924-bc01-84b0-2cf0-b26fe78b823a.png (Ganacheの生成アカウントリスト)

### 動作確認

Remix側のアカウントのETHが減少したため、Deployが成功しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/c638c8c2-77c9-6a4a-4527-b079d60081e5.png)

Ganache側でもトランザクションが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626247/797e9eec-fcb8-8524-7b64-9c16e3b43265.png)

# なぜローカル環境を構築するのか
今回は、スマートコントラクトの開発にはローカル環境を構築しました。ただし、スマートコントラクトの動作確認はローカル環境でしか行えないわけではありません。各チェーンが提供するテストネットワークを利用して同様に動作確認できますが、デプロイタイミングによってGAS代が変わります。GASは開発者自身がマイニングする必要があり、マイニング制限もかけられています。また、テストネットワークではデバッグが難しい場合もあります。
そのため、プロジェクト納期にある程度の影響を与えると考えられます。ローカル環境を使用して開発することが、最も効率的だと考えられます。

# まとめ
本記事は、
Web3.0開発においてはTRUFFLEやGanacheといった開発ツールが重要であり、ローカル環境の構築やスマートコントラクトの開発・デプロイ手順について説明しました。さらに、よく使っている Hardhat と Remix IDE を使用して、 Ganache と接続手順を紹介しました。また、プロジェクトの納期に影響を与える可能性があるため、効率的な開発が求められていることを話しました。

以上

※本稿に記載されている会社名、製品名、サービス名は、各社の商標または登録商標です。