Blockchain Analyzer

こんにちは、(株)日立製作所 研究開発グループ サービスコンピューティング研究部の西島です。

# はじめに
OSSのブロックチェーン基盤プロジェクトHyperledgerは、Hyperledger FabricやHyperledger Sawtoothなどの公式のプロジェクト以外にも、実験的なプロジェクトを行う場を提供するHyperledger labsがあります。
 
https://wiki.hyperledger.org/display/labs/Hyperledger+Labs+Home
https://github.com/hyperledger-labs
 
今回はHyperledger labsの実験的なプロジェクトの１つ、Blockchain Analyzerを紹介します。Blockchain AnalyzerはElasticsearchのagentで、ブロックチェーンネットワークのブロックやトランザクションを取得することができます。このプロジェクトはHyperledger summer internship programの成果の１つです。
https://github.com/hyperledger-labs/blockchain-analyzer
https://wiki.hyperledger.org/display/INTERN/Analyzing+Hyperledger+Fabric+Ledger%2C+Transactions%2C+and+Logs+using+Elasticsearch+and+Kibana

Hyperledgerにはブロックチェーンネットワークの状況を可視化することができるHyperledger Explorerという公式のプロジェクトがあります。Hyperledger Explorerは情報収集やデータの保存、可視化を全て行うのに対して、Blockchain Analyzerは、データの保存にElasticsearchを利用し、可視化はKibanaを利用しています。
 
# 環境構築
基本的には"Getting Started with Basic Network"の通りに行います。
https://github.com/hyperledger-labs/blockchain-analyzer/blob/master/docs/Basic_setup.md


## 構成
今回は1台のサーバでHyperledger Fabricと、Elasticsearch, Kibana、Blockchain Analyzerを動かします。OSはubuntu 18.04を使います。
 

## Prerequests
公式には以下のソフトウェアが必要と記載されていますが実際はもう少しバージョンが低くても大丈夫です。セットアップを簡単にするためにdockerとdocker-compose以外はubuntuの公式レポジトリから取得できるものを利用します。

| パッケージ | 公式 | 今回使用したバージョン |
|---|---|---|
| Go | v1.12.7+ | v1.10 |
| Docker | v19.03.0+ | 19.03.5 |
| docker-compose | v1.24.1+ | v1.25.0 |
| Node.js| v8.10+ | v8.10 |
| python| 2.7 | 2.7|
| virtualenv| 16.7.0+ | 15.1.0 |

それぞれのパッケージをインストールします。

```
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sh get-docker.sh
$ sudo usermod -aG docker ubuntu
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo apt install -y nodejs npm python virtualenv make gcc golang
```
Ubuntuユーザーでdockerコマンドを実行するために一旦ログアウトして再度ログインします。

## Blockchain Analyzerのセットアップ
Goのパスを通してソースコードを取得します。

```
$ export GOPATH=~/go
$ export PATH=$PATH:$GOPATH/bin
$ mkdir -p $GOPATH/src/github.com
$ cd $GOPATH/src/github.com
$ git clone https://github.com/hyperledger-labs/blockchain-analyzer.git
 ```

## Hyperledger Fabric networkのセットアップ
組織は4つで各組織に1つpeerとなる構成のfabric networkを立ち上げます。

```
$ cd $GOPATH/src/github.com/blockchain-analyzer/network/basic/
$ make start
Linux ip-10-0-0-94 4.15.0-1051-aws #53-Ubuntu SMP Wed Sep 18 13:35:53 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
org1.el-network.com
org2.el-network.com
org3.el-network.com
org4.el-network.com
2019-12-04 01:36:31.983 UTC [common.tools.configtxgen] main -> WARN 001 Omitting the channel ID for configtxgen for output operations is deprecated. Explicitly passing the channel ID will be required in the future, defaulting to 'testchainid'.
2019-12-04 01:36:31.983 UTC [common.tools.configtxgen] main -> INFO 002 Loading configuration
2019-12-04 01:36:32.019 UTC [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
...
Installing chaincode on peer4...
2019-12-04 01:38:22.199 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2019-12-04 01:38:22.199 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
2019-12-04 01:38:22.249 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >
2019-12-04 01:38:22.350 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2019-12-04 01:38:22.350 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
 ```
上記のOKが出力されていれば、chaincodeのインストールは成功です。

## appsのセットアップ
必要なnpmをインストールします。

