Hyperledger FabricのSample「fabcar」を試してみる。

前回のEthereumのTruffle、Vue-boxに続いて、今回はコンソーシアム型ブロックチェーンHyperledger Fabricのサンプルについてです。

公式は以下のサイトですが、英語で文章量が結構多めであること、日本語でそのままずばりの情報がないようなので、とりあえずサンプルを動かすところまでをまとめてみました。

hyperledger-fabric.readthedocs.io

ざっくりした手順は以下の通りです。

  1. 必要なツール類のインストール
  2. fabric-samplesのインストール
  3. テストネットワークの起動、チャネル生成、chaincodeのデプロイ
  4. chaincodeの実行

それではいってみましょう。

環境

  • Ubuntu 18.04 LTS
  • Git 2.17.1
  • cURL 7.58.0
  • Docker 19.03.9 / docker-compose 1.25.4
  • Go 1.14.3
  • Node.js 12.16.3 / NPM 0.35.3
  • Python 2.7.17

UbuntuVirtualBox上で動作させています。VirtualBox仮想マシン上でDockerの仮想環境を動かしている感じです。 VirtualBox仮想マシンのCPU数、メモリは多めに設定しています。

ツール類のインストール

事前に入れておきなさいと言われているものはこちら。上述の環境にも記載しましたが、必要なものがちょっと多めですね。

hyperledger-fabric.readthedocs.io

Git、cURLPythonは元々入っていたのでとりあえず作業なし。 node/npmの手順はググれば出てくるので割愛。 本記事ではDockerとGoのメモだけ。

Dockerのインストール

Docker公式の通りaptでのインストールで特に問題なし。

docs.docker.com

日本語だとこちらのサイトがよいと思いました。

qiita.com

docker-composeのインストール

こちらも公式に従って1.25.4をインストール。 権限の関係でsudoを付けています。

sudo curl -L https://github.com/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

github.com

Goのインストール

snapを使ってインストール。snapはUbuntu16.04以上であればプレインストールされているはず。こちらもsudoを付けて実行。

sudo snap install go --classic

fabric-samplesのインストール

Hyperledger Fabricのサンプル一式をダウンロードして配置します。

公式はこちら。

hyperledger-fabric.readthedocs.io

長々と説明が書かれていますが、以下のコマンドでインストールされます。

curl -sSL https://bit.ly/2ysbOFE | bash -s

パーミッション関連のエラーが出るかもしれません。 ツール類をインストールしたらOS(Ubuntu)を一旦リブートしておくのが吉です。 curlの実行が終わると、fabric-samplesという名前のディレクトリができており、サンプルファイル一式が格納されています。

メモ:fabric-samplesの構造

主なものだけ。

  • chaincode/fabcar : (かっこよく言うと)自動車の所有権等管理のサンプル。各言語別にfabcar用ソースコードが格納されています。
  • test-network : テスト用ネットワークのファイル一式(fabcar専用?)
  • test-network/script : スクリプトファイル一式。手順を進める上では意識しなくてよいです。
  • bin : Hyperledger Fabricのツール群(実行ファイル)。

binには以下のようなツールが格納されています。

configtxgen
configtxlator
cryptogen
discover
fabric-ca-client
fabric-ca-server
idemixgen
orderer
peer

メモ:Docker Imageの確認

この時点でDockerのイメージ(コンテナ)を確認すると、hyperledger fabricノード用のイメージが複数登録されれいます。

sudo docker images

登録されるのは以下の11個。

hyperledger/fabric-ca
hyperledger/fabric-tools
hyperledger/fabric-peer
hyperledger/fabric-orderer
hyperledger/fabric-ccenv
hyperledger/fabric-baseos
hyperledger/fabric-nodeenv
hyperledger/fabric-javaenv
hyperledger/fabric-zookeeper
hyperledger/fabric-kafka
hyperledger/fabric-couchdb

テストネットワークの起動~chaincodeのデプロイ

テストネットワーク

test-networkディレクトリの下にnetwork.shというスクリプトファイルがあります。 test-networkディレクトリに移動して、コマンド

./network.sh up

を実行すると、ログがたくさん出た後、3つのノード(Dockerコンテナ)が立ち上がります。

  • orderer.example.comという名前のordererノード
  • peer0.org1.example.comという名前のpeerノード(以下、Org1)
  • peer0.org2.example.comという名前のpeerノード(以下、Org2)

Dockerのコマンドでも同様の情報を確認できます。

docker ps -a

チャネル生成

以下のコマンドでチャネルを生成します。

./network.sh createChannel

mychannelという名前のチャネルが生成され、PeerノードであるOrg1とOrg2がmychannelにJOINされます。 ちゃんと理解できていませんが、おそらく複数のPeerを1つのチャネルでグルーピングしているのだと思われます。

「fabcar」chaincodeのデプロイ

「fabcar」のchaincode(スマートコントラクト)を以下のコマンドでmychannelにデプロイします。

./network.sh deployCC

こちらもたくさんのログが出力された後、最終的に自動車10台分の車種や色、所有者のデータが登録されます。 こんなデータです。

[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},
{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},
{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},
{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},
{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},
{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},
{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},
{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},
{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},
{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]

chaincodeの実行

実行前の準備

これから実行する作業のために環境変数を2つ設定します。絶対パスじゃないのでなんだかいまいちなのですが。。。公式に従います。 カレントディレクトリはfabric-samples/test-networkです。

export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/

また、トランザクションの受付ノードをOrg1ににするため?に環境変数を5つ設定します。(多い。。。)

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

chaincode実行:自動車一覧の取得

で、やっとchaincodeの実行。データ一覧を取得するクエリです。fabric-samples/bin/peerに引数をいくつか付けてますね。

peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'

結果としては前述の自動車の車種や色、所有者のデータ一覧が表示されます。(省略)

chaincode実行:オーナーの変更

Car9のオーナーをデーブさんに変更してみます。この時点でのトランザクション受付ノードはOrg1です。

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls true --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n fabcar --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":"changeCarOwner","Args":["CAR9","Dave"]}'

な、長い。。。長すぎる。実行結果としては簡単なログが出るだけです。

2020-05-20 08:44:53.732 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200

トランザクションの受付ノードをOrg2ににするため?に環境変数を変更して、データが変更されていることを確認します。

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051

で、やっと確認。

peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryCar","CAR9"]}'

実行結果はこんな感じ。ちゃんとオーナーが変更されていますね。オーストラリアの自動車メーカーなんてマニアックな。

{"make":"Holden","model":"Barina","colour":"brown","owner":"Dave"}

ここまでの感想

実行しているシェルスクリプトを読まないと何をしているか分からず、ただ手順に沿ってコマンドたたいているだけになってしまいます。 スクリプトも幾重にもなっており、末端はbinディレクトリに格納されているツール類を実行しているようです。 また、CA(認証局)やユーザが明示的に登場していないので物足りないです。 サンプルを動かせたとしても、応用は効かないかも。

公式ではこれから先は自分でスマートコントラクトを書いて実行してみる手順に続くようです。気が向いたらやってみて追記します。

本日はここまで。