鷹架式 Go Chaincode 專案

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

如果 chaincode 專案使用 Go 語言,則結構化的專案包含三個主要檔案:
  • main.go
  • <chaincodeName>.model.go
  • <chaincodeName>.controller.go
會安裝並封裝所有必要的程式庫。

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

結構專案位於 $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"'
}
驗證型態
透過定義驗證標記來驗證特性的基本 Go 類型。下列驗證標記是以基本類型為基礎:
  • 字串:validate: "string"
  • 日期:validate: "date"
  • 編號:validate: "int"
  • 布林值:validate: "bool"
最小值驗證程式
validate:"min=<param>"
您可以使用 min 驗證工具來設定類型為數字或字串之特性的最小值。
對於類型 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:類似於最小驗證器,如果為結構欄位指定的值大於驗證器中提供的值,則會傳回錯誤。
對於類型字串:與最小值驗證程式類似,最大值驗證程式會根據指定的值檢查字串的長度。在下列範例中,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 來存取它們。

下列 SDK 方法實行 ORM:
  • 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 命令以判斷區塊鏈 App 產生器的版本。

在舊版中,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 之後,請在使用舊版區塊鏈 App 產生器建立的所有鏈碼專案中進行這項變更。如果您使用 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) - 要擷取之物件範圍的結束 ID。
  • asset interface - (選擇性) 透過參照傳送的空白資產陣列。這個陣列將包含方法結果。如果需要特定類型的結果,請使用此參數。
傳回值:
  • []map[string]interface{} - 此陣列包含從分類帳取得的資產清單。您可以重複此陣列,將物件宣告為 map[string]interface{},並使用公用程式轉換成資產物件,以存取物件。
  • error - 如果傳回錯誤,或為 nil,則包含錯誤。
GetByRangeWithPagination
GetByRangeWithPagination 方法是 OchainModel 類別的靜態方法,由 {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 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) - 豐富的 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 的 getStateByPartialCompositeKeysplitCompositeKey 以及 getState 方法。
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
傳回要作為字串陣列的鏈碼 InitInvoke 方法引數。
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 方法,請參閱 Tokenization Support Using Blockchain App Builder 下的主題。

控制器

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。區塊鏈 App 產生器會根據規格檔案中指定的引數類型,自動新增引數的驗證程式。

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

//	
//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 鏈碼,每個自訂方法都必須傳回兩個值:一個 empty interface 和一個 error,如下列範例所示:
func (t *Controller) FetchRawMaterial(supplierId string, rawMaterialSupply int) (interface{}, error) { 
    return nil, nil
}

起始方式

控制器中提供了定義空白的自訂 Init 方法。如果您使用區塊鏈 App 產生器來部署或升級,系統會自動呼叫 Init 方法。如果您從 Oracle Blockchain Platform 主控台部署或升級,則必須手動呼叫 Init 方法。您可以使用第三方工具 (例如 Postman) 來手動呼叫 Init 方法。

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

然後您可以使用此方法來初始化任何應用程式狀態。