如何根据 Hyperledger 结构中的链代码获取所有交易历史记录
How to get all transaction history against a chaincode in Hyperledger fabric
我能够在 Hyperledger(结构实现)中进行交易。我想查看用户通过传递用户密钥发起的所有交易及其负载详细信息。
例如:
A transfers 10 units to B
A transfers 5 units to C
D transfers 8 units to A
当我传递 A 的密钥时,fabric 必须向我提供 A 的所有交易。
有什么办法吗?或者我应该使用哪个结构 API 函数调用?
您可以在您的链代码中开发适当的索引和查询功能。
意味着您将每笔交易的详细信息存储在内部 key/value 商店 (stub.PutState) 中,用户作为键,return 所有与您查询中的用户关联的交易(stub.GetState).
/chain/blocks/{Block}
端点携带 指定区块中的有序交易列表 。
使用 /chain
端点获取链的高度(块数),然后使用 /chain/blocks/{Block}
REST 端点从每个块检索交易。
最好和最简单的方法是使用 shim 包 函数
GetHistoryForKey(key string)
如文档所述:
GetHistoryForKey function can be invoked by a chaincode to return a history of key values across time.
GetHistoryForKey is intended to be used for read-only queries.
如果有人需要 Java SDK 和 go 链码组合。给你
在这里回答
Java code
public List<HistoryDao> getUFOHistory(String key) throws Exception {
String[] args = { key };
Logger.getLogger(QueryChaincode.class.getName()).log(Level.INFO, "UFO communication history - " + args[0]);
Collection<ProposalResponse> responses1Query = ucc.getChannelClient().queryByChainCode("skynetchaincode", "getHistoryForUFO", args);
String stringResponse = null;
ArrayList<HistoryDao> newArrayList = new ArrayList<>();
for (ProposalResponse pres : responses1Query) {
stringResponse = new String(pres.getChaincodeActionResponsePayload());
Logger.getLogger(QueryChaincode.class.getName()).log(Level.INFO, stringResponse);
newArrayList = gson.fromJson(stringResponse, new TypeToken<ArrayList<HistoryDao>>() {
}.getType());
}
if (null == stringResponse)
stringResponse = "Not able to find any ufo communication history";
return newArrayList;
}
你去chancode实现如下
Go code
func (t *SmartContract) getHistoryForUFO(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
if len(args) < 1 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}
ufoId := args[0]
resultsIterator, err := APIstub.GetHistoryForKey(ufoId)
if err != nil {
return shim.Error(err.Error())
}
defer resultsIterator.Close()
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)
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("- History returning:\n%s\n", buffer.String())
return shim.Success(buffer.Bytes())
}
如果您有疑问,请告诉我。
如果您使用的是 composer-client,您可以简单地使用 Historian 命令。
var historian = await businessNetworkConnection.getHistorian();
historian.getAll().then(historianRecords => console.log(historianRecords));
我能够在 Hyperledger(结构实现)中进行交易。我想查看用户通过传递用户密钥发起的所有交易及其负载详细信息。
例如:
A transfers 10 units to B
A transfers 5 units to C
D transfers 8 units to A
当我传递 A 的密钥时,fabric 必须向我提供 A 的所有交易。 有什么办法吗?或者我应该使用哪个结构 API 函数调用?
您可以在您的链代码中开发适当的索引和查询功能。
意味着您将每笔交易的详细信息存储在内部 key/value 商店 (stub.PutState) 中,用户作为键,return 所有与您查询中的用户关联的交易(stub.GetState).
/chain/blocks/{Block}
端点携带 指定区块中的有序交易列表 。
使用 /chain
端点获取链的高度(块数),然后使用 /chain/blocks/{Block}
REST 端点从每个块检索交易。
最好和最简单的方法是使用 shim 包 函数
GetHistoryForKey(key string)
如文档所述:
GetHistoryForKey function can be invoked by a chaincode to return a history of key values across time. GetHistoryForKey is intended to be used for read-only queries.
如果有人需要 Java SDK 和 go 链码组合。给你
在这里回答
Java code
public List<HistoryDao> getUFOHistory(String key) throws Exception {
String[] args = { key };
Logger.getLogger(QueryChaincode.class.getName()).log(Level.INFO, "UFO communication history - " + args[0]);
Collection<ProposalResponse> responses1Query = ucc.getChannelClient().queryByChainCode("skynetchaincode", "getHistoryForUFO", args);
String stringResponse = null;
ArrayList<HistoryDao> newArrayList = new ArrayList<>();
for (ProposalResponse pres : responses1Query) {
stringResponse = new String(pres.getChaincodeActionResponsePayload());
Logger.getLogger(QueryChaincode.class.getName()).log(Level.INFO, stringResponse);
newArrayList = gson.fromJson(stringResponse, new TypeToken<ArrayList<HistoryDao>>() {
}.getType());
}
if (null == stringResponse)
stringResponse = "Not able to find any ufo communication history";
return newArrayList;
}
你去chancode实现如下
Go code
func (t *SmartContract) getHistoryForUFO(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
if len(args) < 1 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}
ufoId := args[0]
resultsIterator, err := APIstub.GetHistoryForKey(ufoId)
if err != nil {
return shim.Error(err.Error())
}
defer resultsIterator.Close()
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)
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("- History returning:\n%s\n", buffer.String())
return shim.Success(buffer.Bytes())
}
如果您有疑问,请告诉我。
如果您使用的是 composer-client,您可以简单地使用 Historian 命令。
var historian = await businessNetworkConnection.getHistorian();
historian.getAll().then(historianRecords => console.log(historianRecords));