Hyperledger FabricのService Discovery機能を動かしてみた

こんにちは、(株)日立製作所 研究開発グループ サービスコンピューティング研究部の永井です。今回は、コンソーシアム型のブロックチェーン(BC)基盤の一つであるHyperledger FabricのService Discovery機能をご紹介します。

# はじめに
Hyperledger Fabricでは、「エンドースメントポリシー」と呼ばれるポリシーベースの合意形成アルゴリズムが導入されています。ある参加者がトランザクションを実行しようとした場合、エンドースメントポリシーで設定された数の検証ノードでトランザクションを検証（エンドース）してもらう必要があります。その際、エンドースを迅速に行うため、実行しようとするスマートコントラクト(Chaincode)を相手の検証ノードが持っていて、かつ正常に動作しているかを確認する必要があります。Hyperledger FabricのService Discovery機能を使うことにより、参加者はこの情報を取得できます。
以下、Service Discovery機能の使い方を紹介します。なお以下の手順は、Ubuntu 18.04で実行することを前提に記載します。また、Hyperledger Fabricは2019年11月現在、v1.4.4が最新であり、本バージョンを導入することを前提とします。

# 前提環境構築
Hyperledger Fabricの前提環境は以下の通りです。
・Docker version 17.06.2-ce or greater
・Docker Compose
・Go version 1.12.x
・Node.js - version 8.x
・Python
これらに加えて、必要となるツール群をインストールする手順を以下に示します。ホームディレクトリで以下のコマンドを実行します。

```
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common
# install Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# install Docker Compose 
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# install Go
sudo wget https://redirector.gvt1.com/edgedl/go/go1.12.13.linux-amd64.tar.gz
sudo tar -C /opt -xzf go1.12.13.linux-amd64.tar.gz
export GOROOT=/opt/go
export PATH=$PATH:$GOROOT/bin
# install Node.js
sudo apt-get install nodejs npm
sudo npm install -g n
sudo n 8.16.0
sudo apt-get purge nodejs npm
sudo apt-get autoremove
# install python
sudo apt install python
```

rootユーザ以外でもdockerコマンド実行できるよう、以下のコマンドを実行します。

```
sudo gpasswd -a $(whoami) docker
sudo chgrp docker /var/run/docker.sock
sudo service docker restart
```
上記実行後、いったんログオフしてください。

# Hyperledger Fabric＆サンプルプログラムのインストール
次に、Hyperledger Fabricと、サンプルプログラム(fabric-samples)一式をインストールする手順を以下に示します。

```
curl -sSL http://bit.ly/2ysbOFE | bash -s
cd fabric-samples
curl -sS https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh -o ./scripts/bootstrap.sh
chmod +x ./scripts/bootstrap.sh
./scripts/bootstrap.sh
```

# Hyperledger Fabricの起動＆スマートコントラクトのデプロイ
OSSコミュニティからは、現在複数のサンプルプログラムが提供されています。今回は、fabcarと呼ばれるサンプルを用いてBCネットワークを立ち上げます。本サンプルでは、以下の手順を一気に実行します。
- BCネットワークの立ち上げに必要な構成ファイルや、台帳に格納するデータの暗号化に用いる鍵の生成
- BCネットワークを構成するPeerやOrdererといったノードを格納したDockerコンテナの起動
- チャネル(BCネットワーク内に作られるサブネットワーク)の作成
- スマートコントラクト(Chaincode)のデプロイ

```
cd ~/fabric-samples/fabcar/
./startFabric.sh
```
これで、1つのOrderer(solo)、2つの組織、各組織当たり2つのPeer、1つのCA(認証局)からなるBCネットワークを構築できます。

```
BCネットワーク
├ Orderer
├ 組織1(org1.example.com)
│ ├ Peer0(peer0.org1.example.com) :Chaincodeあり
│ ├ Peer1(peer1.org1.example.com)
│ └ 組織1向けCA
└ 組織2(org2.example.com)
　 ├ Peer0(peer0.org2.example.com) :Chaincodeあり
　 ├ Peer1(peer1.org2.example.com)
　 └ 組織2向けCA
```
4つのPeerは"mychannel"という名称のチャネルに所属します。また、各組織の2つのPeerのうち1つに"fabcar"という名称のChaincodeがデプロイされます。

