スキャフォールド済Goチェーンコード・プロジェクト

ブロックチェーン・アプリケーション・ビルダーは、仕様ファイルから入力を受け取り、完全に機能するチェーンコード・プロジェクトを生成します。このプロジェクトには、自動生成されたクラスと関数、CRUDメソッド、SDKメソッド、引数の自動検証、マーシャリング/アンマーシャリングおよび透過的な永続性機能(ORM)が含まれます。

チェーンコード・プロジェクトがGo言語の場合、スキャフォールディング済プロジェクトには次の3つのメイン・ファイルが含まれます:
  • main.go
  • <chaincodeName>.model.go
  • <chaincodeName>.controller.go
必要なライブラリがすべてインストールされ、パッケージ化されます。

modelサブディレクトリの<chaincodeName>.model.goファイルには複数のアセット定義が含まれ、controllerサブディレクトリの<chaincodeName>.controller.goファイルにはアセットの動作とCRUDメソッドが含まれます。model.goおよびcontroller.goの様々なGo構造体タグおよびパッケージは、引数の自動検証、引数の整列化/非整列化、透過的永続性機能(ORM)およびリッチ問合せのコールなどの機能をサポートします。

スキャフォールド済プロジェクトは、$GOPATH/src/example.com/<chaincodeName>にあります

モデル

Asset Typeプロパティ

デフォルトでは、すべての構造体にAssetTypeという追加プロパティがあります。このプロパティは、このタイプのアセットのみをフェッチする場合に役立ちます。このプロパティに対する変更は、アセットの作成および更新時に無視されます。デフォルトのプロパティ値は<modelName>です。
type Supplier struct {
AssetType string 'json:"AssetType" default:"TestGoProject.Supplier"'

SupplierId            string      'json:"SupplierId" validate:"string,mandatory" id:"true'
RawMaterialAvailable  int         'json:"RawMaterialAvailable" validate:"int,min=0"'
License               string      'json:"License" validate:"string,min=10"'
ExpiryDate            date.Date   'json:"ExpiryDate" validate:"date,before=2020-06-26"'
Active                bool	  'json:"Active" validate:"bool" default:"true"'
Metadata              interface{} 'json:"Metadata,omitempty"'
}

バリデータ

ID
id:"true"
このバリデータは、基礎となるアセットを一意に定義するプロパティを識別します。アセットは、このキーの値によって保存されます。この検証は、新しいGoプロジェクトがスキャフォールディングされると自動的に適用されます。
次のスクリーンショットでは、"SupplierId"はサプライヤ・アセットのキーであり、SupplierIdプロパティのタグ・プロパティ id:"true"があります。
type Supplier struct {
    Supplierld              string        'json:"Supplierld" validate:"string,mandatory" id:"true"' 
    RawMaterialAvailable    int           'json:"RawMaterialAvailable" validate:"int,min=0"'
    License                 string        'json:"License" validate:"string,min=10"'
    ExpiryDate              date.Date     'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                  bool          'json:"Active" validate:"bool" default :"true"'
    Metadata                interface{}   'json:"Metadata,omitempty"'   
}
計算結果
derived:"strategy,algorithm,format"
この装飾は、他のプロパティから導出された属性を定義するために使用します。このデコレータには、次の2つの必須パラメータがあります:
  • strategy: concatまたはhashの値を使用します。hashが選択されている場合は、追加のパラメータalgorithmが必要です。デフォルトのアルゴリズムはsha256で、md5もサポートされています。
  • format: 戦略で使用される仕様文字列と値の配列を使用します。
