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


 ## はじめに
一生懸命最適解を探しているAIも可愛いが、せっせとブロックを積み上げているValidatorたちも愛らしい。
この箱庭の愉悦を会社の皆さんに味わってもらおうと、ハンズオンの資料を作ろうとした老技術者。
ところがだ。
開発チームの皆さんは当然のごとくMac使いなのだが、ビジネスチームは皆さんWindows使い。
一昔前だとVMwareだのVirtual PCというそれこそ箱庭の中でごにょごにょするわけだったのだが、現代はWSLなる便利なものをMSさんが用意してくれている。
そして最近それがWSL2になったそうだから気にはなっていたのである。
というわけで久々に火を入れたWindowsマシンでWSL2投入し、ここを乗り切ることにしたのだった。

## 1. Windows10でUbuntuを使う
参考：　https://qiita.com/whim0321/items/ed76b490daaec152dc69
### 1-1　スタートボタンを右クリックWindows Powershell（管理者）を立ち上げる

<img width="200pix" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/d4559a0c-c827-05a2-36b9-5403fa9e3281.png">

### 1-2　デフォルトでWSL2を使うように設定
Powershellで
```
wsl --install
```
でまずはWSLをインストールし,システム再起動。

再度Powershellで
```
wsl --set-default-version 2
```
と打ち込みリターン。


### 1-3 Microsoft StoreからUbuntu 20.04 LTSをインストールし起動

![03-09-23_11h30_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/207b0be1-2885-fab1-c9a8-fd1aabc82846.png)

 
### 1-4 Ubuntu用ユーザIDとパスワードを設定

![03-09-23_11h33_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/d59ec590-ff95-a46a-03eb-4b051a084355.png)

 
設定すると次のようなメッセージが出る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/f9137ce9-d772-90f1-80ef-65bc7fb0c5b0.png)


### 1-5　現在のwslのバージョンを確認
Powershellで
```
wsl -l -v
```
と打ち込みリターン。
Ubuntu-20.04の行のVERSIONが2となっていればOK。

```
  NAME            STATE           VERSION
* Ubuntu-20.04    Stopped         2
```

 

### Tips. Windows-Linux間のファイル共有

#### LinuxからのWindows上のファイルへのアクセス
WindowsのCドライブがLinuxの/mnt/cにマウントされている。/mnt/cにアクセスすることで、Windows上のファイルにアクセス可能。

#### WindowsからLinux上のファイルへのアクセス

```
\\wsl.localhost\[ディストリビューション名]
```
でLinux上のファイルにアクセス可能。
Ubuntuを使っている場合は、

```
\\wsl.localhost\Ubuntu-20.04\
```

でアクセスする。


## 2. WSL2上で Docker Desktopを使う
### 2-1 Docker Desktop stable 2.3.0.2 以上のリリースをダウンロード
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をスタートメニューから立ち上げ、
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のバージョンを調べる。

![taka@taka2600K_ ~ 2022-12-25 02.18.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/0f5858da-bc70-fc2a-0064-90df0ccbaa84.png)


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

![taka@taka2600K_ ~ 2022-12-25 02.22.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/86c0b985-b4a8-d475-fb0b-462b0d69265b.png)


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

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

```
$ truffle version
```

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

![taka@taka2600K_ ~ 2022-12-25 02.27.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/0d303df2-1598-765c-15b1-582a2e5e90da.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.
****************************************************************
```
もし，「docker endpoint for "default" not found」で止まったら
以下ディレクトリにある「meta.json」を削除します。
``
C:\Users\<ユーザ名>.docker\contexts\meta\XXXXXX\meta.json
``
この「XXXXXX」部分は任意の長い文字列です。.dockerディレクトリにcontextsしかない場合は.dockerディレクトリから全削除しても問題ありません。


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。
```
Resuming network...
----------------------------------
[+] Running 15/15
 ⠿ Container quorum-test-network-grafana-1         Started                                                         6.3s
 ⠿ Container quorum-test-network-elasticsearch-1   Started                                                         5.4s
 ⠿ Container quorum-test-network-redis-1           Started                                                         5.8s
 ⠿ Container quorum-test-network-prometheus-1      Started                                                         5.7s
 ⠿ Container quorum-test-network-validator1-1      Started                                                         8.5s
 ⠿ Container quorum-test-network-kibana-1          Started                                                         3.9s
 ⠿ Container quorum-test-network-metricbeat-1      Started                                                         3.1s
 ⠿ Container quorum-test-network-filebeat-1        Started                                                         4.0s
 ⠿ Container quorum-test-network-logstash-1        Started                                                         3.8s
 ⠿ Container quorum-test-network-validator3-1      Started                                                         6.8s
 ⠿ Container quorum-test-network-validator4-1      Started                                                         5.9s
 ⠿ Container quorum-test-network-validator2-1      Started                                                         7.3s
 ⠿ Container rpcnode                               Started                                                         6.3s
 ⠿ Container quorum-test-network-explorer-1        Started                                                         3.6s
 ⠿ Container quorum-test-network-ethsignerProxy-1  Started
```


### (2) Block explorerでネットワークの概要を見る
Windows10側のブラウザで
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でノードたちの様子を見る
次にやはりWindows10側のブラウザで
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は眠りにつく。