Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 17 additions & 13 deletions docs/build/guides/storage/choosing-the-right-storage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Examples of data that may be stored on persistent storage include user balances,
Let's look at a contract for a loyalty points system where users can accumulate points and redeem them for rewards. Each user's point balance will be stored in persistent storage.

```rust
use soroban_sdk::{contractimpl, contracttype, Address, Env};
use soroban_sdk::{contract, contractimpl, contracttype, Address, Env};

#[contracttype]
pub enum DataKey {
Expand Down Expand Up @@ -97,12 +97,14 @@ Instance storage is best suited for data that has a well-known size limit and is
Let's look at additional functions for the loyalty points contract from the previous section, specifically the functions that define the contract admin and add points to the users:

```rust
use soroban_sdk::{contractimpl, Address, Env};
use soroban_sdk::{contractimpl, contracttype, Address, Env};

// This is the `DataKey` from the previous section, with `Admin` added. Declare
// it only once in your contract.
#[contracttype]
pub enum DataKey {
Points(Address),
Admin
Admin,
}

#[contractimpl]
Expand Down Expand Up @@ -152,10 +154,10 @@ It is also unsafe to rely on an entry expiring as it can be extended by anyone.

Temporary storage is best suited for easily replaceable data, or data that is only relevant within a certain time period. For example, oracle price feed data that is only relevant for a few minutes, or limited time authorizations such as token allowances, session tokens, auctions, timelocks, etc. Nonces for the Soroban signatures are also stored in the temporary storage, at least until the signature itself expires.

Let's look at how temporary storage may be implemented in a contract that runs auctions periodically, and users can place bids that are only valid only until some user-defined time point:
Let's look at how temporary storage may be implemented in a contract that runs auctions periodically, and users can place bids that are valid only until some user-defined time point:

```rust
use soroban_sdk::{contracttype, contractimpl, Env, Address};
use soroban_sdk::{contract, contractimpl, contracttype, Address, Env};

#[contracttype]
pub enum DataKey {
Expand All @@ -171,6 +173,9 @@ pub struct Bid {
expiration_ledger_seq: u32,
}

#[contract]
pub struct AuctionContract;

#[contractimpl]
impl AuctionContract {
// This function lets a user place a bid that lives only until the auction ends.
Expand All @@ -185,29 +190,28 @@ impl AuctionContract {
});
// Compute the TTL that the bid requires.
let bid_ttl = bid_expiration_ledger_seq
.checked_sub(e.ledger().sequence())
.checked_sub(env.ledger().sequence())
.unwrap();
// Extend the TTL for the bid, such that it's guaranteed to live at
// least until the `bid_expiration_ledger_seq` that the user has
// requested. This operation is will fail in
// case if extension is longer than the protocol allows, so there is
// no need to further validate `bid_ttl`.
// requested. This operation will fail if the extension is longer than
// the protocol allows, so there is no need to further validate
// `bid_ttl`.
env.storage().temporary().extend_ttl(&bid_key, bid_ttl, bid_ttl);
}

// This function returns a user's bid (0 if it has expired).
pub fn get_bid(env: Env, user: Symbol) -> i64 {
let maybe_bid: Bid = env.storage().temporary().get(&DataKey::Bid(user));
pub fn get_bid(env: Env, user: Address) -> i128 {
let maybe_bid: Option<Bid> = env.storage().temporary().get(&DataKey::Bid(user));
if let Some(bid) = maybe_bid {
if bid.expiration_ledger_seq <= e.ledger().sequence() {
if bid.expiration_ledger_seq >= env.ledger().sequence() {
bid.value
} else {
// Even though the entry is still in the storage, it has
// logically expired. Somebody must have extended the entry in
// order to trick our contract, so return 0.
0
}

} else {
// There is no bid for the user - it either hasn't existed at all,
// or has been removed from the temporary storage. In either case,
Expand Down
Loading