pub struct StateBuilder<S = StateApi> { /* private fields */ }
Expand description

A state builder that allows the creation of StateMap, StateSet, and StateBox.

It is parametrized by a parameter S that is assumed to implement HasStateApi to support testing with the deprecated test_infrastructure. The S defaults to StateApi, which is sufficient to test with the concordium-smart-contract-testing library.

The StateBuilder is designed to provide an abstraction over the contract state, abstracting over the exact keys (keys in the sense of key-value store, which is the low-level semantics of contract state) that are used when storing specific values.

Implementations§

source§

impl<S> StateBuilder<S>
where S: HasStateApi,

source

pub fn open(state: S) -> Self

Open a new state_builder. Only a single instance of the state_builder should exist during contract execution, thus this should only be called at the very beginning of execution.

source

pub fn new_state_container(&mut self) -> (S, [u8; 8])

Provide clone of HasStateApi instance and new key prefix for any container-like type wishing to store its data on blockchain.

Container types StateBox, StateSet, StateMap provided by Concordium SDK are created using this method internally. Contract developers can use it to implement their own containers.

Any container type which provides more ergonomic APIs and behavior atop raw storage is expected to have two items:

  • Handle-like object which implements HasStateApi. It provides access to contract VM features, including storage management. This object is not serialized, instead it’s provided by executon environment. Can be treated as handle, relatively cheap to clone.
  • Prefix for keys of all entries managed by new container. Storage of Concordium contract behaves like flat key-value dictionary, so each container must have unique prefix for the keys of any entries it stores to avoid collisions with other containers. This prefix is serialized as (part of) persistent representation of container.
§Returns

A pair of:

  • Object which gives access to low-level storage API. Same as the one held by StateBuilder itself and usually the one which refers to current contract storage.
  • New unique key prefix for this container.
source

pub fn new_map<K, V>(&mut self) -> StateMap<K, V, S>

Create a new empty StateMap.

source

pub fn new_set<T>(&mut self) -> StateSet<T, S>

Create a new empty StateSet.

source

pub fn new_box<T: Serial>(&mut self, value: T) -> StateBox<T, S>

Create a new StateBox and insert the value into the state. This stores the serialized value in the contract state. Thus if the StateBox is dropped without calling delete then the value will remain in contract state, leading to a space leak.

Note that this dropping can happen implicitly via assignment. For example,

struct MyState<S: HasStateApi> {
    inner: StateBox<u64, S>,
}
fn incorrect_replace<S: HasStateApi>(
    state_builder: &mut StateBuilder<S>,
    state: &mut MyState<S>,
) {
    // The following is incorrect. The old value of `inner` is not properly deleted.
    // from the state.
    state.inner = state_builder.new_box(0); // ⚠️
}

Instead, the old value should be manually deleted.

fn correct_replace<S: HasStateApi>(
    state_builder: &mut StateBuilder<S>,
    state: &mut MyState<S>,
) {
    let old_box = mem::replace(&mut state.inner, state_builder.new_box(0));
    old_box.delete()
}
source§

impl StateBuilder<StateApi>

source

pub fn new_btree_set<K>(&mut self) -> StateBTreeSet<K>

Create a new empty StateBTreeSet.

source

pub fn new_btree_map<K, V>(&mut self) -> StateBTreeMap<K, V>

Create a new empty StateBTreeMap.

source

pub fn new_btree_set_degree<const M: usize, K>(&mut self) -> StateBTreeSet<K, M>

Create a new empty StateBTreeSet, setting the minimum degree M of the B-Tree explicitly. M must be 2 or higher otherwise constructing the B-Tree results in aborting.

source

pub fn new_btree_map_degree<const M: usize, K, V>( &mut self ) -> StateBTreeMap<K, V, M>

Create a new empty StateBTreeMap, setting the minimum degree M of the B-Tree explicitly. M must be 2 or higher otherwise constructing the B-Tree results in aborting.

source§

impl StateBuilder<TestStateApi>

source

pub fn new() -> Self

👎Deprecated since 8.1.0: Deprecated in favor of concordium-smart-contract-testing.

Create a new Self with an empty TestStateApi.

Trait Implementations§

source§

impl<S: Default> Default for StateBuilder<S>

source§

fn default() -> StateBuilder<S>

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<S> Freeze for StateBuilder<S>
where S: Freeze,

§

impl<S> RefUnwindSafe for StateBuilder<S>
where S: RefUnwindSafe,

§

impl<S> Send for StateBuilder<S>
where S: Send,

§

impl<S> Sync for StateBuilder<S>
where S: Sync,

§

impl<S> Unpin for StateBuilder<S>
where S: Unpin,

§

impl<S> UnwindSafe for StateBuilder<S>
where S: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.