Skip to main content

Module sui::scratch

sui::scratch is an ephemeral, per-transaction key-value store. Unlike sui::dynamic_field, scratch entries are not attached to any object, and are instead dropped at the end of the transaction.

Each entry is identified by the pair of its key type and key value, hashed together in the same way as a dynamic field name (see sui::dynamic_field::hash_type_and_key).

All access (mutable and immutable) is controlled through the module that defines the key type K. The functions are gated by a Permit<K>, which can be granted via an internal::Permit<K>.

Struct Permit

A Permit<K> gates access to all entries keyed by values of type K.
It is issued from an internal::Permit<K>, allowing the module that defines K to control all access to scratch entries.

public struct Permit<phantom K: copy, drop> has copy, drop

Struct BorrowMarker

Occupies a key's slot while get_do, get_fold, or their mutable variants have the value of type V removed, so nothing can add to or read the slot while the value is being "borrowed".
Each one carries a transaction-unique id, so a marker cannot be forged to match one in use.

public struct BorrowMarker<phantom V: drop> has drop
Click to open
Fields
0: u64

Struct BorrowMarkerKey

Key for the scratch entry that holds the monotonic counter backing borrow_marker.

public struct BorrowMarkerKey has copy, drop

Constants

Stand-in parent address used when hashing scratch keys.

const DUMMY_ROOT: address = 0x0;

The scratch store already has an entry for this key.

const EEntryAlreadyExists: u64 = 0;

The scratch store does not have an entry for this key.

const EEntryDoesNotExist: u64 = 1;

The scratch store has an entry for this key, but the value type does not match.

const EEntryTypeMismatch: u64 = 2;

A borrow-style macro found a different BorrowMarker than it left in the slot.

const EBorrowMarkerMismatch: u64 = 3;

Function permit

Issues a Permit<K> from the privileged internal::Permit<K>, granting access to the scratch entries keyed by values of type K.

public fun permit<K: copy, drop>(_: std::internal::Permit<K>): sui::scratch::Permit<K>

Function add

Adds the key-value pair to the scratch store. Requires a Permit<K> for the key type.
Aborts with EEntryAlreadyExists if there is already an entry for key, regardless of its value type.

public fun add<K: copy, drop, V: drop>(_: &mut sui::tx_context::TxContext, _: sui::scratch::Permit<K>, key: K, value: V)

Function read

Returns a copy of the value bound to key. Requires a Permit<K> for the key type.
Aborts with EEntryDoesNotExist if there is no entry for key.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type V.

public fun read<K: copy, drop, V: copy, drop>(_: &sui::tx_context::TxContext, _: sui::scratch::Permit<K>, key: K): V

Function remove

Removes the entry bound to key and returns its value. Requires a Permit<K> for the key type.
Aborts with EEntryDoesNotExist if there is no entry for key.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type V.

public fun remove<K: copy, drop, V: drop>(_: &mut sui::tx_context::TxContext, _: sui::scratch::Permit<K>, key: K): V

Function exists

Returns true if and only if the scratch store has an entry for key, without regard to the value type. Requires a Permit<K> for the key type.

public fun exists<K: copy, drop>(_: &sui::tx_context::TxContext, _: sui::scratch::Permit<K>, key: K): bool

Function exists_with_type

Returns true if and only if the scratch store has an entry for key whose value is of type V.
Requires a Permit<K> for the key type.

public fun exists_with_type<K: copy, drop, V: drop>(_: &sui::tx_context::TxContext, _: sui::scratch::Permit<K>, key: K): bool

Function read_opt

Returns a copy of the value bound to key as some(value) if it exists, or none otherwise.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type V.

public fun read_opt<K: copy, drop, V: copy, drop>(ctx: &sui::tx_context::TxContext, permit: sui::scratch::Permit<K>, key: K): std::option::Option<V>

Function remove_opt

Removes the entry bound to key if it exists, returning some(value), or none otherwise.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type V.

public fun remove_opt<K: copy, drop, V: drop>(ctx: &mut sui::tx_context::TxContext, permit: sui::scratch::Permit<K>, key: K): std::option::Option<V>

Function replace

Removes the existing value at key (if any) and adds value in its place.
Returns the old value if it existed, or none otherwise.
Note: the old and new value types may differ.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type VOld.