```
$ cd $GOPATH/src/github.com/blockchain-analyzer/apps/dummyapp/
$ npm install
 
loadDep:fabric-network → ▌ ╢██████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░╟
WARN engine fabric-network@1.4.4: wanted: {"node":"^8.9.0 || ^10.15.3","npm":"^5.5.1 || ^6.4.1"} (cu
loadDep:fabric-network → ▌ ╢██████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░╟
WARN engine fabric-ca-client@1.4.4: wanted: {"node":"^8.9.0 || ^10.15.3","npm":"^5.5.1 || ^6.4.1"} (
loadDep:fabric-ca-client ▄ ╢████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░╟
WARN engine fabric-client@1.4.4: wanted: {"node":"^8.9.0 || ^10.15.3","npm":"^5.5.1 || ^6.4.1"} (cur
npm WARN deprecated hoek@4.2.1: This version has been deprecated in accordance with the hapi support
policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes,
and security patches. If you are unable to upgrade at this time, paid support is available for olde
r versions (hapi.im/commercial).
...
 
npm WARN optional Skipping failed optional dependency /chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.2.9
npm WARN dummyapp@ No repository field.
npm WARN dummyapp@ No license field.
 ```

各組織のadminとユーザーを作成します。

```
$ make users
NETWORK=basic node enrollAdmins.js
Wallet path: /home/ubuntu/go/src/github.com/blockchain-analyzer/apps/dummyapp/wallet
Successfully enrolled admin user and imported it into the wallet: adminOrg1
Successfully enrolled admin user and imported it into the wallet: adminOrg2
Successfully enrolled admin user and imported it into the wallet: adminOrg3
Successfully enrolled admin user and imported it into the wallet: adminOrg4
NETWORK=basic node registerUsers.js
Wallet path: /home/ubuntu/go/src/github.com/blockchain-analyzer/apps/dummyapp/wallet
Successfully registered and enrolled user and imported it into the wallet: user1
Successfully registered and enrolled user and imported it into the wallet: user2
Successfully registered and enrolled user and imported it into the wallet: user3
Successfully registered and enrolled user and imported it into the wallet: user4
 ```

トランザクションを投げます。

```
$ make invoke
NETWORK=basic CHANNEL=mychannel node invoke.js
Wallet path: /home/ubuntu/go/src/github.com/blockchain-analyzer/apps/dummyapp/wallet
Transaction has been submitted: user1 setValue Key1
Transaction has been submitted: user2 setValue Key2 Key1
Transaction has been submitted: user3 setValue Key3 Key2
Transaction has been submitted: user4 setValue Key4
Transaction has been submitted: user1 setValue Key2
Transaction has been submitted: user1 setValue Key3
Transaction has been submitted: user2 setValue Key2
Transaction has been submitted: user3 setValue Key2
Transaction has been submitted: user4 setValue Key4
Transaction has been submitted: user2 setValue Key4
 ```

トランザクションの中身を確認します。

```
$ make query-all
NETWORK=basic node queryAll.js
Wallet path: /home/ubuntu/go/src/github.com/blockchain-analyzer/apps/dummyapp/wallet
No key provided, querying all values
Transaction has been evaluated, result is: [{"Key":"Key1","Record":{"hash":"d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35","keyval":"2"}},{"Key":"Key2","Record":{"hash":"2c624232cdd221771294dfbb310aca000a0df6ac8b66b696d90ef06fdefb64a3","keyval":"8"}},{"Key":"Key3","Record":{"hash":"4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a","keyval":"4"}},{"Key":"Key4","Record":{"hash":"e7f6c011776e8db7cd330b54174fd76f7d0216b612387a5ffcfb81e6f0919683","keyval":"6"}}]
 ```

## Elasticsearch, Kibanaのセットアップ

Elasticsearchは大量にメモリを利用するので、プロセスが使用可能なメモリマップ領域の最大数を引き揚げます。

```
$ sudo sysctl -w vm.max_map_count=262144
```

Blockchain AnalyzerがElasticsearchとKibanaのdocker-composeを用意しているので起動します。

