如何解决DeleteState 和 PutState 函数不会改变分类帐状态
我是智能合约开发的新手,并试图使其适用于处理资产。我的资产称为 GOcerts。
我已经使用token UTXO智能合约作为基础开始学习,并根据我的需要添加了变化和功能。
我添加了一个名为 ClaimGO() 的附加函数,它应该删除资产并在分类帐中创建和存储两个新资产。但是函数 DeleteState 和 putState 似乎没有在账本上存储任何东西,因为当我调用该函数后查询账本时,就像没有改变账本状态一样。
//ClaimGO claims an amount X of GOcert Y. This function is implemented following the UTXO model
func (s *SmartContract) ClaimGO(ctx contractapi.TransactionContextInterface,goCertInputKey string,amount int) ([]GOCERT,error) {
//1. Get ID of submitting client identity
clientID,err := ctx.GetClientIdentity().GetID()
if err != nil {
return nil,fmt.Errorf("Failed to get client id: %v",err)
}
//2. Validate GOcert input
goCertInputCompositeKey,err := ctx.GetStub().CreateCompositeKey("goCert",[]string{clientID,goCertInputKey})
if err != nil {
return nil,fmt.Errorf("Failed to create composite key: %v",err)
}
goCertInput := GOCERT{}
//2.1 Validate that client has a GOcert matching the input key
goCertAsBytes,err := ctx.GetStub().GetState(goCertInputCompositeKey)
if err != nil {
return nil,fmt.Errorf("Failed to read goCertInputCompositeKey %s from world state: %v",goCertInputCompositeKey,err)
}
errr := json.Unmarshal(goCertAsBytes,&goCertInput)
if errr != nil {
return nil,fmt.Errorf("goCertInput %s not found for client %s: %v\n,gocertInput: %#v\n gocerAsbytes: %v",goCertInputKey,clientID,errr,goCertInput,goCertAsBytes)
}
txID := ctx.GetStub().GetTxID()
pbKey := goCertInput.ProdBatchKey
expDate := goCertInput.ExpirationDate
//erase prevIoUs GOcert
err = ctx.GetStub().DelState(goCertInputCompositeKey)
if err != nil {
return nil,err
}
log.Printf("goCertInput deleted: %+v",goCertInput)
var goCertOutputs []GOCERT
//goCertOutput1 is the GO with the cancelled amount
goCertOutput1 := GOCERT{}
goCertOutput1.Amount = amount
goCertOutput1.ExpirationDate = expDate
goCertOutput1.Owner = clientID
goCertOutput1.ProdBatchKey = pbKey
goCertOutput1.State = "Cancelled"
goCertOutput1.Key = fmt.Sprintf("%s.%d",txID,0)
goCertOutputs = append(goCertOutputs,goCertOutput1)
goCertAsBytes,_ := json.Marshal(goCertOutput1)
goCertOutputCompositeKey,[]string{goCertOutput1.Owner,goCertOutput1.Key})
err = ctx.GetStub().PutState(goCertOutputCompositeKey,goCertAsBytes)
if err != nil {
return nil,err
}
log.Printf("goCertOutput created: %+v",goCertOutput1)
//goCertOutput 2 is the GO with the remaining amount that has not been claimed yet
goCertOutput2 := GOCERT{}
goCertOutput2.Amount = goCertInput.Amount - amount
goCertOutput2.ExpirationDate = expDate
goCertOutput2.Owner = clientID
goCertOutput2.ProdBatchKey = pbKey
goCertOutput2.State = "Issued"
goCertOutput2.Key = fmt.Sprintf("%s.%d",1)
goCertOutputs = append(goCertOutputs,goCertOutput2)
goCertAsBytes2,_ := json.Marshal(goCertOutput2)
goCertOutputCompositeKey2,[]string{goCertOutput2.Owner,goCertOutput2.Key})
err = ctx.GetStub().PutState(goCertOutputCompositeKey2,goCertAsBytes2)
if err != nil {
return nil,goCertOutput2)
return goCertOutputs,nil
}
我正在尝试使用 Hyperledger Fabric 测试网络的智能合约。使用logspout工具,可以看到显示了两条日志信息,所以我知道代码正在正确执行。问题是,尽管它执行时没有错误,DeleteState 和 PutState 函数实际上并没有改变分类帐上的任何内容。
对于可能出现的问题的任何帮助将不胜感激。
非常感谢。
解决方法
在交易被背书、提交给排序者、提交到一个块中并分发给对等点以便他们可以更新其本地分类帐状态之后,分类帐实际上不会得到更新。如果不满足某些背书要求,交易发送给orderer后仍有可能无法提交成功。
如果您使用 peer chaincode query
命令进行调用,交易不会发送给排序者,因此不会发生分类帐更新。如果您使用 peer chaincode invoke
命令,则背书交易将发送给订购者并更新分类帐。
然而,在调用命令之后的查询命令不会看到由调用引起的账本更新,直到它们执行的对等方收到来自排序节点的提交块并更新其本地账本状态。要让 peer chaincode invoke
命令在退出之前等待交易在对等分类账中提交,请使用 --waitForEvent
命令行标志。
运行 peer chaincode invoke --help
以获取可用命令行标志的详细信息。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。