Hyperledger FabricのSample「fabcar」を試してみる。
前回のEthereumのTruffle、Vue-boxに続いて、今回はコンソーシアム型ブロックチェーンHyperledger Fabricのサンプルについてです。
公式は以下のサイトですが、英語で文章量が結構多めであること、日本語でそのままずばりの情報がないようなので、とりあえずサンプルを動かすところまでをまとめてみました。
hyperledger-fabric.readthedocs.io
ざっくりした手順は以下の通りです。
- 必要なツール類のインストール
- fabric-samplesのインストール
- テストネットワークの起動、チャネル生成、chaincodeのデプロイ
- 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
UbuntuはVirtualBox上で動作させています。VirtualBox仮想マシン上でDockerの仮想環境を動かしている感じです。 VirtualBox仮想マシンのCPU数、メモリは多めに設定しています。
ツール類のインストール
事前に入れておきなさいと言われているものはこちら。上述の環境にも記載しましたが、必要なものがちょっと多めですね。
hyperledger-fabric.readthedocs.io
Git、cURL、Pythonは元々入っていたのでとりあえず作業なし。 node/npmの手順はググれば出てくるので割愛。 本記事ではDockerとGoのメモだけ。
Dockerのインストール
Docker公式の通りaptでのインストールで特に問題なし。
日本語だとこちらのサイトがよいと思いました。
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
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(認証局)やユーザが明示的に登場していないので物足りないです。 サンプルを動かせたとしても、応用は効かないかも。
公式ではこれから先は自分でスマートコントラクトを書いて実行してみる手順に続くようです。気が向いたらやってみて追記します。
本日はここまで。