いるねすのブログ

働きたくない系SEが無駄に遊んだ記録

Hyperledger Fabric と戯れる part.1

ということで今日はさくっと Hyperledger Fabric を動かしてみる。

ちょっと調べたかんじ Hyperledger Composer も便利そうだったので、あわせて導入だけしておく。

その前に

Hyperledger Fabric がどんなもんか、用語とその内容がわかる程度にザックリ読んどく。

hyperledger-fabric.readthedocs.io

理解したことをすげえざっくりまとめると

  • Network
    • Hyperledger Fabric をつかって作るシステム全体を指すよ
    • 1つ以上の Organization が network の管理をする権利を持てるよ
      • これは厳密には System Channel という特別な channel として扱われるよ
    • 1つ以上の Channel を含むよ
    • 1つ以上の Orderer を含むよ
  • Organization
    • この network に参加する組織を指すよ
    • 1つ以上の channel に参加できるよ
    • 1つ以上の peer を持つよ
    • 1つの MSP を持つよ
  • Peer
    • (物理的な意味で) organization が管理するノードだよ
      • つまり、 1 つ以上の channel に参加できるよ
        • つまり、 1 つ以上の台帳を持つよ
      • (論理的な意味では) channel にホストされるノードだよ
    • 4 種の役割があり、各 peer は1つ以上の役割を担うよ
      • Commitment Peer
        • 台帳を保有しているよ
        • 検証されたトランザクションを自身の台帳に反映するよ
        • 基本的にすべての peer は commitment peer になると思うよ
      • Endorsement Peer
      • Anchor Peer
        • network に参加する他の organization との通信の窓口になるよ
      • Leader Peer
        • orderer と直接やりとりするよ
        • 1 organization につき必ず 1 leader peer が必要だよ
  • Channel
    • 1つの台帳と、それを扱う organization たちをまとめた単位だよ
    • channel に所属する organization だけが channel に所属する台帳を保持、制御できるよ
    • 1つ以上の peer をもつよ
      • 常に 1 つの Leader Peer をもつよ
      • 少なくとも 1 つの Commitment Peer をもつよ
      • 少なくとも 1 つの Endorsement Peer をもつよ
  • 台帳
    • そのままだよ
      • 内部的には、現在(最新)の状態を保持した DB と、それまでの操作履歴を保持した BlockChain で構成されるよ
    • 台帳とおなじ channel に所属する organization (の peer) がそれぞれ全く同じ台帳のコピーを保持してるよ
    • 台帳とおなじ channel に所属する organization (の peer) が chaincode を通して台帳を制御できるよ
      • DB みたいなノリでアクセスできるよ
  • Endorsement Policy
    • トランザクションが受け入れられるために、どの organization が承認する必要があるかの定義だよ
    • channel 構成に含まれ、channel 内のすべての endorsement peer は同一のポリシで動く必要があるよ
  • Chain Code
    • 台帳に対する操作を定義したプログラムみたいなものだよ
    • peer にインストールし、インスタンス化することで使用することができるよ
      • バージョンは管理されるよ
  • Orderer
    • 各 peer に対するトランザクションの順番やコンセンサスを管理する特別なノードだよ
    • network につき 1 つ以上含まれるよ
      • 複数ある場合は、Apache Kafka で冗長構成をとるだけだよ
    • network にあるいずれかの organization に所属しているよ
      • 複数ある場合は、複数の organization でそれぞれ持つことができるよ
    • network に含まれるすべての channel を跨いで存在しているよ
      • 所属している organization がすべての channel に含まれていなくても大丈夫だよ
  • CA
    • ただの認証局だよ
      • Peer や Orderer、 Client とかに X.509 証明書を分配するよ
      • Fabric-CA というものがパッケージに含まれてるけど、普通に組織独自の CA 使えばいいよ
    • 通常、各 organization がそれぞれ CA を持ってるよ
  • MSP
    • Membership Services Provider
    • CA をつかって、network 内の各ノードやチャンネル、ユーザなんかの Hyperledger Fabric 特有のあれこれを管理するよ
    • 各 organization がそれぞれ運用するよ
  • Client
    • network 中の台帳を参照・制御するアプリケーションだよ
      • あくまでも Hypeledger Fabric システムに対するクライアントを指すので混乱しないよう注意だよ
    • たいていは各 organization がそれぞれに作成・管理するよ

