Hyperledger Fabric v1.0.1 のセットアップとサンプルの実行


最近公開された v1.0.1 でサンプル "Build Your First Network" と "Balance transfer" を動かしてみたのでメモ。

他のサンプルも実行したら順次追記する予定です。

# Hyperledger Fabric とは？

エンタープライズシステム向けのブロックチェーンフレームワーク。

ビットコインのブロックチェーンはパブリックなネットワークで動かすことが前提ですが、Hyperledger Fabric はプライベートなネットワークで動かすことが前提となっています。

ドキュメント(英語): https://hyperledger-fabric.readthedocs.io/en/latest/
本体ソースコード : https://github.com/hyperledger/fabric
サンプルソースコード : https://github.com/hyperledger/fabric-samples

# v0.6 と v1.0 の違い

Hyperledger Fabric 1.0 概要 @ SlideShare
https://www.slideshare.net/Hyperledger_Tokyo/hyperledger-fabric-10

# 実行環境
- Windows 7 
- Virtual-Box 5.1.22
- Lubuntu 16.10

Lubuntu はデフォルトでは ssh-server が入っていないのでホストマシンからSSHで接続して作業する場合は、

```bash
$ sudo apt-get install openssh-server
```

それから Virtual-Box でポート22をポートフォワーディングするように設定する。

# Fabric の前提条件

- cURL
- 
```bash
$ sudo apt install curl
```

- Docker (17.03.1-ce or greater) 

```bash
# 古い docker が入っている場合は削除。
$ sudo apt-get remove docker docker-engine docker.io
```

```bash
$ sudo apt-get update

# Recommended extra packages for Trusty 14.04（ここは要らないかもだけど一応）
$ sudo apt-get install \
    linux-image-extra-$(uname -r) \
    linux-image-extra-virtual
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common

# Add Docker’s official GPG key
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88

# リポジトリの追加
$ 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-compose (1.8 or greater)

```bash
$ sudo su -
$ curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
$ exit
$ sudo chmod +x /usr/local/bin/docker-compose
```

- golang 1.7.x

```bash
$ sudo apt-get update
$ wget https://storage.googleapis.com/golang/go1.7.1.linux-amd64.tar.gz
$ sudo tar -zxvf  go1.7.1.linux-amd64.tar.gz -C /usr/local/
$ mkdir $HOME/work
$ export PATH=$PATH:/usr/local/go/bin
$ export GOPATH=$HOME/work
```

- Node.js (version 6.9.x or greater)  *version 7.x は非サポート*

```bash
$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
$ sudo apt-get install -y nodejs
$ sudo npm install npm@3.10.10 -g
```

# Fabric のバイナリと Docker Images のインストール

Docker Images のダウンロードに時間がかかります。

```bash
$ sudo su 
# 次のシェルは v1.0.0 と v1.0.1 でファイルが異なる
$ curl -sSL https://goo.gl/eYdRbX | bash
$ exit
# Facricのバイナリがあるところにパスを通す
$ export PATH=$PATH:[Your Home]/bin
```

# Hyperledger Fabric Samples のクローン

```bash
$ cd
$ git clone https://github.com/hyperledger/fabric-samples.git
```

# サンプル１: Build Your First Network (byfn)

とりあえず fabric ネットワークを立ち上げてみよう、というデモ。

まずは genesis block を作る。

```bash
cd ~/fabric-samples/first-network
$ sudo ./byfn.sh -m generate
```

```
Generating certs and genesis block for with channel 'mychannel' and CLI timeout of '10000'
Continue (y/n)? y
proceeding ...
/home/****/bin/cryptogen

##########################################################
##### Generate certificates using cryptogen tool #########
##########################################################
org1.example.com
org2.example.com

/home/****/bin/configtxgen
##########################################################
#########  Generating Orderer Genesis block ##############
##########################################################
2017-08-15 17:16:31.433 JST [common/configtx/tool] main -> INFO 001 Loading configuration
2017-08-15 17:16:31.463 JST [common/configtx/tool] doOutputBlock -> INFO 002 Generating genesis block
2017-08-15 17:16:31.465 JST [common/configtx/tool] doOutputBlock -> INFO 003 Writing genesis block

