pub struct StorageKey<T> {
    /// The key of the 32-byte-long storage slot.
    slot: b256,
    /// The offset, *in words*, starting from the beginning of the `slot`.
    offset: u64,
    /// The unique identifier for the storage slot being referred to, used by zero-sized _storage types_.
    field_id: b256,
}
Expand description

Describes a location in storage, made of slots of 32 bytes in size,
at which a value of type T can be read or written.

Additional Information

The location in storage is specified by the b256 key of a particular storage slot and an
offset, given in words, from the start of that slot. The parameter T is the type of
the data to be read from or written to at the offset.

The T must be a non-zero-sized type in order to be written to or read from storage.

Depending on the size of T and the offset, reading or writing a value of type T
may require accessing multiple consecutive storage slots.

A value can share the slot with another values within the same storage slot.

If T is a zero-sized type, no storage access will occur. Moreover, if T is a zero-sized type,
StorageKey will assume that it is a storage type, i.e., a type that provides a custom access
to the storage. StorageVec, StorageString, and StorageBytes given in the Sway
standard library are all examples of storage types.

The field_id is a unique identifier for the storage slot being referred to.
It is used for zero-sized storage types to differentiate between multiple zero-sized storage entries
that might live at the same storage location but represent different storage constructs.

Fields

slot: b256

The key of the 32-byte-long storage slot.

offset: u64

The offset, in words, starting from the beginning of the slot.

field_id: b256

The unique identifier for the storage slot being referred to, used by zero-sized storage types.

Trait Implementations

pub fn abi_encode(self, buffer: Buffer) -> Buffer

pub fn is_encode_trivial() -> bool

pub fn abi_decode(refmut buffer: BufferReader) -> Self

pub fn is_decode_trivial() -> bool

pub fn fmt(
self,
refmut _f: Formatter,
)

pub fn new(slot: b256, offset: u64, field_id: b256) -> Self

Creates a new StorageKey.

Arguments

  • slot: [b256] - The key of the location in storage where the value will be stored.
  • offset: [u64] - The offset, in words, from the start of the slot at which the value will be stored.
  • field_id: [b256] - A unique identifier used by zero-sized storage types.

Returns

  • [StorageKey] - The newly created StorageKey.

Examples

use std::hash::sha256;

fn foo() {
    let key = StorageKey::<u64>::new(b256::zero(), 0, sha256(b256::zero()));
    assert_eq(key.slot(), b256::zero());
    assert_eq(key.offset(), 0);
    assert_eq(key.field_id(), sha256(b256::zero()));
}

pub fn slot(self) -> b256

Returns the storage slot key.

Returns

  • [b256] - The key of the storage slot that this StorageKey points to.

Examples

use std::hash::sha256;

fn foo() {
    let key = StorageKey::<u64>::new(b256::zero(), 0, sha256(b256::zero()));
    assert_eq(key.slot(), b256::zero());
}

pub fn offset(self) -> u64

Returns the offset, in words, from the start of the slot, at which the value will be stored.

Returns

  • [u64] - The offset from slot, in words, that this StorageKey points to.

Examples

use std::hash::sha256;

fn foo() {
    let key = StorageKey::<u64>::new(b256::zero(), 0, sha256(b256::zero()));
    assert_eq(key.offset(), 0);
}

pub fn field_id(self) -> b256

Returns the storage slot field id.

Returns

  • [b256] - The field id for this StorageKey.

Examples

use std::hash::sha256;

fn foo() {
    let key = StorageKey::<u64>::new(b256::zero(), 0, sha256(b256::zero()));
    assert_eq(key.field_id(), sha256(b256::zero()));
}

pub fn zero() -> Self

Creates and returns a new zero value for the StorageKey<T> type.

Returns

  • [StorageKey] -> The zero value for the StorageKey<T> type.

Examples

