DEV Community

yuzurush
yuzurush

Posted on • Updated on

Soroban Contracts 101 : Storing Data

Hi there! Welcome to my second post of my series called "Soroban Contracts 101", where I'll be explaining the basics of Soroban contracts, such as data storage, authentication, custom types, and more. All the code that we're gonna explain throughout this series will mostly come from soroban-contracts-101 github repository.

In this second post of the series, I'll be covering soroban contract storing data funcionalities.

The Contract Code

const COUNTER: Symbol = symbol!("COUNTER");

pub struct IncrementContract;

#[contractimpl]
impl IncrementContract {
    pub fn increment(env: Env) -> u32 {
        let mut count: u32 = env
            .storage()
            .get(COUNTER)
            .unwrap_or(Ok(0)) // If no value set, assume 0.
            .unwrap(); // Panic if the value of COUNTER is not u32.
        log!(&env, "count: {}", count);
        count += 1;
        env.storage().set(COUNTER, count);
        count
    }
}
Enter fullscreen mode Exit fullscreen mode

A constant symbol called COUNTER defined. This will be used as the key to store and retrieve our counter value from storage.
const COUNTER: Symbol = symbol!("COUNTER");
So COUNTER will be our persistent, unique key to store and retrieve the counter value.

Then a struct named IncrementContract defined, this is our contract name.

The increment function is the main function of the smart contract. It takes an Env object as an argument, which provides access to the blockchain and other necessary functions. The function does the following :

  • The function will gets the current counter value from storage, or defaults to 0 if no value is set yet (using env.storage().get() and unwrap_or()).
  • Logs the current count
  • Increments the count
  • Stores the incremented count back to storage (using env.storage().set())
  • Returns the incremented count

So each call to increment function will increment the counter and return the new value, storing it persistently in blockchain storage using the COUNTER key.

The Test Code

#[test]
fn test() {
    let env = Env::default();
    let contract_id = env.register_contract(None, IncrementContract);
    let client = IncrementContractClient::new(&env, &contract_id);

    assert_eq!(client.increment(), 1);
    assert_eq!(client.increment(), 2);
    assert_eq!(client.increment(), 3);
}
Enter fullscreen mode Exit fullscreen mode

This code is a unit test for our IncrementContract. It does the following:

  • Creates a default Env (environment) for testing
  • Registers the IncrementContract with the environment using the contract type
  • Creates an IncrementContractClient which can be used to call methods on our contract.
  • Calls increment function three times and asserts that it returns the expected values (1, then 2, then 3).

So this is a simple test which deploys our contract and calls the increment method a few times to check that it is incrementing correctly.

Running Contract Tests

To ensure that the contract functions as intended, you can run the contract tests using the following command:

cargo test -- --nocapture
Enter fullscreen mode Exit fullscreen mode

If the tests are successful, you should see an output similar to:

running 1 test
count: U32(0)
count: U32(1)
count: U32(2)
test test::test ... ok
Enter fullscreen mode Exit fullscreen mode

Building The Contract

To build the contract, use the following command:

cargo build --target wasm32-unknown-unknown --release
Enter fullscreen mode Exit fullscreen mode

This should output a .wasm file in the ../target directory:

../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm
Enter fullscreen mode Exit fullscreen mode

Invoking The Contract

To invoke the increment function of the contract, use the following command with Soroban-CLI:

soroban contract invoke \
    --wasm ../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \
    --id 1 \
    -- \
    increment
Enter fullscreen mode Exit fullscreen mode

You should see the following output:

1
Enter fullscreen mode Exit fullscreen mode

When you invoke the contract for the second time,you will get the following output:

2
Enter fullscreen mode Exit fullscreen mode

So each call to increment function will increment a counter stored in the contract's storage, and return the new incremented value.

Conclusion

In this second post of the series, we explained one of many soroban contracts functionality which is Storing Data. We hope this article has given you an idea of how Soroban Contracts storing and retrieving data. Stay tuned for more post in this "Soroban Contracts 101" Series where we will dive deeper into Soroban Contracts and their functionalities.

Top comments (0)