Using Composite Key formation to get states for a date range in Hyperledger Fabric V1.0

+1 vote

Suppose my composite key is formed with the fields Owner_id~dateOfcreation, for example:

  • Owner1~01-08-2018
  • Owner1~02-08-2018
  • Owner1~03-08-2018
  • ...
  • ...
  • Owner1~30-08-2018

Now I want to get the states for date range Owner1~15-08-2018 to Owner1~20-08-2018. I want to know if this is possible. 

If I use stub.GetStateByRange(startKey,endKey), it will return the keys which are in lexical order, so it will not return the expected range. 

So, how can I handle this situation and get desired output?

Jul 20, 2018 in Blockchain by ariaholic
• 7,320 points
678 views

2 answers to this question.

+2 votes
Best answer

I think you have found a partial answer. You could use the function GetStateByRange? This function doesn't return keys, it returns an iterator with the values.

You could use the GetStateByRange function and pass the date range to it. 

Please refer to the example below:

func get_all_components(stub shim.ChaincodeStubInterface, args []string) pb.Response {
    var err error
    fmt.Println("starting get_all_components")

    // input sanitation
    err = sanitize_arguments_len(args, 1)
    if err != nil {
        return shim.Error(err.Error())
    }

    // ---- Get All Components ---- //
    resultsIterator, err := stub.GetStateByRange("c0", "c9999999999999999999")
    if err != nil {
        return shim.Error(err.Error())
    }
    defer resultsIterator.Close()

    // buffer is a JSON array containing QueryRecords
    var buffer bytes.Buffer
    buffer.WriteString("[")

    bArrayMemberAlreadyWritten := false
    for resultsIterator.HasNext() {
        //queryKeyAsStr, queryValAsBytes, err := resultsIterator.Next()
        queryResponse, 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("{\"Key\":")
        buffer.WriteString("\"")
        buffer.WriteString(queryResponse.Key)
        buffer.WriteString("\"")

        buffer.WriteString(", \"Record\":")
        // Record is a JSON object, so we write as-is
        buffer.WriteString(string(queryResponse.Value))
        buffer.WriteString("}")
        bArrayMemberAlreadyWritten = true
    }
    buffer.WriteString("]")

    fmt.Printf("get_all_components:\n%s\n", buffer.String())

    return shim.Success(buffer.Bytes())
}
answered Jul 20, 2018 by charlie_brown
• 7,710 points

selected May 7 by Omkar
Hello,

With regards to your answer, I am a bit confused by your proposed solution. The asker mentioned he is using a composite key and is asking whether there is a way to use GetStateByRange with a composite key. I have a similar problem and don´t see how your solution solves the issue given that to my understanding GetStateByRange utilizes keys, not composite keys. Is there a way of using this function along with composite keys or making the function getStateByPartialCompositeKey be queriable by range? In your solution are you suggesting changing the composite key to just be a key made of the date cause that would change functionality completely.

Yes, I think @charlie_brown means that you should change composite keys to keys with the date. 

Something like stub.GetStateByRange("Owner1_<long timestamp of (first_date)>", "Owner1_<long timestamp of (second_date)>")

Another solution I found while researching about this is to use stub.GetStateByPartialCompositeKey

Hi. How to create composite keys?

@Vincy, You can create composite keys using the CreateCompositeKey function as follows:

CreateCompositeKey(objectType string, attributes []string)(string,error)
Hi guys. I am new to hyperledger and I am following the steps mentioned in a tutorial. The steps tell that after creating the composite key I have to push it in the Blockchain. The problem is that I don't know how to do it. Please help.

Hi @Kiran. After creating the Composite keys using the CreateCompositeKey function, you will get an output. Note it. Then to push it into the Blockchain, use the below command:

PutState(key string, value []byte) error

Replace the key with the output got from the CreateCompositeKey function. 

+1 vote

Use the GetStateByRange function. The syntax for this is as follows:

GetStateByRange(startKey, endKey string)

And you will have to use the below code to get your job done. 

GetStateByRange(Owner1~15-08-2018, Owner1~20-08-2018)
answered May 7 by Kamal

Related Questions In Blockchain

0 votes
1 answer

How to get the already existing channels in Hyperledger v1.0?

You cannot see all available channels,  but you ...READ MORE

answered Jun 4, 2018 in Blockchain by Perry
• 17,010 points
184 views
0 votes
1 answer

Hyperledger Fabric: How to get transaction history using key?

history, err := stub.GetHistoryForKey(key_value) for history.HasNext() { ...READ MORE

answered Nov 20, 2018 in Blockchain by Omkar
• 67,290 points
542 views
0 votes
1 answer
0 votes
1 answer
0 votes
1 answer

Invalid Batch or signature in Savtooth

This will solve your problem import org.apache.commons.codec.binary.Hex; Transaction txn ...READ MORE

answered Aug 1, 2018 in Blockchain by digger
• 27,630 points
58 views
+1 vote
1 answer
0 votes
1 answer

Not Able to register a user with Hyperledger-Fabric v1.1 preview

The error: "Certificate not found with AKI 'e729224e8b3f31784c8a93c5b8ef6f4c1c91d9e6e577c45c33163609fe40011' ...READ MORE

answered Jun 16, 2018 in Blockchain by charlie_brown
• 7,710 points
357 views
0 votes
1 answer

How to store picture(s) in a hyperledger blockchain channel

You can hold images as encrypted characters ...READ MORE

answered Jun 16, 2018 in Blockchain by charlie_brown
• 7,710 points
129 views