fn foo() {
    let zero_storage_key: StorageKey<u64> = StorageKey::zero();
    assert_eq!(zero_storage_key.slot(), b256::zero());
    assert_eq!(zero_storage_key.offset(), 0);
    assert_eq!(zero_storage_key.field_id(), b256::zero());
}

pub fn is_zero(self) -> bool

Returns whether a StorageKey<T> is equal to its zero value.

Returns

  • [bool] -> True if the StorageKey<T> is equal to its zero value, otherwise false.

Examples

fn foo() {
    let zero_storage_key: StorageKey<u64> = StorageKey::zero();
    assert(zero_storage_key.is_zero());
}

pub fn read(self) -> T

Reads a value of type T starting at the location specified by self. If the value
crosses the boundary of a 32-byte-long storage slot, reading continues at the following slot.

Returns

  • [T] - Returns the value previously stored, if the storage reads were
    valid and contain a value.

Number of Storage Accesses

  • Reads: 1

Reverts

  • When T is a zero-sized type.
  • When any of the storage slots to read from do not contain a value.

Examples

fn foo() {
    let key: StorageKey<u64> = StorageKey::new(b256::zero(), 2, b256::zero());
    // Reads the third word from the storage slot with key 0x000...0.
    let _: u64 = key.read();
}

pub fn try_read(self) -> Option<T>

Reads a value of type T starting at the location specified by self. If the value
crosses the boundary of a 32-byte-long storage slot, reading continues at the following slot.

Returns

  • [Option] - Returns Some(value), if the storage slots reads were valid and contain value.
    Otherwise, None.

Number of Storage Accesses

  • Reads: 1

Examples

fn foo() {
    let key: StorageKey<u64> = StorageKey::new(b256::zero(), 2, b256::zero());
    // Reads the third word from storage slot with key 0x000...0.
    let _: Option<u64> = key.try_read();
}

pub fn write(self, value: T)

Writes a value of type T starting at the location specified by self. If the value
crosses the boundary of a 32-byte-long storage slot, writing continues at the following slot.

Arguments

  • value: [T] - The value of type T to write.

Number of Storage Accesses

  • Reads: 0 if the value occupies full slots, 1 otherwise (to read the existing data that will be partially overwritten)
  • Writes: 1

Examples

fn foo() {
    let key: StorageKey<u64> = StorageKey::new(b256::zero(), 2, b256::zero());
    // Writes 42 at the third word of storage slot with key 0x000...0.
    key.write(42);
}

pub fn clear(self) -> bool

Clears the value at self. Returns true if the value existed in the storage before clearing, otherwise false.

Additional Information

The whole slot or multiple slots will be cleared, even if the StorageKey points to an offset within the slot.
This means that if there are multiple values stored in a same slot, they will all be cleared.

Number of Storage Accesses

  • Clears: 1

Examples

fn foo() {
    let key: StorageKey<u64> = StorageKey::new(b256::zero(), 2, b256::zero());
    key.write(42);
    let cleared = key.clear();
    assert(cleared); // The value 42 existed before clearing, so `clear` returns `true`.
    let cleared = key.clear();
    assert(!cleared); // The value was already cleared, so `clear` returns `false`.
}

pub fn get(self, key: K) -> StorageKey<V>

Retrieves the StorageKey that describes the location in storage of the value
stored at key, regardless of whether a value is actually stored at that location or not.

Arguments

  • key: [K] - The key to which the value is paired.

Returns

  • [StorageKey] - Describes the location in storage of the value stored at key.

Examples

storage {
    map: StorageMap<u64, bool> = StorageMap {}
}

fn foo() {
    let key = 5_u64;
    let value = true;
    storage.map.insert(key, value);
    let retrieved_value = storage.map.get(key).read();
    assert_eq(value, retrieved_value);
}

fn get_slot_key(self, key: K) -> b256

pub fn insert(
self,
key: K,
value: V,
)

Inserts a key-value pair into the map.

Arguments

  • key: [K] - The key to which the value is paired.
  • value: [V] - The value to be stored.