#################################################################
### Generating channel configuration transaction 'channel.tx' ###
#################################################################
2017-08-15 17:16:31.495 JST [common/configtx/tool] main -> INFO 001 Loading configuration
2017-08-15 17:16:31.498 JST [common/configtx/tool] doOutputChannelCreateTx -> INFO 002 Generating new channel configtx
2017-08-15 17:16:31.499 JST [common/configtx/tool] doOutputChannelCreateTx -> INFO 003 Writing new channel tx

#################################################################
#######    Generating anchor peer update for Org1MSP   ##########
#################################################################
2017-08-15 17:16:31.527 JST [common/configtx/tool] main -> INFO 001 Loading configuration
2017-08-15 17:16:31.530 JST [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 002 Generating anchor peer update
2017-08-15 17:16:31.530 JST [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 003 Writing anchor peer update

#################################################################
#######    Generating anchor peer update for Org2MSP   ##########
#################################################################
2017-08-15 17:16:31.558 JST [common/configtx/tool] main -> INFO 001 Loading configuration
2017-08-15 17:16:31.561 JST [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 002 Generating anchor peer update
2017-08-15 17:16:31.562 JST [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 003 Writing anchor peer update
```

Fabricネットワークの起動。ピアが4つとordererなどが立ち上がります。

```
$ sudo ./byfn.sh -m up
```

```
Starting with channel 'mychannel' and CLI timeout of '10000'
Continue (y/n)? y
proceeding ...
Creating network "net_byfn" with the default driver
Creating peer0.org2.example.com ...
Creating peer1.org2.example.com ...
Creating peer0.org1.example.com ...
Creating peer1.org1.example.com ...
Creating orderer.example.com ...
Creating peer1.org2.example.com
Creating peer1.org1.example.com
Creating orderer.example.com
Creating peer0.org1.example.com
Creating orderer.example.com ... done
Creating cli ...
Creating cli ... done

 ____    _____      _      ____    _____
/ ___|  |_   _|    / \    |  _ \  |_   _|
\___ \    | |     / _ \   | |_) |   | |
 ___) |   | |    / ___ \  |  _ <    | |
|____/    |_|   /_/   \_\ |_| \_\   |_|

Build your first network (BYFN) end-to-end test

Channel name : mychannel
Creating channel...

*** 省略 ***

========= All GOOD, BYFN execution completed ===========


 _____   _   _   ____
| ____| | \ | | |  _ \
|  _|   |  \| | | | | |
| |___  | |\  | | |_| |
|_____| |_| \_| |____/
```

終了

```bash
$ sudo ./byfn.sh -m down
```

# サンプル２: Balance transfer

AさんからBさんに（何かの）10単位分の価値を移動する、といったデモ。

起動

```bash
$ # jq のインストール
$ sudo apt-get install jq
$ cd ~/fabric-samples/balance-transfer
$ sudo ./runApp.sh
```

```
Creating network "artifacts_default" with the default driver
Creating ca_peerOrg2 ...
Creating ca_peerOrg1 ...
Creating ca_peerOrg2
Creating orderer.example.com ...
Creating ca_peerOrg1
Creating orderer.example.com ... done
Creating peer1.org1.example.com ...
Creating peer1.org2.example.com ...
Creating peer0.org2.example.com ...
Creating peer0.org1.example.com ...
Creating peer1.org2.example.com
Creating peer1.org1.example.com
Creating ca_peerOrg1 ... done
Creating peer1.org1.example.com ... done
/home/daiwabc/fabric-samples/balance-transfer


============== node modules installed already =============

[2017-08-16 14:18:59.195] [DEBUG] Helper - [crypto_ecdsa_aes]: constructor, keySize: 256
[2017-08-16 14:18:59.198] [DEBUG] Helper - [crypto_ecdsa_aes]: Hash algorithm: SHA2, hash output size: 256
[2017-08-16 14:18:59.268] [DEBUG] Helper - [utils.CryptoKeyStore]: CryptoKeyStore, constructor - start
[2017-08-16 14:18:59.269] [DEBUG] Helper - [utils.CryptoKeyStore]: constructor, no super class specified, using config: fabric-client/lib/impl/FileKeyValueStore.js
[2017-08-16 14:18:59.274] [DEBUG] Helper - [crypto_ecdsa_aes]: constructor, keySize: 256
[2017-08-16 14:18:59.274] [DEBUG] Helper - [crypto_ecdsa_aes]: Hash algorithm: SHA2, hash output size: 256
[2017-08-16 14:18:59.274] [DEBUG] Helper - [utils.CryptoKeyStore]: CryptoKeyStore, constructor - start
[2017-08-16 14:18:59.274] [DEBUG] Helper - [utils.CryptoKeyStore]: constructor, no super class specified, using config: fabric-client/lib/impl/FileKeyValueStore.js
[2017-08-16 14:18:59.298] [INFO] SampleWebApp - ****************** SERVER STARTED ************************
[2017-08-16 14:18:59.298] [INFO] SampleWebApp - **************  http://localhost:4000  ******************
```

各サービスが立ち上がり待受状態となりました、

もうひとつターミナルを立ち上げて、APIをテストするシェルを実行します。

```bash
cd ~/fabric-samples/balance-transfer
sudo ./testAPIs.sh
```

```
POST request Enroll on Org1  ...

{"success":true,"secret":"adAVpKtRcdDi","message":"Jim enrolled Successfully","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MDI4OTc2MTcsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE1MDI4NjE2MTd9.RAbz1IQwVwsJv9TqP18v81Q1gibu8zxGJr6BuY35DbU"}

ORG1 token is eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MDI4OTc2MTcsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE1MDI4NjE2MTd9.RAbz1IQwVwsJv9TqP18v81Q1gibu8zxGJr6BuY35DbU

POST request Enroll on Org2 ...

{"success":true,"secret":"rRcntAKVCWSw","message":"Barry enrolled Successfully","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MDI4OTc2MTcsInVzZXJuYW1lIjoiQmFycnkiLCJvcmdOYW1lIjoib3JnMiIsImlhdCI6MTUwMjg2MTYxN30.dplrRrWrX7jVgCOHAEJdUhn8Y0K__1JXmF9BXLVCljg"}

ORG2 token is eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MDI4OTc2MTcsInVzZXJuYW1lIjoiQmFycnkiLCJvcmdOYW1lIjoib3JnMiIsImlhdCI6MTUwMjg2MTYxN30.dplrRrWrX7jVgCOHAEJdUhn8Y0K__1JXmF9BXLVCljg


POST request Create channel  ...

{"success":true,"message":"Channel 'mychannel' created Successfully"}

POST request Join channel on Org1

{"success":true,"message":"Successfully joined peers in organization org1 to the channel 'mychannel'"}

POST request Join channel on Org2

{"success":true,"message":"Successfully joined peers in organization org2 to the channel 'mychannel'"}

POST Install chaincode on Org1

Successfully Installed chaincode on organization org1

POST Install chaincode on Org2

Successfully Installed chaincode on organization org2

POST instantiate chaincode on peer1 of Org1

Chaincode Instantiateion is SUCCESS

POST invoke chaincode on peers of Org1 and Org2

Transacton ID is 55aa799121798fce605030c42f39afec844d21b950afb050017b6254982b1234


GET query chaincode on peer1 of Org1

a now has 90 after the move

GET query Block by blockNumber
[省略]

GET query Transaction by TransactionID
[省略]
{"key":"a","is_delete":false,"value":"90"},{"key":"b","is_delete":false,"value":"210"}
[省略]

GET query ChainInfo
[省略]

GET query Installed chaincodes

["name: mycc, version: v0, path: github.com/example_cc"]

GET query Instantiated chaincodes

["name: mycc, version: v0, path: github.com/example_cc"]

GET query Channels

{"channels":[{"channel_id":"mychannel"}]}

Total execution time : 35 secs ...
```

"GET query Transaction by TransactionID" のところでAさんBさんのバランス内容が確認できる。ただこれ何度実行しても同じ値（笑）。実行するたびに chaincode をインストールしてるから初期化されてるのかな？

# その後

そして時は2021年。ブロックチェーンの熱が冷めていくとともに HyperLedger の名前を聞くことも減りました。ビットコインの高騰に伴って仮想通貨コミュニティはまだ存続しているみたいだけど、なんとかだったんだろう数年前のあの騒ぎは...。