- Read stored value from the ledger data
- Read stored value by calling a smart contract function
- Read the balance of an account
1. Create a default project
Before getting into creating a ledger snapshot and getting into the testing, let’s first create a simple smart contract that can be used for the test examples. Get started by creating the default Hello World contract:set_value() for storing a value, and get_value() for reading the value from storage. Replace the default hello() function with these two functions:
Build contract
Use the Stellar CLI to build the contract:Deploy contract
Next, we deploy the contract to Testnet:CB5QCALXDP2N6H473AQBNIFEAPCNHWCIWOASRNGTHCSC4WNC3SOROBAN), which will be used in the following steps.
####Invoke contract
Finally, we invoke the set_value() function to store a value on the Testnet ledger:
get_value() function.
2. Create a ledger snapshot
A snapshot of the ledger can be created using the Stellar CLI. The CLI command allows you to customize and limit the scope of the snapshot, since it’s most likely not necessary for you to create a snapshot of all ledger entries. See the documentation for full details about how to limit the snapshot. For the examples used here, we want to limit the ledger snapshot to include entries related to:- The smart contract
- The user
alice - The native token address (XLM)
snapshot.json.
This is a sample of the snapshot, which shows the value stored when the contract function set_value() was invoked:
set_value() is invoked again, run the stellar snapshot create command again to ensure the snapshot reflects the ledger.
3. Read stored values and balances
To illustrate how smart contract tests can utilize the ledger snapshot data, we will read the stored value in two different ways and get the balance of the useralice.
Loading snapshot data
As a starting point, we use the test filetest.rs included in the default smart contract project we created and modified. Since the hello() function was removed and replaced with the functions to store and get a value, the test for hello() can also be removed.
First, the ledger snapshot data is loaded into the environment:
Read stored value from the ledger
In this first example, we read the stored value directly from the ledger usingenv.storage(). The method env.as_contract() allows us to execute code in the context of a given contract ID. This means we can execute code as if we were inside the contract.
First, we define the contract ID for the test, which is the contract ID returned when the smart contract was deployed.
Then env.as_contract() is used to get the value from storage, which means from the ledger. When the contract function set_value() was invoked, we used count as the key, so the same key is used to get the value.
123456, and the value is checked by assert_eq!(). If the test doesn’t pass, the test will panic.
Read stored value with contract function
The more typical way of reading a stored value in tests is to call the contract function that reads the value. The test for this approach is the same as if the default environment were loaded, except we don’t need to register the contract in the test; we use a real contract ID, like in the previous example, because in the ledger snapshot, the value is tied to the specific contract ID.Read account balance
In this last example, we want to read the balance of an account. It can be the balance of a user account or of a smart contract - any account that can hold a balance. In this example, we check the balance of the user accountalice.
In this example, we assume that alice already has a balance in XLM, and since the examples are based on Testnet, the alice account was funded by FriendBot if this guide was followed while creating the account. The address of alice can be looked up by running this command:
TokenClient.
Then we define the address of the account we want to look up the balance of, and call client.balance() with the account address as the argument.