オープンソースのブロックチェーン Hyperledger Fabric を試してみる

オープンソースのブロックチェーン基盤の一つ、Hyperledger Fabric を試してみました。
環境構築からチェーンコードの設置・実行まで挑戦してみましたので、今から始める方の参考になれば幸いです。

# Hyperledger とは

![screenshot-www.hyperledger.org 2016-09-15 20-07-16.png](https://qiita-image-store.s3.amazonaws.com/0/44003/11abebfe-5057-aea3-343b-75fd7163b959.png)

Hyperledger (ハイパーレッジャー) とは、オープンソースのブロックチェーン技術推進コミュニティです。

> ブロックチェーン技術とは、ネットワーク接続された数多くのコンピュータ群で分散処理/データ管理を行うことで、1つの巨大高性能システムと同等の機能を実現するという技術です。"変更不可能な形でデータを保持するデータベース" と表現されます。

> Hyperledger Project は、The Linux Foundation のプロジェクトとして、これらの技術検証について、オープンソース精神に基づき、グローバルレベルで共同検証を実施し、デファクトスタンダードとなるブロックチェーン基盤の技術開発/推進を行っています。(http://www.ossnews.jp/oss_info/Hyperledger_Project)

このコミュニティには IBM や富士通、MUFG など30社以上の大手企業や金融機関が参画しており、共同でブロックチェーン基盤の技術検証・開発を行っているそうです。

# Hyperledger Fabric とは

Hyperledger Fabric (ハイパーレッジャーファブリック, 以下 Fabric) は、そんな Hyperledger プロジェクトの元で開発されているブロックチェーン基盤の一つであり、オープンソースなので誰でも利用することができます。

# Fabric の特徴

## Industry-focused Design (ビジネスに焦点を当てた設計)

元々、ビットコインに利用されるブロックチェーンは、貨幣として機能させるため、不特定多数を対象としていました。
しかし多くのビジネスにおいて、知っている者同士で契約を行う場面が圧倒的に多いはずです。初期のブロックチェーンは、そのニーズに適していませんでした。

Fabric は、**ビジネスにおける多様なユースケースに応える設計** が意識されています。
参加者の登録と証明書発行、権限設定を担うメンバーシップ・サービスを実装しており、トランザクションは個々の参加者の証明書を用いて暗号化されています。プライベートな複数のブロックチェーンネットワークを有効にすることもできます。

![](http://hyperledger-fabric.readthedocs.io/en/latest/biz/images/Canonical-Use-Cases_B2BContract.png)
画像元: http://hyperledger-fabric.readthedocs.io/en/latest/biz/usecases/

## Modular Architecture (モジュラー型アーキテクチャ)

また、Fabric はモジュラー型アーキテクチャを採用しています。

Fabric は **メンバーシップサービス・ブロックチェーンサービス・チェーンコードサービス** という3つのカテゴリのコアコンポーネントの集まりになっています。
これらは論理的な構造ではなく、個別のプロセス・名前空間・仮想マシンを持った物理的な個々の部品になっており、それぞれプラグアンドプレイが可能です。

![](http://hyperledger-fabric.readthedocs.io/en/latest/images/refarch.png)
画像元: http://hyperledger-fabric.readthedocs.io/en/latest/protocol-spec/#2-fabric_1

### メンバーシップサービス

> Membership provides services for managing identity, privacy, confidentiality and auditability on the network. 

メンバーシップサービスは、参加者のアイデンティティと権限を管理するものです。
参加者に対して登録証明書(Enrollment Certificates, ECert)や取引証明書(Transaction Certificates, TCert)を発行する認証局(CA)の役割を担います。

### ブロックチェーンサービス

> Blockchain services manage the distributed ledger through a peer-to-peer protocol, built on HTTP/2. 

ブロックチェーンサービスは、HTTP/2 上に構築された P2P プロトコルを通じて、ブロックチェーンを管理するものです。
異なるコンセンサス(PBFT, Raft, PoW, PoS)にプラグイン可能で、デプロイ毎に設定することができます。

### チェーンコードサービス

> Chaincode services provides a secured and lightweight way to sandbox the chaincode execution on the validating nodes. 

チェーンコードとは、ブロックチェーンにトランザクションの一部として保存されるアプリケーションレベルのコードです。
Fabric では、チェーンコードがトランザクションを実行します。いわゆるスマートコントラクトというものがこれになります。

チェーンコードサービスは、各ノードでトランザクションを実行する方法(= チェーンコードの実行環境)を提供するものです。
実行環境は OS と言語、Runtime と SDK をセットにした Docker イメージになっており、Go, Java, Node.js をサポートしています。必要に応じて他の言語も使用可能とのこと。

その他の詳細については、公式ドキュメントの Protocol Spec を参照すると良いかなと思います。
http://hyperledger-fabric.readthedocs.io/en/latest/protocol-spec/

refs:
公式サイト https://www.hyperledger.org/
公式 Github リポジトリ https://github.com/hyperledger/fabric
公式ドキュメント http://hyperledger-fabric.readthedocs.io/

# チェーンコードを実行する準備

「ブロックチェーンを試すなら、まずトランザクションを作るところまでやると良い」と聞いたので、Fabric におけるトランザクション作成(= チェーンコードのデプロイと実行)までやってみたいと思います。

## 環境のセットアップ

環境構築にあたっては、以下の記事を参考にさせていただきました。

hyperledger/fabricをEC2で動かす http://qiita.com/MizukiSonoko/items/13506c315bc0085028d0

- 必要な package をインストール
- Go の環境をセットアップ
- rocksdb をインストール
- docker をインストール
- hyperledger/fabric リポジトリを clone

かなりメモリとストレージを使うため、EC2 のスペックには注意してください。
また、インストール完了までには結構時間がかかりました。

公式ドキュメントでは、ローカル環境上で仮想マシンを立てる方法についても詳しく説明されています。

refs: http://hyperledger-fabric.readthedocs.io/en/latest/Setup/Chaincode-setup/

## CA サーバの起動

clone した hyperledger/fablic のディレクトリに移動し、まずは CA サーバを立ち上げます。
これはセキュリティのためのオプションなのですが、せっかくなのでやってみました。

```
cd $GOPATH/src/github.com/hyperledger/fabric
make membersrvc && membersrvc
```

このコマンドを実行すると、`membersrvc/membersrvc.yaml` ファイルに定義されているデフォルト設定で CA サーバが構築・実行されます。
デフォルトでは、既に CA にユーザが登録されており、`sca.users` セクションに記載されています。

```
eca:
        affiliations:
           banks_and_institutions:
              banks:
                  - bank_a
                  - bank_b
                  - bank_c
              institutions:
                  - institution_a
        users:
                admin: 1 Xurw3yU9zI0l institution_a '{"registrar":{"roles":["client","peer","validator","auditor"],"delegateRoles":["client"]}}'
                WebAppAdmin: 1 DJY27pEnl16d institution_a '{"registrar":{"roles":["client"]}}'
                lukas: 1 NPKYL39uKbkj bank_a
                system_chaincode_invoker: 1 DRJ20pEql15a institution_a
                diego: 1 DRJ23pEQl16a institution_a
                jim: 1 6avZQLwcUe9b bank_a
                binhn: 1 7avZQLwcUe9q institution_a
                ...
```

ご覧のように、ユーザIDの後に権限を示す整数、パスワード、所属、そしてオプションが続きます。
権限を示す整数は 1: クライアント, 2: 非検証ピア, 4: 検証ピア, 8: 監査人 を示しています。

## 検証ピアサーバの起動

次に、検証用のピアサーバを立ち上げます。
セキュリティが有効の場合は、まず `peer/core.yml` の `security.enabled` の値を `true` にします。

そして別のターミナルを開き、以下のコマンドを実行します。

```
cd $GOPATH/src/github.com/hyperledger/fabric
make peer
peer node start
```

これでピアサーバが立ち上がります。

## チェーンコードの起動

そして、チェーンコードをビルドします。
今回は `chaincode_example02` という公式のサンプルコードを使用するので、それを curl でダウンロードします。

```
mkdir -p $GOPATH/src/github.com/chaincode_example02/
cd $GOPATH/src/github.com/chaincode_example02
curl GET https://raw.githubusercontent.com/hyperledger/fabric/master/examples/chaincode/go/chaincode_example02/chaincode_example02.go > chaincode_example02.go
go build
```

チェーンコードを起動し、検証ピアサーバに登録するには、以下のコマンドを実行します。

```
CORE_CHAINCODE_ID_NAME=mycc CORE_PEER_ADDRESS=0.0.0.0:7051 ./chaincode_example02
```

# チェーンコードの設置と実行

これで準備が整いました。いよいよクライアントからトランザクションを実行してみます。
Fabric では CLI と REST API が用意されていますが、今回は REST API を使用します。

エンドポイントはさほど多くなく、シンプルです。

- Block
    - GET /chain/blocks/{Block}
- Blockchain
    - GET /chain
- Chaincode
    - POST /chaincode
- Network
    - GET /network/peers
- Registrar
    - POST /registrar
    - DELETE /registrar/{enrollmentID}
    - GET /registrar/{enrollmentID}
    - GET /registrar/{enrollmentID}/ecert
    - GET /registrar/{enrollmentID}/tcert
- Transactions
    - GET /transactions/{UUID}

この中でも、今回はユーザのログインや証明書発行を行う Registerar API と、チェーンコードの設置や実行を行う Chaincode API を利用します。

refs:
APIs - CLI, REST, and Node.js https://github.com/hyperledger/fabric/blob/master/docs/API/CoreAPI.md

### ユーザログイン

オプショナルではありますが、今回は CA サーバを立ち上げているので、`membersrvc/membersrvc.yaml` ファイルに定義されているユーザ `jim` でログインしてみたいと思います。

Request:

```
echo '{
  "enrollId": "jim",
  "enrollSecret": "6avZQLwcUe9b"
}' |
curl -X POST -H "Content-Type: application/json" -d @- "http://localhost:7050/registrar"
```

Response:

```
{"OK":"Login successful for user 'jim'."}
```

`jim` としてログインできました。

### チェーンコードの設置

ブロックチェーン上にチェーンコードを設置します。
`chaincode ID` の `name` に起動しているチェーンコードの名前を指定すると、そのチェーンコードを設置・初期化処理を行います。

Request:

```
echo '{
  "jsonrpc": "2.0",
  "method": "deploy",
  "params": {
    "type": 1,
    "chaincodeID":{
        "name": "mycc"
    },
    "ctorMsg": {
        "function":"init",
        "args":["a", "100", "b", "200"]
    },
    "secureContext": "jim"
  },
  "id": 1
}' |
curl -X POST -H "Content-Type: application/json" -d @- "http://localhost:7050/chaincode"
```

Response:

```
{"jsonrpc":"2.0","result":{"status":"OK","message":"ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539"},"id":1}
```

Peer Logs:

```
06:34:58.856 [rest] ProcessChaincode -> INFO 038 REST processing chaincode request...
06:34:58.856 [rest] processChaincodeDeploy -> INFO 039 REST deploying chaincode...
06:34:58.859 [container] WriteGopathSrc -> INFO 03a rootDirectory = /home/ubuntu/work/src
06:34:58.859 [container] WriteFolderToTarPackage -> INFO 03b rootDirectory = /home/ubuntu/work/src
06:35:00.687 [rest] processChaincodeDeploy -> INFO 03c Successfully deployed chainCode: ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539
06:35:00.687 [rest] ProcessChaincode -> INFO 03d REST successfully deploy chaincode: {"jsonrpc":"2.0","result":{"status":"OK","message":"ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539"},"id":1}
```

チェーンコードが設置され、レスポンスの `message` にチェーンコードを示す ID が発行されて返ってきます。

### チェーンコードの実行

チェーンコードを実行します。
先程のレスポンスで返ってきた `message` の値を、`chaincodeID` の `name` として渡すことで、デプロイしたチェーンコードを実行します。

エンドポイントはデプロイ時と同じで、ペイロードの `method` の値を `invoke` にします。

Request:

```
echo '{
  "jsonrpc": "2.0",
  "method": "invoke",
  "params": {
      "type": 1,
      "chaincodeID":{
          "name":"ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539"
      },
      "ctorMsg": {
         "function":"invoke",
         "args":["a", "100", "b", "200"]
      },
      "secureContext": "jim"
  },
  "id": 1
}' |
curl -X POST -H "Content-Type: application/json" -d @- "http://localhost:7050/chaincode"
```

Response:

```
{"jsonrpc":"2.0","result":{"status":"OK","message":"f2eff0ae-f872-4bfa-bd77-6e8af3d5b39f"},"id":1}
```

Peer Logs:

```
06:42:53.081 [rest] ProcessChaincode -> INFO 042 REST processing chaincode request...
06:42:53.081 [rest] processChaincodeInvokeOrQuery -> INFO 043 REST invoke chaincode...
06:42:53.081 [devops] invokeOrQuery -> INFO 044 Transaction ID: f2eff0ae-f872-4bfa-bd77-6e8af3d5b39f
06:42:53.081 [rest] processChaincodeInvokeOrQuery -> INFO 045 Successfully submitted invoke transaction with txid (f2eff0ae-f872-4bfa-bd77-6e8af3d5b39f)
06:42:53.081 [rest] ProcessChaincode -> INFO 046 REST successfully submitted invoke transaction: {"jsonrpc":"2.0","result":{"status":"OK","message":"f2eff0ae-f872-4bfa-bd77-6e8af3d5b39f"},"id":1}
```

これで `f2eff0ae-f872-4bfa-bd77-6e8af3d5b39f` という ID を持ったトランザクションを追加することができました。

# おわりに

今回はここまで。Fabric の概念や用語には難しいところがあり、まだまだ理解しきれていないところはありますが
とは言え、公式ドキュメントはとても充実しているので、まず触ってみるには良いと思います。

また今回は紹介しませんでしたが、IBM Bluemix ではもっと簡単にプロックチェーンを体感できるアプリケーションが用意されていますので、ぜひ興味のある方はそちらも試してみてください。

追記: [IBM Blockchain を触ってみる](http://qiita.com/kyrieleison/items/87088866e9158aff13eb) を書きました。

# 参考
- Hyperledger Projectとは http://www.ossnews.jp/oss_info/Hyperledger_Project
- 公式サイト https://www.hyperledger.org/
- 公式 Github リポジトリ https://github.com/hyperledger/fabric
- 公式ドキュメント http://hyperledger-fabric.readthedocs.io/
- APIs - CLI, REST, and Node.js https://github.com/hyperledger/fabric/blob/master/docs/API/CoreAPI.md
- IBMに聞く、ブロックチェーンへの取り組みと今後の展望 https://www.coin-portal.net/2016/06/19/9835/
- IBMがブロックチェーン戦略を公開「よりビジネスに特化した用途を」 https://www.coin-portal.net/2016/03/15/6529/
- Hyperledger fabric Client (HFC) SDK for Node.js https://github.com/hyperledger/fabric/blob/master/docs/nodeSDK/node-sdk-indepth.md
- チェーンコードとは何か? Chaincode? http://qiita.com/hshimo/items/ebee2432dfb768c2eef2
- スマートコントラクトとは何か? Smart Contractの定義 http://qiita.com/hshimo/items/093f40b856ba2436fbba
- hyperledger/fabricをEC2で動かす http://qiita.com/MizukiSonoko/items/13506c315bc0085028d0
- ブロックチェーン入門〜ただしFinTechを除く〜 http://www.slideshare.net/MikiYutani/blockchain-fornonfintechbusiness-60982831