Number of Storage Accesses

  • Reads: 0 if the value occupies full slots, 1 otherwise (to read the existing data that will be partially overwritten)
  • Writes: 1

Examples

storage {
    map: StorageMap<u64, bool> = StorageMap {}
}

fn foo() {
    let key = 5_u64;
    let value = true;
    storage.map.insert(key, value);
    let retrieved_value = storage.map.get(key).read();
    assert_eq(value, retrieved_value);
}

pub fn remove(self, key: K) -> bool

Clears a value previously stored at key.

Arguments

  • key: [K] - The key to which the value is paired.

Returns

  • [bool] - true if there was a value previously stored at key.

Number of Storage Accesses

  • Clears: 1

Examples

storage {
    map: StorageMap<u64, bool> = StorageMap {}
}

fn foo() {
    let key = 5_u64;
    let value = true;
    storage.map.insert(key, value);
    let removed = storage.map.remove(key);
    assert(removed);
    assert(storage.map.get(key).is_none());
}

pub fn try_insert(
self,
key: K,
value: V,
) -> Result<V, StorageMapError<V>>

Inserts a key-value pair into the map if a value does not already exist for the key.

Arguments

  • key: [K] - The key to which the value is paired.
  • value: [V] - The value to be stored.

Returns

  • [Result<V, StorageMapError>] - Result::Ok(value) if the value was inserted, or Result::Err(StorageMapError::OccupiedError(pre_existing_value)) if a value already existed for the key.

Number of Storage Accesses

  • Reads: 1 (to check if a value already exists for the key)
  • Writes: 1 if the value is inserted, otherwise 0

Examples

use std::storage::storage_map::StorageMapError;

storage {
    map: StorageMap<u64, bool> = StorageMap {}
}

fn foo() {
    let key = 5_u64;
    let value = true;
    storage.map.insert(key, value);

    let new_value = false;
    let result = storage.map.try_insert(key, new_value);
    assert(result == Result::Err(StorageMapError::OccupiedError(value))); // The old value is returned.

    let retrieved_value = storage.map.get(key).read();
    assert_eq(value, retrieved_value); // New value was not inserted, as a value already existed.

    let key2 = 10_u64;
    let returned_value = storage.map.try_insert(key2, new_value);
    assert_eq(returned_value, Result::Ok(new_value)); // New value is returned.
}

pub fn push(self, value: V)

Appends value to the end of the vector.

Arguments

  • value: [V] - The item being added to the end of the vector.

Number of Storage Accesses

  • Reads: 3
  • Writes: 2

Examples

use std::storage::storage_vec::*;

storage {
    vec: StorageVec<u64> = StorageVec {},
    vec_of_vec: StorageVec<StorageVec<u64>> = StorageVec {},
}

fn foo() {
    let five = 5_u64;
    storage.vec.push(five);
    assert_eq(five, storage.vec.get(0).unwrap().read());

    storage.vec_of_vec.push(StorageVec {});
    assert_eq(0, storage.vec_of_vec.get(0).unwrap().len());
}

pub fn pop(self) -> Option<V>

Removes the last element of the vector and returns it, or None if the vector is empty,
or it contains a nested storage type.

Additional Information

If V is a nested storage type, pop always returns None, even if the vector is not
empty and the last element got removed.

WARNING: If V is a nested storage type, pop will reduce the vector length and
remove the last element from the vector, but the nested content of the removed element
will remain in the storage.

Returns

  • [Option] - The last element of the vector, or None if the vector is empty, or it contains a nested storage type.

Number of Storage Accesses

  • Reads: 3
  • Writes: 1

Examples

use std::storage::storage_vec::*;

storage {
    vec: StorageVec<u64> = StorageVec {},
}

fn foo() {
    let five = 5_u64;
    storage.vec.push(five);
    let popped_value = storage.vec.pop().unwrap();
    assert_eq(five, popped_value);
    let none_value = storage.vec.pop();
    assert(none_value.is_none());
}

