随时间返回键值的历史记录。对于每一个历史的key更新,历史的值,有关联的交易ID和时间戳会被返回,这个时间戳是客户端在提案头部提供的,GetHistoryForKey需要peer的配置参数core.ledger.history.enableHistoryDatabase为true,在验证阶段查询不会被预执行。也就是说其他已经提交的交易可能同时已经更新key,也同时影响结果集,并且在验证和提交阶段这个不会被检测到,应用程序易受此影响因此不应该使用GetHistoryForKey作为事务的一部分更新分类账,并且应该限制使用只读链代码操作。
/args:name hashvalue owner
func (sc *SimpleChaincode) queryHistoryAsset(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) < 3 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}
name := args[0]
hashvalue := args[1]
owner := args[2]
kk, _ := stub.CreateCompositeKey(name, []string{hashvalue, owner})
fmt.Printf("- start getHistoryForMarble: %s\n", kk)
resultsIterator, err := stub.GetHistoryForKey(kk)
if err != nil {
return shim.Error(err.Error())
}
defer resultsIterator.Close()
// buffer is a JSON array containing historic values for the marble
var buffer bytes.Buffer
buffer.WriteString("[")
bArrayMemberAlreadyWritten := false
for resultsIterator.HasNext() {
response, err := resultsIterator.Next()
if err != nil {
return shim.Error(err.Error())
}
// Add a comma before array members, suppress it for the first array member
if bArrayMemberAlreadyWritten == true {
buffer.WriteString(",")
}
buffer.WriteString("{\"TxId\":")
buffer.WriteString("\"")
buffer.WriteString(response.TxId)
buffer.WriteString("\"")
buffer.WriteString(", \"Value\":")
// if it was a delete operation on given key, then we need to set the
//corresponding value null. Else, we will write the response.Value
//as-is (as the Value itself a JSON marble)
if response.IsDelete {
buffer.WriteString("null")
} else {
buffer.WriteString(string(response.Value))
}
buffer.WriteString(", \"Timestamp\":")
buffer.WriteString("\"")
buffer.WriteString(time.Unix(response.Timestamp.Seconds, int64(response.Timestamp.Nanos)).String())
buffer.WriteString("\"")
buffer.WriteString(", \"IsDelete\":")
buffer.WriteString("\"")
buffer.WriteString(strconv.FormatBool(response.IsDelete))
buffer.WriteString("\"")
buffer.WriteString("}")
bArrayMemberAlreadyWritten = true
}
buffer.WriteString("]")
fmt.Printf("- getHistoryForMarble returning:\n%s\n", buffer.String())
return shim.Success(buffer.Bytes())
}
运行结果:
image.png
网友评论