``` 
$ cd $GOPATH/src/github.com/blockchain-analyzer/stack
$ make start
docker-compose -f docker-compose.yml up -d
WARNING: Some services (elasticsearch, elasticsearch2, elasticsearch3, kibana) use the 'deploy' key, which will be ignored. Compose does not support 'deploy' configuration - use `docker stack deploy` to deploy to a swarm.
Creating network "stack_elastic" with the default driver
Creating network "stack_ingress" with the default driver
Creating volume "stack_esdata1" with default driver
Creating volume "stack_esdata2" with default driver
Creating volume "stack_esdata3" with default driver
Creating volume "stack_logs" with default driver
...
Digest: sha256:50cf965a6e08ec5784009d0fccb380fc479826b6e0e65684d9879170a9df8566
Status: Downloaded newer image for nginx:latest
Creating elasticsearch1 ... done
Creating stack_nginx_1 ... done
Creating kibana ... done
Creating elasticsearch3 ... done
Creating elasticsearch2 ... done
 ```

これで準備が整いました。

# Blockchain Analyzer agent

agentをビルドするために必要なgoのライブラリを取得します。
## build
``` 
$ cd $GOPATH/src/github.com/blockchain-analyzer/agent/fabricbeat
$ make go-get
go get -v github.com/hyperledger/fabric/core/ledger
github.com/hyperledger/fabric (download)
github.com/hyperledger/fabric/common/metrics
github.com/hyperledger/fabric/vendor/go.uber.org/zap/buffer
github.com/hyperledger/fabric/vendor/google.golang.org/grpc/internal/grpcsync
github.com/hyperledger/fabric/vendor/google.golang.org/grpc/encoding
github.com/hyperledger/fabric/vendor/golang.org/x/text/transform
github.com/hyperledger/fabric/vendor/golang.org/x/crypto/sha3
...
github.com/blockchain-analyzer/agent/fabricbeat/vendor/github.com/elastic/beats/libbeat/cmd/export
github.com/blockchain-analyzer/agent/fabricbeat/vendor/github.com/elastic/beats/libbeat/cmd/test
github.com/blockchain-analyzer/agent/fabricbeat/vendor/github.com/elastic/beats/libbeat/cmd
github.com/blockchain-analyzer/agent/fabricbeat/cmd
github.com/blockchain-analyzer/agent/fabricbeat
# this package is include twice. also present in github.com/golang.org/x/net/trace
rm -rf ../../../hyperledger/fabric/vendor/golang.org/x/net/trace
 ```

agentをビルドします。

```
$ make
go build -i -ldflags "-X /home/ubuntu/go/src/github.com/blockchain-analyzer/agent/fabricbeat/vendor/github.com/elastic/beats/libbeat/version.buildTime=2019-12-04T04:50:35Z -X /home/ubuntu/go/src/github.com/blockchain-analyzer/agent/fabricbeat/vendor/github.com/elastic/beats/libbeat/version.commit=32116c1360edf7a91d32355542f7ac41ff17d6f4"
```

fabricbeatができました。

```
$ ls
CONTRIBUTING.md README.md config fabricbeat.docker.yml go.sum main.go tests
LICENSE.txt _meta data fabricbeat.reference.yml include main_test.go vendor
Makefile beater docs fabricbeat.yml keystore make.bat
NOTICE.txt cmd fabricbeat go.mod magefile.go modules
```

設定ファイルfabricbeat.ymlに書き込み権限を与えます。

```
$ chmod go-w /home/ubuntu/go/src/github.com/blockchain-analyzer/agent/fabricbeat/fabricbeat.yml
```

## start

agentを起動します。環境変数でpeerのorgやpeerの情報を渡します。

