Struct soroban_sdk::storage::Storage
source · pub struct Storage { /* private fields */ }
Expand description
Storage stores and retrieves data for the currently executing contract.
All data stored can only be queried and modified by the contract that stores it. Contracts cannot query or modify data stored by other contracts.
There are three types of storage - Temporary, Persistent, and Instance.
Temporary entries are the cheaper storage option and are never in the Expired State Stack (ESS). Whenever a TemporaryEntry expires, the entry is permanently deleted and cannot be recovered. This storage type is best for entries that are only relevant for short periods of time or for entries that can be arbitrarily recreated.
Persistent entries are the more expensive storage type. Whenever a persistent entry expires, it is deleted from the ledger, sent to the ESS and can be recovered via an operation in Stellar Core. Only a single version of a persistent entry can exist at a time.
Instance storage is used to store entries within the Persistent contract instance entry, allowing users to tie that data directly to the TTL of the instance. Instance storage is good for global contract data like metadata, admin accounts, or pool reserves.
Examples
use soroban_sdk::{Env, Symbol};
let storage = env.storage();
let key = symbol_short!("key");
storage.persistent().set(&key, &1);
assert_eq!(storage.persistent().has(&key), true);
assert_eq!(storage.persistent().get::<_, i32>(&key), Some(1));
Implementations§
source§impl Storage
impl Storage
sourcepub fn persistent(&self) -> Persistent
pub fn persistent(&self) -> Persistent
Storage for data that can stay in the ledger forever until deleted.
Persistent entries might expire and be removed from the ledger if they run out of the rent balance. However, expired entries can be restored and they cannot be recreated. This means these entries behave ‘as if’ they were stored in the ledger forever.
This should be used for data that requires persistency, such as token balances, user properties etc.
sourcepub fn temporary(&self) -> Temporary
pub fn temporary(&self) -> Temporary
Storage for data that may stay in ledger only for a limited amount of time.
Temporary storage is cheaper than Persistent storage.
Temporary entries will be removed from the ledger after their lifetime ends. Removed entries can be created again, potentially with different values.
This should be used for data that needs to only exist for a limited period of time, such as oracle data, claimable balances, offer, etc.
sourcepub fn instance(&self) -> Instance
pub fn instance(&self) -> Instance
Storage for a small amount of persistent data associated with the current contract’s instance.
Storing a small amount of frequently used data in instance storage is likely cheaper than storing it separately in Persistent storage.
Instance storage is tightly coupled with the contract instance: it will be loaded from the ledger every time the contract instance itself is loaded. It also won’t appear in the ledger footprint. All the data stored in the instance storage is read from ledger every time the contract is used and it doesn’t matter whether contract uses the storage or not.
This has the same lifetime properties as Persistent storage, i.e. the data semantically stays in the ledger forever and can be expired/restored.
The amount of data that can be stored in the instance storage is limited by the ledger entry size (a network-defined parameter). It is in the order of 100 KB serialized.
This should be used for small data directly associated with the current contract, such as its admin, configuration settings, tokens the contract operates on etc. Do not use this with any data that can scale in unbounded fashion (such as user balances).
sourcepub fn max_ttl(&self) -> u32
pub fn max_ttl(&self) -> u32
Returns the maximum TTL (number of ledgers that an entry can have rent paid for it in one moment).
When counting the number of ledgers an entry is active for, the current ledger is included. If an entry is created in the current ledger, its maximum live_until ledger will be the TTL (value returned from the function) plus the current ledger. This means the last ledger that the entry will be accessible will be the current ledger sequence plus the max TTL minus one.
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Storage
impl !Send for Storage
impl !Sync for Storage
impl Unpin for Storage
impl !UnwindSafe for Storage
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T, U, V, E, C> Compare<(T, U, V)> for Cwhere
C: Compare<T, Error = E, Error = E, Error = E> + Compare<U> + Compare<V>,
impl<T, U, V, E, C> Compare<(T, U, V)> for Cwhere
C: Compare<T, Error = E, Error = E, Error = E> + Compare<U> + Compare<V>,
§impl<T, U, V, W, E, C> Compare<(T, U, V, W)> for Cwhere
C: Compare<T, Error = E, Error = E, Error = E, Error = E> + Compare<U> + Compare<V> + Compare<W>,
impl<T, U, V, W, E, C> Compare<(T, U, V, W)> for Cwhere
C: Compare<T, Error = E, Error = E, Error = E, Error = E> + Compare<U> + Compare<V> + Compare<W>,
type Error = E
fn compare( &self, a: &(T, U, V, W), b: &(T, U, V, W) ) -> Result<Ordering, <C as Compare<(T, U, V, W)>>::Error>
§impl<T, U, V, W, X, E, C> Compare<(T, U, V, W, X)> for Cwhere
C: Compare<T, Error = E, Error = E, Error = E, Error = E, Error = E> + Compare<U> + Compare<V> + Compare<W> + Compare<X>,
impl<T, U, V, W, X, E, C> Compare<(T, U, V, W, X)> for Cwhere
C: Compare<T, Error = E, Error = E, Error = E, Error = E, Error = E> + Compare<U> + Compare<V> + Compare<W> + Compare<X>,
type Error = E
fn compare( &self, a: &(T, U, V, W, X), b: &(T, U, V, W, X) ) -> Result<Ordering, <C as Compare<(T, U, V, W, X)>>::Error>
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.