> ## Documentation Index
> Fetch the complete documentation index at: https://developers.stellar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# 3. Storing Data

> Follow along with the increment example to write a simple contract that stores and retrieves data on the Stellar network. Learn about storage and TTL.

Now that we've built a basic Hello World example contract, we'll write a simple contract that stores and retrieves data. This will help you see the basics of Soroban's storage system.

This is going to follow along with the [increment example](https://github.com/stellar/soroban-examples/tree/v22.0.1/increment), which has a single function that increments an internal counter and returns the value. If you want to see a working example, [try it in Devcontainers](https://github.com/codespaces/new?repo=stellar/soroban-examples\&editor=web).

This tutorial assumes that you've already completed the previous steps in Getting Started: [Setup](https://developers.stellar.org/docs/build/smart-contracts/getting-started/setup.md), [Hello World](https://developers.stellar.org/docs/build/smart-contracts/getting-started/hello-world.md), and [Deploy to Testnet](https://developers.stellar.org/docs/build/smart-contracts/getting-started/deploy-to-testnet.md).

## Adding the increment contract

In addition to creating a new project, the `stellar contract init` command also allows us to initialize a new contract workspace within an existing project. In this example, we're going to initialize a new contract and use the `--name` flag to specify the name of our new contract, `increment`.

This command will not overwrite existing files unless we explicitly pass in the `--overwrite` flag. From within our `soroban-hello-world` directory, run:

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract init . --name increment
```

This creates a new `contracts/increment` directory with placeholder code in `src/lib.rs` and `src/test.rs`, which we'll replace with our new increment contract and corresponding tests.

```
└── contracts
    ├── increment
        ├── Cargo.toml
        ├── Makefile
        └── src
            ├── lib.rs
            └── test.rs
```

We will go through the contract code in more detail below, but for now, replace the placeholder code in `contracts/increment/src/lib.rs` with the following.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
#![no_std]
use soroban_sdk::{contract, contractimpl, log, symbol_short, Env, Symbol};

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

#[contract]
pub struct IncrementContract;

#[contractimpl]
impl IncrementContract {
    /// Increment increments an internal counter, and returns the value.
    pub fn increment(env: Env) -> u32 {
        let mut count: u32 = env.storage().instance().get(&COUNTER).unwrap_or(0);
        log!(&env, "count: {}", count);

        count += 1;
        env.storage().instance().set(&COUNTER, &count);
        env.storage().instance().extend_ttl(50, 100);

        count
    }
}

mod test;
```

### Imports

This contract begins similarly to our Hello World contract, with an annotation to exclude the Rust standard library, and imports of the types and macros we need from the `soroban-sdk` crate.

```rust title="contracts/increment/src/lib.rs" theme={"theme":{"light":"github-light","dark":"github-dark"}}
#![no_std]
use soroban_sdk::{contract, contractimpl, log, symbol_short, Env, Symbol};
```

### Contract Data Keys

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
const COUNTER: Symbol = symbol_short!("COUNTER");
```

Contract data is associated with a key, which can be used at a later time to look up the value.

`Symbol` is a short (up to 32 characters long) string type with limited character space (only `a-zA-Z0-9_` characters are allowed). Identifiers like contract function names and contract data keys are represented by `Symbol`s.

The `symbol_short!()` macro is a convenient way to pre-compute short symbols up to 9 characters in length at compile time using `Symbol::short`. It generates a compile-time constant that adheres to the valid character set of letters (a-zA-Z), numbers (0-9), and underscores (\_). If a symbol exceeds the 9-character limit, `Symbol::new` should be utilized for creating symbols at runtime.

### Contract Data Access

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let mut count: u32 = env
    .storage()
    .instance()
    .get(&COUNTER)
    .unwrap_or(0); // If no value set, assume 0.
```

The `Env.storage()` function is used to access and update contract data. The executing contract is the only contract that can query or modify contract data that it has stored. The data stored is viewable on ledger anywhere the ledger is viewable, but contracts executing within the Soroban environment are restricted to their own data.

The `get()` function gets the current value associated with the counter key.

If no value is currently stored, the value given to `unwrap_or(...)` is returned instead.

Values stored as contract data and retrieved are transmitted from [the environment](https://developers.stellar.org/docs/learn/fundamentals/contract-development/environment-concepts.md) and expanded into the type specified. In this case a `u32`. If the value can be expanded, the type returned will be a `u32`. Otherwise, if a developer cast it to be some other type, a panic would occur at the unwrap.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
env.storage()
    .instance()
    .set(&COUNTER, &count);
```

The `set()` function stores the new count value against the key, replacing the existing value.

### Managing Contract Data TTLs with `extend_ttl()`

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
env.storage().instance().extend_ttl(100, 100);
```

All contract data has a Time To Live (TTL), measured in ledgers, that must be periodically extended. If an entry's TTL is not periodically extended, the entry will eventually become "archived." You can learn more about this in the [State Archival](https://developers.stellar.org/docs/learn/fundamentals/contract-development/storage/state-archival.md) document.

For now, it's worth knowing that there are three kinds of storage: `Persistent`, `Temporary`, and `Instance`. This contract only uses `Instance` storage: `env.storage().instance()`. Every time the counter is incremented, this storage's TTL gets extended by 100 [ledgers](https://developers.stellar.org/docs/learn/fundamentals/stellar-data-structures/ledgers.md), or about 500 seconds.

### Build the contract

From inside `soroban-hello-world`, run:

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract build
```

Check that it built:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
ls target/wasm32v1-none/release/*.wasm
```

You should see both `hello_world.wasm` and `increment.wasm`.

## Tests

Replace the placeholder code in `contracts/increment/src/test.rs` with the following increment test code.

```rust title="contracts/increment/src/test.rs" theme={"theme":{"light":"github-light","dark":"github-dark"}}
#![cfg(test)]
use crate::{IncrementContract, IncrementContractClient};
use soroban_sdk::Env;

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

    assert_eq!(client.increment(), 1);
    assert_eq!(client.increment(), 2);
    assert_eq!(client.increment(), 3);
}
```

This uses the same concepts described in the Hello World example.

Make sure it passes:

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
cargo test
```

You'll see that this runs tests for the whole workspace; both the Hello World contract and the new Increment contract.

If you want to see the output of the `log!` call, run the tests with `--nocapture`:

```
cargo test -- --nocapture
```

You should see the the diagnostic log events with the count data in the output:

```
running 1 test
[Diagnostic Event] contract:CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM,
    topics:[log],
    data:["count: {}", 1]
[Diagnostic Event] contract:CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM,
    topics:[log],
    data:["count: {}", 2]
[Diagnostic Event] contract:CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM,
    topics:[log],
    data:["count: {}", 3]
test test::test ... ok
```

## Take it further

Can you figure out how to add `get_current_value` function to the contract? What about `decrement` or `reset` functions?

## Summary

In this section, we added a new contract to this project, that made use of Soroban's storage capabilities to store and retrieve data. We also learned about the different kinds of storage and how to manage their TTLs.

Next we'll learn a bit more about deploying contracts to Soroban's Testnet network and interact with our incrementor contract using the CLI.
