Wallet

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

ウォレットは、ユーザーのアイデンティティを集めたものです。 ユーザーが起動したアプリケーションは、その中のアイデンティティの一つを選んで、チャネルに接続します。 例えば台帳といったチャネルの資源へのアクセス権は、このアイデンティティとMSPの組み合わせで判断されます。

このトピックでは、次のことについて扱います。

Scenario

アプリケーションは、PaperNetのようなネットワークチャネルに接続するとき、それを行うためのユーザーアイデンティティ(例えばID1)を選択します。 チャネルMSPは、ID1と、ある組織の中の役割を関連付け、この役割によって、最終的にアプリケーションのチャネル資源に対する権利が決まります。 例えば、ID1は、台帳に対する読み書きのできるMagnetoCorp組織のメンバーとしてユーザーを識別するかもしれませんし、一方ID2は、コンソーシアムに新しい組織を追加できるMagnetoCorpの管理者を識別するものかもしれません。

wallet.scenario 二人のユーザーIsabellaとBalajiは、PaperNetとBondNetという別々のネットワークに接続する際に使用可能な、異なるアイデンティティを含むウォレットを持っています

MagnetoCorpのIsabellaとDigiBankのBalajiという二つのユーザーの例について考えてみましょう。 Isabellaは、App 1を使って、PanerNetのスマートコントラクトとBondNetの別のスマートコントラクトを実行しようとしています。 Balajiも同じように、App 2を使って、スマートコントラクトを実行しようとしていますが、PaperNetのスマートコントラクトのみです。 (アプリケーションが複数のネットワークとそのネットワーク内のスマートコントラクトにアクセスするのは、非常に簡単です)

このとき次のことがわかるでしょう。

  • アイデンティティを発行するのに、MagnetoCorpはCA1を用い、DigiBankはCA2を用いている。 これらのアイデンティティはユーザーのウォレットに格納されます。
  • Balajiのウォレットは、CA2で発行されたID4というアイデンティティを一つだけ格納しています。 Isabellaのウォレットは、CA1で発行されたID1ID2ID3という多くのアイデンティティを持っています。 ウォレットは、一人のユーザーに対する複数のアイデンティティを持つことができ、各アイデンティティは別々のCAによって発行されることもあります。
  • IsabellaとBalajiはともにPaperNetに接続し、そのMSPは、アイデンティティを発行しているCAに基づいて、IsabellaがMagnetoCorp組織のメンバーであり、BalajiをDigiBank組織のメンバーとして判断します。 (一つの組織が複数のCAを用いることも、一つのCAが複数の組織に対応することも可能です)
  • Isabellaは、ID1をPaperNetとBondNetのどちらに接続するときも使うことができます。 どの場合でも、このアイデンティティを使用すると、彼女はMagnetoCorpのメンバーとして認識されます。
  • Isabellaは、ID2をBondNetに接続するときに使うことができ、この場合、彼女はMagnetoCorpの管理者として識別されます。 このようにして、Isabellaは二つの非常に異なる特権を持つことができます。 ID1は、BondNetの台帳を読み書きできるMagnetoCorpの単純なメンバーとして彼女を識別します。 一方、ID2は、BondNetに対して新しい組織を追加できるMagnetoCorpの管理者として彼女を識別します。
  • Balajiは、ID4を用いてBondNetに接続することはできません。 もし接続しようとしたなら、BondNetのMSPはCA2のことを知らないので、ID4はDigiBankに属しているとは認識されないでしょう。

Types

どこにアイデンティティを格納するかによって、ウォレットにはいくつかの種類があります。

wallet.types 3つの異なる種類のウォレットストレージであるファイルシステム・インメモリ・CouchDB

  • ファイルシステム: もっとも一般的なウォレットの格納先です。 ファイルシステムは、広く使われており、わかりやすく、ネットワーク経由でマウントすることもできます。 ウォレットのデフォルトとしてよい選択肢です。
  • インメモリ: アプリケーション内に格納されるウォレットです。 ファイルシステムに対してアクセスができないような、典型的にはブラウザのような制限された環境でアプリケーションが動いている場合に、この種類のウォレットを使用してください。 この種類のウォレットは揮発性であり、アプリケーションが終了したりクラッシュしたりすると、アイデンティティは失われることは覚えておくとよいでしょう。
  • CouchDB: CouchDBに格納されたウォレットです。 これは使われることが最もまれな形のウォレットの格納先ですが、データベースのバックアップと復元機構を使いたいユーザーには、CouchDBウォレットは、ディザスタリカバリを単純にする便利な選択肢となるかもしれません。

ウォレットを作成するには、Walletsクラスが提供するファクトリ関数を使用してください。

Hardware Security Module

ハードウェアセキュリティモジュール(HSM)は、非常にセキュアで耐タンパ性をもつデバイスで、特に秘密鍵のようなデジタルアイデンティティ情報を格納するものです。 HSMは、コンピュータにローカルに接続されたり、ネットワーク経由でアクセス可能であったりします。 ほとんどのHSMは、秘密鍵を用いた内部での暗号化が可能で、秘密鍵がHSMの外に出ないようになっています。

