Returning the preivous global state from smart contract

I am wondering if the smart contract is able to return the previous value of its global state.

For example, one contract is counting the number of opted-in users and recording the number into one of its global states. The contract, we assume, is created on round 12345, and it keeps running to round 23456. Generally, the contract records the state on round 23456, but I am curious about the number of users opted-in to contract on round 20000. So, a function that searching for the previous state of the contract is required.

Is there any function could do that kind of thing?

Saving all the values for each application is clearly cannot be done in the TEAL code itself, since the node doesn’t index all that data.
The indexer, however, might.

In the example above, you did not mention anything about what makes round 200,000 special. Do you need to look at any particular round, or just few “predefined” or periodic ones ?

Would it be acceptable to have an approximation for the value ?
i.e. round 10,000 had 40 users, round 20,000 had 50 users, so round 13,000 might have had 43 users.

Thanks for your reply @tsachi . I will answer your question here.

The reason I mention round 20000 in my previous statement is: I am taking this example to explain that the function I am looking for is expected to take the round number as input, and output the counter value (recorded in global state) at that round.

In my expectation, this function should take any valid round number as input, and output the exact result. Approximation is not acceptable here.

Until now, I have tried function “indexer.account_info” with round number as input variable. But it seems that this function returns only the latest value of the global state…

I am looking forward to your ideas and thoughts.

Hi, thank you for your continuous help! I want to ask some basic questions first to make sure that we are on the same page.

As far as I understand, Algorand is a kind of public ledger where modifications are recorded and visible to everyone. Thus, I am curious about whether it is possible to see modifications for certain round.

We have seen many APIs such as “indexer.account_info” have params of “round_num” which seems to be used to search for certain states/apps given certain round number. As mentioned here, seems this function is only enabled in dev-mode which means theoretically if we have our own indexer node we can enable this option to search for global states given certain round number?

I am just curious whether this is theoretically doable but in practice we must build our own indexer node, or this operation is not supported for some reasons?

Thank you!

A “regular” node saves only the latest 1000 rounds, so making such a request ( even if doable ) would have a very limited range.

A node can be also configured as “archival”, meaning it will keep the entire block history. However, this doesn’t give it the ability to index “when was each account modified between round 0 and now”.

That’s exactly where the indexer comes in. The indexer provide that type of indexing in an extensible schema database, allowing the end user to custimize the needed data sets.

Hi tsachi, thank you for your reply!

Yes, I understand this is tricky. I think the goal is there is an app, within this app, there is a global state called “counter”. We may want to query for the counter’s value given a previous round number. This round number is known to us and we don’t need to associate this round number with any timestamp.

So from my understanding, this is doable using a customized indexer with proper configuration and settings. Is that correct? Thanks again!

The developer mode option of the indexer is used to allow searching accounts on a previous round.

If you are just looking at the state of a single account, you do not need this option.

However, there is another limitation with the current version of the indexer: you cannot get previous application state of an account. See backend: rewind Application state · Issue #62 · algorand/indexer · GitHub

However, if you only need to count the number of accounts that opted-in your contract, you may just use the endpoint indexer /v2/transactions to get all transactions for a given application between the rounds you are interested in. And then count the opt-in.

1 Like

Hi fabrice, yes this makes sense to me. Thank you for your explanations!