# Service Discovery機能実行の準備
Service Discovery機能の実行ファイルが以下の場所にあるので、カレントパスを移動します。

```
~/fabric-samples/bin
```
次に、以下のコマンドを実行してconf.yamlファイル(Service Discovery実行時の設定ファイル)を生成します。"--userKey"以下に指定するファイルの名前は毎回ランダムに付与されるので、"~/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/keystore/"フォルダを確認し、実在するファイルの名前に置き換えてください。

```
./discover --configFile conf.yaml \
--peerTLSCA ~/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
--userKey ~/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/keystore/d65e8c1b62d5c43b91aa8c8c1ca4a0c59c68eb97a249832a64a5ae31b66aeafc_sk \
--userCert ~/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/signcerts/peer0.org1.example.com-cert.pem \
--MSP Org1MSP \
saveConfig
```
# Peer一覧取得
以下のコマンドにより、先述した"mychannel"というチャネルに属しているPeerの一覧を取得できます。各PeerへのChaincodeのデプロイ状況も確認できます。

```
./discover --configFile conf.yaml peers --channel mychannel  --server peer0.org1.example.com:7051
```
・実行結果の例（"Identity"の値は長いため、一部割愛しています）

```
[
        {
                "MSPID": "Org1MSP",
                "LedgerHeight": 5,
                "Endpoint": "peer0.org1.example.com:7051",
                "Identity": "-----BEGIN CERTIFICATE-----\nMIIC(中略)\n-----END CERTIFICATE-----\n",
                "Chaincodes": [
                        "fabcar"
                ]
        },
        {
                "MSPID": "Org1MSP",
                "LedgerHeight": 5,
                "Endpoint": "peer1.org1.example.com:8051",
                "Identity": "-----BEGIN CERTIFICATE-----\nMIIC(中略)\n-----END CERTIFICATE-----\n",
                "Chaincodes": null
        },
        {
                "MSPID": "Org2MSP",
                "LedgerHeight": 5,
                "Endpoint": "peer1.org2.example.com:10051",
                "Identity": "-----BEGIN CERTIFICATE-----\nMIIC(中略)\n-----END CERTIFICATE-----\n",
                "Chaincodes": null
        },
        {
                "MSPID": "Org2MSP",
                "LedgerHeight": 5,
                "Endpoint": "peer0.org2.example.com:9051",
                "Identity": "-----BEGIN CERTIFICATE-----\nMIIC(中略)\n-----END CERTIFICATE-----\n",
                "Chaincodes": [
                        "fabcar"
                ]
        }
]
```
次に、以下のコマンドで1つのPeerをダウンさせた後、discoverコマンドを再度実行してみましょう。すると、そのPeerは表示されなくなります。

```
docker stop peer1.org1.example.com
```
# まとめ
以上のように、Hyperledger FabricのService Discovery機能を使うことにより、BCネットワーク内におけるスマートコントラクト(Chaincode)のデプロイ状況や、Peerの動作状況を確認することができました。今回はコマンドラインで実行する方法をご紹介しましたが、Hyperledger Fabric SDKを用いてAPIベースで実行することも可能です。
Hyperledger Fabricでは、現在も様々な新機能の実装が続いています。動向を引き続きウォッチし、ご紹介していきたいと思います。

# 参考
Hyperledger Fabric公式ドキュメントにおけるService Discovery機能の紹介：
[https://hyperledger-fabric.readthedocs.io/en/release-1.4/discovery-overview.html](https://hyperledger-fabric.readthedocs.io/en/release-1.4/discovery-overview.html)
ブロックチェーンの特長やユースケースについて：
[https://www.hitachi.co.jp/products/it/blockchain/index.html](https://www.hitachi.co.jp/products/it/blockchain/index.html)