老技術者がローカルにブロックチェーンを立てて遊んでみた（2023年版　Windows11+WSL2+Hyperledger Besu）

 ## はじめに
ブロックチェーンを基礎から教えてほしいという要請が社内のみならずエージェントを通じて他社様から舞い込むことが多くなった．
もっと若い人に聞いたほうがいいのでは？と駄々をこねると「若い人はあなたと違って忙しいのだ」などと言う失礼な人はさすがにいないのだが，多分そうなのであろう．
P2PからはじめてコンセンサスアルゴリズムだERC20だと進めていっても生徒さんはおそらく真実とは全く違うものを思い浮かべているだろうという危惧が教えだした当初からあり，実際その通りであったという苦い経験を経て，やはり「作って学ぶ」じゃないとこの世界ダメなのだと．
そして昨年こんな記事を書いたのだった．
https://qiita.com/oldEng/items/557ceb29a7849e92b5f2
viewは1000を超えたもののいっこうに「いいね」がつかないので友人にこの通りにやってもらうとあっちこっちハマりどころがあるのだと．そういうことね，と最近買ったWindows11マシンで最新版に改訂することにした次第．

## 1. Windows11でUbuntuを使う
まずはWindows11のターミナルで何とかしようなどとは思わずにWSL2を使ってUbuntuを立ち上げよう．
(1) スタートボタン右クリックからターミナル（管理者）を起動
![2023-02-10_20h01_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/ccdb1c1b-ec17-cf51-1b83-9b5f134c152e.png)


(2) WSL2をインストール
 ```
   wsl --install
 ```
(3) ubuntuでusernameとpasswordを設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/327ca8c4-9bf8-2491-f6ce-1772b57d34bc.png)

うまくいかないようなら，こちらを参考にしてほしい．
参考：https://qiita.com/oldEng/items/d6f6e296167eb3ddda9b

さて，このububtu上にブロックチェーンを立ち上げるというのが今回の主題．

## 2. Docker Desktopをインストール
### 2-1 Docker Desktop stable 2.3.0.2 以上のリリースをダウンロード
Windowsに戻り，
https://hub.docker.com/editions/community/docker-ce-desktop-windows/
からインストーラをダウンロードしインストール。

![Install on Windows _ Docker Documentation および他 10 ページ - 個人 - Microsoft​ Edge 2022-12-25 01.56.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/a7ca8cfb-bba7-e759-3948-75ae1ac59c57.png)

![Installing Docker Desktop 4.15.0 (93002) 2022-12-25 02.00.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/9e568852-8f1f-9675-4667-026fc9f39ca9.png)

通常の Docker Desktop のインストール手順に従い、インストールを行いWindows スタート・メニューから Docker Desktop をスタート。

![Installing Docker Desktop 4.15.0 (93002) 2022-12-25 02.05.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/5b95cfbd-3c31-391d-fc7f-b8a84e0853e7.png)


### 2-2 WSL2 対応エンジンを使う
Docker メニューから、 Settings > General を選択。
Use WSL 2 based engine （WSL2 対応エンジンを使う） のチェックボックスを選択。
Apply & Restart （適用と再起動）をクリック。
（WSL 2 をサポートしているシステム上に Docker Desktop をインストールした場合は、デフォルトでこのオプションが有効化されているので確認後Cancelをクリック）。

![03-09-23_12h19_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/12057294-fc06-d00e-1f4a-2a82e05c4952.png)


## 3. node.jsのインストール
### 3-1 nvmのインストール
まず、ubuntuをスタートメニューから立ち上げる。

![2023-02-13_00h24_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/7182dbdb-0b1f-7a9f-d60e-eb7d39fcf53a.png)



ubuntuで下記のコマンドでインストールスクリプトを実行する。
（参考：https://github.com/nvm-sh/nvm#install--update-script）
```
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
```
実行後、ubuntu再起動。

### 3-2 node.jsのインストール
```
$ nvm list-remote
```
で利用可能なNodeのバージョンを調べる。

![2023-02-13_00h18_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/31639dc3-2e08-c90c-a3ac-f2add563370a.png)

<b>Tips--------------------------------------------------</b>
もし，これが出ずに代わりにN/Aなんて出てしまったら，
```
$ echo insecure >> ~/.curlrc
```
というおまじないを試してみよう．ちゃんとリストが表示されるようになる．
<b>-------------------------------------------------------</b>

このリストからLatest LTSであるv18.14.0をubuntu下記コマンドでインストール
```
$ nvm install v18.14.0
```
ちゃんとインストールできたか確認するには
```
$ nvm list
```
を実行して

