雖然 Fabric v2.2 已經發布了很久了,但之前因為專案歷史問題,一直使用的都是 Fabric v1.4.8,所以智慧合約也一直使用的都是 github.com/hyperledger/fabric/core/chaincode/shim
包。
在合約開發過程中,我一般都是使用下面的介面格式來定義合約的業務邏輯:
func create(stub shim.ChaincodeStubInterface, payload string) ([]byte, error)
在開發 Fabric v2.2 的智慧合約時, 使用 github.com/hyperledger/fabric-contract-api-go/contractapi
替換 github.com/hyperledger/fabric/core/chaincode/shim
,介面格式如下:
func create(ctx contractapi.TransactionContextInterface, payload string) ([]byte, error)
然而這樣的介面在合約範例化的時候翻車了:
Error compiling schema for SmartContract [create]. Return schema invalid. required items must be unique [recovered]
翻閱 github.com/hyperledger/fabric-contract-api-go
時,在其使用教學發現一些限制:
仔細閱讀會發現 func create(ctx contractapi.TransactionContextInterface, payload string) ([]byte, error)
並沒有違法上面的規則,但範例化的時候就是無法通過。
上面的報錯資訊也明確說了是返回值不對,那就改下介面的返回值:
func create(ctx contractapi.TransactionContextInterface, payload string) (string, error)
func create(ctx contractapi.TransactionContextInterface, payload string) (*Company, error)
func create(ctx contractapi.TransactionContextInterface, payload string) (int, error)
修改後在進行範例化,這次不再報錯了。
但是明明之前的也沒有違反規則,為什麼會報錯呢?想不通為什麼,所以準備給官方提個Issue,萬一真是個bug呢?
結果就在issues裡發現了這個Possible issues with byte[] as return type,一看日期Oct 20, 2021,快兩年了也沒官方的迴應......
最後搜了一圈也沒找到原因,檢視原始碼,感覺問題可能是出在 contractFunctionReturns
,具體還得等研究完原始碼之後才能有答案
type contractChaincodeContract struct {
info metadata.InfoMetadata
functions map[string]*internal.ContractFunction
unknownTransaction *internal.TransactionHandler
beforeTransaction *internal.TransactionHandler
afterTransaction *internal.TransactionHandler
transactionContextHandler reflect.Type
}
// ContractChaincode a struct to meet the chaincode interface and provide routing of calls to contracts
type ContractChaincode struct {
DefaultContract string
contracts map[string]contractChaincodeContract
metadata metadata.ContractChaincodeMetadata
Info metadata.InfoMetadata
TransactionSerializer serializer.TransactionSerializer
}
// ContractFunction contains a description of a function so that it can be called by a chaincode
type ContractFunction struct {
function reflect.Value
callType CallType
params contractFunctionParams
returns contractFunctionReturns
}
type contractFunctionReturns struct {
success reflect.Type
error bool
}
宣告:本作品採用署名-非商業性使用-相同方式共用 4.0 國際 (CC BY-NC-SA 4.0)進行許可,使用時請註明出處。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 戀水無意