无法使用 Hyperledger fabric v1.0.0 链代码查询所有 history/count 数据
Unable to query all history/count data with Hyperledger fabric v1.0.0 chaincode
我的链代码有问题,因为我无法查询所有数据(过去的记录)并显示出来。
我希望做的是在键入相同的 uniqueID
变量时添加一个计数器。
有了计数器,再加上uniqueID值我就可以得到正确的查询。
目前,当我 运行 这个命令时,我可以从区块链获取单一条目数据:
peer chaincode query -C food -n food_ccv01 -c '{"Args":["queryFoodInfo","1","123456789"]}'
使用 "123456789"
作为唯一 ID,使用“1”作为计数器,将它们结合起来得到一个唯一条目
但是我无法使用这个“123456789”+计数器来提取之前输入区块链的所有数据。
我该怎么做?或者有更好的方法吗?
我不确定为什么我的计数器不能初始化为整数,我现在使用的是字符串...
这是我的chaincode.
我认为您不需要在密钥上附加一个计数器,相反您可以简单地继续更新相同的密钥并查询所有更新,因为您可以使用以下 API:
// GetHistoryForKey returns a history of key values across time.
// For each historic key update, the historic value and associated
// transaction id and timestamp are returned. The timestamp is the
// timestamp provided by the client in the proposal header.
// GetHistoryForKey requires peer configuration
// core.ledger.history.enableHistoryDatabase to be true.
// The query is NOT re-executed during validation phase, phantom reads are
// not detected. That is, other committed transactions may have updated
// the key concurrently, impacting the result set, and this would not be
// detected at validation/commit time. Applications susceptible to this
// should therefore not use GetHistoryForKey as part of transactions that
// update ledger, and should limit use to read-only chaincode operations.
GetHistoryForKey(key string) (HistoryQueryIteratorInterface, error)
例如这些方面的东西应该对你有用:
func queryFoodFullInfo(stub shim.ChaincodeStubInterface, args []string) pb.Response {
fmt.Println("Entering Query Food information")
// Assuming food key is at zero index
historyIer, err := stub.GetHistoryForKey(args[0])
if err != nil {
errMsg := fmt.Sprintf("[ERROR] cannot retrieve history of food record with id <%s>, due to %s", args[0], err)
fmt.Println(errMsg)
return shim.Error(errMsg)
}
result := make([]FavouritefoodInfo, 0)
for historyIer.HasNext() {
modification, err := historyIer.Next()
if err != nil {
errMsg := fmt.Sprintf("[ERROR] cannot read food record modification, id <%s>, due to %s", args[0], err)
fmt.Println(errMsg)
return shim.Error(errMsg)
}
var food FavouritefoodInfo
json.Unmarshal(modification.Value, &food)
result = append(result, food)
}
outputAsBytes, _ := json.Marshal(&result)
return shim.Success(outputAsBytes)
}
按照您的初始路径,您可能想要探索 range query 功能:
// GetStateByRange returns a range iterator over a set of keys in the
// ledger. The iterator can be used to iterate over all keys
// between the startKey (inclusive) and endKey (exclusive).
// The keys are returned by the iterator in lexical order. Note
// that startKey and endKey can be empty string, which implies unbounded range
// query on start or end.
// Call Close() on the returned StateQueryIteratorInterface object when done.
// The query is re-executed during validation phase to ensure result set
// has not changed since transaction endorsement (phantom reads detected).
GetStateByRange(startKey, endKey string) (StateQueryIteratorInterface, error)
我的链代码有问题,因为我无法查询所有数据(过去的记录)并显示出来。
我希望做的是在键入相同的 uniqueID
变量时添加一个计数器。
有了计数器,再加上uniqueID值我就可以得到正确的查询。
目前,当我 运行 这个命令时,我可以从区块链获取单一条目数据:
peer chaincode query -C food -n food_ccv01 -c '{"Args":["queryFoodInfo","1","123456789"]}'
使用 "123456789"
作为唯一 ID,使用“1”作为计数器,将它们结合起来得到一个唯一条目
但是我无法使用这个“123456789”+计数器来提取之前输入区块链的所有数据。
我该怎么做?或者有更好的方法吗?
我不确定为什么我的计数器不能初始化为整数,我现在使用的是字符串...
这是我的chaincode.
我认为您不需要在密钥上附加一个计数器,相反您可以简单地继续更新相同的密钥并查询所有更新,因为您可以使用以下 API:
// GetHistoryForKey returns a history of key values across time.
// For each historic key update, the historic value and associated
// transaction id and timestamp are returned. The timestamp is the
// timestamp provided by the client in the proposal header.
// GetHistoryForKey requires peer configuration
// core.ledger.history.enableHistoryDatabase to be true.
// The query is NOT re-executed during validation phase, phantom reads are
// not detected. That is, other committed transactions may have updated
// the key concurrently, impacting the result set, and this would not be
// detected at validation/commit time. Applications susceptible to this
// should therefore not use GetHistoryForKey as part of transactions that
// update ledger, and should limit use to read-only chaincode operations.
GetHistoryForKey(key string) (HistoryQueryIteratorInterface, error)
例如这些方面的东西应该对你有用:
func queryFoodFullInfo(stub shim.ChaincodeStubInterface, args []string) pb.Response {
fmt.Println("Entering Query Food information")
// Assuming food key is at zero index
historyIer, err := stub.GetHistoryForKey(args[0])
if err != nil {
errMsg := fmt.Sprintf("[ERROR] cannot retrieve history of food record with id <%s>, due to %s", args[0], err)
fmt.Println(errMsg)
return shim.Error(errMsg)
}
result := make([]FavouritefoodInfo, 0)
for historyIer.HasNext() {
modification, err := historyIer.Next()
if err != nil {
errMsg := fmt.Sprintf("[ERROR] cannot read food record modification, id <%s>, due to %s", args[0], err)
fmt.Println(errMsg)
return shim.Error(errMsg)
}
var food FavouritefoodInfo
json.Unmarshal(modification.Value, &food)
result = append(result, food)
}
outputAsBytes, _ := json.Marshal(&result)
return shim.Success(outputAsBytes)
}
按照您的初始路径,您可能想要探索 range query 功能:
// GetStateByRange returns a range iterator over a set of keys in the
// ledger. The iterator can be used to iterate over all keys
// between the startKey (inclusive) and endKey (exclusive).
// The keys are returned by the iterator in lexical order. Note
// that startKey and endKey can be empty string, which implies unbounded range
// query on start or end.
// Call Close() on the returned StateQueryIteratorInterface object when done.
// The query is re-executed during validation phase to ensure result set
// has not changed since transaction endorsement (phantom reads detected).
GetStateByRange(startKey, endKey string) (StateQueryIteratorInterface, error)