Identity と MSP あたりがわりと理解あやしい。それら含め何か勘違いしてるようなら後ほど修正する。 (ので、指摘等してくれる人がいたら嬉しい。)

インストール

公式ドキュメント通り進める。インストールマニュアルを和訳する趣味はないのでリンクだけ貼っとく。

注意すべきところは、 Node.js は v8 系じゃないとダメとの事なので nvm を使ってバージョンを指定すること、pyenv などで python コマンドのバージョンを 3 系にしてるときは忘れず 2.7 系になるようにしておくこと、くらい。 ということで prereqs がわりと重要なのであわせて貼っとく。

なお Fabric のインストールスクリプトはカレントディレクトリに samples リポジトリをクローンするので、変な場所で実行すると微妙な気持ちになるので注意。

もう既にインストール済なものもあったので色々飛ばしたり等したのもあるが、 MacOS 10.14.4 の環境でだいたいこんなかんじになった。

$ node --version
v8.15.1
$ python --version
Python 2.7.10
$ go version
go version go1.12.1 darwin/amd64
$ docker --version
Docker version 18.09.2, build 6247962
$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01
$ composer --version
v0.20.8
$ docker images -a | sort  
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
hyperledger/fabric-ca          1.2.1               be8400395e15        6 months ago        251MB
hyperledger/fabric-ca          1.4.1               3a1799cda5d7        9 hours ago         252MB
hyperledger/fabric-ca          latest              3a1799cda5d7        9 hours ago         252MB
hyperledger/fabric-ccenv       1.2.1               8651e7160d88        6 months ago        1.43GB
hyperledger/fabric-ccenv       1.4.1               d7433c4b2a1c        9 hours ago         1.43GB
hyperledger/fabric-ccenv       latest              d7433c4b2a1c        9 hours ago         1.43GB
hyperledger/fabric-couchdb     0.4.10              3092eca241fc        9 months ago        1.61GB
hyperledger/fabric-couchdb     0.4.15              8de128a55539        3 weeks ago         1.5GB
hyperledger/fabric-couchdb     latest              8de128a55539        3 weeks ago         1.5GB
hyperledger/fabric-javaenv     1.4.1               b8c9d7ff6243        11 hours ago        1.74GB
hyperledger/fabric-javaenv     latest              b8c9d7ff6243        11 hours ago        1.74GB
hyperledger/fabric-kafka       0.4.15              b4ab82bbaf2f        3 weeks ago         1.44GB
hyperledger/fabric-kafka       latest              b4ab82bbaf2f        3 weeks ago         1.44GB
hyperledger/fabric-orderer     1.2.1               b1a1dd788841        6 months ago        152MB
hyperledger/fabric-orderer     1.4.1               ec4ca236d3d4        9 hours ago         173MB
hyperledger/fabric-orderer     latest              ec4ca236d3d4        9 hours ago         173MB
hyperledger/fabric-peer        1.2.1               ef0e7788ead0        6 months ago        159MB
hyperledger/fabric-peer        1.4.1               a1e3874f338b        9 hours ago         178MB
hyperledger/fabric-peer        latest              a1e3874f338b        9 hours ago         178MB
hyperledger/fabric-tools       1.4.1               432c24764fbb        9 hours ago         1.55GB
hyperledger/fabric-tools       latest              432c24764fbb        9 hours ago         1.55GB
hyperledger/fabric-zookeeper   0.4.15              20c6045930c8        3 weeks ago         1.43GB
hyperledger/fabric-zookeeper   latest              20c6045930c8        3 weeks ago         1.43GB

CA とか Orderer とか Peer なんかのイメージがインストールされてることが確認できた。

Hyperledger Fabric の最新版は 1.4.1 だが、Composer の最新版の対象バージョンはいまだ 1.2 系なので一部 1.2 系が含まれている。 v1.4 系が LTS なのと、v1.4 系からプログラミングモデルが更新されたとの事なので、できるかぎり v1.2 は使わないで行きたいところではある。

チュートリアルを動かす

チュートリアルめっちゃ沢山あるのでガンガンすすめてく。

sample リポジトリは上述の通りインストールスクリプトを実行した場所に clone されている。

以降は tags/v1.4.1(6c0203a) での勉強結果。

Building Your First Application チュートリアル

チュートリアルの目次を見ると Writing Your First Application を先にやるべきっぽいのだが、動かしかた知る前に書きかたから入るのってどうなのと思ったので先にこっち。

./byfn.sh generate