public fun replace<K: copy, drop, VNew: drop, VOld: drop>(ctx: &mut sui::tx_context::TxContext, permit: sui::scratch::Permit<K>, key: K, value: VNew): std::option::Option<VOld>

Function begin_borrow

Not intended for direct usage. Instead, call get_do, get_fold, or their mutable variants, which handle the borrow-style usage of the value.
Begins a "borrow" of key: removes and returns its value, leaving a unique BorrowMarker in the slot so nothing can add to or read it until end_borrow restores the value. Returns the value and the marker, which must be passed to end_borrow.
While it is not verified that the same value is restored, the intended usage is guaranteed by the borrow-style macros (get_do, get_fold, and their mutable variants).
Aborts with EEntryDoesNotExist if there is no entry for key.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type V.

public fun begin_borrow<K: copy, drop, V: drop>(ctx: &mut sui::tx_context::TxContext, permit: sui::scratch::Permit<K>, key: K): (V, sui::scratch::BorrowMarker<V>)

Function end_borrow

Not intended for direct usage. Instead, call get_do, get_fold, or their mutable variants, which handle the borrow-style usage of the value.
Ends a "borrow" begun by begin_borrow: removes the BorrowMarker from key's slot and restores value.
While it is not verified that the same value is restored, the intended usage is guaranteed by the borrow-style macros (get_do, get_fold, and their mutable variants).
Aborts with EEntryDoesNotExist if the borrow was already ended.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not a BorrowMarker<V>.
Aborts with EBorrowMarkerMismatch unless the slot still holds marker.

public fun end_borrow<K: copy, drop, V: drop>(ctx: &mut sui::tx_context::TxContext, permit: sui::scratch::Permit<K>, key: K, value: V, marker: sui::scratch::BorrowMarker<V>)

Macro function get_do

If an entry exists for key, calls $f on an immutable reference to its value; otherwise does nothing.
Note that the value is not actually borrowed, but a placeholder is used while value is temporarily removed for the duration of the $f operation. As such, the function may abort if the $key is accessed during the $f operation.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $V.

public macro fun get_do<$K: copy, drop, $V: drop, $R: drop>($ctx: &mut sui::tx_context::TxContext, $permit: sui::scratch::Permit<$K>, $key: $K, $f: |&$V| -> $R)

Macro function get_mut_do

If an entry exists for key, calls $f on a mutable reference to its value; otherwise does nothing.
Note that the value is not actually borrowed, but a placeholder is used while value is temporarily removed for the duration of the $f operation. As such, the function may abort if the $key is accessed during the $f operation.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $V.

public macro fun get_mut_do<$K: copy, drop, $V: drop, $R: drop>($ctx: &mut sui::tx_context::TxContext, $permit: sui::scratch::Permit<$K>, $key: $K, $f: |&mut $V| -> $R)

Macro function get_fold

If an entry exists for key, applies $some to an immutable reference to its value and returns the result; otherwise returns $none.
Note that the value is not actually borrowed, but a placeholder is used while value is temporarily removed for the duration of the $some operation. As such, the function may abort if the $key is accessed during the $some operation.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $V.

public macro fun get_fold<$K: copy, drop, $V: drop, $R>($ctx: &mut sui::tx_context::TxContext, $permit: sui::scratch::Permit<$K>, $key: $K, $none: $R, $some: |&$V| -> $R): $R

Macro function get_mut_fold

If an entry exists for key, applies $some to a mutable reference to its value and returns the result; otherwise returns $none.
Note that the value is not actually borrowed, but a placeholder is used while value is temporarily removed for the duration of the $some operation. As such, the function may abort if the $key is accessed during the $some operation.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $V.

public macro fun get_mut_fold<$K: copy, drop, $V: drop, $R>($ctx: &mut sui::tx_context::TxContext, $permit: sui::scratch::Permit<$K>, $key: $K, $none: $R, $some: |&mut $V| -> $R): $R

Macro function internal_add

A wrapper for add that constructs the Permit<$K> directly.
Aborts with EEntryAlreadyExists if there is already an entry for $key, regardless of its value type.

public macro fun internal_add<$K: copy, drop, $V: drop>($ctx: &mut sui::tx_context::TxContext, $key: $K, $value: $V)

Macro function internal_read

