鷹架 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 個字元。
範例:
 outputclass="language-go"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 方法。如果您從 Oracle Blockchain Platform 主控台進行部署或升級,則必須手動呼叫 Init 方法。您可以使用協力廠商工具 (例如 Postman) 手動呼叫 Init 方法。

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

您可以使用此方法來初始化目前的所有應用程式狀態。