1

I was trying to implement GetHistoryFromKey() in my Golang Chaincode, but I just get the current token state all the time (and not historic).

  1. My Hyperledger Fabric network (latest version) is very basic for this issue. I am using the fabcar chaincode from fabric-samples in Golang and SDK Node.

  2. After calling InitLedger, I was creating a new car with CreateCar(CarNumber: "121", ...). CarNumber is key in this situation.

  3. Next step is a transaction with ChangeCarOwner("121", "NewOwner")

  4. Now I want to get the history of this car. Therefore I was implementing following function.

     func (s *SmartContract) GetHistoryForKeyAccIDUUIDAMO(ctx contractapi.TransactionContextInterface, carNumber string) (string, error) {
    
     historyIter, err := ctx.GetStub().GetHistoryForKey(carNumber)
    
     if err != nil {
         return "0", fmt.Errorf("Error in loading History by Key", carNumber)
     }
    
     if historyIter.HasNext() {
         modification, err := historyIter.Next()
         if err != nil {
             return "0", fmt.Errorf("Error in getting History by Key in Iteration", carNumber)
         }
         return string(modification.Value), nil
     } else {
         return "0", fmt.Errorf("Error in getting HistorybyKey", carNumber)
     }
    

    }

Result: {"make":"Toyota","model":"Rav4","colour":"Grey","owner":"NewOwner"}

This is not a historic car token, but the car after changing the owner of Car121 to PersonX

How can I get historic transaction data from the creation of car?

EDIT: Here is my new function, but it is still the same behaviour.

func (s *SmartContract) GetAssetHistory(ctx contractapi.TransactionContextInterface, account string, carNumber uint64) ([]HistoryQueryResult, error) {

historyKey, err := ctx.GetStub().CreateCompositeKey(Prefix, []string{owner, strconv.FormatUint(carNumber, 10)})
resultsIterator, err := ctx.GetStub().GetHistoryForKey(historyKey)
defer resultsIterator.Close()

var records []HistoryQueryResult
for resultsIterator.HasNext() {
    response, err := resultsIterator.Next()
    if err != nil {
        return nil, err
    }

    var asset Asset
    if len(response.Value) > 0 {
        err = json.Unmarshal(response.Value, &asset)
        if err != nil {
            return nil, err
        }
    } else {
        asset = Asset{Account: account}
    }

    timestamp, err := ptypes.Timestamp(response.Timestamp)
    if err != nil {
        return nil, err
    }

    record := HistoryQueryResult{
        TxId:      response.TxId,
        Timestamp: timestamp,
        Record:    &asset,
        IsDelete:  response.IsDelete,
    }
    records = append(records, record)
}

return records, nil

}

hejte
  • 21
  • 2

1 Answers1

0

You are just reading the first value from the history iterator so you are seeing just one of the values that has been associated with that key. To see all the historic values you need to iterate over all of them, perhaps collecting them into a slice. See here for an example:

https://github.com/hyperledger/fabric-samples/blob/8ca50df4ffec311e59451c2a7ebe210d9e6f0004/asset-transfer-ledger-queries/chaincode-go/asset_transfer_ledger_chaincode.go#L389-L433

bestbeforetoday
  • 1,302
  • 1
  • 8
  • 12
  • Thanks a lot! But I still do not get any historic values. My new function is in the original post. Maybe you can show me, what I am doing wrong. – hejte Jun 07 '22 at 13:57