新しい IBM Developer JP サイトへようこそ!サイトのデザインが一新され、旧 developerWorks のコンテンツも統合されました。 詳細はこちら

プライベート・データを保持する権利を有することの意味

この記事では、プライベート・データ集合体について簡単に確認し、プライベート・データを保持する権利を有するとは実際に何を意味するのかを説明します。具体的には、データ集合体を定義するドキュメントに見られる policy 属性の関連性を探り、ネットワーク内の組織にとってこの属性が何を意味するのかを考えます。

プライベート・データ集合体

Hyperledger Fabric ビジネス・ネットワークに接続する組織は、プライバシーおよび機密性に関するメカニズムのツールボックスを自由に使用できます。このうち、主要なメカニズムはチャネルです。組織はチャネルを使用して分散型レジャーを共有し、他のメンバーと取り引きするためのチェーンコードを呼び出します。このコンテキストにおいて、チェーンコードによるデータの拡散を抑制することを可能にするのは、プライベート・データ集合体です。「集合体」として保管されたプライベート・データは、ネットワーク・メンバーのサブセットにしか可視にならないため、データのプライバシーが確保されます。

ブロックチェーン・ネットワーク内でプライベート・データ集合体を利用するには、その集合体の名前と併せて、次のようなアクセス・ルールおよびデータ保持ルールを指定する、集合体の定義を確立する必要があります。

  • プライベート・データを保持することが許可される者
  • 承認プロセスを正常に開始するために、データの配布先とする必要がある最小 のピア数
  • 承認プロセスを正常に開始するために、データの配布先とする必要がある最大 のピア数
  • 非公開データベース内にプライベート・データを保持する期間 (ブロック数という観点で判断)

この記事で特に注目するのは、「プライベート・データを保持することが許可される者」という属性です。この属性は、集合体データを保持することが許可される組織のピアを規定します。データ集合体の定義ドキュメント内でそのような組織を宣言するのは、policy 属性です。例えば、次の集合体の定義ドキュメントを見てください。

[
   {
          "name": "pdc_xyz",
          "policy": "OR('Org1MSP.member', 'Org2MSP.member','Org3MSP.member'')",
          "requiredPeerCount": 0,
          "maxPeerCount": 3,
          "blockToLive": 1000000,
          "memberOnlyRead": true
  }
]

上記のデータ集合体の定義では、Org1、Org2、Org3 の各組織に属するピア・ノードに pdc_xyz という名前のプライベート・データの集合体を保持することが許可されると規定しています。ですが、このことは実際に何を意味するのでしょうか?

シナリオの例: AcmeChain

プライベート・データを保持する権限を有するという意味について考える前に、例として架空のシナリオを規定しましょう。例えば、AcmeChain というブロックチェーン・ネットワークに以下の組織が参加しているとします。

  • Org1
  • Org2
  • Org3
  • Org4

また、AcmeChain にあるチャネルは 1 つだけで (channel1)、このチャネル内には PDC1 と PDC2 という 2 つのプライベート・データの集合体があり、それぞれの policy 属性には以下の値が設定されているとします。

  • PDC1 –> OR('Org1MSP.member', 'Org2MSP.member')
  • PDC2 –> OR('Org3MSP.member', 'Org4MSP.member')

上記の policy 属性では、Org1 および Org2 ピアに PDC1 の保持を許可し、Org3 および Org4 ピアに PDC2 の保持を許可すると規定しています。

この場合、ご存知のとおり (チェーンコードがインスタンス化された時点で) プライベート・データの集合体が作成されると、チェーンコード内からその集合体を使用できるようになります。プライベート・データの読み取りと書き込みを行うには、次のチェーンコード API を使用します。

  • GetPrivateData("<集合体の名前>", "<キー名>")
  • PutPrivateData("<集合体の名前>", "<キー名>", <キー値>)

チェーンコード・コンポーネント内で使用されるいくつかのメソッドの中に、以下の 4 つのメソッドがあるとします。

  • readPDC1(key) — PDC1 から、key 引数に対応する値を読み取る
  • readPDC2(key) — PDC2 から、key 引数に対応する値を読み取る
  • writePDC1(key, value) — 指定した値を key 引数に割り当てた上で、PDC1 内に保管する
  • writePDC2(key, value) — 指定した値を key 引数に割り当てた上で、PDC2 内に保管する

上記のネットワークとチェーンコードの構成を前提とすると、Org1 に属するピアには writePDC2(key, value) メソッドの呼び出しは許可されないように思えます。このメソッドを呼び出そうとした場合、その処理は失敗し、無許可のエラーがスローされそうですが、それはかなり一般的に広まっている誤解です。集合体の定義に含まれる policy フィールドは、PutPrivateData("<集合体の名前>", "<キー名>", <キー値>) メソッドを呼び出してプライベート・データを永続化することを許可する組織を指定します。けれども、それはこの場合には当てはまりません。