```
$ ORG_NUMBER=1 PEER_NUMBER=0 NETWORK=basic ./fabricbeat -e -d "*"
2019-12-04T04:54:16.846Z INFO instance/beat.go:606 Home path: [/home/ubuntu/go/src/github.com/blockchain-analyzer/agent/fabricbeat] Config path: [/home/ubuntu/go/src/github.com/blockchain-analyzer/agent/fabric
beat] Data path: [/home/ubuntu/go/src/github.com/blockchain-analyzer/agent/fabricbeat/data] Logs path: [/home/u
buntu/go/src/github.com/blockchain-analyzer/agent/fabricbeat/logs]
2019-12-04T04:54:16.846Z DEBUG [beat] instance/beat.go:658 Beat metadata path: /home/ubuntu/go/src/github.com/blockchain-analyzer/agent/fabricbeat/data/meta.json
2019-12-04T04:54:16.846Z INFO instance/beat.go:614 Beat ID: 6968295d-01a8-4df1-b945-40452f2340e2 2019-12-04T04:54:16.863Z DEBUG [filters] add_cloud_metadata/add_cloud_metadata.go:164 add_clo
ud_metadata: starting to fetch metadata, timeout=3s
2019-12-04T04:54:16.867Z DEBUG [filters] add_cloud_metadata/add_cloud_metadata.go:196 add_cloud_metadata: received disposition for digitalocean after 2.659717ms. result=[provider:digitalocean, error=faile
d with http status code 404, metadata={}] 2019-12-04T04:54:16.867Z DEBUG [filters] add_cloud_metadata/add_cloud_metadata.go:196 add_clo
ud_metadata: received disposition for az after 3.93326ms. result=[provider:az, error=failed with http status co
de 404, metadata={}]
...
2-04T04:54:59.582Z INFO beater/fabricbeat.go:124 Start event loop
2019-12-04T04:55:00.582Z INFO beater/fabricbeat.go:124 Start event loop
2019-12-04T04:55:01.582Z INFO beater/fabricbeat.go:124 Start event loop
2019-12-04T04:55:02.582Z INFO beater/fabricbeat.go:124 Start event loop
2019-12-04T04:55:03.582Z INFO beater/fabricbeat.go:124 Start event loop
...
```

## 確認
http://localhost:5601にアクセスして確認します。
画面左側の上から3つ目の四角が並んでいるアイコンDashboardを選択します。
![スクリーンショット 2019-12-04 14.03.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546649/fda723ec-e621-37cf-4acb-de9910162730.png)


indexを作成するためにfabricbeat-*を選択します。
![スクリーンショット 2019-12-04 14.04.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546649/f3730573-a09b-9cb7-e455-68e19eb23afc.png)


右上の星を押してデフォルトのindexにします。
![スクリーンショット 2019-12-04 14.04.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546649/5d688fcc-c275-80c7-285a-d62b29521919.png)


もう一度Dashboardを押すと既に用意されているものが表示されます。Overview Dashboardを選択します。
![スクリーンショット 2019-12-04 14.04.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546649/d10e9bf6-322f-7b3a-5236-0a59b7a7aa2c.png)


一覧が表示されますが、15分以内のトランザクションが表示されるので、もしblock数が0であれば真ん中右側のカレンダーのアイコンをして、minutesからhoursに変えます。
![スクリーンショット 2019-12-04 14.05.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546649/5a805176-6b5c-b5a7-230a-6b2a78145f20.png)

これで、blockchain analyzerを使って、ブロックやトランザクションが見える様になりました。
![スクリーンショット 2019-12-04 14.05.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546649/672eabfe-7cf6-c79d-011e-4e0e8295f080.png)


## invoke
invokeのアプリケーションを実行してblockを増やしてみます。

 ```
$ make invoke
NETWORK=basic CHANNEL=mychannel node invoke.js
Wallet path: /home/ubuntu/go/src/github.com/blockchain-analyzer/apps/dummyapp/wallet
Transaction has been submitted: user1 setValue Key1
Transaction has been submitted: user2 setValue Key2 Key1
Transaction has been submitted: user3 setValue Key3 Key2
Transaction has been submitted: user4 setValue Key4
Transaction has been submitted: user1 setValue Key2
Transaction has been submitted: user1 setValue Key3
Transaction has been submitted: user2 setValue Key2
Transaction has been submitted: user3 setValue Key2
Transaction has been submitted: user4 setValue Key4
Transaction has been submitted: user2 setValue Key4
 ```

## 再確認
36個のBlockが見えました。
![スクリーンショット 2019-12-04 14.08.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546649/3507ee5b-a10f-ef2f-8e33-748c9cf458e4.png)


他にもBlock DashboardやTransaction Dashboardもあります。
![スクリーンショット 2019-12-04 14.09.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546649/b460d05d-bd23-11ef-7fa8-362dec39e661.png)
![スクリーンショット 2019-12-04 14.08.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546649/c3c75ac0-b293-c669-1c45-75f131dd6a82.png)

# まとめ
以上のように、Blockchain Analyzerの動作状況を確認できました。Hyperledgerでは、現在も様々なプロジェクトや新機能の実装が続いています。動向を引き続きウォッチし、ご紹介していきたいと思います

# 参考
ブロックチェーンの特徴やユースケースについて
https://www.hitachi.co.jp/products/it/blockchain/index.html