# Enable hash tracking

An image

The ledger in Hyperledger Fabric is the sequenced, tamper-resistant record of all state transitions. State transitions are a result of chaincode invocations (“transactions”) submitted by participating parties. Each transaction results in a set of asset key-value pairs that are committed to the ledger as creates, updates, or deletes.

In some blockchain applications, certain data fields in the key-value pairs can be hashed for safeguarding the integrity of the data.

Data collector for Chaincode can be configured to track the hash changes of those fields and label it. They are defined during the data collector initialization time.

To enable this hash tracking feature, use the hashTracking (for JS or TS) or HashTrackingFunc (for Go) attribute when initializing the data collector.

For example (Javascript & TypeScript):






 















require('@ravenpod/ravenpod-cc-dc')(
    ['vaccine'], // param is an array of chaincode contract filename to be instrumented
    {
       accessKey: 'YOUR ACCESS KEY',
       secretAccessKey: 'YOUR SECRET ACCESS KEY',     
       hashTracking: {
           'collectionVaccinationPrivate': (key, data) => {
               const labeledHash  = generateVaccinationHash(key, data) // Call an external function to generate a hash
               console.log(labeledHash) // { label: 'SOME LABEL', hash: 'SOME HASH' }
               return labeledHash
           },
           'collectionLogisticsPublic': (key, data) => {
               const labeledHash  = generateLogisticsHash(key, data) // Call an external function to generate a hash
               console.log(labeledHash) // { label: 'SOME LABEL', hash: 'SOME HASH' }
               return labeledHash
           }
       },
       debug: true
    }    
)

hashTracking must be a JS Object where:

  • Attribute name is either channelStateData (representing the channel state data store), or the name of the private data collection.
  • Attribute value is a function accepting two parameters, key and data, representing the asset key-value pair that are committed to the ledger as creates, updates, or deletes. The function must make use of the key and data and return a JS Object containing two attributes: label and hash.

For example (Go):







 












// Ravenpod
contract := chaincode.SmartContract{}
rpDC := contractapi.NewDataCollector(
    "[YOUR ACCESS KEY]",
    "[YOUR SECRET ACCESS KEY]",
    contractapi.DCOptions{
        HashTrackingFunc: func(collection string, key string, data []byte) (string, string) {
            labeledHash = GenerateLogisticsHash(collection, key, data) // Call a function to generate a hash
            log.Println("Labeled hash", labeledHash) // 'SOME LABEL', 'SOME HASH'
            return labeledHash
        },
    },
)
contract.RpDataCollector = rpDC
contract.BeforeTransaction = rpDC.RpBeforeHook
contract.AfterTransaction = rpDC.RpAfterHook
assetChaincode, err := contractapi.NewChaincode(&contract)
// Ravenpod

HashTrackingFunc must be a function type with this signature func(collection string, key string, data []byte) (string, string), where:

  • First parameter is the ledger private data collection name. In the case of channel state data, its value will be CHANNEL STATE DATA
  • Second parameter is the ledger key
  • Third parameter is the value of the key in the form of byte array. A common practice is to unmarshal it to JSON or struct and extract the individual values in the data structure.
  • Your function should make use of the parameter values and return two string. The first one is the label you would like to tag this kind of hash and the second one is the hash for this particular data instance.