pub fn get(self, index: u64) -> Option<StorageKey<V>>

Gets the value at the given index or None if index is out of bounds.

Arguments

  • index: [u64] - The index to retrieve the item from.

Returns

  • [Option<StorageKey>] - Location in storage of the value stored at index or None if index is out of bounds.

Number of Storage Accesses

  • Reads: 1

Examples

use std::storage::storage_vec::*;

storage {
    vec: StorageVec<u64> = StorageVec {}
}

fn foo() {
    let five = 5_u64;
    storage.vec.push(five);
    assert_eq(five, storage.vec.get(0).unwrap().read());
    assert(storage.vec.get(1).is_none());
}

pub fn remove(self, index: u64) -> V

Removes the element at the given index and moves all the elements at the following indices
down one index. Returns the removed element.

Additional Information

This method is not supported for nested storage types and will revert if V is a nested storage type.

WARNING: Gas consuming for larger vectors.

Arguments

  • index: [u64] - The index to remove the element from.

Returns

  • [V] - The removed element.

Reverts

  • If index is out of bounds.
  • If V is a nested storage type, i.e. if it is a zero-sized type.

Number of Storage Accesses

  • Reads: 3 + (2 * (self.len() - index))
  • Writes: self.len() - index

Examples

use std::storage::storage_vec::*;

storage {
    vec: StorageVec<u64> = StorageVec {}
}

fn foo() {
    storage.vec.push(5);
    storage.vec.push(10);
    storage.vec.push(15);
    let removed_value = storage.vec.remove(1);
    assert_eq(10, removed_value);
    assert_eq(storage.vec.len(), 2);
}

pub fn swap_remove(self, index: u64) -> V

Replaces the element at the given index with the last element, and removes the last element.
Returns the replaced element.

Additional Information

This method is not supported for nested storage types and will revert if V is a nested storage type.

If index is the index of the last element, the last element will be returned and removed from the vector.

Arguments

  • index: [u64] - The index at which to replace the element with the last element.

Returns

  • [V] - The replaced element.

Reverts

  • If index is out of bounds.
  • If V is a nested storage type, i.e. if it is a zero-sized type.

Number of Storage Accesses

  • Reads: 5
  • Writes: 2

Examples

use std::storage::storage_vec::*;

storage {
    vec: StorageVec<u64> = StorageVec {}
}

fn foo() {
    storage.vec.push(5);
    storage.vec.push(10);
    storage.vec.push(15);
    let removed_value = storage.vec.swap_remove(0);
    assert_eq(5, removed_value);
    let swapped_value = storage.vec.get(0).unwrap().read();
    assert_eq(15, swapped_value); // The first element is replaced by the last element.
    assert_eq(2, vec.len()); // The last element is removed.
}

pub fn set(
self,
index: u64,
value: V,
)

Sets the value at the given index.

Additional Information

This method is not supported for nested storage types and will revert if V is a nested storage type.

Arguments

  • index: [u64] - The index to set the value at.
  • value: [V] - The value to be set.

Reverts

  • If index is out of bounds.
  • If V is a nested storage type, i.e. if it is a zero-sized type.

Number of Storage Accesses

  • Reads: 1 or 2 (1 to get vector’s length, and 0 if the value occupies full slots, or 1 otherwise to read the existing data that will be partially overwritten)
  • Writes: 1

Examples

use std::storage::storage_vec::*;

storage {
    vec: StorageVec<u64> = StorageVec {}
}

fn foo() {
    storage.vec.push(5);
    storage.vec.push(10);

    storage.vec.set(0, 15);
    let set_value = storage.vec.get(0).unwrap().read();
    assert_eq(15, set_value);
}

pub fn insert(
self,
index: u64,
value: V,
)

Inserts the value at the given index, moving the current value at index
as well as the following indices up by one index.

Additional Information

This method is not supported for nested storage types and will revert if V is a nested storage type.

If index is equal to vector’s length, appends the value at the end of the
vector, effectively acting the same as push.