![2023-02-13_00h21_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/3cb90c53-2f0a-c0ca-8fd6-a41cb866e5ba.png)


こんなのが出ていればOK。

## 4. Truffleのインストール
これ一発でOK。
```
$ npm install truffle -g
```
結構時間かかるが、

```
$ truffle version
```

でこういうのが出ればOK。

![2023-02-13_00h31_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/1ed9e2ad-2671-e51f-d081-80b512815130.png)


## 5. cURLのインストール
これ一発でOK
```
$ sudo apt install curl
```
確認は
```
$ curl -V
```
Vは大文字にしないとエラーになる。

![03-09-23_13h28_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/c47aa6ef-8bd2-e220-c959-52eb30a78a19.png)
 
みたいなのが出ればOK。

## 6. MetaMaskのインストール
Windows10側のChromeに拡張機能MetaMaskを追加。
これで、後で作るBesuに外から操作ができるようになる。

https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=ja
から「Chromeに追加」でOK。

 ![03-09-23_13h44_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/ec772407-ad4c-87ce-b2ba-4694a6f173ae.png)
 
こんなのが出るので開始をクリック。

<img width="300pix" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/52d731ac-1269-a068-72eb-bfd6492d79a1.png">

こんなのが出るので「ウォレットの作成」を選択。
![03-09-23_13h48_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/51c4588a-c9ac-58da-b4b3-62bb130ebf4d.png)
 
## 7. Hyperledger Besuで遊ぼう
### (1) Hyperledger Besuネットワークを生成する
Ubuntuから
```
$ npx quorum-dev-quickstart
```
を実行すると、どんどんやってくれる。
はじめに質問が出るので、
Hyperledger Besuを選ぶ
Codefi Orchestrate、Quorum Key Managerとprivate transactionsはnと答える。
logging with ELKを選ぶ
BlockscoutはNと答える
Where should we create the config files for this network?
という問いにはEnterでdefault設定にする｡
Installation complete.が出ればOK！

```
$ cd quorum-test-network
```
で移動して、Dockerを起動しているのを確認してから，
```
$ ./run.sh
```
こんなのが出たら成功。

```
*************************************
Quorum Dev Quickstart
*************************************
Setting up the index patterns in kibana ...
----------------------------------
List endpoints and services
----------------------------------
JSON-RPC HTTP service endpoint                 : http://localhost:8545
JSON-RPC WebSocket service endpoint            : ws://localhost:8546
Web block explorer address                     : http://localhost:25000/explorer/nodes
Prometheus address                             : http://localhost:9090/graph
Grafana address                                : http://localhost:3000/d/XE4V0WGZz/besu-overview?orgId=1&refresh=10s&from=now-30m&to=now&var-system=All
Collated logs using Grafana and Loki           : http://localhost:3000/d/Ak6eXLsPxFemKYKEXfcH/quorum-logs-loki?orgId=1&var-app=besu&var-search=
Collated logs using Kibana endpoint            : http://localhost:5601/app/kibana#/discover

For more information on the endpoints and services, refer to README.md in the installation directory.
****************************************************************
```

<b>Tips--------------------------------------------------</b>
もし，「docker endpoint for "default" not found」で止まったら
以下ディレクトリにある「meta.json」を削除します。
```
C:\Users\<ユーザ名>.docker\contexts\meta\XXXXXX\meta.json
```
この「XXXXXX」部分は任意の長い文字列です。.dockerディレクトリにcontextsしかない場合は.dockerディレクトリから全削除しても問題ありません。
<b>-------------------------------------------------------</b>

2回目からはWindows上でスタートボタンメニューで出てきたUbuntuをつついて起動し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/93e8dbab-2b4f-a8ef-3385-5d62d371ff96.png)

Docker Desktop起動後に
```
$ cd quorum-test-network
```
で移動して、
```
$ ./resume.sh
```

