Chaincode namespace

対象読者: アーキテクト、アプリケーションおよびスマートコントラクト開発者、管理者

チェーンコードネームスペースによって、チェーンコードのワールドステートは他のチェーンコードと分離することが可能になります。 具体的にいうと、同じチェーンコード内のスマートコントラクトは、同じワールドステートに直接アクセスすることができますが、異なるチェーンコードのスマートコントラクトは、互いのワールドステートには直接アクセスすることができません。 もしスマートコントラクトが、他のチェーンコードのワールドステートにアクセスすることが必要な場合は、チェーンコード間呼び出しを行うことで可能です。 そして、ブロックチェーンは異なるワールドステートに関するトランザクションを格納することができます。

このトピックでは、次の項目について述べます。

Motivation

ネームスペースは、一般的な概念です。 ニューヨークのパークストリートシアトルのパークストリートは、同じ名前であっても違う通りであるということがわかります。 パークストリートに対して、都市名はネームスペースを構成していて、同時に自由度とわかりやすさを与えています。

コンピュータシステムにおいても同様です。 ネームスペースによって、別々のユーザーが、互いに邪魔をすることなく、共有システムの異なる部分でプログラム及び処理を行うことができます。 多くのプログラミング言語は、ネームスペースをもっています。これによって、プログラムは、例えば変数名といった固有の識別子を自由に使うことができ、ほかのプログラムのことを心配する必要がありません。 Hyperledger Fabricでは、ネームスペースによって、スマートコントラクトがその台帳ワールドステートを、他のスマートコントラクトとは分離できていることを、これから見ていきましょう。

Scenario

それでは、台帳ワールドステートにおいて、チャネルの組織に対して重要なビジネスデータに関する事実をどのように構成しているかを、下記の図を用いて詳しく見ていきましょう。 これらのデータがコマーシャルペーパーか債権か自動車登録かに関わらず、また、ライフサイクル上のどこに位置していても、台帳ワールドステートデータベース内に保持されています。 スマートコントラクトは、これらのデータを台帳(ワールドステートおよびブロックチェーン)とのやりとりを行うことで管理し、ほとんどの場合には、台帳ワールドステートのクエリや更新を行います。

台帳ワールドステートが、アクセスするスマートコントラクトのチェーンコードに応じて分割されていると理解することが極めて重要です。 そしてこの分割、すなわちネームスペースをもつことは、アーキテクトや管理者やプログラマにとってきわめて重要な設計上の留意点となります。

chaincodens.scenario 台帳ワールドステートは、アクセスするチェーンコードに応じて分割されています。 あるチャネルにおいて、同じチェーンコード内のスマートコントラクトは同じワールドステートを共有し、異なるチェーンコードのスマートコントラクトは互いのワールドステートに直接アクセスすることはできません。 このように、ブロックチェーンは、異なるチェーンコードワールドステートに関するトランザクションを格納することができます。

ここでの例では、2つのチェーンコードで定義された4つのスマートコントラクトがあることがわかります。それぞれのチェーンコードは、その専用のチェーンコードコンテナ内にあります。 euroPaperyenPaperの2つのスマートコントラクトは、papersチェーンコード内に定義されています。 euroBondyenBondの2つのスマートコントラクトも、同様の状況で、bondsチェーンコード内に定義されています。 この設計によって、アプリケーションプログラマは、ユーロまたは円建てのコマーシャルペーパー(papers)あるいは債権(bonds)を扱っているのかを理解することができます。 そして、それぞれの金融商品の規則は、通貨が違ってもあまり変わらないため、同じチェーンコードでデプロイを管理することは理にかなっています。

この図は、また、このデプロイの方針による結果も表しています。 データベース管理システム(DBMS)は、papersbondsのチェーンコードとそれに含まれるスマートコントラクトのために、チェーンコードごとに別のワールドステートデータベースを作成します。 world state Aworld state Bは、それぞれ別のデータベースに格納されています。 データは互いに隔離されており、例えば1つのワールドステートのクエリでは、両方のワールドステートにアクセスすることはできません。 ワールドステートは、チェーンコードに応じてネームスペースに分かれているということができます。

world state Aが、2つのコマーシャルペーパーのリスト paperListEuropaperListYenを含んでいるのがわかるでしょうか。 ステートPAP11PAP21は、それぞれeuroPaperyenPaperスマートコントラクトによって管理されているコマーシャルペーパーのインスタンスです。 この二つのステートは、同じチェーンコードネームスペースにあるため、キー(PAPxyz)は、papersチェーンコードのネームスペース内で一意でなくてはなりません。 これは、町の中で通りの名前が一意であるのと少し似ています。 papersチェーンコードで、ユーロ建てか円建てかにかかわらず、すべてのコマーシャルペーパーを集計するスマートコントラクトを書くことができることに注意してください。 これは、コマーシャルペーパーが同じネームスペースを共有しているためです。 債権についても状況は同様で、債権はworld state Bに格納されており、これは別のbondsデータベースにマップされており、キーはこの中でユニークでなくてはなりません。

そして同じように重要なのは、ネームスペースがあるということは、euroPaperyenPaperは直接world state Bにはアクセスできず、euroBondyenBondは直接world state Aにアクセスすることができないということです。 コマーシャルペーパーと債権は大きく異なる金融商品であり、異なる属性をもち異なるルールに従うため、この隔離は有用なものです。 また、異なるネームスペースにあるため、papersbondsは、同じキーを持つこともできることを意味します。 名前付けに関して大きな自由度を与えるため、これも有用なものです。 この自由度を使って、ビジネスデータに意味のある名前付けをするのに役立てましょう。