type Supplier struct{
   AssetType string 'json:"AssetType" final:"chaincode1.Supplier"'
   SupplierId   string  'json:"SupplierId" validate:"string" id:"true" mandatory:"true" derived:"strategy=hash,algorith=sha256,format=IND%1%2,License,Name"'
   Name         string  'json:"Name" validate:"string,min=2,max=4"'
   License      string  'json:"License" validate:"string,min=2,max=4"'
}
必須
validate:"mandatory"
これにより、次のプロパティが必須としてマークされ、レジャーへの保存中にスキップできません。スキップすると、エラーがスローされます。次の例では、"SupplierId"validate:"mandatory"タグがあります。
Type Supplier struct {
    Supplierld              string      'json:"Supplierld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable    int         'json:"RawMaterialAvailable" validate:"int,min=0"'
    License                 string      'json:"License" validate:"string,min=10"'
    ExpiryDate              date.Date   'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                  bool        'json:"Active" validate:"bool" default :"true"'
    Metadata                interface{} 'json:"Metadata,omitempty"'
}
デフォルト
default:"<param>"
これは、次のプロパティがデフォルト値を持つことができることを示します。台帳への保存中にプロパティがスキップされると、デフォルト・タグのデフォルト値が使用されます。次のプロパティの例では、Activeのデフォルト値はtrueで、タグdefault:"true"として提供されます
Type Supplier struct {
    Supplierld            string       'json:"Supplierld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable  int          'json:"RawMaterialAvailable" validate:"int,min=0"'
    License               string       'json:"License" validate:"string,min=10"'
    ExpiryDate            date.Date    'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                bool         'json:"Active" validate:"bool" default :"true"'
    Metadata              interface{}  'json:"Metadata,omitempty"'
}
タイプの検証
Goの基本的な型は、検証タグを定義することでプロパティに対して検証されます。型に基づく検証タグは次のとおりです:
  • 文字列: validate: "string"
  • 日付: validate: "date"
  • 数値: validate: "int"
  • ブール: validate: "bool"
最小バリデータ
validate:"min=<param>"
最小バリデータを使用すると、数値型および文字列型のプロパティに最小値を設定できます。
int型の場合: この例では、RawMaterialAvailableプロパティの最小値は0で、0未満の値がRawMaterialAvailableに適用されると、エラーが返されます。
string型の場合: string型の最小バリデータは、指定された値を持つ文字列の長さをチェックします。したがって、次の例では、Licenseプロパティの長さを10文字以上にする必要があります。
次に例を示します:
Type Supplier struct {
    Supplierld             string       'json:"Supplierld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable   int          'json:"RawMaterialAvailable" validate:"int,min=0"'
    License                string       'json:"License" validate:"string,min=10"'
    ExpiryDate             date.Date    'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                 bool         'json:"Active" validate:"bool" default :"true"'
    Metadata               interface{}  'json:"Metadata,omitempty"'
}
最大バリデータ
validate:"max=<param>"
最大バリデータを使用すると、数値タイプおよび文字列タイプのプロパティに最大値を設定できます。
int型の場合: 最小バリデータと同様に、int型の場合、structfieldに指定された値がバリデータに指定された値よりも大きいと、エラーが返されます。
string型の場合: 最小バリデータと同様に、最大バリデータは指定された値を持つ文字列の長さもチェックします。この例では、Domainプロパティの最大値は50であるため、Domainプロパティの文字列長が50文字を超えると、エラー・メッセージが返されます。
type Retailer struct {
    Retailerld         string        'json:"Retailerld" validate:"string,mandatory" id:"true"'   
    ProductsOrdered    int           'json:"ProductsOrdered" validate:"int,mandatory"'
    ProductsAvailable  int           'json:"ProductsAvailable" validate:"int" default:"1"' 
    ProductsSold       int           'json:"ProductsSold" validate:"int"'
    Remarks            string        'json:"Remarks" validate:"string" default :"open for business"'
    Items              []int         'json:"Items" validate:"array=int,range=l-5"'
    Domain             string        'json:"Domain" validate:"url,min=30,max=50"'
    Metadata           interface{}   'json:"Metadata,omitempty"'
}
日付バリデータ
バリデータの前:
validate:"before=<param>"
ビフォア・バリデータは、date型のプロパティを検証して、パラメータで指定された値よりも小さい値を持つようにします。
この例では、ExpiryDateプロパティは"2020-06-26"の前にある必要があり、そうでない場合はエラーが返されます。
Type Supplier struct {
    Supplierld            string       'json:"Supplierld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable  int          'json:"RawMaterialAvailable" validate:"int,min=0"'
    License               string       'json:"License" validate:"string,min=10"'
    ExpiryDate            date.Date    'json:"ExpiryDate" validate:"date,before=2020-06-26"'
    Active                bool         'json:"Active" validate:"bool" default :"true"'
    Metadata              interface{}  'json:"Metadata,omitempty"'
}
バリデータの後:
validate:"after=<param>"
ビフォア・バリデータは、date型のプロパティを検証して、パラメータで指定された値より大きい値を持つようにします。
この例では、CompletionDateプロパティは"2020-06-26"より後である必要があり、そうでない場合はエラーが返されます。
Type Supplier struct {
    Manufacturerld        string       'json:"Manufacturerld" validate:"string,mandatory" id:"true"'
    RawMaterialAvailable  int          'json:"RawMaterialAvailable" validate:"int,max=8"'
    ProductsAvailable     int          'json:"ProductsAvailable" validate:"int"'
    CompletionDate        date.Date    'json:"CompletionDate" validate:"date,after=2020-06-26"'
    Metadata              interface{}  'json:"Metadata,omitempty"'
}
URL検証機能
validate:"url"
URL検証機能では、URL文字列のプロパティが検証されます。
この例では、Domainプロパティは有効なURLである必要があります。
type Retailer struct {
    Retailerld         string        'json:"Retailerld" validate:"string,mandatory" id:"true"'   
    ProductsOrdered    int           'json:"ProductsOrdered" validate:"int,mandatory"'
    ProductsAvailable  int           'json:"ProductsAvailable" validate:"int" default:"1"' 
    ProductsSold       int           'json:"ProductsSold" validate:"int"'
    Remarks            string        'json:"Remarks" validate:"string" default :"open for business"'
    Items              []int         'json:"Items" validate:"array=int,range=l-5"'
    Domain             string        'json:"Domain" validate:"string,url,min=30,max=50"'
    Metadata           interface{}   'json:"Metadata,omitempty"'
}
正規表現バリデータ
validate:"regexp=<param>"
正規表現バリデータは、入力正規表現のプロパティを検証します。
この例では、PhoneNumberプロパティは、正規表現に従ってモバイル番号を検証します。
type Customer struct {
Customerld      string       'json:"Customerld" validate:"string,mandatory" id:"true"'
Name            string       'json:"Name" validate:"string,mandatory"'
ProductsBought  int          'json:"ProductsBought" validate:"int"'
OfferApplied    int          'json:"OfferApplied" validate :"int,nax=0"'
PhoneNumber     string       'json:"PhoneNumber" validate:"string,regexp=A\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$"'
Received        bool         'json:"Received" validate:"bool"'
Metadata        interface{}  'json:"Metadata,omitempty"'
}
複数のバリデータ
複数の検証者をプロパティに適用できます。
この例では、Domainプロパティに文字列、URL、および文字列の最小長と最大長を検証します。
type Retailer struct {
    Retailerld         string        'json:"Retailerld" validate:"string,mandatory" id:"true"'   
    ProductsOrdered    int           'json:"ProductsOrdered" validate:"int,mandatory"'
    ProductsAvailable  int           'json:"ProductsAvailable" validate:"int" default:"1"' 
    ProductsSold       int           'json:"ProductsSold" validate:"int"'
    Remarks            string        'json:"Remarks" validate:"string" default :"open for business"'
    Items              []int         'json:"Items" validate:"array=int,range=l-5"'
    Domain             string        'json:"Domain" validate:"string,url,min=30,max=50"'
    Metadata           interface{}   'json:"Metadata,omitempty"'
}

ORM

透過的永続性機能または簡略化されたORMは、コンテキスト(Ctx)オブジェクトのModelクラスに取得されます。モデルで次のSDKメソッドのいずれかをコールする場合は、t.Ctx.Modelを使用してアクセスします。

ORMを実装するSDKメソッドは次のとおりです。
  • Save - これはHyperledger FabricのPutStateメソッドをコールします
  • Get - これはHyperledger FabricのGetStateメソッドをコールします
  • Update - これはHyperledger FabricのPutStateメソッドをコールします
  • Delete - これはHyperledger FabricのDeleteStateメソッドをコールします
  • History - これはHyperledger FabricのGetHistoryForKeyメソッドをコールします
  • GetByRange - これはHyperledger FabricのGetStateByRangeメソッドをコールします
  • GetByRangeWithPagination - Hyperledger FabricのGetStateByRangeWithPaginationメソッドをコールします。

SDKメソッド

Goチェーンコードは、モデル・パッケージを使用して透過永続性機能(ORM)を実装します。

ノート:

バージョン21.2.3以降、ORMメソッドにアクセスする方法が変更されました。ochain --versionコマンドを実行して、ブロックチェーン・アプリケーション・ビルダーのバージョンを確認します。

以前のリリースでは、ORMメソッドはモデル・パッケージで静的メソッドとして公開されていました。メソッドが、トランザクション・スタブを保持するモデル・レシーバで定義されるようになりました。これらのメソッドをコールするには、コントローラのトランザクション・コンテキストによって保持されているモデル・レシーバを使用します。これらのメソッドは、model.<method_name>ではなくt.Ctx.Model.<method_name>としてコールします。

次の例は、以前のリリースのSaveおよびGetメソッド・コールを示しています。

func (t *Controller) CreateSupplier(asset Supplier) (interface{}, error) {
  return model.Save(&asset)
}

func (t *Controller) GetSupplierById(id string) (Supplier, error) {
  var asset Supplier
  _, err := model.Get(id, &asset)
  return asset, err
}

次の例は、バージョン21.2.3以降からのSaveおよびGetメソッド・コールを示しています。

func (t *Controller) CreateSupplier(asset Supplier) (interface{}, error) {
  return t.Ctx.Model.Save(&asset)
}

func (t *Controller) GetSupplierById(id string) (Supplier, error) {
  var asset Supplier
  _, err := t.Ctx.Model.Get(id, &asset)
  return asset, err
}

バージョン21.2.3にアップグレードした後、以前のバージョンのブロックチェーン・アプリケーション・ビルダーで作成したすべてのチェーンコード・プロジェクトで、この変更を行います。syncコマンドを使用して仕様ファイルとソース・コード間の変更を同期すると、すぐに使用できるメソッドの変更がコントローラに自動的に反映されます。競合は手動で解決する必要があります。

モデル・パッケージを介して、次のORMメソッドが表示されます:

Get
指定されたIDに基づいて、格納されたアセットのレジャーを問い合せます。
func Get(Id string, result ...interface{}) (interface{}, error)
パラメータ:
  • ID - レジャーからの必須アセットのID。
  • result (interface{}) - これは特定のタイプの空アセット・オブジェクトで、参照によって渡されます。このオブジェクトには、このメソッドからの結果が含まれます。タイプ固有の結果が必要な場合にのみ使用します。
  • asset (interface) - 参照によって渡される空アセット・オブジェクト。このオブジェクトには、このメソッドからの結果が含まれます。タイプ固有の結果が必要な場合にのみ使用します。
戻り値:
  • interface {} - インタフェースには、map[string]interface{}の形式のアセットが含まれます。このマップで操作する前に、取得したインタフェースをタイプmap[string]interface{}でアサーションする必要があります。このマップをアセット・オブジェクトに変換するには、ユーティリティAPI util.ConvertMaptoStructを使用します(「ユーティリティ・パッケージ」を参照)。
  • error - 返される場合はエラーが含まれるか、そうでない場合は0です。
Update
台帳内の指定されたアセットを新しい値で更新します。
func Update(args ...interface{}) (interface{}, error)
パラメータ:
  • obj (interface) - レジャーで更新する必要があるオブジェクトは、新しい値を使用してこのAPIを参照することによって渡されます。入力アセットは、モデル仕様に記載されている構造体タグに従って検証および確認され、レジャーに格納されます。
戻り値:
  • interface{} - 保存されたアセットはインタフェースとして返されます。
  • error - 返される場合はエラーが含まれるか、そうでない場合は0です。
Save
すべての構造体タグを検証した後、アセットを元帳に保存します。
func Save(args ...interface{}) (interface{}, error)
パラメータ:
  • obj/args[0] (interface{}) - レジャーに格納する必要があるオブジェクトは、このユーティリティ・メソッドで参照によって渡されます。
  • metadata/args[1] (interface{}) - このパラメータはオプションです。これは、実行時にアセットとともにメタデータをレジャーに格納する必要があるかどうかを容易にするために提供されています。このような要件が存在しない場合は、このパラメータをスキップできます。
戻り値:
  • interface {} - アセットはインタフェースとして返されます。
  • error - 返される場合はエラーが含まれるか、そうでない場合は0です。
Delete
アセットをレジャーから削除します。
func Delete(Id string) (interface{}, error)
パラメータ:
  • ID (string) - 元帳から削除する必要があるアセットのID。
戻り値:
  • interface {} - 削除されるアセットがmap[string]interface{}の形式で含まれます。
GetByRange
IDの範囲別にアセットのリストを返します。
func GetByRange(startKey string, endKey string, asset ...interface{})
([]map[string]interface{}, error)
パラメータ:
  • startkey (string) - 必要なオブジェクトの範囲の開始ID。
  • endkey (string) - 必要なオブジェクトの範囲の終了。
  • asset interface - (オプション)参照によって渡されるアセットの空の配列。この配列には、このメソッドからの結果が含まれます。タイプ固有の結果が必要な場合に使用します。
戻り値:
  • []map[string]interface{} - この配列には、レジャーから取得されたアセットのリストが含まれます。この配列に対して反復するオブジェクトにアクセスし、オブジェクトをmap[string]interface{}としてアサーションし、ユーティリティを使用してアセット・オブジェクトに変換できます。
  • error - 返される場合はエラーが含まれるか、そうでない場合は0です。
GetByRangeWithPagination
GetByRangeWithPaginationメソッドは、{chaincodeName}.model.tsの具象Modelクラスによって継承されるOchainModelクラスの静的メソッドです。
これは、ページ・サイズおよびブックマークでフィルタされた、startIdからendIdの範囲のアセットのリストを返します。このメソッドは、Hyperledger FabricのGetStateByRangeWithPaginationメソッドを内部的にコールします。
modelNameパラメータが指定されていない場合、メソッドはPromise<Object [ ] >を返します。modelNameパラメータが指定されている場合、メソッドは呼出し側のModel型へのキャストを処理します。次の例では、結果配列はSupplier型です。台帳から返されたアセットがModelタイプでない場合は、リストには含まれません。このチェックは、Modelクラスの読取り専用のassetTypeプロパティによって行われます。
ページ・サイズおよびブックマークでフィルタされた、startIdからendIdの範囲内のすべてのアセットを返すには、汎用コントローラ・メソッドgetAssetsByRangeを使用します。
func (m *Model) GetByRangeWithPagination(startKey string, endKey string, pageSize int32, bookmark string, asset ...interface{}) ([]map[string]interface{}, error) 
パラメータ:
  • startkey : string - 範囲の開始キー。範囲に含まれます。
  • endkey : string - 範囲の終了キー。範囲から除外されます。
  • pageSize : number - 問合せのページ・サイズ。
  • Bookmark : string - 問合せのブックマーク。出力はこのブックマークから始まります。
  • asset interface - (オプション)参照によって渡されるアセットの空の配列。この配列には、このメソッドからの結果が含まれます。このパラメータを使用して、タイプ固有の結果を取得します。
戻り値:
  • []map[string]interface{} - 元帳から取得されたアセットのリストを含む配列。オブジェクトにアクセスするには、この配列を反復し、オブジェクトをmap[string]interface{}としてアサーションし、ユーティリティを使用してアセット・オブジェクトに変換します。
  • error - エラーが返された場合はエラーが含まれます。それ以外の場合はnilです。
GetHistoryById
指定されたIDのアセットの履歴を返します。
func GetHistoryByID(Id string) ([]interface{}, error)
パラメータ:
  • ID (string) - 履歴が必要なアセットのID。
戻り値:
  • []interface{} - このスライスには、レジャーから取得されたアセットの履歴がmap[string]interface{}のスライスの形式で含まれます。各履歴要素にアクセスするには、このスライスに対して反復し、オブジェクトをmap[string]interface{}としてアサーションし、ユーティリティを使用してアセット・オブジェクトに変換します。
  • error - 対象となる場合はエラーが含まれます。
Query
問合せメソッドでは、レジャーに対してSQL/Couch DB問合せが実行されます。このメソッドは、Oracle Blockchain Platformでのリモート・デプロイメントでのみサポートされます。これは、レジャーでSQL問合せを実行するための一般的な方法です。
func Query(queryString string) ([]interface{}, error)
パラメータ:
  • queryString (string) - 問合せ文字列を入力します。
戻り値:
  • []interface{} - 問合せの出力が含まれます。結果は、インタフェースのスライスの形式になります。スライスに対して反復し、適切なタイプに変換して要素を使用する必要があります。
  • error - 対象となる場合はエラーが含まれます。
QueryWithPagination
問合せメソッドでは、ページ・サイズおよびブックマークでフィルタされた、レジャーに対してSQL/Couch DB問合せが実行されます。このメソッドは、Oracle Blockchain Platformでのリモート・デプロイメントでのみサポートされます。これは、レジャーでSQL問合せを実行するための一般的な方法です。
func (m *Model) QueryWithPagination(queryString string, pageSize int32, bookmark string) ([]interface{}, error)
パラメータ:
  • queryString (string) - Rich SQL/Couch DB問合せ。
  • pageSize : number - 問合せのページ・サイズ。
  • bookmark : string - 問合せのブックマーク。出力はこのブックマークから始まります。
戻り値:
  • []interface{} - 問合せの出力が含まれます。結果は、インタフェースのスライスの形式になります。スライスに対して反復し、適切なタイプに変換して要素を使用する必要があります。
  • error - 対象となる場合はエラーが含まれます。
InvokeCrossChaincode
このメソッドをチェーンコードで使用して、別のチェーンコード内の関数を呼び出すことができます。両方のチェーンコードが同じピアにインストールされている必要があります。
func InvokeCrossChaincode(chaincodeName string, method string, args []string, channelName string) (interface{}, error)
パラメータ:
  • chaincodeName - コールするチェーンコードの名前。
  • methodName - チェーンコード内でコールするメソッドの名前。
  • arg - コール元のメソッドの引数。
  • channelName - コールするチェーンコードがあるチャネル。
戻り値:
  • interface{} - 3つのキーを含むmap[string]interface{}オブジェクトを返します。
    • isValid - コールが有効な場合はtrue
    • payload - JSONオブジェクトとしてクロスチェーンコード・コールによって返される出力。
    • message - UTF-8形式のクロスチェーンコード・コールによって返されるメッセージ。
戻り値の例:
{
      "isValid": true,
      "message": "Successfully invoked method [CreateAccount] on sub-chaincode [erc721_go_453]",
      "payload": {
                  "AccountId": "oaccount~6b83b8ab931f99442897dd04cd7a2a55f808686f49052a40334afe3753fda4c4",
                  "AssetType": "oaccount",
                  "BapAccountVersion": 0,
                  "NoOfNfts": 0,
                  "OrgId": "appdev",
                  "TokenType": "nonfungible",
                  "UserId": "user2"
      }
}
InvokeChaincode
このメソッドをチェーンコードで使用して、別のチェーンコード内の関数を呼び出すことができます。両方のチェーンコードが同じピアにインストールされている必要があります。
func InvokeChaincode(chaincodeName string, method string, args []string, channelName string) (interface{}, error)
パラメータ:
  • chaincodeName - コールするチェーンコードの名前。
  • methodName - チェーンコード内でコールするメソッドの名前。
  • arg - コール元のメソッドの引数。
  • channelName - コールするチェーンコードがあるチャネル。
戻り値:
  • interface{} - 3つのキーを含むmap[string]interface{}オブジェクトを返します。
    • isValid - コールが有効な場合はtrue
    • payload - UTF-8形式のクロスチェーンコード・コールによって返される出力。
    • message - UTF-8形式のクロスチェーンコード・コールによって返されるメッセージ。
戻り値の例:
{
    "isValid": true,
    "message": "Successfully invoked method [CreateAccount] on sub-chaincode [erc721_go_453]",
    "payload": "{\"AssetType\":\"oaccount\",\"AccountId\":\"oaccount~c6bd7f8dcc339bf7144ea2e1cf953f8c1df2f28482b87ad7895ac29e7613a58f\",\"UserId\":\"user1\",\"OrgId\":\"appdev\",\"TokenType\":\"nonfungible\",\"NoOfNfts\":0,\"BapAccountVersion\":0}"
} 

コンポジット・キー・メソッド

GenerateCompositeKey
このメソッドは、indexNameおよび引数で指定された属性に基づいてコンポジット・キーを生成し、返します。
func GenerateCompositeKey(indexName string, attributes []string)
(string, error)
パラメータ:
  • indexName (string) - コンポジット・キーのオブジェクト・タイプ。
  • attrbutes ([]string) - 作成する必要があるコンポジット・キーに基づいたアセットの属性。
戻り値:
  • string - コンポジット・キーの結果が格納されます。
  • error - 対象となる場合はエラーが含まれます。
GetByCompositeKey
このメソッドは、パラメータで指定されたキーおよび列に一致するアセットを返します。indexパラメータは、スタブ・メソッドSplitCompositeKeyの配列で返されるキーの索引を示します。
内部的には、このメソッドはHyperledger FabricのgetStateByPartialCompositeKeysplitCompositeKey、およびgetStateを呼び出します。
func GetByCompositeKey(key string, columns []string, index int)
(interface{}, error)
パラメータ:
  • key (string) - コンポジット・キーの作成時に指定されたオブジェクト・タイプ。
  • column ([]string) - コンポジット・キーを使用してレジャーに問い合せる必要がある属性のスライスです。
  • index(int) - 属性の索引。
戻り値:
  • Interface{} - このメソッドの結果であるアセットのリストが含まれます。
  • error - エラーが含まれます(存在する場合)。

スタブ・メソッド

GetNetworkStub
このメソッドは、Hyperledger Fabric chaincodeStubを返します。
shimスタブにアクセスするには、GetNetworkStubメソッドをコールします。これは、アセットを直接操作する独自の実装を記述するのに役立ちます。
func GetNetworkStub() shim.ChaincodeStubInterface
パラメータ:
  • なし
戻り値:
  • shim.ChaincodeStubInterface - これはHyperledger Fabricチェーンコード・スタブです。

その他の方法

  • GetTransactionId()
  • GetTransactionTimestamp()
  • GetChannelID()
  • GetCreator()
  • GetSignedProposal()
  • GetArgs()
  • GetStringArgs()
  • GetCreatorMspId()
  • GetId
GetTransactionId
現在のチェーンコード呼出しリクエストのトランザクションIDを返します。トランザクションIDは、チャネルのスコープ内でトランザクションを一意に識別します。
func GetTransactionId() string
パラメータ:
  • なし
戻り値:
  • string - 必要なトランザクションIDが含まれます。
GetTransactionTimestamp
トランザクションが作成されたときのタイムスタンプを返します。これはトランザクションChannelHeaderから取得されるため、クライアントのタイムスタンプを示し、すべてのエンドーサで同じ値になります。
func GetTransactionTimestamp() (*timestamp.Timestamp, error)
パラメータ:
  • なし
戻り値:
  • timestamp.Timestamp - 必要なタイムスタンプが含まれます。
  • error - エラーが含まれます(存在する場合)。
GetChannelID
処理するチェーンコードの提案のチャネルIDを返します。
func GetChannelID() string
パラメータ:
  • なし
戻り値:
  • string - 必要なチャネルIDが文字列として含まれます。
GetCreator
チェーンコード呼出しの発行者のアイデンティティ・オブジェクトを返します
func GetCreator() ([]byte, error)
パラメータ:
  • なし
戻り値:
  • []byte - 直列化された必須のアイデンティティ・オブジェクトが含まれます。
  • error - エラーが含まれます(存在する場合)。
GetSignedProposal
署名済トランザクション提案の完全にデコードされたオブジェクトを返します。
func GetSignedProposal() (*peer.SignedProposal, error)
パラメータ:
  • なし
戻り値:
  • *peer.SignedProposal - 必要な署名済提案オブジェクトが含まれます。
  • error - エラーが含まれます(存在する場合)。
GetArgs
チェーンコード呼出しリクエストから引数を文字列の配列として返します。
func GetArgs() [][]byte
パラメータ:
  • なし
戻り値:
  • [][]byte - 渡された引数が含まれます。
GetStringArgs
チェーンコードの初期化および呼出し用の引数を文字列配列として返します。
func GetStringArgs() []string
パラメータ:
  • なし
戻り値:
  • []string - 必要な引数が文字列配列として含まれます。
GetCreatorMspId
呼出し側アイデンティティのMSP IDを返します。
func GetCreatorMspId() string
パラメータ:
  • なし
戻り値:
  • string - 呼出し側アイデンティティのMSP IDを返します。
GetId
アセットにIDとして導出キーがある場合、このメソッドを使用して導出IDを取得できます。導出キーに%t (タイムスタンプ)が含まれている場合、このメソッドはエラーを返します。
パラメータ:
  • object - オブジェクトには、導出キーが依存するすべてのプロパティが含まれている必要があります。
戻り値:
  • 導出キーを文字列として返します。
次に例を示します:
func (t *Controller) CustomGetterForSupplier(License string, Name string)(interface{}, error){
   var asset Supplier
   asset.License = License
   asset.Name = Name
   id,err := t.Ctx.Model.GetId(&asset)

   if err !=nil {
      return nil, fmt.Errorf("error in getting ID %v", err.Error())
   }
   return t.GetSupplierById(id)
}

ユーティリティ・パッケージ

ユーティリティ・パッケージの次のメソッドが役立つ場合があります:

Util.CreateModel
指定されたタイプのJSON文字列を分析し、アセット・オブジェクトを作成します。
func CreateModel(obj interface{}, inputString string) error
パラメータ:
  • inputString (string) - オブジェクトの作成元となる入力JSON文字列。
  • obj (interface{}) - JSON文字列から作成されるオブジェクトの参照。このオブジェクトには、バリデータ・タグに従って検証される、作成済モデルが格納されます。
戻り値:
  • error - アセットの作成中または検証中にエラーが発生しました。
util.ConvertMapToStruct
指定されたマップを指定タイプのオブジェクトに変換します。
func ConvertMapToStruct(inputMap map[string](interface{}), resultStruct
interface{}) error
パラメータ:
  • inputMap (map[string](interface{})) - アセット・オブジェクトに変換する必要があるマップ。
  • resultStruct (interface{}) - マップから生成する必要がある必須アセット・オブジェクトの参照。必要な結果アセット・オブジェクトが含まれます。
戻り値:
  • error - アセットの作成中または検証中にエラーが発生しました。

トークンSDKメソッドについては、「ブロックチェーン・アプリケーション・ビルダーを使用したトークン化サポート」のトピックを参照してください。

コントローラ

Controller.goファイルは、アセットのCRUDおよびカスタム・メソッドを実装します。

任意の数のクラス、関数またはファイルを作成できますが、チェーンコード構造体で定義されたメソッドのみが外部から呼出し可能で、残りのメソッドは非表示になります。

自動生成されたメソッド

「入力仕様ファイル」で説明されているように、生成するCRUDメソッドを仕様ファイルで指定できます。たとえば、すべてのメソッドの生成を選択した場合の結果は次のようになります:

//	
//Supplier
//	
func (t *ChainCode) CreateSupplier(inputString string) (interface{}, error) {
    var obj Supplier
    err := util.CreateModel(&obj, inputString)
    if err != nil {
        return nil, err   
    }
    return model.Save(&obj)
}

func (t *ChainCode) GetSupplierById(id string) (interface{}, error) {
    asset, err := model.Get(id) 
    return asset, err
}

func (t *ChainCode) UpdateSupplier(inputString string) (interface{}, error) {
    var obj Supplier
    err := util.CreateModel(&obj, inputstring)
    if err != nil {   
        return nil, err
    }
return model.Update(&obj)
}

func (t *ChainCode) DeleteSupplier(id string) (interface{}, error) { 
    return model.Delete(id)
}

func (t *ChainCode) GetSupplierHistoryById(id string) (interface{}, error) { 
    historyArray, err := model.GetHistoryByld(id) 
    return historyArray, err
}

func (t *ChainCode) GetSupplierByRange(startkey string, endKey string) (interface{}, error) { 
    assetArray, err := model.GetByRange(startkey, endKey) 
    return assetArray, err
}

カスタム・メソッド

この例の仕様ファイルから、次のカスタム・メソッドが生成されました。

executeQueryは、SQLリッチ問合せのコール方法を示しています。引数に対するバリデータは、仕様ファイルで指定された引数のタイプに基づいてブロックチェーン・アプリケーション・ビルダーによって自動的に追加されます。

ビジネス・ロジックに従って機能を実装できます。カスタム・メソッドを追加する場合は、コントローラ・ファイルに追加します。コントローラ・ファイルではなくライブラリにカスタム・メソッドを追加した場合、同期またはチェーンコードのアップグレード・プロセス中にライブラリ・フォルダのコンテンツが更新されると、変更は失われます。

//	
//Custom Methods
//			
/*
*	BDB sql rich queries can be executed in OBP CS/EE.
*	This method can be invoked only when connected to remote OBP CS/EE network.
*/
func (t *ChainCode) ExecuteQuery(inputQuery string) (interface{}, error) { 
    resultArray, err := model.Query(inputQuery) 
    return resultArray, err
}

func (t *ChainCode) FetchRawMaterial(supplierId string, rawMaterialSupply int) (interface{}, error) {
    return nil, nil
}

func (t *ChainCode) GetRawMaterialFromSupplier(manufacturerId string, supplierId string, rawMaterialSupply int) (interface{} error) { 
    return nil, nil
}

Func (t *ChainCode) CreateProducts(manufacturerId string, rawMaterialConsumed int, productsCreated int) (interface{}, error) { 
    return nil, nil
}

func (t *ChainCode) SendProductsToDistribution() (interface{}, error) { 
    return nil, nil
}
Goチェーンコードの場合、すべてのカスタム・メソッドは空のインタフェースエラーの2つの値を返す必要があります。たとえば次のようにします。
func (t *Controller) FetchRawMaterial(supplierId string, rawMaterialSupply int) (interface{}, error) { 
    return nil, nil
}

初期メソッド

コントローラには、空の定義を持つカスタムInitメソッドが用意されています。ブロックチェーン・アプリケーション・ビルダーを使用してデプロイまたはアップグレードする場合、Initメソッドが自動的にコールされます。Hyperledger Fabric v1.4.7プラットフォームでOracle Blockchain Platformコンソールからデプロイまたはアップグレードすると、Initメソッドも自動的にコールされます。Hyperledger Fabric v2.xプラットフォームでOracle Blockchain Platformコンソールからデプロイまたはアップグレードする場合は、Initメソッドを手動でコールする必要があります。Postmanなどのサードパーティ・ツールを使用して、Initメソッドを手動でコールできます。

type Controller struct {
}
func (t *Controller) Init(args string) (interface{}, error) 
    { return nil, nil
}

この時点でアプリケーションの状態を初期化する場合は、このメソッドを使用して初期化できます。