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

ブロックチェーン・アプリケーション・ビルダーは、仕様ファイルから入力を受け取り、完全に機能するスキャフォールド済チェーンコード・プロジェクトを生成します。

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

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

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

バリデータ

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型の場合: 最小バリデータと同様に、最大バリデータは指定された値を持つ文字列の長さもチェックします。この例では、Domianプロパティの最大値は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"'
}

モデル

Asset Typeプロパティ

デフォルトでは、すべての構造体にAssetTypeという追加プロパティがあります。このプロパティは、このタイプのアセットのみをフェッチする場合に役立ちます。このプロパティに対する変更は、アセットの作成および更新時に無視されます。デフォルトのプロパティ値は<chaincodeName>.<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"'
}

ORM

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

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

model.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 - 返される場合はエラーが含まれるか、そうでない場合はnilです。
model.Update
台帳内の指定されたアセットを新しい値で更新します。
func Update(args ...interface{}) (interface{}, error)
パラメータ:
  • obj (interface) - 台帳で更新する必要があるオブジェクトは、新しい値を使用してこのAPIを参照することによって渡されます。入力アセットは、モデル仕様に記載されている構造体タグに従って検証および確認され、台帳に格納されます。
戻り値:
  • interface{} - 保存されたアセットはインタフェースとして返されます。
  • error - 返される場合はエラーが含まれるか、そうでない場合はnilです。
model.Save
すべての構造体タグを検証した後、アセットを台帳に保存します。
func Save(args ...interface{}) (interface{}, error)
パラメータ:
  • obj/args[0] (interface{}) - 台帳に格納する必要があるオブジェクトは、このユーティリティ・メソッドで参照によって渡されます。
  • metadata/args[1] (interface{}) - このパラメータはオプションです。これは、実行時にアセットとともにメタデータを台帳に格納する必要がある場合に簡略化するために提供されています。このような要件が存在しない場合は、このパラメータをスキップできます。
戻り値:
  • interface {} - アセットはインタフェースとして返されます。
  • error - 返される場合はエラーが含まれるか、そうでない場合はnilです。
model.Delete
アセットを台帳から削除します。
func Delete(Id string) (interface{}, error)
パラメータ:
  • ID (string) - 台帳から削除する必要があるアセットのID。
戻り値:
  • interface {} - 削除されるアセットがmap[string]interface{}の形式で含まれます。
model.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 - 返される場合はエラーが含まれるか、そうでない場合はnilです。
model.GetHistoryById
指定されたIDのアセットの履歴を返します。
func GetHistoryByID(Id string) ([]interface{}, error)
パラメータ:
  • Id (string) - 履歴が必要なアセットのID。
戻り値:
  • []interface{} - このスライスには、台帳から取得されたアセットの履歴がmap[string]interface{}のスライスの形式で含まれます。各履歴要素にアクセスするには、このスライスに対して反復し、オブジェクトをmap[string]interface{}としてアサートし、ユーティリティを使用してアセット・オブジェクトに変換します。
  • error - 対象となる場合はエラーが含まれます。
model.Query
問合せメソッドでは、台帳に対してSQL/Couch DB問合せが実行されます。このメソッドは、Oracle Blockchain Platformでのリモート・デプロイメントでのみサポートされます。これは、台帳でSQL問合せを実行するための一般的な方法です。
func Query(queryString string) ([]interface{}, error)
パラメータ:
  • queryString (string) - 問合せ文字列を入力します。
戻り値:
  • []interface{} - 問合せの出力が含まれます。結果は、インタフェースのスライスの形式になります。スライスに対して反復し、適切なタイプに変換して要素を使用する必要があります。
  • error - 対象となる場合はエラーが含まれます。

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

model.GenerateCompositeKey
このメソッドは、indexNameおよび引数で指定された属性に基づいてコンポジット・キーを生成し、返します。
func GenerateCompositeKey(indexName string, attributes []string)
(string, error)
パラメータ:
  • indexName (string) - コンポジット・キーのオブジェクト・タイプ。
  • attrbutes ([]string) - 作成する必要があるコンポジット・キーに基づいたアセットの属性。
戻り値:
  • string - コンポジット・キーの結果が格納されます。
  • error - 対象となる場合はエラーが含まれます。
model.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 - エラーがある場合はそれが含まれます。

スタブ・メソッド

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

その他のメソッド

  • model.GetTransactionId()
  • model.GetTransactionTimestamp()
  • model.GetChannelID()
  • model.GetCreator()
  • model.GetSignedProposal()
  • model.GetArgs()
  • model.GetStringArgs()
  • model.getId
model.GetTransactionId
現在のチェーンコード呼出しリクエストのトランザクションIDを返します。トランザクションIDは、チャネルのスコープ内でトランザクションを一意に識別します。
func GetTransactionId() string
パラメータ:
  • none
戻り値:
  • string - 必要なトランザクションIDが含まれます。
model.GetTransactionTimestamp
トランザクションが作成されたときのタイムスタンプを返します。これはトランザクションChannelHeaderから取得されるため、クライアントのタイムスタンプを示し、すべてのエンドーサで同じ値になります。
func GetTransactionTimestamp() (*timestamp.Timestamp, error)
パラメータ:
  • none
戻り値:
  • timestamp.Timestamp - 必要なタイムスタンプが含まれます。
  • error - エラーがある場合はそれが含まれます。
model.GetChannelID
チェーンコードが処理する提案のチャネルIDを返します。
func GetChannelID() string
パラメータ:
  • none
戻り値:
  • string - 必要なチャネルIDが文字列として含まれます。
model.GetCreator
チェーンコード呼出しの発行者のアイデンティティ・オブジェクトを返します
func GetCreator() ([]byte, error)
パラメータ:
  • none
戻り値:
  • [ ]byte - シリアライズされた必須のアイデンティティ・オブジェクトが含まれます。
  • error - エラーがある場合はそれが含まれます。
model.GetSignedProposal
署名済トランザクション提案の完全にデコードされたオブジェクトを返します。
func GetSignedProposal() (*peer.SignedProposal, error)
パラメータ:
  • none
戻り値:
  • *peer.SignedProposal - 必要な署名済提案オブジェクトが含まれます。
  • error - エラーがある場合はそれが含まれます。
model.GetArgs
チェーンコード呼出しリクエストから引数を文字列の配列として返します。
func GetArgs() [][]byte
パラメータ:
  • none
戻り値:
  • [ ][ ]byte - 渡された引数が含まれます。
model.GetStringArgs
チェーンコードの初期化および呼出し用の引数を文字列配列として返します。
func GetStringArgs() []string
パラメータ:
  • none
戻り値:
  • []string - 必要な引数が文字列配列として含まれます。
model.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 := model.GetId(&asset)
   if err !=nil {
      return nil, fmt.Errorf("error in getting ID %s", 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 - アセットの作成中または検証中に見つかったエラーが含まれます。

コントローラ

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

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

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メソッドが用意されています。このメソッドは、チェーンコードの初回インスタンス化またはアップグレード時にHyperledger FabricのInitメソッドによってコールされます。

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

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