スマート・コントラクトの作成とデプロイ

スマート・コントラクトを作成するには、次の図のエンティティ・モデルに示すように、ブロックチェーンに格納および管理するエンティティを定義する必要があります。


oracle-blockchain-cms-entity.pngの説明が続きます
図oracle-blockchain-cms-entity.pngの説明

これらすべてのエンティティとその関係、エンティティを管理および操作するために必要なすべてのロジック、およびブロックチェーン台帳に永続化するためにも、スマート・コントラクトで定義されます。

フォルダはNFTトークンとして表されるため、NFTとして開発および初期化されます。その他の依存エンティティ(ドキュメントおよびプロパティ)は標準エンティティであり、フォルダの子エンティティであるため、初期化を必要とせずに標準エンティティとして開発されます。

スマート・コントラクトが作成されると、作成したブロックチェーン・ネットワークにインストールしてデプロイします。

スマート・コントラクトの作成

Oracle Blockchainアプリケーション・ビルダーを構成したら、仕様ファイルを作成できます。仕様ファイルは、次のコードに示す単純なYAMLファイルとして作成できます。

ノート:

このファイルは、GitHubからダウンロードすることもできます: YAMLファイルのダウンロード
#
# Token asset to manage the complete lifecycle of a non-fungible token representing a folder to hold docuements. 
# This specification file will generate an Smartcontract project with a non-fungible token for the folders to be maintained by the users.
#
assets:
    - name: folderNFT
      type: token
      symbol: eDocs
      standard: erc721+
      anatomy: 
        type: nonfungible
        unit: whole
      behavior:
        - indivisible
        - singleton
        - mintable:
        - transferable
        - burnable
        - roles:
            minter_role_name: minter
      properties:
          - name: folderHASH
            type: string
          - name: documents
            type: document[]
      metadata:
          - name: folderID
            type: string
            mandatory: true
            id: true
          - name: folderType
            type: string
            mandatory: true
      methods:
        crud: [create, getById, update, delete]
        others: [getHistoryById, getByRange]
    - name: document
      properties:
        - name: docName
          type: string
          mandatory: true
          id: true
        - name: docURL
          type: string
          mandatory: true
        - name: docHASH
          type: string
          mandatory: true
        - name: docType
          type: string
          mandatory: true
        - name: docProperties
          type: docProperty[]
      methods:
        crud: [create, getById, update, delete]
        others: [getHistoryById, getByRange]
    - name: docProperty
      type: embedded
      properties:
          - name: propName
            type: string
            mandatory: true
          - name: propValue
            type: string
            mandatory: true
      methods:
        crud: [create, getById, update, delete]
        others: [getHistoryById, getByRange]
customMethods:
    - executeQuery
    - "attachDocument(tokenId: string, docName: string, docURL: string, docHASH: string, docType: string, docProps: string[], docVals: string[])" # Attach a document to an existing folder. 
    - "retrieveDocuments(tokenId: string)" # Retrieve Documents of an folder. 
    - "transferFolder(tokenId: string, fromOrgId: string, fromUserId: string, toOrgId: string, toUserId: string)" # Transfer the folder among participants. 
    - "updateFolderHASH(tokenId: string, newHash: string)" # Update HASH folder 
    - "getFolderHASH(tokenId: string)" # Check HASH folder 

この仕様ファイルでは、最初に定義されたエンティティー(folderNFT)で、NFTトークンを表すすべてのセクションと属性を表示できます。ファイルで定義されているセクションの概要:

  • アセット: 異なるアセット(標準エンティティ、FT、NFT)が定義される場所。各アセット内では、表されるアセットの種類に応じて異なるセクションを区別できます。NFTと財務取引では、次の様々なサブセクションがあります。
    • Type/Symbol/Standard: このトークンがERC-721 Standardに基づいていることを指定し、一意のシンボル識別子を付与します。
    • 解剖学: NFTであり、小さい分数に分割されるかどうかを指定します(現在はNFTトークンの唯一のオプションです)。
    • 動作: トークンをミントできるかどうかを定義します。その場合、ミニテーブル・トークンの最大数を定義します。ここでは、分割できないトークンであることも述べる必要があります。各クラスにシングルトン、転送可能、および書き込み可能であり、その削除に似ています(ただし消えていないため、まだ存在しますが、まったく使用できません)。また、このセクションでは、トークンの動作を特定の役割に制限できます。
    • Metadata: トークンの作成中に設定する必要があり、将来は変更できません。したがって、その価値はトークンの生涯にわたって不変のままです。
    • プロパティ: フォルダを構成するドキュメントの配列など、トークンの存続期間中に異なる可能性があるトークンの標準属性を定義します。
  • customMethods: カスタム・メソッドのリストを定義する必要がある場所。これらのメソッドの場合、Oracle Blockchainアプリケーション・ビルダーはメソッドへの実装なしで、メソッドの署名のみを生成します。これらのメソッドの実装は、開発者が実装できる唯一のコードです。

次のリンクでは、ビジネス・ニーズに基づいて任意の種類のエンティティ(NFT、FTまたは標準エンティティ)を構成する方法について説明します。

仕様ファイルが作成されたら、次のステップに従って、Oracle Blockchainアプリケーション・ビルダーにプロジェクトのスキャフォールドの作成を義務付けることができます。

  1. 仕様ファイルがOracle Blockchainアプリケーション・ビルダーの外部で作成されている場合は、仕様ファイルをOracle Blockchainアプリケーション・ビルダーにインポートする必要があります。「仕様」フレームの横にある省略記号をクリックし、ポップアップから「仕様のインポート」をクリックします。
  2. 仕様ファイルを選択し、「仕様のインポート」をクリックします。
  3. インポートした仕様ファイルに基づいて新しいチェーンコード・プロジェクトを作成できるようにするには、CHAINCODESフレームの右上隅にある「+」アイコンをクリックします。チェーンコードの作成ウィザードが開きます。
  4. チェーンコードの作成ウィザードで、次の詳細を指定する必要があります:
    • 名前: プロジェクトの名前。
    • 言語: プロジェクトのスキャフォールドを作成する言語。TypescriptとGoLangのいずれかのみを選択できます。このソリューション・プレイブックでTypescriptを使用してカスタム・メソッドを実装しているため、Typescriptを選択することをお薦めします。
    • 仕様: 前のステップで作成した仕様ファイルを選択します。
    • 場所/ドメイン: 選択した言語に応じて、Typescript言語またはGoLang言語のドメインに対してプロジェクトを配置する場所を定義するように求められます。
    すべての詳細が正しい場合は、ウィザードに緑色のメッセージが表示されます。そうでない場合は、プロジェクトのスキャフォールドの作成時に生成された出力を確認します。
  5. 「CHAINCODES」セクションに、新しく生成されたプロジェクトが表示されます。プロジェクト内をクリックして、ソース・コードが生成されているプロジェクト内のsrcフォルダに移動します。
    • src/controllerフォルダ内には、スマート・コントラクトを表すメイン・クラスと、エンティティを管理するための自動生成されたすべてのメソッドが表示されます。
    • src/modelフォルダ内には、NFTエンティティを表すクラスが表示されます。
  6. src/controllerフォルダに移動し、コントローラ・クラスを選択します。Oracle Blockchainアプリケーション・ビルダーによって自動生成されたすべてのコードが表示され、ファイルの最後に、実装なしでカスタム・メソッドのすべてのシグネチャが表示されます。
  7. この時点で、カスタム・メソッドの実装を作成する必要があります。簡単にするために、GitHubで使用可能なファイルCMS_customMethods.tsに、このようなメソッドのすべての実装コードを提供しました。Oracle Blockchainアプリケーション・ビルダーによって自動生成された署名を参照ファイルのコンテンツに置き換えるだけで済みます。
カスタム・メソッドの前の行であるControllerクラスには、NFTトークンのライフサイクルを管理するためのすべての自動生成コードが含まれます。次の図は、このような方法でカバーされる様々な領域を示しています。

oracle-blockchain-nft-token-oracle.zip

この時点でチェーンコードを使用する準備ができているため、ローカルHyperledger Fabricネットワークでのチェーンコードのテストの手順に従って、チェーンコードをローカルにデプロイおよびテストできます。

スマート・コントラクトのデプロイ

チェーンコードをローカルでテストしたら、次によってOracle Blockchainサービス・コンソールを使用して以前に作成した実際のネットワークでデプロイします。

  • チェーンコード・プロジェクトのパッケージ化。
  • チェーンコード・パッケージのインストールおよび単一インスタンスへのデプロイ(founder)
