ローカルでプライベートブロックチェーンを動かしてみた

# はじめに
最近、会社でweb3研究会を立ち上げ、みんなでワイワイやってます。
学習の一環でプライベートブロックチェーンを動かしてみたので、みなさんもやってみてください！

私自身の理解がまだ不十分なため、細かい説明は省いてます:bow:

# ブロックチェーンって何？
この表現が正しいか分かりませんが、物理的に離れている複数のノードで同じデータを管理し、お互いにチェックし合うことで、高い安全性を実現した仕組みです。
それぞれのノードで管理しているデータは暗号化されているので、暗号化と多重チェックで改ざんを防いでます。

# プライベートブロックチェーンとは？
ブロックチェーンには３つの種類があり、プライベートブロックチェーンは、金融機関など、参加者を限定したいシステム向けのブロックチェーンです。
・パブリックチェーン
　　管理者が不在で、誰でもネットワークに参加できる
・プライベートチェーン
　　管理者が単独で存在し、許可されたユーザーだけが参加できる
・コンソーシアムチェーン
　　管理者が複数存在し、許可されたユーザーだけが参加できる

# 事前準備
### 今回利用したサイト
[Hyperledger Fabric](https://hyperledger-fabric.readthedocs.io/ja/latest/index.html)
→ Hyperledgerは、Linux Foundationの傘下で設立されたそうです。
AWSの[Amazon Managed Blockchain](https://aws.amazon.com/jp/managed-blockchain/)でも採用されているので、信頼性は高いであろう、という理由から、こちらを利用しました。

### 必要なものをインストール
[こちらのページ](https://hyperledger-fabric.readthedocs.io/ja/latest/prereqs.html)を参考に、必要なものをインストールしましょう。

### Golangのインストール
途中でGolangが必要になるので、インストールしておきましょう。
公式サイトは[こちら](https://go.dev/doc/install)ですが、Macは
`brew install go`
だけでもOKです。

# プライベートブロックチェーンの構築
以下のコマンドはHyperledger Fabricの[Getting Started](https://hyperledger-fabric.readthedocs.io/ja/latest/getting_started.html)の通りですが、プライベートブロックチェーンの構築をしていきましょう！

### 作業用のディレクトリを作成
以下のコマンドを実行し、作業用のディレクトリを作成して、そこに移動します。（mkdir -p で複数階層のディレクトリを1回で作成できます）
```
mkdir -p ~/work/web3/HyperledgerFabric
cd ~/work/web3/HyperledgerFabric
```

### [Getting Started](https://hyperledger-fabric.readthedocs.io/ja/latest/getting_started.html)に従ってコマンドを実行
続けて以下のコマンドを実行します。
```
curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.2.3 1.5.0
```
このコマンドにより、以下の手順が実行されます。
1. 必要に応じて hyperledger/fabric-samples リポジトリをクローン
2. 適切なバージョンタグをチェックアウト
3. 指定されたバージョンのHyperledger Fabricのプラットフォーム固有のバイナリと設定ファイルをfabric-samplesの/binおよび/configディレクトリにインストール
4. 指定されたバージョンのHyperledger FabricのDockerイメージをダウンロード

```bash:コマンドの実行結果（数分かかります）
$ curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.2.3 1.5.0

Clone hyperledger/fabric-samples repo

===> Cloning hyperledger/fabric-samples repo
Cloning into 'fabric-samples'...
remote: Enumerating objects: 11487, done.
remote: Counting objects: 100% (83/83), done.
...
...
hyperledger/fabric-ca        1.5.0     24a7c19a9fd8   21 months ago   70.8MB
hyperledger/fabric-ca        latest    24a7c19a9fd8   21 months ago   70.8MB
```

### バイナリにパスを通す
クローンしたディレクトリのbin/にバイナリが配置されているので、これらを利用するためにパスを通します。
```
export PATH=${PWD}/fabric-samples/bin:$PATH
```

### ネットワークの起動
まずはtest-netwoekに移動
```
cd fabric-samples/test-network/
```
念のため、ネットワークのダウンコマンドを実行
```
$ ./network.sh down
Stopping network
Removing network fabric_test
...
No containers available for deletion
No images available for deletion
```
ネットワークの立ち上げ
```
$ ./network.sh up
Starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb' with crypto from 'cryptogen'
LOCAL_VERSION=2.2.3
DOCKER_IMAGE_VERSION=2.2.3
...
Creating cli                    ... done
CONTAINER ID   IMAGE                               COMMAND             CREATED         STATUS                  PORTS                                                        NAMES
b3a2768a1220   hyperledger/fabric-tools:latest     "/bin/bash"         2 seconds ago   Up Less than a second                                                                cli
546d7039c34e   hyperledger/fabric-peer:latest      "peer node start"   6 seconds ago   Up 2 seconds            0.0.0.0:9051->9051/tcp, 7051/tcp, 0.0.0.0:19051->19051/tcp   peer0.org2.example.com
f6aaa2ab4b7a   hyperledger/fabric-orderer:latest   "orderer"           6 seconds ago   Up 2 seconds            0.0.0.0:7050->7050/tcp, 0.0.0.0:17050->17050/tcp             orderer.example.com
e55385e07e06   hyperledger/fabric-peer:latest      "peer node start"   6 seconds ago   Up 2 seconds            0.0.0.0:7051->7051/tcp, 0.0.0.0:17051->17051/tcp             peer0.org1.example.com
```

### チャネルの作成
上記実行結果で一番右の「NAMES」を見ると分かりますが、以下２つのpeerノードとorderノードが作成されてます。
peer0.org1.example.com
peer0.org2.example.com
orderer.example.com

次のコマンドで、Org1とOrg2の間のトランザクションを行うためのFabricのチャネルを作成します。
```
$ ./network.sh createChannel
Creating channel 'mychannel'.
If network is not up, starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb 
Generating channel create transaction 'mychannel.tx'
+ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID mychannel
...
...
Anchor peer set for org 'Org2MSP' on channel 'mychannel'
Channel 'mychannel' joined
```
これで、スマートコントラクトを使用してチャネル台帳とやり取りできるようになりました。

### チェーンコードの開始
次のコマンドを使用してチャネル上でチェーンコードを開始します。
```
$ ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
deploying chaincode on channel 'mychannel'
executing with the following
- CHANNEL_NAME: mychannel
...
...
Query chaincode definition successful on peer0.org2 on channel 'mychannel'
Chaincode initialization is not required
```

### ネットワークとやりとりするための準備
続いて、`peer`CLIを使用してそのネットワークとやり取りするための準備を行います。
`peer`CLIをOrg1として操作できるよう、以下の環境変数を設定してください。
```
export FABRIC_CFG_PATH=$PWD/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
```

### 資産台帳の初期化
ちょっと長いですが、このコマンドで資産台帳を初期化します。
```
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"InitLedger","Args":[]}'
```
成功すると、以下のレスポンスが返ってきます。
```
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200 
```

### 資産リストの取得
CLIから台帳にクエリすることができるようになったので、次のコマンドを実行して、チャネルの台帳に追加された資産のリストを取得してみましょう。
```
$ peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
[
{"ID":"asset1","color":"blue","size":5,"owner":"Tomoko","appraisedValue":300},
{"ID":"asset2","color":"red","size":5,"owner":"Brad","appraisedValue":400},
{"ID":"asset3","color":"green","size":10,"owner":"Jin Soo","appraisedValue":500},
{"ID":"asset4","color":"yellow","size":10,"owner":"Max","appraisedValue":600},
{"ID":"asset5","color":"black","size":15,"owner":"Adriana","appraisedValue":700},
{"ID":"asset6","color":"white","size":15,"owner":"Michel","appraisedValue":800}
]
```
これで無事に、ローカルでブロックチェーンが動いていることを確認できました！
ブロックチェーンの利用方法については、学習の上、また改めて書こうと思います。

# さいごに
ブロックチェーンって難しそうなイメージですが、実際に動かしてみると、少しずつイメージしやすくなります。
これから需要が拡大していく分野だと思うので、まずは体験してみるといいのではないでしょうか:slight_smile: