ブロックチェーン・アプリケーション・ビルダーは、仕様ファイルから入力を受け取り、完全に機能するチェーンコード・プロジェクトを生成します。このプロジェクトには、自動生成されたクラスと関数、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の
getStateByPartialCompositeKey
、splitCompositeKey
、および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
- パラメータ:
- 戻り値:
-
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
}
この時点でアプリケーションの状態を初期化する場合は、このメソッドを使用して初期化できます。