Contract names

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

チェーンコードは、コードをHyperledger Fabricのブロックチェーンネットワークにデプロイするための一般的なコンテナです。 一つあるいは複数の関係するスマートコントラクトがチェーンコード内で定義されます。 各スマートコントラクトは、チェーンコード内で一意に識別できる名前を持ちます。 アプリケーションは、このコントラクト名を用いて、チェーンコード内の特定のスマートコントラクトにアクセスします。

このトピックでは、下記について扱います。 * 複数のスマートコントラクトがチェーンコードにどのように含まれているか * どのようにスマートコントラクト名を与えるか * アプリケーションからどのようにスマートコントラクトを使うか * デフォルトのスマートコントラクト

Chaincode

アプリケーション開発のトピックにおいては、Fabric SDKがハイレベルなプログラミングの抽象化を提供し、それによって、アプリケーションやスマートコントラクト開発者が、Fabricネットワークとのやりとりの低レベルの詳細ではなく、ビジネスの問題に集中する助けとなることがわかります。

スマートコントラクトは、高レベルのプログラミングの抽象化の一つの例であり、複数のスマートコントラクトをチェーンコードコンテナ内に定義することが可能です。 チェーンコードがピアにインストールされ、チャネルにデプロイされると、チェーンコード内のスマートコントラクトは全てアプリケーションから利用可能になります。

contract.chaincode 複数のスマートコントラクトをチェーンコード内に定義することが可能です。 それぞれのスマートコントラクトは、名前でチェーンコード内で一意に識別されます。

上の図では、チェーンコードAは、その中に3つのスマートコントラクトが定義されており、チェーンコードBには4つのスマートコントラクトがあります。 特定のスマートコントラクトを表すのにチェーンコード名が使われているのがわかるでしょう。

台帳の構造は、デプロイされているスマートコントラクト群によって定義されます。 これは、台帳は、ネットワークにおいて対象となるビジネスデータ(PaperNetにおけるコマーシャルペーパーのように)に関する事実を含み、そのビジネスデータは、スマートコントラクトで定義されたトランザクション関数によってライフサイクル(例えば、発行、購入、現金化など)の中で遷移するからです。

多くの場合では、チェーンコード内で定義されているスマートコントラクトは一つだけでしょう。 しかし、関連する複数のスマートコントラクトを一つのチェーンコードにまとめることは、理にかなっていることがあります。 例えば、別の通貨のコマーシャルペーパーには、EuroPaperContractDollarPaperContractYenPaperContractというコントラクトを使い、それらは、デプロイされたチャネルで互いに同期していることが必要になるかもしれません。

Name

チェーンコード内のそれぞれのスマートコントラクトは、コントラクト名によって一意に識別されます。 スマートコントラクトは、クラスのコンストラクタで名前を明示的に指定することもできますし、Contractクラスによって与えられる暗黙的なデフォルトの名前を使うこともできます。

チェーンコードのpapercontract.jsファイルを確認してみましょう。

class CommercialPaperContract extends Contract {

    constructor() {
        // チェーンコードファイル内に複数のスマートコントラクトがある場合には一意となる名前
        super('org.papernet.commercialpaper');
    }

CommercialPaperContractのコンストラクタがorg.papernet.commercialpaperをコントラクト名として指定しているのがわかるでしょう。 その結果、このpapercontractチェーンコードにおいては、このスマートコントラクトは、org.papernet.commercialpaperというコントラクト名に結びつけられることとなります。

もし、明示的なコントラクト名が指定されなければ、クラス名がデフォルトの名前として与えられます。 この例では、デフォルトのコントラクト名は、CommercialPaperContractとなるでしょう。

名前を選ぶ際にはよく考えてください。 それぞれのスマートコントラクトの名前は一意でなくてはならないというだけではありません。 良く選択された名前は、わかりやすいものです。 具体的には、明らかで意味のある名前を構成しやすくするものとして、DNSスタイルの命名規則を用いることをお勧めします。 org.papernet.commercialpaperという名前は、PaperNetネットワークが標準のコマーシャルペーパーのスマートコントラクトを定義しているという意味を表しています。

コントラクト名は、あるチェーンコード内の別のスマートコントラクトの同じ名前のトランザクション関数を区別するのに役立ちます。 これは、複数のスマートコントラクトが密接に関係がある場合に起こります。それらのトランザクションの名前は同じものである傾向にあるからです。 チャネルにおいて、チェーンコードとスマートコントラクト名の組み合わせによって、トランザクションが一意に定義されることがわかります。

コントラクト名は、チェーンコードファイル内において一意でなければなりません。 コードエディタによっては、デプロイの前に、同じ名前のクラスが複数存在するのを検知するものもあるでしょう。 いずれにしても、複数のクラスが明示的であれ暗黙的であれ同じスマートコントラクト名を与えられている場合、チェーンコードはエラーを返すでしょう。

Application

チェーンコードがピアにインストールされ、チャネルにデプロイされると、チェーンコード内のスマートコントラクトは、アプリケーションから次のようにアクセス可能になります。

const network = await gateway.getNetwork(`papernet`);

const contract = await network.getContract('papercontract', 'org.papernet.commercialpaper');

const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000');

アプリケーションが、network.getContract()メソッドを使ってスマートコントラクトにアクセスしているのがわかるでしょう。 チェーンコードpapercontractにおける名前org.papernet.commercialpaperで、contractへの参照が返され、それを使ってcontract.submitTransaction() APIを用いることでコマーシャルペーパーを発行するトランザクションを送信することができます。

Default contract

チェーンコードで最初に定義されているスマートコントラクトは、デフォルトスマートコントラクトと呼ばれます。 チェーンコードは普通一つのスマートコントラクトしか定義していないため、デフォルトというのは便利です。 アプリケーションがコントラクト名を指定しなくとも、直接そのトランザクションにアクセスすることができるからです。

default.contract デフォルトスマートコントラクトは、チェーンコードで定義された最初のコントラクトです。

この図では、CommercialPaperContractがデフォルトのスマートコントラクトです。 二つのスマートコントラクトがありますが、デフォルトスマートコントラクトによって、先ほどの例は、次のように、より簡単に書くことができます。

const network = await gateway.getNetwork(`papernet`);

const contract = await network.getContract('papercontract');

const issueResponse = await contract.submitTransaction('issue', 'MagnetoCorp', '00001', '2020-05-31', '2020-11-30', '5000000');

papercontractのデフォルトのスマートコントラクトは、CommercialPaperContractであり、それにはissueトランザクションがあるため、このコードはうまく動きます。 BondContractissueトランザクションを実行するには、明示的に指定しなければならないということに注意してください。 同様に、cancelトランザクションは、BondContractにしかないものであっても、デフォルトスマートコントラクトではないので、これも明示的に指定する必要があります。

多くの場合では、チェーンコードはスマートコントラクトを一つだけしか持たないため、チェーンコードの名前をよく考えて決めることで、開発者がチェーンコードという概念を意識する必要を減らすことができます。 上のコードの例では、papercontractがスマートコントラクトとして感じられるでしょう。

まとめると、コントラクト名は、あるチェーンコード内において各スマートコントラクトを識別する簡単な仕組みです。 コントラクト名によって、アプリケーションは簡単に特定のスマートコントラクトを見つけ、台帳にアクセスするのに使うことができます。