我是智能合约开发的新手,并试图使其适用于处理资产。我的资产叫做GOcerts。
我已经使用令牌UTXO智能合约作为开始学习的基础,并根据我的需求添加了更改和功能。
我添加了一个名为ClaimGO((的替代函数,它应该删除资产,并在分类账中创建和存储两个新资产。但是函数DeleteState和putState似乎没有在分类账上存储任何内容,因为当我在调用该函数后查询分类账时,就像没有任何东西改变分类账状态一样。
ClaimGO功能的实现如下:
//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: %vn, gocertInput: %#vn 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, err := ctx.GetStub().CreateCompositeKey("goCert", []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", txID, 1)
goCertOutputs = append(goCertOutputs, goCertOutput2)
goCertAsBytes2, _ := json.Marshal(goCertOutput2)
goCertOutputCompositeKey2, err := ctx.GetStub().CreateCompositeKey("goCert", []string{goCertOutput2.Owner, goCertOutput2.Key})
err = ctx.GetStub().PutState(goCertOutputCompositeKey2, goCertAsBytes2)
if err != nil {
return nil, err
}
log.Printf("goCertOutput created: %+v", goCertOutput2)
return goCertOutputs, nil
}
我正在试用Hyperledger Fabric测试网络的智能合约。使用logspout工具,我可以看到显示了这两条日志消息,因此我知道代码执行正确。问题是,尽管DeleteState和PutState函数执行时没有错误,但它们实际上并没有改变分类账上的任何内容
我们将非常感谢您对这一问题的任何帮助。
非常感谢。
只有在交易被背书、提交给订购方、在一个区块中提交并分发给同行以便他们可以更新本地账本状态之后,账本才会真正得到更新。如果未满足某些背书要求,则在发送给订购方后,事务仍有可能无法成功提交。
如果使用peer chaincode query
命令进行调用,则不会将交易发送给订购方,因此不会发生分类账更新。如果您使用peer chaincode invoke
命令,则背书的交易将发送给订购方并更新分类账。
但是,invoke命令之后的查询命令将不会看到由调用引起的分类帐更新,直到它们执行的对等方从订购方接收到提交的块并更新了其本地分类帐状态。要使peer chaincode invoke
命令在退出之前等待在对等账本中提交事务,请使用--waitForEvent
命令行标志。
运行peer chaincode invoke --help
以获取可用命令行标志的详细信息。