Blockchain App Builder 會從您的規格檔案進行輸入,並產生功能完整的鷹架式鏈碼專案。專案包含自動產生的類別和函數、CRUD 方法、SDK 方法、引數的自動驗證、封送處理 / 取消封送處理以及透明保存功能 (ORM)。
如果 chaincode 專案是 Go 語言,則 scaffolded 專案包含三個主要檔案:
main.go
<chaincodeName>.model.go
<chaincodeName>.controller.go
會安裝並封裝所有必要的程式庫。
model 子目錄中的 <chaincodeName>.model.go 檔案包含多個資產定義,而 controller 子目錄中的 <chaincodeName>.controller.go 檔案包含資產的行為和 CRUD 方法。model.go 和 controller.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:接受 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,則會傳回錯誤。
- 對於類型字串:對於字串類型,最小驗證程式將會使用提供的值檢查字串的長度。因此,在下面的範例中,
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
「通透保存功能」或簡化的 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 鏈碼使用模型套件實作 Transparent Persistence Capability (ORM)。
附註:
從版本 21.2.3 開始,存取 ORM 方法的方式已變更。執行
ochain --version 命令以判斷區塊鏈 App 產生器的版本。
在舊版中,ORM 方法在模型套件中會以靜態方法顯示。現在可以在保留交易存根的模型接收器上定義方法。若要呼叫這些方法,請使用控制器中由交易相關資訊環境保留的模型接收器。將這些方法稱為 t.Ctx.Model.<method_name>,而非 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 之後,請在使用舊版區塊鏈 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) - 需要的物件範圍結束。
asset interface - (選擇性) 透過參照傳送的空白資產陣列。這個陣列會包含這個方法的結果。在需要特定類型的結果時使用。
- 傳回值:
[]map[string]interface{} - 此陣列包含從分類帳取得的資產清單。您可以存取反覆此陣列的物件,並將物件宣告為 map[string]interface{},並使用公用程式轉換至資產物件。
error - 如果傳回,或為 nil,則包含錯誤。
-
GetByRangeWithPagination
GetByRangeWithPagination 方法是 OchainModel 類別的靜態方法,由 {chaincodeName}.model.ts 的具體 Model 類別繼承。
- 這會傳回範圍
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) - 豐富的 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 的
getStateByPartialCompositeKey、splitCompositeKey 以及 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
- 參數:
- 傳回值:
-
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
- 傳回要用於鏈碼 Init 與 Invoke 作為字串陣列的引數。
func GetStringArgs() []string
- 參數:
- 傳回值:
[]string - 包含作為字串陣列的必要引數。
-
GetCreatorMspId
- 傳回呼叫識別的 MSP ID。
-
func GetCreatorMspId() string
- 參數:
- 傳回值:
-
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 鏈碼,每個自訂方法都應該傳回兩個值:
空的介面、
錯誤。舉例而言:
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
}
您目前可以使用此方法來初始化任何應用程式狀態。