Hyperledger Fabricのビルド方法とネットワーク構築

# はじめに
BlockChain Advent Calendar 2017の10日目の記事です。
この記事は、Hyperledger Fabricのサンプルリポジトリ([hyperledger/fabric-samples](https://github.com/hyperledger/fabric-samples))を使って、ブロックチェーンネットワークの構築手順を解読した結果を記載しました。
設定ファイルや環境変数については、サンプルリポジトリの内容を確認してください。

# Hyperledger Fabricとは
The Linux Foundation主体で開発しているブロックチェーン基盤の1つ。
詳細は、以下の先人の記事を参照してください。

* [公式サイト](http://hyperledger.org/)
* [公式ドキュメント](http://hyperledger-fabric.readthedocs.io/en/release/)
* [オープンソースのブロックチェーン Hyperledger Fabric を試してみる](https://qiita.com/kyrieleison/items/ec5223bbe6140822df4a#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB)

# 環境構成
## 動作環境
* OS: Ubuntu 16.04
* 台数: 1台

## 利用バージョン
* [Hyperledger Fabric](https://github.com/hyperledger/fabric): v1.1.0-preview
* [Hyperleger Fabric-CA](https://github.com/hyperledger/fabric-ca): v1.1.0-preview

## 配備するDockerコンテナ
![HyperledgerFabricNetwork.jpeg](https://qiita-image-store.s3.amazonaws.com/0/152676/aa1c46b0-34ac-ba63-d98b-ce4cb1e92f5c.jpeg)

## 各コンテナの役割

* Root CA/Intermediate CA  
各組織に所属しているユーザーやコンポーネントの管理するための認証局
各ユーザーやコンポーネントに対して証明書群(MSP)を払い出す役割ももつ
* Orderer  
ブロックチェーンネットワークに参加している組織間の接続情報(channel)を管理するコンポーネント  
また、ブロックチェーンのトランザクション/ブロックの順を整理する役割ももつ
* Peer0/Peer1  
ブロックチェーンのトランザクション/ブロックを保持するコンポーネント  
また、自身の組織に配備されているスマートコントラクトの実行基盤の役割ももつ
* Setup/Run  
ブロックチェーンネットワークを構築するためのツールとして利用するためのコンテナ

# Hyperledger Fabricコンポーネントのビルド
## ソースコードのダウンロード

```bash

$ mkdir -p /opt/gopath/src/github.com/hyperledger
$ cd /opt/gopath/src/github.com/hyperledger
$ git clone -b v1.1.0-preview https://github.com/hyperledger/fabric.git
$ git clone -b v1.1.0-preview https://github.com/hyperledger/fabric-ca.git
```

## パッチの適用
Hyperledger Fabricが依存している一部コンポーネントのバージョンが提供されなくなったため、バージョン変更のパッチを適用する。

```bash
$ cd /opt/gopath/src/github.com/hyperleger/fabric
# zookeeper
$ git cherry-pick 21234b6836c0fb98b2ac3e700bbc85fb77975b33
# kafka
$ git cherry-pick 34882dd2b3cba149f7708c6ffe55bb91d3840e4c
$ git cherry-pick 4747235991272c265a0fb7aa861961c94e1514c6
```

## ビルドツールのインストール

公式で用意されているセットアップスクリプトを実行する。
なお、このセットアップスクリプトは、Vagrantで起動したVirtual BoxのVM上で動くことを想定して作られているので、ファイルシステムの構成を合わせる必要がある。

```bash

$ ln -s /opt/gopath/src/github.com/hyperledger/fabric /hyperledger
$ cd /opt/gopath/src/github.com/hyperledger/fabric/devenv
$ ./setup.sh
```

# コンテナイメージのビルド

```
$ cd /opt/gopath/src/github.com/hyperledger/fabric
$ make docker
$ cd /opt/gopath/src/github.com/hyperldger/fabric-ca
$ make docker
```

# ブロックチェーンネットワークの起動
## サンプルリポジトリのダウンロード

```
$ git clone -b master https://github.com/hyperledger/fabric-samples.git
```

## ディレクトリ構成

```bash

$ cd fabric-samples
$ tree fabric-ca
fabric-ca/
├── build-images.sh :コンテナイメージのビルドツール(ただし、ビルドできない)
├── makeDocker.sh :docker-compose.ymlの作成スクリプト
├── README.md
├── scripts
│   ├── env.sh :各コンテナの環境変数設定スクリプト
│   ├── run-fabric.sh :Channelの作成やChaincodeの実行等を試すスクリプト
│   ├── setup-fabric.sh :MSPの設定やChannelブロックの作成を実行するスクリプト
│   ├── start-intermediate-ca.sh :Intermediate CAの起動スクリプト
│   ├── start-orderer.sh :Ordererの起動スクリプト
│   ├── start-peer.sh :Peerの起動スクリプト
│   └── start-root-ca.sh :Root CAの起動スクリプト
├── start.sh :サンプル構成の起動ツール
└── stop.sh　:サンプル構成の停止ツール
```

## 起動ツールの内容
### 実行内容(全体)

1. Root CA/Intermediate CAの起動
3. ユーザの登録
4. Channelブロックの作成
5. Orderer/Peerの起動
7. Channelの作成/加入
9. 動作確認
    10. Chaincodeのインストール
    11. トランザクションの発行
    12. ユーザの作成/削除

### Root CA/Intermediate CAの起動

1. 設定ファイルの作成
    * Root CA  
      ```
      $ fabric-ca-server init -b {初期登録ユーザー名}:{初期登録ユーザのパスワード}
      ```
    * Intermediate CA  
      ```
      $ fabric-ca-server init -b {初期登録ユーザー名}:{初期登録ユーザのパスワード} -u https://{Root CAの初期登録ユーザ名}:{Root CAの初期登録ユーザのパスワード}@{Root CAのホスト名}:{Root CAのポート番号}
      ```
1. サービスの起動  
   ```
   $ fabric-ca-server start
   ```

### ユーザーの登録

各組織のIntermediate CAに対して、以下のユーザを登録する。

* 管理組織
    * Ordererの実行ユーザー(一般ユーザー) × 1
    * Adminユーザー × 1
* 組織A/組織B
    * Peerの実行ユーザー(一般ユーザー) × 2
    * Chaincodeの実行ユーザー(一般ユーザー) × 1
    * Adminユーザー × 1

登録方法:

1. Intermediate CAの起動ユーザーでログイン(Enroll)  
```bash

$ fabric-ca-cliet enroll -d -u https://{Intermediate CAの初期登録ユーザー名}:{Intermediate CAの初期登録ユーザーのパスワード}@{Intermediate CAのホスト名}:{Intermediate CAのポート番号}
```
2. ユーザー登録コマンドの実行
    * 一般ユーザー  
      ```
      $ fabric-ca-client register -d --id.name {ユーザー名} --id.secret {パスワード}
      ```
    * Adminユーザー  
      ```
      $ fabric-ca-client register -d --id.name {ユーザー名} --id.secret {パスワード} --id.attrs "hf.admin=true:ecert"
      ```

### Channelブロックの作成

1. 各組織のMSPを設定
    1. Intermediate CAからcertification chainを取得  
   ```
   $ fabric-ca-client getcacert -d -u https://{Intermediate CAのホスト名}:{Intermediate CAのポート番号} -M {組織のMSP配置ディレクトリ}
   ```
    2. 各組織のAdminユーザーのMSPの取得  
   ```
   $ export FABRIC_CA_CLIENT_HOME={AdminユーザーのMSP配置ディレクトリ}
   ```  
   ```
   $ fabric-ca-client enroll https://{Adminユーザー名}:{Adminユーザーのパスワード}@{Intermediate CAのホスト名}:{Intermediate CAのポート番号}
   ```  
    3.各組織のMSPの作成  
       ```
       $ mkdir -p {組織のMSP配置ディレクトリ}/admincerts
       ```  
       ```
       $ cp {AdminユーザーのMSP配置ディレクトリ}/msp/signcerts/* {組織のMSP配置ディレクトリ}/admincerts/.
       ```
2. Channelブロックの作成
    * Orderer用のChannel設定ファイル  
      ```
      $ configtxgen -profile {OrdererのChannel設定用のProfile名(configtx.ymlに記載)} -outputBlock {Channel設定ファイル名}
      ```
    * Peer用のChannel設定ファイル  
      ```
      $ configtxgen -profile {各組織のChannel設定用のProfile名(configtx.ymlに定義)} -outputCreateChannelTx {Channel設定ファイル名} -channelID {Channel名}
      ```
    * Anchor Peer用のChannel設定ファイル  
      ```
      $ configtxgen -profile {各組織のChannel設定用のProfile名(configtx.ymlに定義)} -outputAnchorPeersUpdate {Channel設定ファイル名} -channelID {Channel名} -asOrg {MSPのID名}
      ```

### Orderer/Peerの起動

設定する環境変数については、makeDocker.shとscripts/env.shに集約されているため、詳細はそちらを参照してください。
必須の設定項目としては、以下の3点のはずです。

* OrdererのChannelの設定は、Channelブロック作成に記載した設定ファイルを用いること
* 各組織にAnchor Peerを設定して、Ordererや他の組織のPeerからアクセス可能なホスト名とポート番号を設定すること
* Peer/Ordererに、上記で作成したユーザーのMSPディレクトリを設定すること

### Channelの作成/加入

* Channelの作成  
  ```
  $ export CORE_PEER_MSPCONFIGPATH={管理組織のAdminユーザーのMSPディレクトリ}
  ```  
  ```
  $ peer channel create -c {Channel名} -f {Peer用のChannel設定ファイル} -o {Ordererのホスト名}:{Ordererのポート名}
  ```
* Channelの加入  
  ```
  $ export CORE_PEER_MSPCONFIGPATH={各組織のAdminユーザーのMSPディレクトリ}
  ```  
  ```
  $ peer channel join -b {Channel作成時に取得したファイル}
  ```

# 記事内容を自動化したリポジトリ
https://github.com/nakao4532/setupHFonEC2/tree/v1.1.0-preview

* VagrantでAWS上にv1.1.0-previewをビルドしたVMを起動します
* 「/home/ubuntu/fabric-samples/fabric-ca」直下にあるstart.shでブロックチェーンネットワークを構築できます

# おわりに

最初はmasterブランチを使って記事を書こうとしていたんですが、Fabric-CAの仕様変更により、TLSの設定ファイルを明示的に設定しないといけなくなり、サンプルのままで動作しない問題が発生してしまいました。
Hyperledger Fabricは、v0.6→v1.0→v1.1.0-previewとバージョンアップを重ねるにつれて、構築方法や仕様が変更されており、公式ドキュメントも情報が足りていない部分もあるため、バージョンアップに追従しようとすると、動かすだけで本当に難しい印象です。
BitCoinやEthereumのように、簡単にテスト環境を構築できるようになるのはいつの日か・・・。

次は、Chaincodeを使ってブロックチェーンに保存したデータの取得方法に関する記事を書けたら良いな。