3

I am trying to get all entries in the ledger (Fabric 1.4.4, using Java Chaincode):

QueryResultsIterator<KeyValue> iterator = ctx.getStub().getStateByRange("","");

But I always get an empty iterator. Is this the correct way to get all entries?

(At least a way to get all keys would work for me as then I can get states one by one, but for that I need all keys)

icordoba
  • 1,834
  • 2
  • 33
  • 60
  • This looks like the correct way. Just have a look at [this](https://github.com/hyperledger/fabric-samples/blob/master/chaincode/fabcar/java/src/main/java/org/hyperledger/fabric/samples/fabcar/FabCar.java#L152) example, just in case you are missing something while iterating. One other possible approach that you can take can be, as mentioned [here](https://stackoverflow.com/a/59201642/8308259) by just changing the event payload with the key that you are putting into the world state. – Udyan Sharma Dec 05 '19 at 19:05
  • I will check those links, thanks. The problem is that I don't have any key. SmartContract has a method that needs to iterate through all values stored to perform a checksum and return it, so I need to get all entries (or get all keys and iterate one by one, that would do the trick) – icordoba Dec 06 '19 at 07:40
  • yes, and that method is getStateByRange, which should probably work, but is somehow not working, do have a look at these links and let me know if they helped. – Udyan Sharma Dec 06 '19 at 07:56
  • I added a reply: getStateByRange("A","Z") is working for me but may not fit everyone. I think getStateByRange("","") definitely is not working or else my workaround should not work either. – icordoba Dec 06 '19 at 12:47
  • Thanks for letting me know, I now can think of one more possible way, can you please try and confirm about this, whether supplying startIndex as "" and endIndex as "~" works? – Udyan Sharma Dec 06 '19 at 12:58
  • icordoba @UdyanSharma have you found something that works? – Eduardo Pascual Aseff Jun 10 '20 at 04:39
  • 1
    @EduardoPascualAseff nothing from my end on the same. Maybe icordoba has something for us. – Udyan Sharma Jun 10 '20 at 07:07

3 Answers3

2

For some reason getStateByRange("","") is not working in Fabric Java SDK but this will work:

getStateByRange("A","Z")

(all my ids start with a capital letters so I get all entries with that)

icordoba
  • 1,834
  • 2
  • 33
  • 60
2

The problem is that getStateByRange can't return states stored using composite keys

if you use directly :

await ctx.stub.putState('objName', Buffer.from(JSON.stringify(obj)));
    

it will work

but if you use a composite key like

   let key = ctx.stub.createCompositeKey("objName", [obj]);
   await ctx.stub.putState('objName', Buffer.from(JSON.stringify(obj))); 

it will return an empty response.

The cause is that getStateByRange uses a null delimiter \u0000 delimiting the key parts and then the stored states would not be returned (e.g {"Key":"\u0000objName\u0000obj1\u0000","Record":"\u0000"} ). To read the states when a composite key is used you'll need to use getStateByPartialCompositeKey

Badr Bellaj
  • 11,560
  • 2
  • 43
  • 44
  • ``getStateByPartialCompositeKey`` works like a charm with composite keys. I wonder why documentation says nothing about the fact that ``getStateByRange`` will not work with composite keys. Also to me remains unclear the reason why ``getStateByRange`` do not support ``ChaincodeStub.createCompositeKey(String key)`` as a search pattern – Nikita Kobtsev May 17 '21 at 20:03
-3

I am not sure that returning the entire blockchain is a good idea.

Anyways, you could get the history for a single key by using

APIstub.GetHistoryForKey(id)

This will return all the transaction involved for that particular id

Riki95
  • 706
  • 1
  • 7
  • 16
  • Thanks but I do need to get all states (not really all the blockchain but at least all the keys). GetHistoryForKey(id) won't work as maybe I don't know the id to ask for. – icordoba Dec 05 '19 at 17:43