Ibm cloud 如何在hyperledger结构中获取资产修改历史记录

Ibm cloud 如何在hyperledger结构中获取资产修改历史记录,ibm-cloud,blockchain,hyperledger,hyperledger-fabric,Ibm Cloud,Blockchain,Hyperledger,Hyperledger Fabric,我正在为我的资产共享演示试用一些智能合约逻辑。 在hyperledger fabric network中是否仍可以查询资产修改历史记录。 我已经查阅了fabric 0.6和1.0版本的文档,但是我只能找到stub.pushState(key,value\u json)和stub.getState(key)来与分类账交互。但是使用stub.getState(key),我只能获取密钥的最新条目,但是如何获取和显示为同一个键编写的一系列更改/修改。 我已经使用{peeraddress}/block/g

我正在为我的资产共享演示试用一些智能合约逻辑。

在hyperledger fabric network中是否仍可以查询资产修改历史记录。

我已经查阅了fabric 0.6和1.0版本的文档,但是我只能找到stub.pushState(key,value\u json)和stub.getState(key)来与分类账交互。
但是使用stub.getState(key),我只能获取密钥的最新条目,但是如何获取和显示为同一个键编写的一系列更改/修改。 我已经使用
{peeraddress}/block/getBlock/{block}
遍历了该块,但是我只是在安全性开启的情况下才获得加密的事务有效负载。我不想为同一个键显示资产修改的历史记录


请告诉我正确的方法。


提前感谢,A.链码API GetHistoryForKey()将返回键的值历史记录。

来自,A.链码API GetHistoryForKey()将返回键的值历史记录。

您可以使用
GetHistoryForKey()
API,如下所示:

    historyIter, err := stub.GetHistoryForKey(key)

    if err != nil {
        errMsg := fmt.Sprintf("[ERROR] cannot retrieve history for key <%s>, due to %s", key, err)
        fmt.Println(errMsg)
        return shim.Error(errMsg)
    }

    for historyIter.HasNext() {
        modification, err := historyIer.Next()
        if err != nil {
            errMsg := fmt.Sprintf("[ERROR] cannot read record modification for key %s, id <%s>, due to %s", key, err)
            fmt.Println(errMsg)
            return shim.Error(errMsg)
        }
        fmt.Println("Returning information about", string(modification.Value))
    }
如果您想检查变更历史,而不是在链码上下文中,您可以使用(查询系统链码),它提供以下功能:

// These are function names from Invoke first parameter
const (
    GetChainInfo       string = "GetChainInfo"
    GetBlockByNumber   string = "GetBlockByNumber"
    GetBlockByHash     string = "GetBlockByHash"
    GetTransactionByID string = "GetTransactionByID"
    GetBlockByTxID     string = "GetBlockByTxID"
)

您可以按如下方式使用
GetHistoryForKey()
API:

    historyIter, err := stub.GetHistoryForKey(key)

    if err != nil {
        errMsg := fmt.Sprintf("[ERROR] cannot retrieve history for key <%s>, due to %s", key, err)
        fmt.Println(errMsg)
        return shim.Error(errMsg)
    }

    for historyIter.HasNext() {
        modification, err := historyIer.Next()
        if err != nil {
            errMsg := fmt.Sprintf("[ERROR] cannot read record modification for key %s, id <%s>, due to %s", key, err)
            fmt.Println(errMsg)
            return shim.Error(errMsg)
        }
        fmt.Println("Returning information about", string(modification.Value))
    }
如果您想检查变更历史,而不是在链码上下文中,您可以使用(查询系统链码),它提供以下功能:

// These are function names from Invoke first parameter
const (
    GetChainInfo       string = "GetChainInfo"
    GetBlockByNumber   string = "GetBlockByNumber"
    GetBlockByHash     string = "GetBlockByHash"
    GetTransactionByID string = "GetTransactionByID"
    GetBlockByTxID     string = "GetBlockByTxID"
)

如果你需要的话。JavaSDK和go链码的组合。这是一个例子

Java代码

public List getUFOHistory(字符串键)引发异常{
字符串[]args={key};
Logger.getLogger(QueryChaincode.class.getName()).log(Level.INFO,“UFO通信历史-”+args[0]);
收集响应1query=ucc.getChannelClient().queryByChainCode(“skynetchaincode”,“getHistoryForUFO”,args);
字符串stringResponse=null;
ArrayList newArrayList=新ArrayList();
for(ProposalResponse压力:responses1Query){
stringResponse=新字符串(pres.getChaincodeActionResponsePayload());
Logger.getLogger(QueryChaincode.class.getName()).log(Level.INFO,stringResponse);
newArrayList=gson.fromJson(stringResponse,newTypeToken()){
}.getType());
}
if(null==stringResponse)
stringResponse=“无法找到任何ufo通信历史记录”;
返回newArrayList;
}
而你去的chancode实现如下

密码

func(t*SmartContract)getHistoryForUFO(APIstub shim.ChaincodeStubInterface,args[]字符串)sc.响应{
如果len(args)<1{
返回shim.Error(“参数数量不正确,应为1”)
}
ufoId:=args[0]
resultsIterator,err:=APIstub.GetHistoryForKey(ufoId)
如果错误!=零{
返回shim.Error(err.Error())
}
延迟resultsIterator.Close()
变量缓冲区字节。缓冲区
buffer.WriteString(“[”)
BarrayMemberalReadyWrited:=false
对于resultsIterator.HasNext(){
响应,错误:=resultsIterator.Next()
如果错误!=零{
返回shim.Error(err.Error())
}
//在数组成员之前添加逗号,对第一个数组成员取消该逗号
如果BarrayMemberalReadyWrited==true{
buffer.WriteString(“,”)
}
buffer.WriteString(“{\”TxId\”:”)
buffer.WriteString(“\”)
buffer.WriteString(response.TxId)
buffer.WriteString(“\”)
buffer.WriteString(“,\”Value\“:”)
//如果这是对给定密钥的删除操作,那么我们需要设置
//对应的值为null。否则,我们将写入response.value
//原样(值本身是JSON)
if response.IsDelete{
buffer.WriteString(“null”)
}否则{
buffer.WriteString(字符串(response.Value))
}
buffer.WriteString(“,\“Timestamp\”:”)
buffer.WriteString(“\”)
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(“}”)
BarrayMemberalReadyWrited=true
}
buffer.WriteString(“]”)
fmt.Printf(“-History returning:\n%s\n”,buffer.String())
返回shim.Success(buffer.Bytes())
}

好了。玩得开心。

如果你需要的话。JavaSDK和go链码的组合。这是一个例子

Java代码

public List getUFOHistory(字符串键)引发异常{
字符串[]args={key};
Logger.getLogger(QueryChaincode.class.getName()).log(Level.INFO,“UFO通信历史-”+args[0]);
收集响应1query=ucc.getChannelClient().queryByChainCode(“skynetchaincode”,“getHistoryForUFO”,args);
字符串stringResponse=null;
ArrayList newArrayList=新ArrayList();
for(ProposalResponse压力:responses1Query){
stringResponse=新字符串(pres.getChaincodeActionResponsePayload());
Logger.getLogger(QueryChaincode.class.getName()).log(Level.INFO,stringResponse);
newArrayList=gson.fromJson(stringResponse,newTypeToken()){
}.getType());
}
if(null==stringResponse)
stringResponse=“无法找到任何ufo通信历史记录”;
返回newArrayList;
}
而你去的chancode实现如下

密码

func(t*SmartContract)getHistoryForUFO(APIstub shim.ChaincodeStubInterface,args[]字符串)sc.响应{
如果len(args)<1{
ret