Fabric Chaincode 中的灵活输入(可变函数)可能吗?
Flexible input (variadic function) in Fabric Chaincode possible?
我正在尝试创建一个 Hyperledger Fabric 链码 function/method,它接受不确定数量的输入(即可变参数函数)。
我在 Go 工作。
这是我的:
38 type Prod struct {
39 ProdID string `json:"prodID"`
40 Attributes []string `json:"attributes"`
41 }
420 func (s *SmartContract) Ver2(ctx contractapi.TransactionContextInterface, prodID string, input...string) error {
421 //create Prod struct
422 var p Prod
423 //set values based on input:
424 p.ProdID = prodID
425 p.Attributes = make([]string,len(input))
426 for i:=0; i<len(input); i++ {
427 p.Attributes[i]=input[i]
428 }
429 //convert Go struct into JSON format
430 assetJSON, err := json.Marshal(p)
431 if err != nil {
432 return fmt.Errorf("Problem encountered during marshaling: %v\n", err)
433 }
434 //write data to ledger
435 return ctx.GetStub().PutState(prodID, assetJSON)
436 }
当我尝试使用以下代码调用此链代码时
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /home/hans/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n scm -c '{"Args":["Ver2","BB","ok","maybe","test"]}'
我收到这个错误:
Error: endorsement failure during invoke. response: status:500 message:"Error managing parameter param1. Conversion error. Value ok was not passed in expected format []string"
我的代码有问题吗?或者这是我使用的 Fabric api 的限制?
我试过在线搜索,但没有发现有关链代码中可变参数函数的任何相关讨论或文档。
我在这里得到了一个类似的(虽然不是链代码)工作版本:https://play.golang.org/p/-7NX8-Uf88p
为了它的价值,我成功地制作了一个可变辅助函数,我可以从另一个链码函数调用它,但是如果不更新链码就不能修改可变输入。 (所以对我不是很有用。)
作为参考,下面列出了这两个函数:
394 func (s *Prod) VeriTest(ctx contractapi.TransactionContextInterface, prodID string, attr ...string) {
395 s.ProdID = prodID
396 s.Attributes = make([]string, len(attr))
397 for i:=0; i<len(attr); i++ {
398 s.Attributes[i]=attr[i]
399 }
400 }
401
402 //Ver: Proof of Concept - linked to VeriTest above
403 func (s *SmartContract) Ver(ctx contractapi.TransactionContextInterface) error {
404 //create Prod struct
405 var p Prod
406 //call VeriTest on Prod
407 p.VeriTest(ctx,"AA","test","string","five")
408 //convert Go struct into JSON format
409 assetJSON, err := json.Marshal(p)
410 if err != nil {
411 return err
412 }
413 //write data to ledger
414 return ctx.GetStub().PutState("AA", assetJSON)
415 }
您遇到的问题是因为您在调用 peer chaincode invoke
.
时没有正确编码 []string 参数
您调用它的方式是发送一组字符串参数,但您想要做的是发送一个字符串参数,然后发送第二个字符串参数。
为此,您需要将第二个参数编码为 JSON 数组:
peer chaincode invoke ... -n scm -c '{"Args":["Ver2","BB","[\"ok\",\"maybe\",\"test\"]"}'
- 第一个Arg当然是函数名
- 第二个 Arg 将映射到 prodID 参数。
- 第三个 Arg 是一个字符串编码的 JSON 数组,它将映射到您的 attr 参数。
工作解决方案的最后一件事是将 attr
参数的类型从可变参数 ...string
更改为数组 []string
.
(为了清楚起见,我用 ...
省略了其他调用参数)
我正在尝试创建一个 Hyperledger Fabric 链码 function/method,它接受不确定数量的输入(即可变参数函数)。
我在 Go 工作。
这是我的:
38 type Prod struct {
39 ProdID string `json:"prodID"`
40 Attributes []string `json:"attributes"`
41 }
420 func (s *SmartContract) Ver2(ctx contractapi.TransactionContextInterface, prodID string, input...string) error {
421 //create Prod struct
422 var p Prod
423 //set values based on input:
424 p.ProdID = prodID
425 p.Attributes = make([]string,len(input))
426 for i:=0; i<len(input); i++ {
427 p.Attributes[i]=input[i]
428 }
429 //convert Go struct into JSON format
430 assetJSON, err := json.Marshal(p)
431 if err != nil {
432 return fmt.Errorf("Problem encountered during marshaling: %v\n", err)
433 }
434 //write data to ledger
435 return ctx.GetStub().PutState(prodID, assetJSON)
436 }
当我尝试使用以下代码调用此链代码时
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /home/hans/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n scm -c '{"Args":["Ver2","BB","ok","maybe","test"]}'
我收到这个错误:
Error: endorsement failure during invoke. response: status:500 message:"Error managing parameter param1. Conversion error. Value ok was not passed in expected format []string"
我的代码有问题吗?或者这是我使用的 Fabric api 的限制?
我试过在线搜索,但没有发现有关链代码中可变参数函数的任何相关讨论或文档。
我在这里得到了一个类似的(虽然不是链代码)工作版本:https://play.golang.org/p/-7NX8-Uf88p
为了它的价值,我成功地制作了一个可变辅助函数,我可以从另一个链码函数调用它,但是如果不更新链码就不能修改可变输入。 (所以对我不是很有用。)
作为参考,下面列出了这两个函数:
394 func (s *Prod) VeriTest(ctx contractapi.TransactionContextInterface, prodID string, attr ...string) {
395 s.ProdID = prodID
396 s.Attributes = make([]string, len(attr))
397 for i:=0; i<len(attr); i++ {
398 s.Attributes[i]=attr[i]
399 }
400 }
401
402 //Ver: Proof of Concept - linked to VeriTest above
403 func (s *SmartContract) Ver(ctx contractapi.TransactionContextInterface) error {
404 //create Prod struct
405 var p Prod
406 //call VeriTest on Prod
407 p.VeriTest(ctx,"AA","test","string","five")
408 //convert Go struct into JSON format
409 assetJSON, err := json.Marshal(p)
410 if err != nil {
411 return err
412 }
413 //write data to ledger
414 return ctx.GetStub().PutState("AA", assetJSON)
415 }
您遇到的问题是因为您在调用 peer chaincode invoke
.
您调用它的方式是发送一组字符串参数,但您想要做的是发送一个字符串参数,然后发送第二个字符串参数。
为此,您需要将第二个参数编码为 JSON 数组:
peer chaincode invoke ... -n scm -c '{"Args":["Ver2","BB","[\"ok\",\"maybe\",\"test\"]"}'
- 第一个Arg当然是函数名
- 第二个 Arg 将映射到 prodID 参数。
- 第三个 Arg 是一个字符串编码的 JSON 数组,它将映射到您的 attr 参数。
工作解决方案的最后一件事是将 attr
参数的类型从可变参数 ...string
更改为数组 []string
.
(为了清楚起见,我用 ...
省略了其他调用参数)