鷹架 Go Chaincode 專案

Blockchain App Builder 會從您的規格檔案中取得輸入,並產生功能完整的鷹架式鏈碼專案。專案包含自動產生的類別和函數、CRUD 方法、SDK 方法、自動驗證引數、封送處理 (Marshal) / 解除封送處理 (un-marshal) 以及通透保存功能 (ORM)。

如果鏈碼專案使用 Go 語言,則鷹架式專案包含三個主要檔案:
  • main.go
  • <chaincodeName>.model.go
  • <chaincodeName>.controller.go
會安裝並封裝所有必要的磁帶櫃。

model 子目錄中的 <chaincodeName>.model.go 檔案包含多個資產定義,而 controller 子目錄中的 <chaincodeName>.controller.go 檔案包含資產的行為和 CRUD 方法。model.gocontroller.go 中的各種 Go 結構標記和套裝程式支援自動驗證引數、封送處理 (Marshal) / 解除封送處理 (Unmarshal) 引數、通透保存功能 (ORM) 以及呼叫 Rich 查詢等功能。

您可以在 $GOPATH/src/example.com/<chaincodeName> 中找到鷹架式專案

Model

資產類型特性

依預設,每個結構都會有一個名為 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"
此修飾器用於定義衍生自其他特性的屬性。此修飾條件有兩個必要參數:
  • strategy:採用 concathash 的值。如果選取 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"'
}
驗證類型
藉由定義驗證標記來驗證特性的基本執行類型。這些是根據類型驗證標記:
  • 字串:validate: "string"
  • 日期:validate: "date"
  • 號碼:validate: "int"
  • 布林值:validate: "bool"
最小驗證器
validate:"min=<param>"
使用最小驗證器,可以為類型為數字和字串的特性設定最小值。
對於類型 int:在範例中,RawMaterialAvailable 特性的最小值為 0,如果將小於 0 的值套用至 RawMaterialAvailable,則會傳回錯誤。
若為字串類型:字串類型最小驗證程式將會以提供的值檢查字串長度。因此,在以下範例中,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 類型:就像 min 驗證器一樣,若為 int 類型,若為 structfield 提供的值大於驗證器中提供的值,則會傳回錯誤。
若為字串類型:與最小驗證程式相同,最大驗證程式也會以指定的值檢查字串長度。在範例中,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

在 Context (Ctx) 物件的 Model 類別中擷取「通透保存功能」或簡化的 ORM。如果您的模型呼叫下列任一 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 鏈碼透過模型套件導入 Transparent Persistence Capability (ORM)。

附註:

從版本 21.2.3 開始,存取 ORM 方法的方式已經變更。執行 ochain --version 命令以判斷 Blockchain App Builder 的版本。

在舊版中,ORM 方法在模型套裝程式中顯示為靜態方法。方法現在是在模型接收器上定義,而模型接收器會保留交易存根。若要呼叫這些方法,您可以使用控制器中異動前後關聯所保留的模型接收器。您將這些方法稱為 t.Ctx.Model.<method_name>,而非 model.<method_name>

下列範例顯示舊版中的 SaveGet 方法呼叫:

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 和更新版本的 SaveGet 方法呼叫:

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 之後,請變更您使用舊版 Blockchain App Builder 建立的所有鏈碼專案。如果您使用 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 - 如果傳回錯誤或為 nil,則包含錯誤。
Update
以新值更新分類帳中提供的資產。
func Update(args ...interface{}) (interface{}, error)
參數:
  • obj (interface) - 在分類帳中需要更新的物件會透過參考至此 API 並使用新值來傳遞。輸入資產會根據模型規格中提及的結構標記進行驗證並驗證,然後儲存至分類帳。
傳回值:
  • interface{} - 儲存的資產會傳回為介面。
  • error - 如果傳回錯誤或為 nil,則包含錯誤。
Save
在驗證所有結構標記後,將資產儲存至分類帳。
func Save(args ...interface{}) (interface{}, error)
參數:
  • obj/args[0] (interface{}) - 需要儲存在分類帳中的物件會透過參考此公用程式方法來傳遞。
  • metadata/args[1] (interface{}) - 此為選擇性參數。如果您需要在執行時期將任何中繼資料與資產一起儲存到分類帳中,系統會提供這些資料以協助您。如果沒有此類需求,則可略過此參數。
