Jettons lock production case
Our team started dTON GraphQL as a tool to enable complex interactions with TON data. If you are developing smart contracts or any on-chain service to work with TON, you are already immersed in this complex architecture, thanks to which we expect to bring blockchain to mass adoption.
With this case study we want to show how to work with TON in a simpler way and get better results.
TON consists of workchain, shards, accounts. For each of the shards blocks are generated, in each block for each account transactions of this account are available.
Each transaction is represented by 1 input message and up to 255 output messages and the state of account at the end of this transaction. It is important to remember that the transaction of an account = the state of the account at that logical point in time for that account.
How are TON concepts used in dTON GraphQL?
We deliver a single interface for all workcahin / shards. But we share 2 main points.
- raw_transactions - table where for each account is available the history of all transactions for all time.
- raw_account_states - table where the last transaction with the current account status is available (actual account state).
Each method consists of:
Fields:
- TLB information of the block at the time of the transaction (e.g. seqno block, workchain, etc., the entire TLB structure of the block is available for each transaction)
- TLB information of the transaction itself, the main things we can highlight are:
- Storage / Credit / Computation / Computation / Action / Bounce Phases
- In / out messages
- Account state (code / data / etc. on the end of transaction)
- Trace information (parent transactions)
- Special parsed info (native support of get methods for NFT, Jettons, etc.)
Filters by fields:
All fields described above can be combined and used for filtering of necessary transactions. The most common use cases are searching for transactions by OP codes, by code hash, in message body hash, etc.
Also, each method has the ability to aggregate, which allows you to solve complex production problems.
Let's look at an example of a product challenge: finding lock smart contracts for Jetton wallets
The easiest way to write dTON Graphql queries is the interface: https://dton.io/graphql, which we will use to write custom queries to the TON blockchain.
First, we need to define the underlying data we will be searching. We have lock smart contract that freeze Jetton tokens and give them away once at some interval.
The smart contract code has the hash: 12D793F9C449BEF45C7BB43685DE21D4E03C7118B5D38F0BF3C7B9BEB497900D
Let's go through it in detail:
- raw_transactions is the name of the method we are using.
- Then we pass to it the account_state_state_init_code_hash filter, which filters only transactions where the smart contract state has this code hash. Filters can be flexible, for example we can filter using the operators: gt (>), gte (>=), lt (<), lte (<=), in, or, and, not. You can read more about filters in the docs.
Next we pass a set of fields that we want to get from the blockchain, in our case:
- workchain / address - fields representing the address of the smart contract. If we combine them into workchain:address we get the RAW address of the smart contract, by which we can find it in other explorers.
- txhash: hash - the hash field is a unique hash of a particular transaction by which it can be identified. The `txhash:` prefix is needed to overwrite the key value in the response.
- Gen_utime - time of block creation in which the transaction was executed
- Account_state_state_init_data - cell, the state of smart contract data at the moment of transaction termination (C4 register of smart contract, what is saved when set_data occurs).
At this point we can make sure that the smart contracts we found through the https://dton.io/graphql interface are the smart contracts we need, they have the correct data and addresses.
Jetton data aggregation
In its raw form this data is not very valuable, let's try to enhance our query to understand: how many lock contracts of tokens exist in total?
To do this, let's run the following query:
Let's analyze it in detail.
- groupAccountStates is the name of the method for grouping the actual states (recent transactions) for all accounts in the network. Read more: https://docs.dton.io/aggregations In short, the method allows you to make a sql analogue of GROUP BY on arbitrary fields using arbitrary aggregators.
- by: [‘account_state_state_init_code_hash’] - grouping keys, by which fields we aggregate values, in our case we want to find all unique smart contracts with jetton lock code hash.
- filter_by - filter set (based on the example from raw_transactions above). Since we are using a table of actual account states we add account_deleted: 0 filter to remove all deleted accounts in the network.
- aggregations: [{field: ‘account_state_state_init_code_hash’, operation: ‘count’}] - set of aggregations. In this case, we want to see the number of actual accounts with this code_hash.
- Account_state_state_init_code_hash / account_state_state_init_code_hash__count as fields allow us to get the necessary information.
Example answer: "account_state_state_init_code_hash__count": 4613
That it, there are currently 4613 actual smart contracts on the network using code-hash Jetton Lock smart contract.
- parsed_jetton_owner_code_hash - allows making filter on code_hash of Jetton wallet owner.
- parsed_jetton_wallet_balance - allows getting the balance of jetton wallet at the moment of transaction (actual moment for account_states table).
- parsed_jetton_wallet_jetton_address_address__friendly - allows identifying Jetton master smart contract for the wallet, i.e. get Jetton type.
As a result, we will get information about how many Jettons are locked, on how many smart contracts and for which Jetton, sorted by locked amount of tokens.