Navid | Flow 4D (2024-07-02)
I'm planning to analyze all accounts to check for a certain stored object. To put it in another way, I'm trying to take a snapshot of all holders of an asset on Cadence side.
The normal way I would do this is to iterate through all accounts (account 0, account 1, etc) and run a batched script to fetch the data I need from an AN. Given the number of accounts on mainnet, this might be inefficient.
Is there an easy way to do the same thing locally using a state snapshot? Any docs or examples are appreciated.
4 Replies
I've created a thread for your message. Please continue any relevant discussion in this thread.
You can rename this thread using
/title <new title>
If this is a technical question that others may benefit from, considering also asking it on Stackoverflow: https://stackoverflow.com/questions/ask?tags=onflow-cadenceYes, please ping me again tomorrow here and on slack
Unknown User•5mo ago
Message Not Public
Sign In & Join Server To View
You can analyze the state "locally" (rather, off-chain – see notes about machine required below).
1. Get a state snapshot. Maybe ask the protocol team how / where to get it, I usually ask them to provide it. This might be documented somewhere. cc @leo
2. Load the snapshot.
- This means loading all registers of the snapshot's trie into memory. This might require few hundred GB (!) for MN and a couple hundred GB for TN
- You can get inspiration from existing tools/commands that do that, for example:
- https://github.com/onflow/flow-go/blob/master/cmd/util/cmd/read-execution-state/list-accounts/cmd.go
- https://github.com/onflow/flow-go/blob/master/cmd/util/cmd/diff-states/cmd.go. There are utility functions like
util.ParseStateCommitment
, util.ReadTrie
, etc.
3. Get an interpreter / storage for the registers.
- You can e.g. use the migration code's NewInterpreterMigrationRuntime
4. Use the interpreter / storage to traverse the state.
- If you want to run a Cadence script, you can use similar code to NewTransactionBasedMigration
: it takes registers, sets up FVM, and runs a TX. In your case pass a fvm.Script
- If you want to use Go, you can access the interpreter's storage, get/iterate over accounts, their storage maps, etc. To traverse Cadence values (containers like arrays, dictionaries, composites) you can use utilities like interpreter.InspectValue
LMK if you have any questions