WARNING: Gas consuming for larger vectors.

Arguments

  • index: [u64] - The index to insert the value into.
  • value: [V] - The value to insert.

Reverts

  • If index is larger than the length of the vector.
  • If V is a nested storage type, i.e. if it is a zero-sized type.

Number of Storage Accesses

  • Reads: if self.len() == index { 3 } else { 5 + (2 * (self.len() - index)) }
  • Writes: if self.len() == index { 2 } else { 2 + self.len() - index }

Examples

use std::storage::storage_vec::*;

storage {
    vec: StorageVec<u64> = StorageVec {}
}

fn foo() {
    storage.vec.push(5);
    storage.vec.push(15);

    storage.vec.insert(1, 10);

    assert_eq(5, storage.vec.get(0).unwrap().read());
    assert_eq(10, storage.vec.get(1).unwrap().read());
    assert_eq(15, storage.vec.get(2).unwrap().read());
}

pub fn len(self) -> u64

Returns the length of the vector.

Returns

  • [u64] - The length of the vector.

Number of Storage Accesses

  • Reads: 1

Examples

use std::storage::storage_vec::*;

storage {
    vec: StorageVec<u64> = StorageVec {},
}

fn foo() {
    assert_eq(0, storage.vec.len());
    storage.vec.push(5);
    assert_eq(1, storage.vec.len());
    storage.vec.push(10);
    assert_eq(2, storage.vec.len());
}

pub fn is_empty(self) -> bool

Returns true if the vector is empty, otherwise false.

Returns

  • [bool] - Indicates whether the vector is empty or not.

Number of Storage Accesses

  • Reads: 1 (to get vector’s length)

Examples

use std::storage::storage_vec::*;

storage {
    vec: StorageVec<u64> = StorageVec {}
}

fn foo() {
    assert(storage.vec.is_empty());
    storage.vec.push(5);
    assert(!storage.vec.is_empty());
    storage.vec.clear();
    assert(storage.vec.is_empty());
}

pub fn swap(
self,
element1_index: u64,
element2_index: u64,
)

Swaps the positions of the two elements at the given indices.

Additional Information

This method is not supported for nested storage types and will revert if V is a nested storage type.

Arguments

  • element1_index: [u64] - The index of the first element.
  • element2_index: [u64] - The index of the second element.

Reverts

  • If element1_index or element2_index is out of bounds.
  • If V is a nested storage type, i.e. if it is a zero-sized type.

Number of Storage Accesses

  • Reads: 5
  • Writes: 2

Examples

use std::storage::storage_vec::*;

storage {
    vec: StorageVec<u64> = StorageVec {}
}

