Hyperledger FabricのMSPについて

# はじめに
今回BlockChain Advent Calendar 2017に参加させてもらう内容としてHyperledgerを取り組んでいるのでそれについて書いていこうと思います。

# Hyperledger Fabric
Hyperledger Fabricとは、The Linux FoundationのHyperledgerプロジェクトの1つであり、主にビジネスに対してBlockChain技術が利用するために開発が進められています。(https://hyperledger-fabric.readthedocs.io/en/release/)

[詳しくはこちら](https://qiita.com/kyrieleison/items/ec5223bbe6140822df4a#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB)

# MSP(メンバーシップサービスプロバイダ)
実際にブロックチェーンを使う際ブロックチェーン実装できれば便利ですが、公開してしまうと問題のある情報があります（戸籍情報など）。これはPubricのネットワークでは個人情報などの機密情報の流出になってしまいますし、Purivateのネットワークで実装するには小さすぎると言った問題点が存在しています。そこで、そのネットワークに参加している人のみ

メンバシップサービスプロバイダ（MSP）は、メンバシップオペレーションアーキテクチャの抽象化を提供することを目的とするコンポーネントです。
特に、MSPは、証明書の発行と検証、およびユーザー認証の背後にあるすべての暗号メカニズムとプロトコルを抽象化します。

- 独自のアイデンティティ
- アイデンティティの検証
- アイデンティティの認証

のルールを定義することができます。


# 定義はわかったけど実際どうなっているの？

見出しのようにドキュメントを読んで思ったのがこれです。
このあとにサーバーごとのMSPを作るって項目があり更にチャンネルのMSPを作るとか書かれててどういうこっちゃとかになっちゃいました。

# 出来得る限り解読してみる

Hyperledger Fabricではノードごとに

- どういう管理者(admin)が存在していて
- どんなユーザーが登録されており
- ルートCAからの証明書があるか

といった内容のデータをノード一つ一つに対し、保存・環境変数にPathを通さなければなりません。
これがサーバーごとのMSPです。

じゃあチャンネルごとのMSPってなに？ってなると思います。

ドキュメントを読み進めていくと書いてありました。Hyperledger FabricではGenesis blockやチャネル構成ブロックのことでした。

> システムの開始において、ネットワークに存在する全てのMSPの検証パラメータを指定し、システムチャネルのGenesis Blockに含める必要があります。MSP検証パラメータは、MSP識別子、信頼証明書のルート、中間のCAおよび管理証明書、OU（組織単位）の仕様およびCRLで構成されていることを明記してください。システムGenesis Blockは、セットアップフェーズで発注者に提供され、チャネル作成要求を認証することができます。ordererは、同じ識別子を持つ2つのMSPが含まれていれば、システム生成ブロックを拒否し、結果的にネットワークのブートストラップは失敗します。
アプリケーションチャネルの場合、チャネルを管理するMSPのみの検証コンポーネントは、チャネルの起点ブロックに存在する必要があります。私たちは、 1つまたは複数のピアをチャネルに参加させるように指示する前に、適切なMSP構成情報がチャネルのGenesis Block（または最新の構成ブロック）に確実に含まれるようにすることがアプリケーションの責任であることを強調します。

つまり、台帳にはデータの他にブロックチェーンのネットワークにどういうノードにどういったユーザー、管理者が存在していて、記入されておりネットワークのノードの変化・ユーザーの増減に対しても記録されていくとのことです。


# 作ってみようか

MSPを作ろうとなると問題になるのは作り方です。
方法は2通りあります。

- Fabric CAサーバーとClientを利用
- cryptogenを利用

それぞれ利点と問題点がありまして、Fabric CAサーバーは「ユーザー登録などはドキュメントを読めば簡単にできるが、MSPを作るためのドキュメントがなさすぎてわからない」。cryptogenは「MSPはある程度抽象的に作成できるがMSPを作るためのyamlを解読しなければならない」。

どちらも問題があるのですが、ドキュメントがなさすぎてCAサーバーを利用しても実行がうまくできませんでした。できた人が居ましたらぜひ共有してほしいです……。
そのため、今回はcryptogenを利用した方法でMSPを作成してみることにします。

## yamlの解読

では解読を始めます。コメント欄を削除したものが次のソースです。

```yaml:crypto-config.yaml
OrdererOrgs:
  - Name: Orderer
    Domain: example.com
    Specs:
      - Hostname: orderer0
PeerOrgs:
  - Name: Org1
    Domain: org1.example.com
    Template:
      Count: 4
    Users:
      Count: 1
```

初めの2つのOdererOgsとPeerOrgsのタグはOrganizationの名前です。
その次に、ノードの名前・ドメイン名・ホスト名を記入していきます。
また、Countで何台のノードが存在するか、UserでUserが何人いるかを指定します。

書くのはこれだけで良いそうです。

## cryptogenの起動

では、次にCryptogenを起動させます。　

```bash
cryptogen generate --config=./crypto-config.yaml
```
実行するとcrypto-configといったディレクトリが作成されており
、その中に各organizationのMSPなどが作られています。

## configtxgenの設定
さて、ここまで実行するとGenesis blockを作ることでチャネル構成を作成します。

……と言いたいのですが、Genesis blockだけでなくチャネル構成のファイルも作成しなければならないそうです。
Genesisblockを含め作成させるのがconfigtxgenというツールです。
使うにはyamlを書かなければなりません。

```yaml:configtx.yaml
Profiles:
    TwoOrgsOrdererGenesis:
        Orderer:
            <<: *OrdererDefaults
            Organizations:
                - *OrdererOrg
        Consortiums:
            SampleConsortium:
                Organizations:
                    - *Org1
    TwoOrgsChannel:
        Consortium: SampleConsortium
        Application:
            <<: *ApplicationDefaults
            Organizations:
                - *Org1
Organizations:
    - &OrdererOrg
        Name: OrdererOrg
        ID: OrdererMSP
        MSPDir: crypto-config/ordererOrganizations/example.com/msp
    - &Org1
        Name: Org1MSP
        ID: Org1MSP
        MSPDir: crypto-config/peerOrganizations/org1.example/msp
        AnchorPeers:
            - Host: peer0.og1.example.com
              Port: 7051
Orderer: &OrdererDefaults
    OrdererType: solo
    Addresses:
        - 10.146.0.6:7050
    BatchTimeout: 2s
    BatchSize:
        MaxMessageCount: 10
        AbsoluteMaxBytes: 99 MB
    Kafka:
            - 127.0.0.1:9092
    Organizations:
Application: &ApplicationDefaults
    Organizations:
```

こんどはMSPの名前やID、それに対応するMSP関連のファイルが存在するディレクトリを指したり、OrdererのTypeや受信するアドレス、ブロックの設定を書いていきます。

## configtxgenの起動

```bash
# genesis blockの作成
configtxgen -profile TwoOrgsOrdererGenesis -outputBlock genesis.block

# genesis blockの内容表示
 configtxgen -profile TwoOrgsOrdererGenesis -inspectBlock genesis.block

# peer用のチャネル構成ブロックの作成
 configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ch1.tx -channelID ch1

# peer用チャネル構成ブロックの表示
configtxgen -profile TwoOrgsChannel -inspectChannelCreateTx ch1.tｘ
```

## ノードに環境変数を入力
あとは環境変数を適切に入力していきます。どこにもドキュメントが(ry

とりあえず各環境変数についてです。

```bash:orderer

#! /bin/bash

# Orderer用の環境変数設定シェル
# ログのレベル設定
ORDERER_GENERAL_LOGLEVEL=info
# ordererにどのアドレスからの通信を許可するか
ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
# どのポートを使用するか
ORDERER_GENERAL_LISTENPORT=7050
#genesis.blockのタイプ。よく使われるのはfile
# file
# ram
ORDERER_GENERAL_GENESISMETHOD=file
# genesis.blockまでのpath
ORDERER_GENERAL_GENESISFILE=~/config/genesis.block

# このordererがどのMSPに参加してるかを示すID
ORDERER_GENERAL_LOCALMSPID=OrdererOrgMSP
# このordererのMSP情報
ORDERER_GENERAL_LOCALMSPDIR=~/crypto-config/ordererOrganizations/itfor/orderers/orderer0.example.com/msp
# HTTPS通信を使用するか
ORDERER_GENERAL_TLS_ENABLED=false
# ブロックを作る際のタイムアウトまでの時間
CONFIGTX_ORDERER_BATCHTIMEOUT=1s 
```

```bash:peer
CORE_PEER_ENDORSER_ENABLED=true
CORE_PEER_PROFILE_ENABLED=true
#このノードのアドレス
CORE_PEER_ADDRESS=peer0:7051
# chaincodeを受信するアドレス
CORE_PEER_CHAINCODELISTENADDRESS=peer0:7052
# このノードのID
CORE_PEER_ID=org0-peer0
# 所属するPeerのOrg
CORE_PEER_LOCALMSPID=Org0MSP
# ゴシップメッセージを配布するアドレス
CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0:7051
CORE_PEER_GOSSIP_USELEADERELECTION=true
CORE_PEER_GOSSIP_ORGLEADER=false
# HTTPSを利用するか
CORE_PEER_TLS_ENABLED=false
# 利用する場合の設定ファイル
CORE_PEER_TLS_KEY_FILE=/root/bcnetwork/conf/crypto-config/peerOrganizations/org0/peers/peer0.org0/tls/server.key
CORE_PEER_TLS_CERT_FILE=/root/bcnetwork/conf/crypto-config/peerOrganizations/org0/peers/peer0.org0/tls/server.crt
CORE_PEER_TLS_ROOTCERT_FILE=/root/bcnetwork/conf/crypto-config/peerOrganizations/org0/peers/peer0.org0/tls/ca.crt
CORE_PEER_TLS_SERVERHOSTOVERRIDE=peer0
# MSPの設定ファイルのpath
CORE_PEER_MSPCONFIGPATH=/root/bcnetwork/conf/crypto-config/peerOrganizations/org0/peers/peer0.org0/msp
```

Peerに関してはわからない環境変数もあるのですがとりあえず設定すれば動くかなとは思います。
ノードの起動確認だけしておりP2Pの接続までは行っていません。

起動に関してはOrderer→アンカーPeer→検証Peerの順に起動することで接続されるそうです。

# 最後に

とりあえず、MSPの説明と作りかた、それを用いてのノード起動まで行ってみました。
ここまでこれればビジネスネットワークを作ることも不可能ではないかなと思います。

早くビジネスネットワークで動かしたい！