さらに重要なことに、ブロックチェーンは、あるチャネルで動作するピアに結びつけられるものであり、world state Aworld state B両方に影響するトランザクションを含んでいるのがわかります。 これは、ブロックチェーンは、ピアに格納される最も基本的なデータ構造であるためです。 ワールドステートは、ブロックチェーンのトランザクションの積み重なった結果であるので、いつでもブロックチェーンから再構成することが可能です。 ワールドステートは、スマートコントラクトが通常必要なのはステートの現在の値であるので、スマートコントラクトを単純にしその効率を改善するのに役立つものです。 ワールドステートをネームスペースによって分離しておくことは、スマートコントラクトが別のスマートコントラクトとロジックを隔離し、別のワールドステートに対するトランザクションの心配をする必要をなくすのに役立ちます。 たとえば、bondsのコントラクトは、paperのトランザクションを心配する必要がありません。なぜならば、bondsからは、paperのトランザクションの結果のワールドステートは見ることができないからです。

また、ピアとチェーンコードコンテナ、DBMSは全て論理的に別のプロセスであるということも注目しておくべきでしょう。 ピアとそのチェーンコードコンテナは、常にOSの物理的に別のプロセスですが、DBMSはその種類によって、設定で組み込みか分離するかを変更することができます。 LevelDBでは、DBMSは完全にピア内に含まれますが、CouchDBでは別のOSのプロセスになります。

ここでの例において、ネームスペースの選択は、異なる通貨のコマーシャルペーパーは共有し、債権からは分離するというビジネス上の要件から来ているものであることは覚えておきましょう。 全ての金融資産の種類を別々にするようなビジネス要件、あるいは、コマーシャルペーパーと債権を共有するようなビジネス要件であったなら、どのようにネームスペースの構造が変わっていたかを考えてみましょう。

Channels

ピアが複数のチャネルに参加した場合、各チャネルに対して新しいブロックチェーンが作られ管理されます。 加えて、新しいチャネルにチェーンコードがデプロイされるたびに、新しいワールドステートデータベースが作られます。 これは、ワールドステートにおけるチェーンコードのネームスペースに加えて、チャネルが一種のネームスペースを構成することを意味しています。

しかし、同じピアとチェーンコードコンテナプロセスは、複数のチャネルに同時に参加することができるため、ブロックチェーンやワールドステートデータベースと異なり、これらのプロセスは参加しているチャネルの数に応じて増えはしません。

例えば、papersbondsチェーンコードを新しいチャネルにデプロイしたとすると、完全に別のブロックチェーンと、2つのワールドステートデータベースが作られるでしょう。しかし、ピアとチェーンコードコンテナは増加せず、ただ複数のチャネルに接続されるだけでしょう。

Usage

コマーシャルペーパーのを用いて、アプリケーションがどのようにネームスペースとスマートコントラクトを使うのかを見てみましょう。 アプリケーションがピアと通信し、ピアは要求を適切なチェーンコードコンテナにルーティングし、チェーンコードがDBMSにアクセスする、ということは触れておくべきでしょう。 このルーティングは、図に示されているピアのコアコンポーネントによって行われます。

以下が、ユーロ建てと円建てのコマーシャルペーパー及び債権を用いるアプリケーションのコードです。 このコードは、説明が不要なほど十分わかりやすいでしょう。

const euroPaper = network.getContract(papers, euroPaper);
paper1 = euroPaper.submit(issue, PAP11);

const yenPaper = network.getContract(papers, yenPaper);
paper2 = yenPaper.submit(redeem, PAP21);

const euroBond = network.getContract(bonds, euroBond);
bond1 = euroBond.submit(buy, BON31);

const yenBond = network.getContract(bonds, yenBond);
bond2 = yenBond.submit(sell, BON41);

このアプリケーションについて下記のことがわかります。

スマートコントラクトのワールドステートとのやりとりについて下記のことがわかります。

ブロックチェーンの、全てのワールドステートに関するトランザクションを格納するやりかたについて下記のことがわかります。

Cross chaincode access

ここでの例のシナリオで見たように、euroPaperyenPaperworld state Bに直接アクセスすることができません。 これは、チェーンコードとスマートコントラクトが、チェーンコードとワールドステートが互いに別々となるように設計されているためです。 しかし、euroPaperworld state Bにアクセスする必要がある場合を考えてみましょう。

どういった場合にこのようなことがあるでしょうか? スマートコントラクトがコマーシャルペーパーを発行するとき、近い満期日の債権の現在のリターンに応じた価格をコマーシャルペーパーにつけたいという場合を考えてみてください。 この場合、euroPaperコントラクトがworld state Bにある債権の価格をクエリできることが必要でしょう。 このやりとりをどのように実現するかを、下記の図を見てみましょう。

chaincodens.scenario チェーンコードとスマートコントラクトが間接的に、チェーンコードを介して他のワールドステートにアクセスする方法

以下のことに注目してください。

invokeChaincode() APIによって、チェーンコード間を制御が渡ります。

このAPIは、あるチェーンコードから別のチェーンコードに制御を渡します。

この例ではクエリトランザクションについてのみ述べましたが、呼ばれた側のチェーンコードのワールドステートを更新するスマートコントラクトを実行(invoke)することも可能です。次の留意点を参照してください。

Considerations