傳回值:
  • interface {} - 將資產傳回為介面。
  • error - 如果傳回錯誤或為 nil,則包含錯誤。
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 - 如果傳回錯誤或為 nil,則包含錯誤。
GetByRangeWithPagination
GetByRangeWithPagination 方法是 OchainModel 類別的 static 方法,由 {chaincodeName}.model.ts 的具體 Model 類別繼承。
這會傳回 startIdendId 範圍之間的資產清單,依頁面大小和書籤篩選。此方法會在內部呼叫 Hyperledger Fabric GetStateByRangeWithPagination 方法。
如果未提供 modelName 參數,則方法會傳回 Promise<Object [ ] >。如果提供 modelName 參數,則方法會處理轉換至呼叫程式 Model 類型。在下列範例中,結果陣列的類型是 Supplier。如果從分類帳傳回的資產不是 Model 類型,則不會將其包含在清單中。此檢查是由 Model 類別中的唯讀 assetType 特性所完成。
若要傳回 startIdendId 範圍之間的所有資產 (依頁面大小和書籤篩選),請使用一般控制器方法 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 資料庫查詢。只有 Oracle Blockchain Platform 上的遠端部署才支援此方法。這是在分類帳上執行 SQL 查詢的一般方法。
func Query(queryString string) ([]interface{}, error)
參數:
  • queryString (string) - 輸入查詢字串。
傳回值:
  • []interface{} - 這將包含查詢的輸出。其結果就是介面的磁碟片段。您必須重複時段,並藉由將元素轉換為適當類型來使用元素。
  • error - 如果發現錯誤,則包含錯誤。
QueryWithPagination
查詢方式會在分類帳上執行 SQL/Couch 資料庫查詢,並依頁面大小與書籤篩選。只有 Oracle Blockchain Platform 上的遠端部署才支援此方法。這是在分類帳上執行 SQL 查詢的一般方法。
func (m *Model) QueryWithPagination(queryString string, pageSize int32, bookmark string) ([]interface{}, error)
參數:
  • queryString (string) - 豐富的 SQL/Couch 資料庫查詢。
  • pageSize : number - 查詢的頁面大小。
  • bookmark : string - 查詢的書籤。輸出會從此書籤開始。
傳回值:
  • []interface{} - 這將包含查詢的輸出。其結果就是介面的磁碟片段。您必須重複時段,並藉由將元素轉換為適當類型來使用元素。
  • error - 如果發現錯誤,則包含錯誤。
InvokeCrossChaincode
您可以在鏈碼中使用此方法來呼叫另一個鏈碼中的函數。兩個鏈碼都必須安裝在同一個對等體上。
func InvokeCrossChaincode(chaincodeName string, method string, args []string, channelName string) (interface{}, error)
參數:
  • chaincodeName - 要呼叫的鏈碼名稱。
  • methodName - 要在鏈碼中呼叫之方法的名稱。
  • arg - 呼叫方法的引數。
  • channelName - 要呼叫之鏈碼所在的通道。
傳回值:
  • interface{} - 傳回包含三個索引鍵的 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{} - 傳回包含三個索引鍵的 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 參數指示 stub 方法 SplitCompositeKey 陣列中傳回的索引鍵索引。
此方法會在內部呼叫 Hyperledger Fabric 的 getStateByPartialCompositeKeysplitCompositeKeygetState
func GetByCompositeKey(key string, columns []string, index int)
(interface{}, error)
參數:
  • key (string) - 建立複合項目索引鍵時提供的物件類型。
  • column ([]string) - 這是必須使用複合索引鍵查詢分類帳的屬性片段。
  • index(int) - 屬性的索引。
傳回值:
  • Interface{} - 包含此方法所產生的資產清單。
  • error - 包含任何錯誤 (如果有的話)。

Stub 方法

GetNetworkStub
此方法會傳回 Hyperledger Fabric chaincodeStub
您可以呼叫 GetNetworkStub 方法來存取 shim stub。這將協助您撰寫直接使用資產的導入工作。
func GetNetworkStub() shim.ChaincodeStubInterface
參數:
傳回值:
  • shim.ChaincodeStubInterface - 這是 Hyperledger Fabric 鏈碼 stub。

其他方法

  • 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
傳回用於鏈碼 Init 和 Invoke 作為字串陣列的引數。
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 方法,請參閱使用區塊鏈 App 產生器進行記號化支援下的主題。

控制器

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 Rich Query。Blockchain App Builder 會根據規格檔案中指定的引數類型,自動新增對引數的驗證程式。

您可以根據業務邏輯來實施功能。如果您新增自訂方法,請將它們增加到控制器檔案中。如果您將自訂方法新增至程式庫而非控制器檔案,則當同步化或鏈碼升級程序期間更新程式庫資料夾內容時,您的變更將會遺失。

//	
//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 鏈碼,每個自訂方法都應該傳回兩個值:空白介面error 。舉例而言:
func (t *Controller) FetchRawMaterial(supplierId string, rawMaterialSupply int) (interface{}, error) { 
    return nil, nil
}

Init 方法

控制器中提供具有空白定義的自訂 Init 方法。如果您使用 Blockchain App Builder 進行部署或升級,系統會自動呼叫 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
}

如果您在此時想要初始化任何應用程式狀態,您可以使用此方法來執行此操作。