fn foo() {
    storage.vec.push(5);
    storage.vec.push(10);
    storage.vec.push(15);

    storage.vec.swap(0, 2);
    assert_eq(15, storage.vec.get(0).unwrap().read());
    assert_eq(10, storage.vec.get(1).unwrap().read());
    assert_eq(5, storage.vec.get(2).unwrap().read());

pub fn first(self) -> Option<StorageKey<V>>

Returns the first element of the vector, or None if it is empty.

Returns

  • [Option<StorageKey>] - The location in storage of the value stored at
    the start of the vector, or None if the vector is empty.

Number of Storage Accesses

  • Reads: 1 (to get vector’s length)

Examples

storage {
    vec: StorageVec<u64> = StorageVec {},
}

fn foo() {
    assert(storage.vec.first().is_none());
    storage.vec.push(5);
    assert_eq(5, storage.vec.first().unwrap().read());
}

pub fn last(self) -> Option<StorageKey<V>>

Returns the last element of the vector, or None if it is empty.

Returns

  • [Option<StorageKey>] - The location in storage of the value stored at
    the end of the vector, or None if the vector is empty.

Number of Storage Accesses

  • Reads: 1 (to get vector’s length)

Examples

storage {
    vec: StorageVec<u64> = StorageVec {},
}

fn foo() {
    assert(storage.vec.last().is_none());
    storage.vec.push(5);
    storage.vec.push(10);
    assert_eq(10, storage.vec.last().unwrap().read());
}

pub fn reverse(self)

Reverses the order of elements in the vector, in place.

Additional Information

This method is not supported for nested storage types and will panic if V is a nested storage type.

Number of Storage Accesses

  • Reads: 1 + (3 * (self.len() / 2))
  • Writes: 2 * (self.len() / 2)

Examples

storage {
    vec: StorageVec<u64> = StorageVec {},
}

fn foo() {
    storage.vec.push(5);
    storage.vec.push(10);
    storage.vec.push(15);

    storage.vec.reverse();

    assert_eq(15, storage.vec.get(0).unwrap().read());
    assert_eq(10, storage.vec.get(1).unwrap().read());
    assert_eq(5, storage.vec.get(2).unwrap().read());
}

pub fn fill(self, value: V)

Replaces all elements in the vector with value.

Additional Information

This method is not supported for nested storage types and will revert if V is a nested storage type.

Arguments

  • value: [V] - Value to copy to each element of the vector.

Reverts

  • If V is a nested storage type, i.e. if it is a zero-sized type.

Number of Storage Accesses

  • Reads: 1 + self.len()
  • Writes: self.len()

Examples

storage {
    vec: StorageVec<u64> = StorageVec {},
}

fn foo() {
    storage.vec.push(5);
    storage.vec.push(10);
    storage.vec.push(15);

    storage.vec.fill(20);

    assert_eq(20, storage.vec.get(0).unwrap().read());
    assert_eq(20, storage.vec.get(1).unwrap().read());
    assert_eq(20, storage.vec.get(2).unwrap().read());
}

pub fn resize(
self,
new_len: u64,
value: V,
)

Resizes self in place so that len is equal to new_len.

Additional Information

If new_len is greater than len, self is extended by the difference, with each
additional element being set to value. If the new_len is less than len, self is
simply truncated.

WARNING: If V is a nested storage type and new_len is less than len,
resize will reduce the vector length and remove the remaining elements from the vector,
but the nested content of those removed elements will remain in the storage.

Arguments

  • new_len: [u64] - The new length to expand or truncate to.
  • value: [V] - The value to set new elements to, if the new_len is greater than the current length.

Number of Storage Accesses

  • Reads - if new_len > self.len() { new_len - len + 2 } else { 2 }
  • Writes - if new_len > self.len() { new_len - len + 1 } else { 1 }

Examples

storage {
    vec: StorageVec<u64> = StorageVec {},
}

fn foo() {
    storage.vec.push(5);
    storage.vec.push(10);

    storage.vec.resize(4, 20);

    assert_eq(5, storage.vec.get(0).unwrap().read());
    assert_eq(10, storage.vec.get(1).unwrap().read());
    assert_eq(20, storage.vec.get(2).unwrap().read());
    assert_eq(20, storage.vec.get(3).unwrap().read());

    storage.vec.resize(2, 0);

    assert_eq(5, storage.vec.get(0).unwrap().read());
    assert_eq(10, storage.vec.get(1).unwrap().read());
    assert_eq(None, storage.vec.get(2));
    assert_eq(None, storage.vec.get(3));
}

pub fn store_vec(
self,
vec: Vec<V>,
)

Stores given vec as a StorageVec.

Additional Information

This will overwrite any existing values in the StorageVec.

This method is not supported for nested storage types and will revert if V is a nested storage type.

Arguments

  • vec: [Vec] - The vector to store in storage.

Reverts

  • If V is a nested storage type, i.e. if it is a zero-sized type.

Number of Storage Accesses

  • Writes: 2

Examples

storage {
    vec: StorageVec<u64> = StorageVec {},
}

fn foo() {
    let mut vec = Vec::<u64>::new();
    vec.push(5);
    vec.push(10);
    vec.push(15);

    storage.vec.store_vec(vec);

    assert_eq(5, storage.vec.get(0).unwrap().read());
    assert_eq(10, storage.vec.get(1).unwrap().read());
    assert_eq(15, storage.vec.get(2).unwrap().read());
}

pub fn load_vec(self) -> Vec<V>

Returns all elements contained in self as a Vec<V>.

Additional Information

This method is not supported for nested storage types and will revert if V is a nested storage type.

Returns

  • [Vec] - The vector containing all elements of self.

Reverts

  • If V is a nested storage type, i.e. if it is a zero-sized type.

Number of Storage Accesses

  • Reads: 2

Examples

storage {
    vec: StorageVec<u64> = StorageVec {},
}

fn foo() {
    let mut vec = Vec::<u64>::new();
    vec.push(5);
    vec.push(10);
    vec.push(15);

    storage.vec.store_vec(vec);

    let loaded_vec = storage.vec.load_vec();

    assert_eq(5, loaded_vec.get(0).unwrap());
    assert_eq(10, loaded_vec.get(1).unwrap());
    assert_eq(15, loaded_vec.get(2).unwrap());
}

pub fn iter(self) -> StorageVecIter<V>

Returns an [Iterator] to iterate over this StorageVec.

Returns

  • [StorageVecIter] - The iterator over this StorageVec.

Number of Storage Accesses

  • Reads: 1 (to get the vector’s length)

Examples

storage {
    vec: StorageVec<u64> = StorageVec {},
}

fn foo() {
    storage.vec.push(5);
    storage.vec.push(10);
    storage.vec.push(15);

    let iter = storage.vec.iter();

    assert_eq(5, iter.next().unwrap().read());
    assert_eq(10, iter.next().unwrap().read());
    assert_eq(15, iter.next().unwrap().read());

    let iter = storage.vec.iter();

    for elem in storage.vec.iter() {
        let elem_value = elem.read();
        log(elem_value);
    }
}

pub fn clear(self) -> bool

Clears stored Bytes in storage.

Returns

  • [bool] - true if all of the cleared storage slots were previously set. Otherwise, false.

Number of Storage Accesses

  • Reads: 1 (to determine the Bytes length)
  • Clears: 2 (one for the Bytes length, and one for the content)

Examples

use std::{storage::storage_bytes::StorageBytes, bytes::Bytes};

storage {
    stored_bytes: StorageBytes = StorageBytes {}
}

fn foo() {
    let mut bytes = Bytes::new();
    bytes.push(5_u8);
    bytes.push(7_u8);
    bytes.push(9_u8);
    storage.stored_bytes.write_slice(bytes);

    assert(storage.stored_bytes.read_slice().is_some());
    let cleared = storage.stored_bytes.clear();
    assert(cleared);
    let retrieved_bytes = storage.stored_bytes.read_slice();
    assert(retrieved_bytes.is_none());
}

pub fn len(self) -> u64

Returns the length of tightly packed bytes in storage, in bytes.

Returns

  • [u64] - The length of the bytes in storage, in bytes, or 0 if there are no valid bytes in storage.

Number of Storage Accesses

  • Reads: 1 (to read the Bytes length)

Examples

use std::{storage::storage_bytes::StorageBytes, bytes::Bytes};

storage {
    stored_bytes: StorageBytes = StorageBytes {}
}

fn foo() {
    let mut bytes = Bytes::new();
    bytes.push(5_u8);
    bytes.push(7_u8);
    bytes.push(9_u8);

    assert_eq(storage.stored_bytes.len(), 0);
    storage.stored_bytes.write_slice(bytes);
    assert_eq(storage.stored_bytes.len(), 3);
}

pub fn read_slice(self) -> Option<Bytes>

Constructs a Bytes type from a collection of tightly packed bytes in storage.

Returns

  • [Option] - The valid Bytes stored, otherwise None.

Number of Storage Accesses

  • Reads: 2 (one for the Bytes length, and one for the content)

Examples

use std::{storage::storage_bytes::StorageBytes, bytes::Bytes};

storage {
    stored_bytes: StorageBytes = StorageBytes {}
}

fn foo() {
    let mut bytes = Bytes::new();
    bytes.push(5_u8);
    bytes.push(7_u8);
    bytes.push(9_u8);

    assert(storage.stored_bytes.read_slice().is_none());
    storage.stored_bytes.write_slice(bytes);
    let retrieved_bytes = storage.stored_bytes.read_slice().unwrap();
    assert_eq(bytes, retrieved_bytes);
}

pub fn write_slice(
self,
bytes: Bytes,
)

Takes a Bytes type and stores the underlying collection of tightly packed bytes.

Arguments

  • bytes: [Bytes] - The bytes which will be stored.

Number of Storage Accesses

  • Reads: 1 (to read the existing data in the slice length slot)
  • Writes: 2 (one for the Bytes length, and one for the content)

Examples

use std::{storage::storage_bytes::StorageBytes, bytes::Bytes};

storage {
    stored_bytes: StorageBytes = StorageBytes {}
}

fn foo() {
    let mut bytes = Bytes::new();
    bytes.push(5_u8);
    bytes.push(7_u8);
    bytes.push(9_u8);

    storage.stored_bytes.write_slice(bytes);
}

pub fn clear(self) -> bool

Clears a stored String in storage.

Returns

  • [bool] - true if all of the cleared storage slots were previously set. Otherwise, false.

Number of Storage Accesses

  • Reads: 1 (to determine the String length)
  • Clears: 2 (one for the String length, and one for the content)

Examples

use std::{storage::storage_string::StorageString, string::String};

storage {
    stored_string: StorageString = StorageString {}
}

fn foo() {
    let string = String::from_ascii_str("Fuel is blazingly fast");

    storage.stored_string.write_slice(string);

    assert(storage.stored_string.read_slice().is_some());
    let cleared = storage.stored_string.clear();
    assert(cleared);
    let retrieved_string = storage.stored_string.read_slice();
    assert(retrieved_string.is_none());
}

pub fn len(self) -> u64

Returns the length of a String in storage, in bytes.

Returns

  • [u64] - The length of the String in storage, in bytes, or 0 if there is no valid String in storage.

Number of Storage Accesses

  • Reads: 1 (to read the String length)

Examples

use std::{storage::storage_string::StorageString, string::String};

storage {
    stored_string: StorageString = StorageString {}
}

fn foo() {
    let string = String::from_ascii_str("Fuel is blazingly fast");

    assert_eq!(storage.stored_string.len(), 0);
    storage.stored_string.write_slice(string);
    assert_eq!(storage.stored_string.len(), 22);
}

pub fn read_slice(self) -> Option<String>

Constructs a String type from a collection of tightly packed bytes in storage.

Returns

  • [Option] - The valid String stored, otherwise None.

Number of Storage Accesses

  • Reads: 2 (one for the String length, and one for the content)

Examples

use std::{storage::storage_string::StorageString, string::String};

storage {
    stored_string: StorageString = StorageString {}
}

fn foo() {
    let string = String::from_ascii_str("Fuel is blazingly fast");

    assert(storage.stored_string.read_slice().is_none());
    storage.stored_string.write_slice(string);
    let retrieved_string = storage.stored_string.read_slice().unwrap();
    assert_eq(string, retrieved_string);
}

pub fn write_slice(
self,
string: String,
)

Takes a String type and saves the underlying data in storage.

Arguments

  • string: [String] - The string which will be stored.

Number of Storage Accesses

  • Reads: 1 (to read the existing data in the slice length slot)
  • Writes: 2 (one for the String length, and one for the content)

Examples

use std::{storage::storage_string::StorageString, string::String};

storage {
    stored_string: StorageString = StorageString {}
}

fn foo() {
    let string = String::from_ascii_str("Fuel is blazingly fast");

    storage.stored_string.write_slice(string);
}