A wrapper for read that constructs the Permit<$K> directly.
Aborts with EEntryDoesNotExist if there is no entry for $key.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $V.

public macro fun internal_read<$K: copy, drop, $V: copy, drop>($ctx: &sui::tx_context::TxContext, $key: $K): $V

Macro function internal_remove

A wrapper for remove that constructs the Permit<$K> directly.
Aborts with EEntryDoesNotExist if there is no entry for $key.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $V.

public macro fun internal_remove<$K: copy, drop, $V: drop>($ctx: &mut sui::tx_context::TxContext, $key: $K): $V

Macro function internal_exists

A wrapper for exists that constructs the Permit<$K> directly.

public macro fun internal_exists<$K: copy, drop>($ctx: &sui::tx_context::TxContext, $key: $K): bool

Macro function internal_exists_with_type

A wrapper for exists_with_type that constructs the Permit<$K> directly.

public macro fun internal_exists_with_type<$K: copy, drop, $V: drop>($ctx: &sui::tx_context::TxContext, $key: $K): bool

Macro function internal_read_opt

A wrapper for read_opt that constructs the Permit<$K> directly.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $V.

public macro fun internal_read_opt<$K: copy, drop, $V: copy, drop>($ctx: &sui::tx_context::TxContext, $key: $K): std::option::Option<$V>

Macro function internal_remove_opt

A wrapper for remove_opt that constructs the Permit<$K> directly.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $V.

public macro fun internal_remove_opt<$K: copy, drop, $V: drop>($ctx: &mut sui::tx_context::TxContext, $key: $K): std::option::Option<$V>

Macro function internal_replace

A wrapper for replace that constructs the Permit<$K> directly.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $VOld.

public macro fun internal_replace<$K: copy, drop, $VNew: drop, $VOld: drop>($ctx: &mut sui::tx_context::TxContext, $key: $K, $value: $VNew): std::option::Option<$VOld>

Macro function internal_get_do

A wrapper for get_do that constructs the Permit<$K> directly.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $V.

public macro fun internal_get_do<$K: copy, drop, $V: drop, $R: drop>($ctx: &mut sui::tx_context::TxContext, $key: $K, $f: |&$V| -> $R)

Macro function internal_get_mut_do

A wrapper for get_mut_do that constructs the Permit<$K> directly.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $V.

public macro fun internal_get_mut_do<$K: copy, drop, $V: drop, $R: drop>($ctx: &mut sui::tx_context::TxContext, $key: $K, $f: |&mut $V| -> $R)

Macro function internal_get_fold

A wrapper for get_fold that constructs the Permit<$K> directly.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $V.

public macro fun internal_get_fold<$K: copy, drop, $V: drop, $R>($ctx: &mut sui::tx_context::TxContext, $key: $K, $none: $R, $some: |&$V| -> $R): $R

Macro function internal_get_mut_fold

A wrapper for get_mut_fold that constructs the Permit<$K> directly.
Aborts with EEntryTypeMismatch if the entry exists, but its value is not of type $V.

public macro fun internal_get_mut_fold<$K: copy, drop, $V: drop, $R>($ctx: &mut sui::tx_context::TxContext, $key: $K, $none: $R, $some: |&mut $V| -> $R): $R

Function borrow_marker

Returns a fresh BorrowMarker<V>, unique within the transaction, from a monotonic counter kept in its own scratch entry.

Function hash_type_and_key

Hashes the type and value of k against DUMMY_ROOT to produce the address identifying its scratch entry.

fun hash_type_and_key<K: copy, drop>(k: K): address

Function add_impl

Aborts with EEntryAlreadyExists if there is an entry already for key, regardless of the type of V

fun add_impl<V: drop>(key: address, value: V)

Function read_impl

Aborts with EEntryDoesNotExist if there is no entry for key.
Aborts with EEntryTypeMismatch if there is an entry for key but it is not of type V.

fun read_impl<V: copy, drop>(key: address): V

Function remove_impl

Aborts with EEntryDoesNotExist if there is no entry for key.
Aborts with EEntryTypeMismatch if there is an entry for key but it is not of type V.

fun remove_impl<V: drop>(key: address): V

Function exists_impl

fun exists_impl(key: address): bool

Function exists_with_type_impl

fun exists_with_type_impl<V: drop>(key: address): bool