2

I have stored data that I would like to retrieve from a deployed smart-contract.

The storage structure was defined using SmartPy:

    def __init__(self):
      self.init(bmap=sp.big_map(tkey=sp.TString,tvalue=(sp.TInt,sp.TInt),
        ad1=sp.address("tz1ad1"),ad2=sp.address("tz1ad2"),active=sp.address("ad1"))

The answer of this post seems to be along the right lines but is no longer valid. If possible, a solution should also return a JSON object as this would be desirable.

I would like to retrieve the data stored in the sp.big_map and three sp.address containers.

There are a fixed 32 items in bmap and it's accessible via an explorer such as better-call.dev

Any help is much appreciated!

2 Answers 2

6

As of the current Babylon protocol and the upcoming Carthage, the RPC only provides you the ability to retrieve the value for a known key that you provide to the RPC. But even in this scenario you need to provide not the readable key you stored, but a hash of that key as that is how it is represented internally. This answer describes how to call the RPC

The RPC does not provide a means to "get all keys" or to "get all values". To accomplish this you must do an impractical amount of parsing so it is recommended that you use either an indexer or a library to do most of the work for you.

For single key lookup, Taquito library allows you to do the following:

const contract = await Tezos.contract.at("KT1...")
const storage = await contract.storage()
const bigMapDetail = await storage.namedbigmap.get("readable lookup key")

Read more on Taquito and big maps at https://medium.com/tezoscommons/new-taquito-release-now-with-bigmaps-7d7352351af4

To get all the values, the tzStats indexer provides an easy to use API (soon other indexers are likely to add this as well). Example TzStats call to get all the values out of a contract with a big map:

curl "https://api.tzstats.com/explorer/bigmap/17/values"

Read more on tzStats big map support at https://tzstats.com/blog/tezos-smart-contract-apis/

You can also use PyTezos "big_map_get" to do some of the heavy lifting for you if you don't want to rely on an indexer. https://baking-bad.github.io/pytezos/

4
  • Thanks for this. Using tzstats suits my case but it is throwing a CORS error when I try to retrieve the json. Is there a way to implement the $.getJSON(https://api.babylonnet.tzstats.com/explorer/contract/{kt}/storage.. function? Appending ?callback=? doesn't seem to get this to work. Jan 28, 2020 at 20:02
  • if you are going to call it from a browser based script you will need to get your calling domain whitelisted for CORS by the provider of the server endpoint you are using. Message Alex at [email protected]
    – cousinit
    Jan 28, 2020 at 21:26
  • I believe Alex provided the second answer, hopefully he will respond soon. I am proxying requests with cors-anywhere to complete the prototype. Jan 28, 2020 at 21:34
  • We have no plans to implement JSONP. You can run your own copy of our indexer which supports CORS headers out of the box or send me a request to get whitelisted on our public API. Jan 29, 2020 at 21:11
3

We maintain an index of all historic bigmap data at TzStats. To fetch all current keys and values in a bigmap call

https://api.tzstats.com/explorer/bigmap/:id/values

If your bigmap is very large you can page through the result with limit and offset parameters (default is 100 entries, max is 500). See our bigmap docu for more details and examples.

If you prefer using the Tezos RPC read this answer. Right now the RPC fetches a single bigmap key per call only and you need to know the script expression hash of your key.

3
  • Hi Alex, I wish to return all bigmap values in a single request. After contract deployment the full bigmap is shown using ../explorer/contract/{hash}/storage but after an update it shows only the bigmap id. I tried ../explorer/bigmap/{id}/values but this produces 20 entries. How would I fetch all key/values (only 32)? Many thanks. Jan 30, 2020 at 16:32
  • I appended the limit parameter to up from default (20 entries). Jan 30, 2020 at 16:44
  • 1
    You found it yourself, good. The ../explorer/bigmap/{id}/values endpoint like all other listing endpoints under ../explorer support paging using offset and limit. Max limit is 100. One important issue is that between two paged calls the chain can advance or reorganize. For stable paging (not-influenced by new blocks) use an additional parameter block={hash|height} which effectively locks your call to a specific point in history. Benefit is that if the chain reorged between calls you get a 409 error, so you know all previous pages are stale. Feb 2, 2020 at 18:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.