出力を見ればなんとなくわかるけど、以下のことをやってる。(自力で分析した内容も多分に含まれるため、正確かどうかは怪しい)

  1. cryptogencrypto-config.yaml の設定通りに証明書を発行して ./crypto-config を生成
    • cryptogen は以下を生成して、各ノード、ユーザの設定となるようディレクトリツリーをつくり配置する
      • orderer ドメイン(example.com) の CA、全ユーザ(Admin)、全ノード(orderer〜orderer5) それぞれに対する証明書と鍵
        • 証明書はそれぞれ交互に配布しあう
      • org1.example.com ドメインの CA、全ユーザ(Admin, User1)、全ノード(peer0, peer1) それぞれに対する証明書と鍵
        • 証明書はそれぞれ交互に配布しあう (ユーザ同士は交換しない)
      • org2.example.com ドメインの CA、全ユーザ(Admin, User1)、全ノード(peer0, peer1) それぞれに対する証明書と鍵
        • 証明書はそれぞれ交互に配布しあう (ユーザ同士は交換しない)
  2. 上記で生成した鍵内容を docker-compose-e2e-template.yaml に適用して docker-compose-e2e.yaml を生成
    • この docker-compose-e2e.yaml なんだけど、以降どこでも使われてない
    • これは別のテスト用のものなので今回は無視する。
  3. configtxgenconfigtx.yaml の設定通りに Orderer の設定を生成して ./channel-artifacts/genesis.block を生成
  4. configtxgenconfigtx.yaml の設定通りに Channel の設定を生成して ./channel-artifacts/channel.tx を生成
    • configtx.yaml から channel の構成について抜粋したみたいなバイナリファイルを作っている。
      • 以降の手順で channel を作成する際に設定ファイルとして渡されている
  5. configtxgenconfigtx.yaml の設定通りに Peer1 の設定を生成して ./channel-artifacts/Org1MSPanchors.tx を生成
  6. configtxgenconfigtx.yaml の設定通りに Peer2 の設定を生成して ./channel-artifacts/Org2MSPanchors.tx を生成
    • configtx.yaml から organization の構成について抜粋したみたいなバイナリファイルを作っている。
      • 以降の手順で anchor peer を channel に登録する際に設定ファイルとして渡されている
./byfn.sh up

オプションで chaincode を Go 実装じゃなくて Node 実装や Java 実装に切り替えられたり、デフォルトで 1 こしか起動させない orderer を Kafka ないし Raft で並列に動かさせることもできる。StateDB を CouchDB (デフォルトは LevelDB) にすることもできるらしい。

今回は既にわりとおなかいっぱいなのでデフォルトオプションにて実行した。

