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.

(为了清楚起见,我用 ... 省略了其他调用参数)