HSMは、どの種類のウォレットでも利用可能です。 この場合、アイデンティティの証明書はウォレットに格納され、秘密鍵はHSMに格納されます。

HSMで管理されたアイデンティティの利用を有効かするには、IdentityProviderにHSMへの接続情報が設定され、ウォレットに登録されている必要があります。 より詳細については、ウォレットを用いたアイデンティティの管理のチュートリアルを参照してください。

Structure

一つのウォレットは、複数のアイデンティティを持つことができ、それぞれのアイデンティティはある認証局(CA)により発行されています。 各アイデンティティは、それを説明するラベル、公開鍵を含むX.509証明書、秘密鍵、Fabric特有のメタデータからなる標準的な構造を持っています。 ウォレットの種類ごとに、この構造が適切にその格納機構にマップされています。

wallet.structure Fabricのウォレットは、異なる証明局によって発行された証明書を含む複数のアイデンティティを持つことができます。 アイデンティティは、証明書、秘密鍵、Fabricのメタデータを持ちます。

ウォレットとアイデンティティを簡単にする重要なクラスメソッドがいくつかあります。

const identity: X509Identity = {
    credentials: {
        certificate: certificatePEM,
        privateKey: privateKeyPEM,
    },
    mspId: 'Org1MSP',
    type: 'X.509',
};
await wallet.put(identityLabel, identity);

メタデータOrg1MSP、証明書certificateと秘密鍵privateKeyを持つidentityが作られているのがわかります。 また、wallet.put()がこのアイデンティティを、identityLabelというラベルでウォレットに追加しているのがわかります。

Gatewayクラスは、アイデンティティについてmspIdtypeメタデータ(上記の例では、それぞれOrg1MSP1X.509)が設定されていることだけを要求します。 Gatewayは、今のところは、例えば、特定の通知のストラテジが要求されたときなどに、このMSP IDの値をコネクションプロファイルのピアを識別するのに使います。 DigiBankのゲートウェイファイル networkConnection.yamlから、Org1MSPの通知がpeer0.org1.example.comに関連付けられていることがわかるでしょう。

organizations:
  Org1:
    mspid: Org1MSP

    peers:
      - peer0.org1.example.com

それぞれのウォレットの種類の内部構造について心配する必要はまったくありませんが、もし興味があれば、コマーシャルペーパーのサンプルで、下記のユーザーアイデンティティのフォルダを見てみてください。

magnetocorp/identity/user/isabella/
                                  wallet/
                                        User1@org1.example.com.id

これらのファイルを詳細にみることもできますが、これまで述べたように、SDKを用いてこれらのデータを操作するほうが簡単です。

Operations

すべての種類のウォレットは、共通のWalletインタフェースを実装しており、アイデンティティの管理のための標準的なAPIを提供しています。 つまり、アプリケーションは、実際のウォレットの格納機構とは独立に作ることができ、たとえば、ファイルシステムとHSMのウォレットは、非常に近い方法で扱うことができるということです。

wallet.operations ウォレットは、あるライフサイクルに従い、新たに作成・既存のものを開くことができますし、アイデンティティを読み、追加し、削除することができます

アプリケーションは、単純なライフサイクルに従ってウォレットを使うことができます。 ウォレットは、既存のものを開くか新たに作成することができ、その後、アイデンティティを追加し、更新し、読み取り、また削除することができます。 JSDocWalletの様々なメソッドについて、どのように動くかを少し見てください。 コマーシャルペーパーのチュートリアルのaddToWallet.jsは、下記のようによい例となっています。

const wallet = await Wallets.newFileSystemWallet('../identity/user/isabella/wallet');

const cert = fs.readFileSync(path.join(credPath, '.../User1@org1.example.com-cert.pem')).toString();
const key = fs.readFileSync(path.join(credPath, '.../_sk')).toString();

const identityLabel = 'User1@org1.example.com';
const identity = {
    credentials: {
        certificate: cert,
        privateKey: key,
    },
    mspId: 'Org1MSP',
    type: 'X.509',
};

await wallet.put(identityLabel, identity);

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

  • プログラムが初めて実行されたとき、ウォレットは、ローカルファイルシステム上の.../isabella/walletに作成されます。
  • 証明書certと秘密鍵keyは、ファイルシステムからロードされます。
  • 新しいX.509アイデンティティは、certkeyOrg1MSPという値で作成されます。
  • 新しいアイデンティティは、User1@org1.example.comというラベルで、wallet.put()によってウォレットに追加されます。

これでウォレットに関して知るべきことはすべてです。 Fabricのネットワーク資源にアクセスするために、ユーザーの代わりにアプリケーションによって使われるアイデンティティを、どのようにウォレットが持っているかを見てきました。 アプリケーションとセキュリティの必要性に応じて、異なる種類のウォレットが利用可能であり、単純なAPIによってアプリケーションがウォレットとその中のアイデンティティを管理することができます。