でこんなのが出ればOK。
```
$ ./resume.sh
*************************************
Quorum Dev Quickstart
*************************************
Resuming network...
----------------------------------
[+] Running 15/15
 ⠿ Container quorum-test-network-loki-1            Started                                                         1.2s
 ⠿ Container quorum-test-network-redis-1           Started                                                         0.5s
 ⠿ Container quorum-test-network-prometheus-1      Started                                                         1.4s
 ⠿ Container quorum-test-network-grafana-1         Started                                                         1.2s
 ⠿ Container quorum-test-network-promtail-1        Started                                                         0.7s
 ⠿ Container quorum-test-network-validator1-1      Started                                                         1.4s
 ⠿ Container quorum-test-network-elasticsearch-1   Started                                                         1.2s
 ⠿ Container quorum-test-network-metricbeat-1      Started                                                         1.3s
 ⠿ Container quorum-test-network-filebeat-1        Started                                                         1.1s
 ⠿ Container quorum-test-network-logstash-1        Started                                                         1.0s
 ⠿ Container quorum-test-network-kibana-1          Started                                                         1.0s
 ⠿ Container quorum-test-network-validator2-1      Started                                                         1.4s
 ⠿ Container quorum-test-network-validator3-1      Started                                                         1.0s
 ⠿ Container quorum-test-network-explorer-1        Started                                                         1.4s
 ⠿ Container quorum-test-network-ethsignerProxy-1  Started                                                         1.5s
```


### (2) Block explorerでネットワークの概要を見る
Windows11に戻ってブラウザで
http://localhost:25000
を見るとこんなのが見える.ノードの一覧。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/43525cf5-d4f9-440f-3ee7-3f4fa331bc89.png)

Explorerというメニューを選ぶと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/52e94beb-da09-9f4e-cee8-4f9e6f1d2ce1.png)
ブロックを横断していろいろ検索できる。
NFTのコントラクトをデプロイしてmintしたところ、Transactionの情報も出てきた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/0edd97d9-fdf1-ad20-6907-8dbc1896b3e4.png)


### (3) Grafanaでノードたちの様子を見る
次にやはりWindows11のブラウザで
http://localhost:3000/
を見ると、こういうのが出るので、

![03-09-23_17h29_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/6fd8b755-762e-4a28-081d-a1165e0a7e45.png)

「Besu Overview」をクリックすると
![03-09-23_17h31_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/280b3cf9-2d84-a32f-be1f-32c7646a9e6e.png)
 
![03-09-23_17h36_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/70367af8-8ce9-965f-9ea9-bcb38b879cbb.png)

という感じでノードの状況がグラフィカルに確認できる。
 
 

## 8. JSON-RPC requests

### (1) Besuのバージョン
ubuntuから
```
$ curl -X POST --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1}' http://localhost:8545
```

を実行するとこんなのが返ってくる。
```
{
  "jsonrpc" : "2.0",
  "id" : 1,
  "result" : "besu/v21.7.1/linux-x86_64/adoptopenjdk-java-11"
}
```

返ってきたJSONの意味は

```
"jsonrpc" : "2.0" 
```

→　JSON-RPC 2.0 spec formatを使用

```
"id" : 1
```
→　request identifier（request と responseの突合用idでこの tutorialでは常に 1）

```
"result" : "besu/v21.7.1/linux-x86_64/adoptopenjdk-java-11"
```
→　besu/v21.7.1は走行しているBesuのバージョン
　 linux-x86_64はこのバージョンをビルドしたアーキテクチャ
　 adoptopenjdk-java-11はこのバージョンをビルドしたJVMの属性

### (2) つながっているノード数
ubuntuから
```
$ curl -X POST --data '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":1}' http://localhost:8545
```
を実行するとこんなのが返ってくる。
```
{
  "jsonrpc" : "2.0",
  "id" : 1,
  "result" : "0x4"
}
```
→　JSON-RPC requestを受け取ったノードがいくつのノードとつながっているかがresultの値で、この場合は4つである。

### (3) 最後に確定したブロックナンバー

ubuntuから
```
$ curl -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' http://localhost:8545
```
を実行するとこんなのが返ってくる。
```
{
  "jsonrpc" : "2.0",
  "id" : 1,
  "result" : "0x204d"
}
```

## 9. MetaMaskを使ってアカウント間でETHを送る
### (1) アカウント作成

Chrome拡張機能リストのMetaMaskのアイコンをクリック。

<img width="300pix" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/8850f6cb-493b-9902-6822-a0c6995d297a.png">

ネットワークからLocalhost 8545を選ぶ。イーサリアムメインネットしか見えないときは上部の「表示・非表示」をクリックして「テストネットワークを表示」をオンにする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/39c15dec-d193-ffed-d023-ed29f55eb4fd.png)


 
これで先ほど立ち上げたBesuのネットワークにMetaMaskが接続した。

次にアカウントのインポート。
 
https://besu.hyperledger.org/en/stable/Tutorials/Examples/Private-Network-Example/#create-a-transaction-using-metamask
にあるprivate key to copyをどれか拝借してコピペしたのちインポートする。