ピア上で実行されるチェーンコードでは、そのピアがどの組織に属しているかに関係なく、PutPrivateData("<集合体の名前>", "<キー名>", <キー値>) メソッドを呼び出して、許可されたチャネル上の任意のデータ集合体にプライベート・データを書き込むことができます。例えば AcmeChain の場合、Org1 または Org2 に属するピアは確かに writePDC2(key, value) メソッドを呼び出して、プライベート・データを PDC2 に書き込むことができます。その際、エラーはスローされません。つまり、AcmeChain ネットワークに参加しているピアであれば、どのピア内のどのチェーンコードでも、channel1 内にある任意のプライベート・データの集合体に書き込むことができます。

そうなると、上述の動作はデータ集合体の定義で指定されているポリシーと矛盾しているのでは? という疑問が浮かんでくるでしょう。 一見すると、矛盾のように思えますが、実はそうではありません。まず知っておくべきことは、チェーンコードによって集合に直接書き込みが行われることは決してないという点です。集合体に直接書き込むのではなく、ピアはデータを一時的なデータベースに保管して、コミット・イベントが発生するのを待ちます。コミット・イベントを受信すると、ピアはゴシップ・プロトコルを使用して、policy で指定された組織のアンカー・ピアにその一時的なデータを配布します。Org1 または Org2 に属するピアであれば、どのピアでもプライベート・データを PDC2 に書き込むことができますが、いずれのピアでも PDC2 を副データベースとして保持することはできません。

2 つ目に知っておくべき点として、書き込み処理が集合体に対して直接適用されることは決してありませんが、チェーンコードでは集合体に対して読み取り操作を実行することはできます。したがって、Org1 または Org2 に属するピアのいずれかが readPDC2(key) メソッドを呼び出したとすると、これらのピアが所有していないデータ・ストレージからデータを読み取ることはできないため、読み取り処理は失敗します。

主な考慮事項

どの組織でも任意のデータを任意の場所に書き込めるように思われるかもしませんが、実際にはそうではありません。このモデルでは、次の重要な側面を考慮する必要があります。

  • チェーンコードによって、使用する集合体が決まります — チェーンコードはネットワーク・レベルで制御されるため、組織はピアにチェーンコードをインストールする前に、そのコードを確認する機会があります。コードを確認すると、集合体がどのように管理されるかを理解できます。
  • 2 つ以上の組織の承認ポリシーにより、誰もトランザクションを偽造することができなくなります — 2 つ以上の組織にチェーンコードを実行させて、その結果に署名させることによって、組織的に結果を改ざんする可能性が低くなります。
  • 適格な組織からチェーンコードを呼び出す責任は、クライアント・アプリケーションにあります — クライアントが誤りを犯しても、チェーンコードによって正しい組織が正しいデータを受信することが確実になりますが、この場合、プライベート・データが一時的に別の組織のピアの一時的なデータベース内に保管される可能性があります。

指摘する価値がある点として、Hyperledger Fabric v2.0 には、プライベート・データの集合体をさらに拡張する次の新機能が導入されています。

  • memberOnlyWrite — ビジネス要件により、現在の動作が望ましくないものであれば、この属性を使用して、この記事で説明した動作を変更できます。この属性を true に設定すると、policy 属性に含まれていない組織のピアがプライベート・データを集合体に書き込めなくなります。別の言葉で言い換えると、memberOnlyWritetrue に設定されている場合は、policy 属性で指定されている組織のピアだけに PutPrivateData("<集合体の名前>", "<キー名>", <キー値>) メソッドの呼び出しが許可されます。
  • プライベート・データ・イベント — Hyperledger Fabric に用意されている強力なメカニズムの 1 つは、ネットワーク上のイベントを listen して、アプリケーションが特定の状況に反応するようにできることです。この機能が導入される前でも、クライアント・アプリケーションでブロックまたはトランザクション・イベントを受信できましたが、これらのイベントはネットワークのすべてのメンバーにとって共通のイベントでした。そのため、クライアントはチェーンコードを介して集合体のクエリーを実行し、新しいイベントについて調べるという方法に頼らざるを得ませんでした。この新しい機能を使用すると、policy に指定された組織がプライベート・データ・イベントを受信できるようになるため、特定の組織にイベントを直接通知できます。

Hyperledger Fabric を使用してエンタープライズ・ブロックチェン・ソリューションを構築している複数の組織のビジネス・ニーズを踏まえ、Fabric 開発チームが初期設計の目標の 1 つとしたのは、チェーンコードで任意の組織のプライベート・データの集合体に書き込みを行えるようにすることでした。例えば、この機能があれば、ある組織のデータ集合体に含まれる資産を別の組織の集合体と一方的に共有できます。受信側組織は、共有資産のハッシュ値を計算し、それがレジャー上のハッシュ値と一致することを確認した上で、もう一方の組織 (送信側) との保留中のトランザクションを続行できます。

結論として…

まずは試してください!プライベート・データの集合体に関する Fabric チュートリアルで、この新しいアプローチを使用ケースに適用する方法を確認できます。