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>.
use std::ascii;
use std::bcs;
use std::internal;
use std::option;
use std::string;
use std::vector;
use sui::address;
use sui::dynamic_field;
use sui::hex;
use sui::object;
use sui::tx_context;
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
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.
fun borrow_marker<V: drop>(ctx: &mut sui::tx_context::TxContext): sui::scratch::BorrowMarker<V>
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