![03-09-23_23h53_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/559de681-79b0-f5d0-0d28-8567f18572eb.png)

 
大変なお金持ちになっている。

<img width="300pix" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/6efd30d7-8553-38be-4b31-fc9bca5df648.png">
  
もう１つアカウントを作成する。
 
アカウント名を入れて、作成をクリック。

![03-09-23_23h39_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/1a3c50e3-83f5-ee2e-7783-be370b44398f.png)

一文無しである。
![03-09-23_23h41_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/794f2f9c-f28e-cb4a-3c03-255b3ca8b6e1.png)



### (2) 送金する
では90000ETH持っているAccount2から一文無しのTestAccount2に15000ETH送金する
まず送金先TestAccount2のアドレスをコピー。

![03-09-24_00h10_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/726f8e40-f2fb-197d-86a0-2762138a73cc.png)

送金元のAccount2に移って送金クリック。

![03-09-24_00h08_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/e9695e4c-5c2e-7ed3-ceb5-bf2509cdf65c.png)


送金先に上でコピーしたアドレスをペーストし送金額15000ETHを入力し次へをクリックする。

![03-09-24_00h14_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/6f2cbe69-0e35-4266-c25c-e81c25a1f4e2.png)
 
確認をクリック。

![03-09-24_00h17_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/408dda0d-a537-8306-2eab-93094f259c8d.png)

少しの間の後に残高が変わった。

![03-09-24_00h18_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/316e8e6f-4374-8acf-7c52-04bd2d4ce6cb.png)

![03-09-24_00h20_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/8b1c7007-986c-02e8-f84d-2a75abc91125.png)

これで送金完了である。

## 10. Remixでスマートコントラクトの実装とデプロイ
参考 https://ai-china.hatenablog.com/entry/2022/01/01/130000

Remixというweb上でSolidityのコードを書いてコンパイルまでできる便利なツールを使ってスマートコントラクトを作成，Besu上にデプロイしてみる。

### (1) スマートコントラクトを書く
まずRemixを開いて、
https://remix.ethereum.org/


test文字を右クリックしてNew Fileを選択し，新規ファイルを作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/27ffd30d-f31b-baf7-1cf4-f9bc0cf93c37.png)

作成したいスマートコントラクト名.sol，例えばtakaToken1.solとファイル名を設定する。
こうしてできた新しいタブにコードを書いていく。

```solidity:takaToken1.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

import "@openzeppelin/contracts@4.4.1/token/ERC20/ERC20.sol";

contract takaCoin0 is ERC20 {
    constructor() ERC20("taka Coin", "TKC") {
        _mint(msg.sender, 150000 * 10 ** decimals());
    }
}
```

これを書き終えたら左側のSOLIDITY COMPILERをクリックする。そうするとこのようなCompile takaToken1.solというボタンが表示されるので突いてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/50de8f92-c9be-7d6f-f3d9-42d38c594a16.png)

Remix表示中のタブでMetamaskを立ち上げてすでに作成しておいた例えばAccount1というアカウントを表示する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/1fc367b8-f5b0-461d-9961-11b54dd2b734.png)



RemixでDEPLOY & RUN TRANSACTIONを左側で選択、ENVIRONMENTをInjected Web3にし、AccountをMetamaskの先ほどのアカウントAccount2のアドレスにしてDeploy｡

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/e5e964c8-7a48-1d4a-897c-49e22c51d628.png)


するとガス代が見積もられるが、どうせガスフリーだから気にせず確認ボタンを押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/267c3dd3-6977-b14b-f4de-165c3b52894f.png)

ぴぽぱぽーんという音とともにこんなのが小さく出てくる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/6fa9f49f-5e7d-c708-878c-bdab80b78c1e.png)

そうしたら左下の端に出てくるこれをコピーボタンで取得し
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/a3f5b891-d570-a659-a27f-0f9da8236dce.png)


Metamaskのトークンをインポートを押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/2c190f8b-a537-9f87-abca-f44771e37c83.png)



トークンコントラクトアドレスに先ほどコピーで取得したやつをペースト、トークンシンボルにTKCと入れてカストムトークンを追加。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/4cf7d3bf-0b30-de84-19eb-4723851940da.png)



トークンをインポート。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/efdf1ce0-932e-6b7a-ed7f-4a916dc5a54a.png)



入った。TKCで大富豪になった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/7be987d9-6d02-fed1-e718-fe7c6a6e8b96.png)



## 11. 終了する
ubuntuで
```$ cd quorum-test-network```
とした後、
```$ ./stop.sh```
でBesuは眠りにつく。