次の項では、デプロイメントを実行するための詳細なステップについて説明します。
  1. チェーンコード・プロジェクトからデプロイ可能なパッケージを作成します。Visual Studioで、チェーンコード・プロジェクト名の上部にある右ボタンをクリックし、ポップアップ・メニューから「パッケージ」オプションを選択し、チェーンコード・パッケージ・ファイルを保存するディレクトリを選択します。
  2. Oracle Blockchain Serviceコンソールにアクセスして、チェーンコード・パッケージをインストールし、ファウンダ・インスタンスにデプロイします。
  3. 「チェーンコード」タブに移動し、「新しいチェーンコードのデプロイ」をクリックします。
  4. 「拡張デプロイメント」オプションを選択します。
  5. チェーンコード・パッケージをファウンダ・インスタンスにインストールするためのすべての値を設定し、「次へ」をクリックします。
    • パッケージ・ラベル: 異なる既存のチャネルにインストールされているパッケージを識別するのに役立つ名前を付けます。同じスマート・コントラクトの複数のバージョンを異なるチャネルにデプロイできるため、次のようなパッケージ・ラベル名を設定することをお薦めします。
      <smartContractName>_<channel>_<version>
      
    • チェーンコード言語: チェーンコードを開発した言語に基づいて、様々な言語の中から選択します。
    • ターゲット・ピア: チェーンコード・パッケージをインストールするピアを選択します。
    • パッケージ・チェーンコード: zipファイルをアップロードする場合は、このチェック・ボックスの選択を解除したままにします。tar.gzファイルのチェック・ボックスを選択します。
    • チェーンコード・ソース: 「チェーンコード・ファイルのアップロード」をクリックし、チェーンコードzipファイルを選択します。
  6. インストールが成功すると、成功メッセージが表示されます。次のステップは、選択したチャネルのチェーンコードのデプロイメントであるため、デプロイメント・フェーズに関連するすべての値を設定して「次へ」をクリックする必要があります。
    • チャネル: スマート・コントラクトをデプロイするチャネルを選択します。
    • チェーンコード名: チャネルにスマート・コントラクトをデプロイする名前を設定します。
    • バージョン: このデプロイメントに番号を付けます。このデプロイメントは、以前にインストールしたパッケージと整合しています。このようにして、インストールされたパッケージを異なるチャネルにデプロイされたチェーンコードに関連付けることができます。
    • 初期必須: ユーザー・トランザクションを許可する前にチェーンコードのinitメソッドを起動する必要がある場合は、このチェック・ボックスを選択します。
    • エンドースメント・ポリシー: デプロイメント時にエンドースメント・ポリシーを指定します。このソリューション・プレイブックの例では、エンドースメント・ポリシーを使用していません。
    • プライベート・データ収集: 必要に応じてプライベート・データ収集を設定します。このソリューション・プレイブックの例では、プライベート・データ収集は設定しません。
デプロイメントが成功した場合は、インストールおよびデプロイメントのクローズ後に、そのパッケージがインスタンスの2つのピアにインストールされ、いずれかのチャネルでインスタンス化されていることを確認する必要があります。

スマート・コントラクトの初期化

FTおよびNFTトークンを処理する場合、ビジネス・メソッドを実行する前に実行する管理アクションのセットがあります。Oracle Blockchainを使用すると、すべての管理タスクを単純なRESTコールとして実行でき、スマート・コントラクトの初期化に必要な労力を大幅に削減できます。

ノート:

次のステップを実行する前に、スマート・コントラクト・メソッドへのアクセス権を付与されたユーザーのRESTプロキシにenrollmentIDsを作成する必要があります。登録は、REST APIを起動するユーザー名と、「RESTプロキシ・ノードへの登録の作成」のトピックの説明に従ってトークンが割り当てられるブロックチェーンによって内部的に管理されるアカウントとの間のマッピングです。

次のPostmanコレクションを使用して、スマート・コントラクトを簡単に初期化します: Postmanコレクションのダウンロード

このPostmanコレクションのAdminStepsフォルダには、スマート・コントラクトの初期化のために実行される3つのリクエスト・コールがあります。

Postmanコレクションを使用する準備ができていますが、独自の環境(パスワード、URLなど)に適合するように構成する必要がある変数のセットがあります。これらの変数は、Postmanコレクションの「変数」タブで設定します。次の表に、定義した変数をすべて示し、環境に適応させる必要があります。

