概要
ブロックチェーンを可視化するツール「Hyperledger Explorer」をインストールして Hyperledger Fabric のブロックチェーンを見てみたので備忘録を兼ねて共有したいと思います。
(参照)Hyperledger Explorerとは? -> Hyperledger Explorer(v0.3.7版)で確認できる情報
本記事ではHyperledger Fabricのバージョン v1.2.1 を利用しました(執筆中にリリースされたHLF v1.3でも同様手順で問題ないことは確認済)。また、Hyperledger Explorerは開発中の release-3.8 ブランチを利用しました。
このほか、Hyperledger Fabricや公式サンプルの導入方法は他記事としてまとめています。
こちらのリンクから各記事に遷移できますので、ご興味があれば。
参考
Hyperledger Fabric 1.2.1を動かして、ブロックチェーンの動作を確認・検証しよう
Hyperledger Explorer のインストール
公式サイトの手順(non-Docker版)を参考にしました。
(このほかにもDocker版も追加されたようなのでまたの機会にでも)。
前提ソフトウェアのインストール
- Hyperledger Fabric v1.2 (執筆時点最新 1.2.1)
- Hyperledger Fabric 公式サンプル "fabric-samples"(fabcar サンプルを含む)
- Docker CE 17.06.2-ce / Docker compose 1.14.0 以上
- nodejs 8.11.x 以上 (v9.xは未サポート)
- PostgreSQL 9.5 以上
- jq (https://stedolan.github.io/jq/)
- OSは Ubuntu Linux 18.04 LTS を使用(筆者は macOS + Vagrant/VirtualBox + ubuntu/bionic64 を利用)
参考
Hyperledger Fabric と 公式サンプル
まずは今回利用するHyperledger Fabric v1.2 (curr: 1.2.1) と公式サンプルをインストールします。
Docker CE および Docker compose
Hyperledger Fabric の前提ツールなので上で一緒にインストールされます。
nodejs v8.11.x 以上(v9.xはNG)
Hyperledger Explorer は Hyperledger Fabric Node SDK などを使用して実装されている Node.js アプリケーションです。
Node.js ランタイムのインストールは Hyperledger Fabric 公式サンプルの前提ソフトウェアとしてインストール済ですが、注意点として、公式手順に従って対応バージョンにしておかないとnpm install
が正常に動作しないなどしてハマることがあるようです(ハマりました)。
公式手順に従って対応バージョンをインストールする:
sudo npm install npm@5.6.0 -g
このほかUbuntu 18.04 LTS
ではさらにハマることがある(あった?)らしい。npm install
の際にundefined symbol: SSL_library_init
が出て失敗するというもの:
node_modules/grpc/src/node/extension_binary/node-v57-linux-x64-glibc/grpc_node.node: undefined symbol: SSL_library_init
この問題は執筆中に公式に対応されたようなのでもはや不要かもしれません。が、一応解決方法をメモしておきます。
メモ:nodesourceから入れ直せば解決する
sudo apt -y purge nodejs
curl -sL https://deb.nodesource.com/setup_8.x | sudo bash -
sudo apt -y install nodejs
nodesource経由だと、執筆時点では v8.12.0 がインストールされました。
$ node -v; npm -v
v8.12.0
6.4.1
postgreSQL
Hyperledger Explorer は Fabric に定期的に問い合わせしたりイベント通知を受けて情報をローカルDB(postgreSQL DB)に蓄えるらしい(何に使われているかはよくわかってない)。
sudo apt -y install locate postgresql
sudo systemctl enable postgresql
sudo service postgresql start
jq (コマンドライン JSON パーサー)
Hyperledger Explorer のセットアップスクリプトなどで使用されている jq をインストールします。このツール JSON string を扱うのにものすごくパワフルですよね(下記手順でも活用してます)。
sudo apt -y install jq
確認。
$ jq --version
jq-1.5-1-a5b5cbe
終わり。
Hyperledger Explorerのダウンロードと初期設定
ダウンロード
本記事で利用する release-3.8 ブランチの執筆時点のcommit hash
はe450fa3790116e9ebc4b8e49d3534a9c8e1587ba
。
$ git clone https://github.com/hyperledger/blockchain-explorer.git
Cloning into 'blockchain-explorer'...
念のため利用バージョンをcheckout
しておきます。
$ cd ~/blockchain-explorer
$ git checkout release-3.8
初期セットアップ
後は公式手順通り初期セットアップを行うだけなのですが、確認用のユニットテストがすんなり通らず意外とハマった(ただし、Ubuntu固有?)のでその辺りもメモっておきます。
データベースの初期化
$ cd ~/blockchain-explorer/app/persistence/fabric/postgreSQL/db
$ ./createdb.sh
確認:fabricexplorer データベースができていれば成功。
$ sudo -u postgres psql -l |grep fab
fabricexplorer | hppoc | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
初期設定
$ cd ~/blockchain-explorer
$ npm install
$ cd ~/blockchain-explorer/app/test
$ npm install
$ npm run test
ここのユニットテストで次のようなエラーが出ました。
(node:18469) UnhandledPromiseRejectionWarning: error: password authentication failed for user "postgres"
at Connection.parseE (/home/vagrant/blockchain-explorer/app/test/node_modules/pg/lib/connection.js:553:11)
at Connection.parseMessage (/home/vagrant/blockchain-explorer/app/test/node_modules/pg/lib/connection.js:378:19)
at Socket.<anonymous> (/home/vagrant/blockchain-explorer/app/test/node_modules/pg/lib/connection.js:119:22)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at Socket.Readable.push (_stream_readable.js:208:10)
at TCP.onread (net.js:601:20)
(node:18469) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:18469) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
#ユニットテストなので無視すればいいのかもしれませんが、、なんだか気持ち悪いのでpassさせます。
Node/NPM + pg module で MD5認証がうまくいかないという件っぽいですが、ネットにある情報で解消できなかったので、とりあえず trust 設定にして誤魔化します。
$ sudo sed -i.bak '/^host.*md5/ s/md5/trust/' /etc/postgresql/*/main/pg_hba.conf
$ sudo service postgresql restart
$ npm run test
(略)
1..54
# tests 54
# pass 54
続き。
$ cd ~/blockchain-explorer/client
$ npm install
$ npm test -- -u --coverage
こんどはここで下記のように Test failed・・(どうなってるんだ?)。
RUNS src/components/View/LandingPage.spec.js
/home/vagrant/blockchain-explorer/client/node_modules/react-scripts/scripts/test.js:20
throw err;
^
TypeError: getBlockActivity is not a function
at LandingPage.componentDidMount (/home/vagrant/blockchain-explorer/client/src/components/View/LandingPage.js:136:5)
at <anonymous>
npm ERR! Test failed. See above for more details.
#こちらもユニットテストなので無視すればいいのでしょう、、でもやはり気持ち悪いのでpassさせときます。
(getBlockActivity
関数を追加した際のテスト定義更新もれ?)spec
ファイルの問題? とりあえず、下記のようにして解決・・っと。
$ sed -i.bak '/getTransactionByOrg:/i \ getBlockActivity: jest.fn(),' src/components/View/LandingPage.spec.js
$ npm test -- -u --coverage
FailしていたLandingPage
テストも突破して下記のようなメッセージ(最後のcoverage表も)が出れば成功(多分)。
Test Suites: 26 passed, 26 total
Tests: 171 passed, 171 total
Snapshots: 0 total
Time: 12.221s
Ran all test suites.
...
続き。
$ npm run build
...
Creating an optimized production build...
Compiled successfully.
注意:
Vagrant/VirtualBox
を使用しているとここでメモリー不足で"API fatal error handler returned after process out of memory"
エラーになることがあった。デフォルト1GB
程度だと足りないようでその場合は4GB
などにして再実行すれば解決する。
終わり。
Hyperledger Explorer を動かしてみる
可視化したい対象のブロックチェーンネットワークに合わせてアプリ(Hyperledger Explorer)の設定ファイルを修正します。
アプリの設定ファイルはblockchain-explorer/app/platform/fabric/config.json
。
デフォルトはBYFNに接続するサンプルになっているので、手っ取り早く動かすにはそれを利用するのが良さそうです。
BYFN ブロックチェーンネットワークの可視化
というわけで、手っ取り早くサンプルの byfn に接続してみます。
アプリ設定ファイルの修正(byfn)
設定ファイルのfabric-path
を BYFN (というか fabric-samples )のインストールディレクトリに合わせて修正します。
例えば $HOME/fabric/fabric-samples/first-network
にある場合:
$ cd ~/blockchain-explorer
$ sed -i.bak s@fabric-path@$HOME/fabric@ app/platform/fabric/config.json
参考:編集済のファイル (gistリンク)
BYFN の起動
BYFNブロックチェーンネットワークを起動します。これは公式サンプル手順通り:
$ cd ~/fabric/fabric-samples/first-network
$ ./byfn.sh up
Starting for channel 'mychannel' with CLI timeout of '10' seconds and CLI delay of '3' seconds
Continue? [Y/n] Y
...
========= All GOOD, BYFN execution completed ===========
_____ _ _ ____
| ____| | \ | | | _ \
| _| | \| | | | | |
| |___ | |\ | | |_| |
|_____| |_| \_| |____/
Hyperledger Explorer の起動
Hyperledger Explorer を起動します。
$ cd ~/blockchain-explorer
$ ./start.sh
************************************************************************************
**************************** Hyperledger Explorer **********************************
************************************************************************************
***** Please check the log [logs/console/console-2018-10-02.log] for any error *****
************************************************************************************
バックグラウンドで実行されるので、アプリの動作ログlogs/app/app.log
を例えばtail
して観察します。
$ tail -f logs/app/app.log
...
Hyperledger Explorer の画面を開く
http://localhost:8080 をブラウザで開き、下のような画面が見えれば成功です。
参考:Hyperledger Explorer(v0.3.7版)で確認できる情報
Well done!
注意:ここの手順でDB関連のエラーで起動ができないことがあった:(
logs/console/console-YYYY-MM-DD.log
に"Error : [ 'Explorer is closing due to channel name [%s] is already exist in DB', 'mychannel' ]"
というエラーメッセージが残される)。その場合は(cd ~/blockchain-explorer/app/persistence/fabric/postgreSQL/db; ./createdb.sh)
を実行してDBを作りなおせば解決するので、ブラウザで画面が表示されない場合には確認すると良いかもしれません。
Hyperledger Explorerの停止、BYFNの消去
やめるときには stop.sh
を実行します。
^C
$ ./stop.sh
$ cd ~/fabric/fabric-samples/first-network
$ ./byfn.sh down
Stopping for channel 'mychannel' with CLI timeout of '10' seconds and CLI delay of '3' seconds
Continue? [Y/n] y
...
ついでにDBを初期化し直しておきます(上記「注意」を回避するため)。
$ (cd ~/blockchain-explorer/app/persistence/fabric/postgreSQL/db/; ./createdb.sh)
fabcar ブロックチェーンネットワークの可視化
デフォルト以外のブロックチェーンにも繋いでみてみたいので、続けて fabcar サンプルに接続してみました。
参考
Fabcarサンプルで学ぶHyperledger Fabric Node.js SDK
アプリ設定ファイルの修正(fabcar/basic-network)
fabcarサンプルは basic-network サンプルのブロックチェーンネットワークを使って動作するアプリなのでfabric-path
などを basic-network に設定します。また、byfn と違い、basic-network は non-TLS モードで動作するのでそのあたりも合わせこむ必要があります。具体的には下記の通りです。
config.json の修正①
まずは簡単なところから。
例えば $HOME/fabric/fabric-samples/basic-network
にある場合:
-
fabric-path
->$HOME/fabric
- サンプルの
first-network
をbasic-network
に書き換え
続けて non-TLS の設定:
- tlsEnable を false に設定
- grpcs -> grpc
面倒なので以上を行う sed one-liner を実行します:
$ cd ~/blockchain-explorer
$ sed -i.bak -e s@fabric-path@$HOME/fabric@ -e s@first-network@basic-network@ -e '/tlsEnable/ s/true/false/' -e s@grpcs@grpc@ app/platform/fabric/config.json
config.json の修正②
次に basic-network に不要なOrg
やPeer
の設定を削除します:
- Organization を Org1 のみにする(他のOrg設定は削除)
- peers を peer0.org1.example.com のみにする(他のピア定義を削除)
- non-TLS 接続のため tlsCACerts 定義を削除
面倒なので以上を行う jq one-liner(もっと効率的な書き方ありそう。とりあえずベタに羅列)を実行します:
$ cp app/platform/fabric/config.json app/platform/fabric/config.json.org
$ jq '. | del(."network-configs"."network-1"."organizations"."Org2MSP") | del(."network-configs"."network-1"."peers"."peer0.org2.example.com",."network-configs"."network-1"."peers"."peer1.org2.example.com",."network-configs"."network-1"."peers"."peer1.org1.example.com",."network-configs"."network-1"."peers"."peer0.org1.example.com"."tlsCACerts")' app/platform/fabric/config.json.org > app/platform/fabric/config/config.json
参考:編集済のファイル (gistリンク)
basic-network - docker-compose.ymlの修正
初めて試した時にはHyperledger Explorerの画面でブロックやノード情報が何も表示されずハマりました。調べた結果、最新の Hyperledger Explorer は Fabric v1.2 で追加された Service Discovery を利用してノード情報を取得しているようで、これが basic-networkで構成されていないことが原因のようでした。
この機能を basic-network で利用できるようにするためには docker-compose.yml を修正して、CORE_PEER_GOSSIP_EXTERNAL_ENDPOINT
とCORE_PEER_GOSSIP_BOOTSTRAP
環境変数の設定を追加します。具体的には下記の箇所になります(# For using v1.2 Service Discovery from app
以下3行を追加):
peer0.org1.example.com:
container_name: peer0.org1.example.com
image: hyperledger/fabric-peer
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_PEER_ID=peer0.org1.example.com
- CORE_LOGGING_PEER=info
- CORE_CHAINCODE_LOGGING_LEVEL=info
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
# For using v1.2 Service Discovery from app
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
(後者の環境変数だけで良いかもしれないが、とりあえず両方つけておいた)
参考:Stack Overflow CORE_PEER_GOSSIP_EXTERNAL_ENDPOINT/CORE_PEER_GOSSIP_BOOTSTRAP環境変数の解説(英語)
参考:編集済のファイル (gistリンク)
fabcar(basic-network) の起動と初期設定
basic-networkのブロックチェーンネットワークを起動します。これは公式サンプル手順通り:
$ cd ~/fabric/fabric-samples/fabcar
$ npm install
$ ./startFabric.sh
$ node enrollAdmin.js
...
Successfully enrolled admin user "admin"
...
$ node registerUser.js
...
User1 was successfully registered and enrolled and is ready to interact with the fabric network
...
このあたりで何をしているかなどはこちらに詳しく書いてありますので、ご興味があればご参照ください -> Fabcarサンプルで学ぶHyperledger Fabric Node.js SDK
確認のため query.js を実行してブロックチェーン上の資産(車)の一覧を取得してみます。
$ node query.js
...
Successfully loaded user1 from persistence
Query has completed, checking results
Response is [{"Key":"CAR0", "Record":{"colour":"blue","make":"Toyota","model":"Prius","owner":"Tomoko"}},{"Key":"CAR1", "Record":{"colour":"red","make":"Ford","model":"Mustang","owner":"Brad"}},{"Key":"CAR2", "Record":{"colour":"green","make":"Hyundai","model":"Tucson","owner":"Jin Soo"}},{"Key":"CAR3", "Record":{"colour":"yellow","make":"Volkswagen","model":"Passat","owner":"Max"}},{"Key":"CAR4", "Record":{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}},{"Key":"CAR5", "Record":{"colour":"purple","make":"Peugeot","model":"205","owner":"Michel"}},{"Key":"CAR6", "Record":{"colour":"white","make":"Chery","model":"S22L","owner":"Aarav"}},{"Key":"CAR7", "Record":{"colour":"violet","make":"Fiat","model":"Punto","owner":"Pari"}},{"Key":"CAR8", "Record":{"colour":"indigo","make":"Tata","model":"Nano","owner":"Valeria"}},{"Key":"CAR9", "Record":{"colour":"brown","make":"Holden","model":"Barina","owner":"Shotaro"}}]
問題なさそうですね。
Hyperledger Explorer の起動
BYFN の例(上記)と同じ手順です。
$ cd ~/blockchain-explorer
$ ./start.sh
************************************************************************************
**************************** Hyperledger Explorer **********************************
************************************************************************************
***** Please check the log [logs/console/console-2018-10-02.log] for any error *****
************************************************************************************
バックグラウンドで実行されるので、アプリの動作ログlogs/app/app.log
を例えばtail
して観察します。
$ tail -f logs/app/app.log
...
Hyperledger Explorer の画面を開く
http://localhost:8080 をブラウザで開き、下のような画面が見えれば成功です。
参考:Hyperledger Explorer(v0.3.7版)で確認できる情報
Well done!!
invoke トランザクションを実行してブロックチェーンを追加してみる
初期状態を見るだけなのも少々つまらないので、せっかくなので、トランザクションを起こして Hyperledger Explorer の表示の変化を見てみましょう。
invoke.js の修正(fcnとargsの箇所)
fabcar サンプル付属のinvoke.js
スクリプトを修正して、チェーンコードのcreateCar
関数を呼び出してCAR10
(Nissan GTR) 資産を追加するトランザクションを実行してみます。
var request = {
//targets: let default to the peer assigned to the client
chaincodeId: 'fabcar',
fcn: 'createCar',
args: ['CAR10', 'Nissan', 'GTR', 'Gun Metallic', 'Paul Allen'],
chainId: 'mychannel',
txId: tx_id
};
参考:編集済のファイル (gistリンク)
invoke.js の実行
$ cd ~/fabric/fabric-samples/fabcar
$ node invoke.js
...
実行が成功し、資産CAR10
が追加されたはずです。query.js
を利用して念のため確認します。
$ node query.js | grep Response | sed -E 's/Response is (.*)/\1/g' | jq 'map(select(.Key == "CAR10"))[]'
{
"Key": "CAR10",
"Record": {
"colour": "Gun Metallic",
"make": "Nissan",
"model": "GTR",
"owner": "Paul Allen"
}
}
うまくいきました。
Hyperledger Explorerの画面にも反映される
Hyperledger Explorer 画面の内容が更新されて、追加されたブロックやトランザクションの内容が確認できるはずです。
いい感じに見えてますね!
Hyperledger Explorer の停止、basic-network の消去
最後にクリーンアップして終わります。
$ cd ~/blockchain-explorer
$ ./stop.sh
$ cd ~/blockchain-explorer/app/persistence/fabric/postgreSQL/db/
$ ./createdb.sh
$ cd ~/fabric/fabric-samples/basic-network
$ ./stop.sh; ./teardown.sh
# Shut down the Docker containers that might be currently running.
...
Untagged: dev-peer0.org1.example.com-fabcar-1.0-5c906e402ed29f20260ae42283216aa75549c571e2e380f3615826365d8269ba:latest
Deleted: sha256:87f02230cf12f7490d02f14f09c60b3a37dd83cf8457177ca0d5af28cd091ec7
Deleted: sha256:41ad9de237e53679ed99e5d286fa6900a2f8bca3c626f3dc96ddb4273dd886e2
Deleted: sha256:91fab37bc2bb1c5175a4432aa45f6c8f9f64862fbe9fed8f35ef22351d67ffe8
Deleted: sha256:ca0492ce9b313c1a273a00c8d5e3d0120ae80ec4994cda092c0e364ae5c5434d
(終わり)