ブロックチェーン基盤 Hyperledger Fabric v1.0 アーキテクチャ概説

はじめに

オープンソースブロックチェーン基盤であるHyperledger Fabric(v1.0)を最近学習中なので理解した範囲で本エントリーにまとめます。 Hyperledger Fabricのアーキテクチャトランザクションの流れを理解することや、 アプリケーションの実装方法を学ぶことが目的なので、ブロックチェーンそのものがどのような場面で適用できるかなどは述べる気はないです。そういった話はここを読むといいかもしれません。
Introduction — hyperledger-fabricdocs master documentation

システム・アーキテクチャ

以降ではここに書いてある説明を参考にしています。
Architecture Explained — hyperledger-fabricdocs master documentation

まず、Hyperledger Fabricでは次に示すように複数のノードが協調して元帳(Ledger)の管理を実現しています。
f:id:hiroki-sawano:20171029200149p:plain

  • Application(SDK)
    トランザクションの実行を要求します。 ClientはNode.jsやJavaで実装できます(今後PythonやGo用のSDKも提供される予定)。
  • Membership
    PeerUserの登録・承認をすることで、許可されたノードだけがブロックチェーンネットワークに参加できます。 不特定多数が参加するBitcoinのようなブロックチェーンには存在しない、Enterprise用に実装されているHyperledger Fabricならではの機能です。
  • Peer
    すべてのPeerが同じデータをPeerLedgerに保持しています。 事前にPeerにデプロイしたChaincode(スマートコントラクト)によって、同トランザクション中に各PeerLedgerが更新されます。 ChaincodeはGoやJavaで実装できます。
  • Ordering-service
    Peerトランザクションの実行を承認した後、Ordering-serviceトランザクションの順序を整列します。続けて、すべてのPeerに対して更新情報を伝達します。

トランザクションの種類

公式では次の4種類のトランザクションについて触れられています。

  • Deploy transaction
    新しいChaincodeをデプロイします。Deploy transactionの成功にともなって、Chaincodeブロックチェーン上にインストールされます。
  • Invoke transaction
    事前にデプロイされたChaincodeが提供するオペレーションを実行します。 Invoke transactionの実行は、指定するオペレーションによってLedgerの更新や参照結果の返却を伴います。
  • Query transaction(included in v1)
    v1.0で追加となった読み取り専用トランザクションです。
  • Cross-chaincode transaction(post-v1 feature)
    複数のChaincodeを使用したトランザクションですが、v1.0では未実装です。

トランザクション承認の基本フロー

前述のInvoke Transactionを例に絵を書いてみました(大体あってるはずです..)。Deploy transactionの場合には、tx.txPayloadChaincodeソースコード等が設定される点で違いがありますが流れは基本的に同じようです。Query transactionは後日確認します。

f:id:hiroki-sawano:20171029183421p:plain

要約すると次の流れになります。

  1. [Client]トランザクションの提案
    PROPOSEメッセージでどのChaincodeのメソッドを実行したいのかをEndorsing Peer(承認者となるPeer)に伝える。

  2. [Peer]トランザクションのシミュレーション
    Endorsing Peerは自身のPeerLedger上でトランザクションを仮実行し、read version dependencies(readset)とstate updates(writeset)を取得する(おそらく下図のようなイメージです...)。

f:id:hiroki-sawano:20171029210749p:plain

  1. [Peer]トランザクションの承認
    Peerは内部的にtran-proposalを自身の承認ロジックに渡す。デフォルトでは単にtran-proposalに署名するだけだが、 任意の機能を実行することも可能(e.g. txtran-proposalを入力としたレガシーシステムとの連携によるトランザクション承認)。

  2. [Client]承認されたトランザクションOrdering-serviceに送信
    TRANSACTION-ENDORSEDメッセージをすべて受信した後にOrdering-servicebroadcast(blob)を実行する。 Ordering-serviceに渡すblobは署名されたTRANSACTION-ENDORSEDメッセージのコレクションであり、endorsementとも呼ばれる。 endorsementが集まらなかった場合にはトランザクション提案を取り下げる(後でリトライすることもできるらしい)。

  3. [Ordering-service]トランザクションを整列してPeerに更新情報を転送
    トランザクションを整列して、Peerdeliverイベントを実行する。 多くの場合には効率的に処理するため、Clientから送信された各々のトランザクション(blobs)を出力せずにグルーピングし、1つのdeliverイベントにblocksを設定するとのこと。

  4. [Peer]承認内容の検証
    今回処理するトランザクションseqno未満のseqnoで処理される状態の更新が完了した後に、 blob.endorsementが妥当であるかをChaincode(blob.tran-proposal.chaincodeID)のポリシーに従って検証する。

  5. [Peer]MVCC
    read version dependencies(blob.endorsement.tran-proposal.readset)が破られていないかを検証する。 つまり、承認時のLedgerの状態が他の更新系トランザクションによって変わっていないか(Anomalyの発生)を確認する必要があるということだと思う(i.e. MultiVersion Concurrency Controlを用いたSnapshot Isolationの実装(トランザクション分離レベルではいわゆるRead Commited))。 (MVCCについては理解が浅いので別途確認します.. )

  6. [Peer]トランザクションのコミット
    トランザクションをコミットし、blob.endorsement.tran-proposal.writesetブロックチェーンの状態に反映する。

さいごに

本エントリーでは、Hyperledger Fabric v1.0の構成要素やトランザクション実行の流れを説明しました。 次回は実際に開発環境を準備し、ブロックチェーンを活用したアプリケーションの実装方法を確認していきます。