Blockchain App Builder 會從您的規格檔案進行輸入,並產生功能完整的鷹架式鏈碼專案。專案包含自動產生的類別和函數、CRUD 方法、SDK 方法、引數自動驗證、封送處理 (Marshalling) / 解除封送處理 (un-marshalling) 和透明保存功能 (ORM)。
如果 chaincode 專案是 Go 語言,鷹架式專案會包含三個主要檔案:
main.go
<chaincodeName>.model.go
<chaincodeName>.controller.go
已安裝並封裝所有必要的程式庫。
model
子目錄中的 <chaincodeName>.model.go
檔案包含多個資產定義,而 controller
子目錄中的 <chaincodeName>.controller.go
檔案包含資產的行為和 CRUD 方法。model.go
和 controller.go
中的各種 Go 結構標記和套裝軟體都支援自動驗證引數、封送處理 (Marshalling/unmarshalling) 引數、通透保存功能 (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"'
}
-
驗證類型
- 定義驗證標記來驗證特性的基本執行類型。以下是根據類型的驗證標記:
- 字串:
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:與最小驗證程式一樣,對於類型 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>"
- Regexp 驗證程式將會驗證輸入正規表示式的特性。
- 在此範例中,
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 會擷取在相關資訊環境 (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 鏈碼透過模型套件實作透明持續性功能 (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
- 如果傳回錯誤或為無,則包含錯誤。
-
Update
- 以新值更新分類帳中提供的資產。
-
func Update(args ...interface{}) (interface{}, error)
- 參數:
obj (interface)
- 必須在分類帳中更新的物件,會透過使用新值參照此 API 傳送。輸入資產會根據模型規格中提及的結構標記進行驗證和驗證,然後儲存到分類帳中。
- 傳回值:
interface{}
- 已儲存的資產會以介面傳回。
error
- 如果傳回錯誤或為無,則包含錯誤。
-
Save
- 驗證所有結構標記後,將資產儲存至分類帳。
-
func Save(args ...interface{}) (interface{}, error)
- 參數:
obj/args[0] (interface{})
- 必須儲存在分類帳中的物件會透過此公用程式方法中的參照來傳送。
metadata/args[1] (interface{})
- 此為選擇性參數。如果您需要在執行階段將任何中繼資料與資產一起儲存到分類帳,系統會提供此功能以協助您。如果沒有此類需求,則可略過此參數。
- 傳回值:
interface {}
- 資產會以介面傳回。
error
- 如果傳回錯誤或為無,則包含錯誤。
-
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
- 如果傳回錯誤或為無,則包含錯誤。
-
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
– 如果傳回錯誤,則包含錯誤,否則為零。
-
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)
- Rich 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 鏈碼存根。
其他方法
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
- 以字串陣列傳回用於鏈碼初始化與呼叫的引數。
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 方法,請參閱使用區塊鏈 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 鏈碼,每個自訂方法都應該傳回兩個值:
空白介面、
錯誤。舉例而言:
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
}
如果現在想要初始化任何應用程式狀態,您可以使用此方法來執行該動作。