変数名 変数値
bc_founder_provider_url https://org1-w....
bc_timeout 60000
bc_nft_founder_userid1 cmsleg001
bc_nft_founder_userid1_pwd パスワード
bc_nft_founder_userid2 cmsfin001
bc_nft_founder_userid2_pwd パスワード
bc_nft_founder_userid3 cmsrsk001
bc_nft_founder_userid4_pwd パスワード
bc_channel_name ウェドクム
bc_chaincode_name WEDOCMS

Blockchain ServiceコンソールからREST APIにアクセスできるエンドポイントを見つけます。

  1. OCIコンソールからブロックチェーン・サービス・コンソールにアクセスします。
  2. 「ノード」タブに移動します。このインスタンスを構成するすべてのノードが表示され、restproxyノードには「ルート」列にエンドポイントURLが表示されます。
    登録はネットワーク・レベルではなくインスタンス・レベルで作成されるため、ユーザーの登録はファウンダ・インスタンスのrestproxy URLを介してのみ使用可能になるため、新しいインスタンスがネットワークに参加する場合、ネットワークへのアクセスを許可された新規ユーザーの場合、それらのユーザーは適切なテナンシに存在する必要があり、それらのユーザーの登録も対応するインスタンスのrestproxyに作成する必要があります。
Postmanコレクションが適切に構成されると、スマートコントラクトの初期化を続行できます。NFTスマート・コントラクトの初期化は、FTスマート・コントラクトの初期化よりもかなり単純であるため、次の3つのステップを実行する必要があります。
  1. スマート・コントラクトの初期化(初期管理ユーザー・アカウント)。
  2. NFTトークンを所有できるユーザー用のウォレットの作成。
  3. その権限が必要なユーザーの割当てミニター・ロール。
次のAPI RESTコールは、提供されたPostmanコレクションからのAdminStepsフォルダへのコールに対応します。
  1. 管理タスクの実行を許可するユーザー・アカウントを示すチェーンコード(ステップ0: 管理ユーザー・アカウントの初期化)を初期化します。initメソッドの引数を正しく設定することが重要です: args: Scaped array of user_ids with their org_ids
    
    {
        "chaincode": "{{bc_nft_chaincode_name}}",
        "args": [
            "init",
            "[{\"orgId\":\"org1\",\"userId\":\"cmsleg001\"},{\"orgId\":\"org1\",\"userId\":\"cmsfin001\"},{\"orgId\":\"org1\",\"userId\":\"cmsrsk001\"}]"
        ],
        "timeout": {{bc_timeout}},
        "isInit": true,
        "sync": true
    }
    
  2. 物理アセットを表すNFTアセットの顧客になることができるすべてのユーザーのユーザー・アカウントを作成します。これは、Step-1: Create account Postmanリクエストを実行して実行できます。ユースケースの詳細は、ネットワークに属する同じ単一組織に関連する3人のユーザーのみです。このコールは、アカウントを作成するユーザーと同じ回数実行する必要があります。このケースでは、それぞれに次のパラメータがあります。
    • "createAccount", "org1", "cmsleg001", "nonfungible"
    • "createAccount", "org1", "cmsfin001", "nonfungible"
    • "createAccount", "org1", "cmsrsk001", "nonfungible"
    
    {
        "chaincode": "{{bc_nft_chaincode_name}}", //Smartcontract name
        "args": [
            "createAccount", "org1","cmsleg001","nonfungible" //Method, OrgID, UserID, fungible for FT / nonfungible for NFT
        ],
        "timeout": 60000,
        "sync": true
    }
    
  3. トークンのミントを許可するユーザーを設定します。この場合、mint a tokenは、新しいドキュメント・セットを保持する新規フォルダを作成することを意味するため、3人の既存のユーザー(cmsleg001cmsfin001またはcmsrsk001)のうち、これらのアクションを実行できるユーザー(Step-2: AddRole)を決定できます。
    
    {
        "chaincode": "{{bc_nft_chaincode_name}}", //Smartcontract name
        "args": [
            "addRole", //Method name
            "minter","org1","cmsleg001" //Role, OrgId, UserID
            ],
        "timeout": 60000,
        "sync": true
    }