以降、やはり自力で分析した内容も多分に含まれるため、正確かどうかは怪しい

  1. docker-compose で各ノードを起動する
    • オプション等をつけなかった場合、 docker-compose-cli.yaml だけが使用される。
      • ここに orderer2 〜 orderer5 までの 4 つの orderer は含まれていない
      • 各ノードは cryptogen で作ったディレクトリツリーの自身に対応する部分を適宜マウントするようになっている
    • 起動するのは以下。なおすべて byfn ネットワークに属する。
      • orderer.example.com
      • peer0.org1.example.com
      • peer1.org1.example.com
      • peer0.org2.example.com
      • peer1.org2.example.com
      • cli
        • 突然現れたけど、これはクライアントノード。
          • docker exec cli peer ... のように呼ぶことで peer0.org1.example.com を対象に(環境変数のセット等をせずとも)簡単に peer コマンドが呼べるようになってる
      • CA サーバは起動してない。
        • (あとで調べる)
  2. 作った cliscripts/script.sh を実行させる
    1. peer channel create
      • orderer に対して実行している
        • TLS を有効にし、crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pemTLS CA 証明書として付加したうえで、
        • configtxgen で作成した channel.tx の設定で、
        • mychannel という名前の channel を作成させる
      • ここで mychannel.blockcli の working directory に作成される
    2. peer channel join
      • 全 peer ノード(4つ)それぞれに対して実行してる。
        • 上で作成された mychannel.block を渡して、対象 peer ノードを mychannel に参加させる
    3. peer channel update
      • orderer に対して実行している
        • Anchor Peer となる 2 つの peer0 ノードそれぞれに対して、
        • TLS を有効にし、crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pemTLS CA 証明書として付加したうえで、
        • configtxgen で作成した Org*MSPanchors.tx の設定で、
        • mychannel を更新させる
      • これで Org* のアンカーピアとして peer0.org*.example.com が設定される
        • 設定内容は channel 内の全 peer に伝達される
    4. peer chaincode install
      • Anchor Peer である 2つの peer0.org*.example.comノードに対して実行されている
        • 文字通り chaincode をインストールしている
        • パス は ../chaincode/chaincode_example02/go/
          • ビルドとかはせず、そのまんま渡しているっぽい
          • chaincode の内容は次のチュートリアルで学ぶのでとりあえず無視。
        • chaincode 名は mycc、 バージョン 1.0、実装言語は golang、とそれぞれ指定している。
    5. peer chaincode instantiate
      • peer0.org2.example.com ノード 1 つのみに対して実行されている
        • orderer orderer.example.com に対し、
          • TLS を有効にし、crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pemTLS CA 証明書として付加したうえで、
        • mychannel において、
        • 初期化メッセージ {"Args":["init","a","100","b","200"]} を渡し、
          • "a" に "100" を、 "b" に "200" をそれぞれセットしているっぽい
        • ポリシー AND ('Org1MSP.peer','Org2MSP.peer') も渡して、
          • Org1 の承認、および Org2 の承認の 2 つが必要ということ
        • mycc のバージョン 1.0インスタンス化する
      • どうもこのタイミングでソースコードのビルドが行われているらしい
      • インスタンス化の操作は channel 内の全 peer に伝達される
        • インストールされているのは peer0.org* の 2 ノードだけなので、実際に query, invoke ができるのはこれら 2 ノードだけとなる
    6. peer chaincode query
      • peer0.org1 ノードに対する query の動作確認
        • "a" の値を問い合わせて "100" であることを確認しているっぽい
        • chaincode の内容は次のチュートリアルで学ぶのでとりあえず無視。
    7. peer chaincode invoke
      • peer0.org1 および peer0.org2 ノードに対する invoke の動作確認
        • "a" から "b" に "10" だけ移動しているっぽい
        • chaincode の内容は次のチュートリアルで学ぶのでとりあえず無視。
    8. peer chaincode install
      • peer1.org2.example.com ノードにも chaincode をインストールしている
        • chaincode は既にインスタンス化されているため、peer1.org2.example.commycc は直ちに使えるようになる
        • インストールされているのは peer0.org* を含めた 3 ノードで、実際に query, invoke ができるのもこれら 3 ノードとなる
    9. peer chaincode query
      • peer1.org2 ノードに対する query の動作確認
        • "a" の値を問い合わせて "90" であることを確認しているっぽい
        • chaincode の内容は次のチュートリアルで学ぶのでとりあえず無視。

ここで、Docker コンテナを一覧してみると

$ docker ps --format "table {{.Names}}\t{{.CreatedAt}}\t{{.Status}}\t{{.Ports}}" | sort
NAMES                                 CREATED AT                      STATUS              PORTS
cli                                   2019-04-12 17:04:04 +0900 JST   Up 2 hours
dev-peer0.org1.example.com-mycc-1.0   2019-04-12 17:04:55 +0900 JST   Up 2 hours
dev-peer0.org2.example.com-mycc-1.0   2019-04-12 17:04:38 +0900 JST   Up 2 hours
dev-peer1.org2.example.com-mycc-1.0   2019-04-12 17:05:12 +0900 JST   Up 2 hours
orderer.example.com                   2019-04-12 17:04:03 +0900 JST   Up 2 hours          0.0.0.0:7050->7050/tcp
peer0.org1.example.com                2019-04-12 17:04:03 +0900 JST   Up 2 hours          0.0.0.0:7051->7051/tcp
peer0.org2.example.com                2019-04-12 17:04:03 +0900 JST   Up 2 hours          0.0.0.0:9051->9051/tcp
peer1.org1.example.com                2019-04-12 17:04:03 +0900 JST   Up 2 hours          0.0.0.0:8051->8051/tcp
peer1.org2.example.com                2019-04-12 17:04:03 +0900 JST   Up 2 hours          0.0.0.0:10051->10051/tcp

こんな感じで dev-*-mycc-1.0 というものが出来ている。これが要するにインスタンス化した chaincode って事らしい。

./byfn.sh down

単純なおそうじスクリプト。上記までで作ったものをみんな削除する。

まとめ

まずは起動と動作確認とを実施できた。今回はお勉強項目がやたらと多かったのですっごい疲れた。