Expand description
This SDK facilitates writing Thruput contracts in Rust.
A contract is an ordinary Rust crate. Its persistent state lives in one or
more structs deriving Storage; its behavior lives
in one or more impl or trait blocks marked
#[contract], which generate the guest entrypoints
and a typed client that other contracts and tests call through.
use thruput_sdk::storage::Value;
use thruput_sdk::*;
#[derive(Storage)]
pub struct MyContract {
contract_owner: Value<ContractAddress>,
}
#[contract]
impl MyContract {
pub fn initialize(&mut self, contract_owner: &ContractAddress) {
self.contract_owner.set(contract_owner);
}
pub fn get_owner(&self) -> ContractAddress {
self.contract_owner.get()
}
}#[derive(Storage)] can also be spelled
#[storage].
That expands to a MyContractClient for callers, guest entrypoints for the
deployed artifact, and a contract spec describing the interface. Declaring
exceptions is a separate step, covered under
calling and errors.
Sections: Cargo features, storage, calling and errors, events, authorization, arithmetic, system functions, interfaces and specs, and testing.
§Cargo features
The features are layered: each implies the one above it. A contract
targeting riscv32im-unknown-none-elf normally enables none of them; the
host-side test build enables dev.
- (none) — the default, and what a deployed contract is built with:
no_std, no allocator, no host dependencies.storage, events, exceptions, authorization and the syscall wrappers all work here. Only the allocating and host-side APIs need more. alloc— links thealloccrate, makingVec,String, and other allocating types usable in contract code and in storage. See Allocation for what backs it on a guest.std— impliesalloc. Adds the interfaces that needstd, owned (allocating) contract-spec models, and detailed XDR decode errors. Host-only: enablingstdfor ariscv32build is a hard compile error, as is omitting it for a native build.dev— impliesstd. The native mock executor and everything that hangs off it:TestEnvironment,client_test,test_rv32(),declare_mock_contract!, and the storage-cost helpers. A contract crate forwards this from its owndevfeature. It is the only feature that pullsthruput-native-exec, and through it the hogd FFI library, into the dependency graph. That is why it is a feature: crates that only read contract specs buildthruput-sdkwithout it and never fetch that library.logging— trace contract calls during native tests. Not implied bydev; enable it when you want the trace.source-build— compile the cmake source-build path intothruput-sys. It does not select that path:HOGD_FFI_BUILD=1does, and it needs this feature to have something to select. Set both to build the hogd FFI library from source rather than download a prebuilt one, which is also the only way to build on a platform with no prebuilt binary. Only meaningful alongsidedev.
With alloc, owned String values can also be contract parameters and return
values, including inside Option. Borrowed &str inputs and
heapless::String<N> are alternatives when a bounded representation is useful.
A contract crate wires them up like this:
[features]
# Yours, not the SDK's. `#[contract]` gates guest entrypoint codegen on it,
# so a dependency cannot inject entrypoints into your binary.
entrypoints = []
dev = ["thruput-sdk/dev"]
[lib]
crate-type = ["rlib"]
# The rv32 artifact. `thruput build -p my-contract` derives
# `--bin my-contract` from the package name, so this name must match it.
# src/main.rs is a `#![no_std] #![no_main]` wrapper whose `extern crate
# my_contract;` force-links the rlib so the entrypoint records reach the
# binary.
[[bin]]
name = "my-contract"
path = "src/main.rs"
required-features = ["entrypoints"]
[dependencies]
thruput-sdk = { workspace = true }
[dev-dependencies]
my-contract = { path = ".", features = ["dev"] }Two things that look like features are keyed on the target instead:
- Diagnostics. The
Displayimpls on exception types and the formatting they need are host-only. Off a Cargo feature, no dependency can turn them on for a deployed contract, so they cannot change what a contract computes. - The guest runtime.
#[global_allocator],#[panic_handler],_startand entrypoint dispatch come fromthruput-rv32-runtime, force-linked onriscv32and absent from host builds.
§Allocation
§Stack and heap budgets
Each RV32 invocation shares a fixed memory budget between stack, static data
and heap. Increasing the stack reserve reduces heap capacity; enabling alloc
does not increase memory. See the runtime
stack and memory configuration
for defaults and overrides.
Without alloc, SDK call scratch and entrypoint calldata use fixed buffers
of about 4 KiB. An owned exn::RawException also holds an inline buffer of
about 4 KiB. Result temporaries and nested calls can keep several buffers on
the stack, even when the exception payload itself is small. Inlining can keep
those slots in a caller’s frame after their values are no longer live, so
source scopes alone do not establish peak stack use.
| Need | Choice |
|---|---|
| Bounded, short-lived values and scratch | Stack storage is appropriate; budget the whole call chain. |
| Classify a caught exception immediately | MapExceptions returns a compact value without retaining its wire buffer. |
| Keep the full exception for later | Ordinary try_* retains an owned error; account for its storage. |
| Dynamic collections or larger working buffers | Enable alloc and bound cumulative allocation per invocation. |
The guest allocator does not reclaim dropped values during an invocation.
SDK call scratch is pooled under alloc, but other allocations, including
owned exceptions and collection growth, can accumulate. Construct large
buffers directly in heap storage: Box::new(large_value) can still create a
large stack temporary.
Native tests enable dev, which enables alloc, and do not establish guest
stack headroom. Test release RV32 artifacts with maximum inputs, nested calls
and error paths.
§Static
Static allocations are facilitated in contracts by ContractCell and
contract_local!.
§Heap
With feature alloc:
- The
alloccrate is linked in, giving access to allocating datatypes likeStringandVec. - A simple bump allocator is installed by the guest runtime crate
(
thruput-rv32-runtime). Allocations are not freed until the current contract invocation terminates.
Datatypes defined by third-party libraries or by the user may be used in memory and in persistent storage, noting that:
- Heap allocation requires feature
alloc. - Persistent storage fields must use SDK storage types or nested structs derived
with
Storage.
§Storage
The storage module provides a high-level layer over persistent state,
including collection types like Map,
Vector and Array. It is available in every feature configuration.
Important storage-model rules:
- Plain data in persistent state must be wrapped in
Value<T>. Map<K, V>entries are individually addressed and may be absent.Vector<S>is sparse-capable.Vector::len()reports the in-bounds extent; individual slots may still be empty if their storage has been deleted.Array<S, N>is a fixed-lengthMap<u32, S>: indices0..Nare always in bounds, and individual elements may be unset.- Use
Vector::push_with()for the common append-and-initialize flow, andVector::push_empty_slot()only when you intentionally want to expose the new slot before initializing it. Value::load_mut()returns an auto-flushing edit guard: the updated value is written back when the guard is dropped.- Nested storage structs inside collections must be wrapped in
Node<T>, for exampleVector<Node<MyFields>>.
Two types enforce their invariant in the storage layer instead of in contract
code: NNInt for counters that must not go negative, and
Balance, whose increase/decrease fail on overflow
and overdraft in every build profile (see Arithmetic). This
matters most under concurrency: when two transactions in the same block both
move a balance, the check has to hold against the committed value, not the
one the contract read.
Deletable derives recursive deletion for a
storage struct.
Each contract’s state occupies its own storage domain. #[contract] generates
a per-crate test asserting the crate’s own roots do not collide; a binary that
links several contract crates should also invoke
storage_domain_uniqueness_test! so the aggregate is checked.
The low-level syscall wrappers (bytestring_set and friends) will corrupt
this module’s bookkeeping if pointed at the same keys. Use them, with
static_key!, only for state that
storage does not own.
§Contract macros
The storage macro is shorthand for
#[derive(Storage)].
The contract macro exports contract methods for
cross-contract calls and also generates client types for calling those methods.
It applies to a trait, a trait impl, an inherent impl, or a free function —
see its own page for the interface-versus-implementation split, throws, and
entrypoint-identifier customization.
Client naming defaults:
#[contract] trait FoogeneratesFooClient#[contract] impl Foo { ... }generatesFooClientclient = CustomClientis an override, not a requirement
§Calling And Errors
ContractClient is the low-level call surface. Most code goes through a
generated client, which exposes these calling styles:
client.method(...): success-oriented path. Typed exceptions are re-thrown to the caller, and faults stay faults.client.try_method(...): inspection path. ReturnsResult<ReturnType, CallError>. A caught exception stays undecoded: match it withmatch_exn!, or decode it as a named type withtry_as/try_decode.client.map_exceptions(classify).try_method(...): returnsResult<ReturnType, RawCallError<X>>, where the mapper producesXfrom a borrowedexn::RawExceptionRef. SeeMapExceptionsfor the callback contract.
match token.try_transfer(&to, amount) {
Ok(()) => { /* ... */ }
Err(CallError::Fault(f)) => { /* ... */ }
Err(e) => match_exn!(e, {
ERC20Error::TooLarge => { /* ... */ }
LibraryExn::NonNegativeIntOverflow => { /* ... */ }
_ => e.re_throw(),
}),
}When only a classification is needed, avoid retaining the full exception:
let outcome = token.map_exceptions(|exn| {
match_exn!(exn, {
ERC20Error::TooLarge => true,
_ => exn.re_throw(),
})
}).try_transfer(&to, amount);
match outcome {
Ok(()) => { /* ... */ }
Err(RawCallError::Exception(true)) => { /* handle TooLarge */ }
Err(other) => { /* handle call faults and other failures */ }
}Everything structural — Ok, Fault, Invalid — stays an ordinary Rust
match with real exhaustiveness checking; the macro’s only job is typed
downcasting. See match_exn! for the matching rules.
Use InvokeConfig (or the generated with_gas_limit constructor) to bound
the gas a subcall may spend, and deploy_contract to create new contracts.
get_deploy_address computes the resulting address ahead of time.
At the frame level, contract execution ends in one of three states:
- Success: return data is produced and the frame commits.
- Exception: the frame reverts with a structured payload (
throw, library exception, or forwarded exception). - Fault: the frame reverts without a structured exception payload
(for example
panic!).
Only success commits the current invocation frame’s storage changes.
§Exceptions
A throwable type is one annotated with
#[contract_exception] (or
#[exn] if you write your own derives), which implements
Exn and gives the type a selector derived from its canonical signature.
Clients dispatch on that selector, so a caller can tell your exceptions apart
from an unrelated contract’s without agreeing on discriminant numbering.
Declare which ones a contract may throw with throws = ... on #[contract].
The SDK’s own failures arrive as LibraryExn. Absence (a missing key, an
empty queue) is an expected outcome, and comes back the same way; identify it
with is_storage_missing, or use
none_if_missing to narrow just that case
to None while re-throwing everything else.
A try_* function never aborts the VM on its own account: its syscalls,
buffer fetches and decoding all report failure through the return type, so the
only way one aborts is a closure you handed it. exn states this in
full.
§Events
Emit with event; derive the type with
#[derive(Event)].
Declare emitted types with #[contract(emits(MyEvent))] so their definitions
are retained in the generated contract spec. Emitting an event at runtime does
not by itself retain its spec; see #[contract].
Derived events reserve topic 0 for the event signature. That signature is based on the package name, package version, and event type name, so changing any of those changes the emitted signature topic.
Thruput currently supports up to three total topics per event. With
#[derive(Event)], that means the signature plus up to two additional
#[topic] fields.
Topic fields use their IntoTopic representation. Supported scalar types
encode directly; strings and byte slices are hashed and cannot be recovered
from a topic. Non-topic fields form the decoded payload.
TypedEvent holds the raw topics and that payload. The harness queries
assert_event and
filter_events provide this typed view.
§Authorization
Authorization travels with the call. A Signed<T> parameter is a handle to
a host-held auth token: it encodes to zero bytes, and the handle rides
alongside the XDR arguments. A method signature therefore states in its types
which arguments must have been authorized.
Signed::consume hands back the payload and the address that minted the
token. Any contract can mint a token whose payload decodes as T, so
consuming proves only that some contract minted it and that this contract is
its intended consumer. Check the returned minter against an address you
trust before acting on the payload. Skipping that check is an authorization
bypass.
#[contract_type]makes a struct or enum usable as an argument, return value, or auth-token payload. It generates the auth-handle walkers that let aSigned<T>nest inside it (an enum variant included), and theMintablepreimage mirror used to mint tokens.signerholds the token vocabulary:Signed<Opaque>for a token whose payload type is not yet known,Signed::assumeto reinterpret one, andAssumeTokensto destructure aVec<Signed<Opaque>>into a typed tuple.get_auth_claimreads the current transaction’sAuthClaim; for a contract acting as an account,set_address_required_weight,add_address_public_key, andremove_address_public_keydeclare the public keys and weights its address requires.
thruput-signed-op is the wallet-facing shape of this — Thruput’s
ERC-1271 equivalent, with the message typed and domain-separated in the
spirit of EIP-712 and replay-protected by the chain’s uniquifier model.
execute_signed_op returns the one auth token a wallet mints — the root of
whatever it authorizes, with tokens for downstream contracts as child nodes.
The caller names its payload type with Signed::assume, then consumes it
and checks its minter against the wallet address it trusts.
§Minting limits
A token node carries at most 4 direct children
(thruput_xdr::auth_token::kAuthTokenMaxChildNodes), and mint_auth_token
panics past that rather than reporting it. The count is per node and per
level of the preimage — containers do not open a new level, so five elements
in a Vec<Signed<u64>> field are five children of one node. A nested
Signed<T> does open a level: its own payload gets its own budget of four.
This matters more on chain than in a test: a panicking contract faults with no message, code or location (#358), so a preimage that outgrew the cap is indistinguishable from any other trap. Keep preimage shapes within the cap by construction.
The encoded payload is separately capped at 256 bytes
(kAuthTokenMaxLen), which is reported — as
AuthTokenError::MintEncodeFailure.
§Arithmetic
U256 and its signed counterpart I256 behave like u128 and i128,
including on overflow: the operators wrap when overflow-checks is off — as
in every contract profile — and panic when it is on. The native test harness
builds with overflow checks on, so an overflow that fails a test wraps
silently on-chain. A passing test proves nothing about overflow behavior in
deployment.
Signed division is the one exception, and it follows the primitives: I256::MIN / -1 and I256::MIN % -1 panic in every profile, because that is what
i128 does — the hardware alternative is a trap, so Rust does not gate it on
overflow-checks. Use wrapping_div / wrapping_rem if you need the wrap.
Both types store eight 32-bit limbs, which is what the rv32 guest multiplies
natively, and I256 is the same bits read signed rather than a second
implementation. Prefer them over a general-purpose big-integer crate: those
typically use 64-bit limbs and multiply through u128, which the guest has to
synthesize, so they cost far more code and gas for the same arithmetic.
For money math, be explicit rather than relying on operators:
checked_add/checked_sub/checked_mulon the primitives and onU256, with a typed throw onNone;mul_div_u128/checked_mul_div_u128fora * b / dwith a 256-bit intermediate (the panics ofmul_div_u128are unconditional, notoverflow-checks-gated);U256::mul_divwhen the operands are themselves 256-bit — full precision, on an exact 512-bit intermediate;- the storage-level guards
NNIntandBalance, which check in every profile.
Beyond that, U256 and I256 carry OpenZeppelin’s Math.sol and
SignedMath.sol surfaces — mul_shr, mul_mod, mod_exp, inv_mod,
average, ceil_div, and integer_sqrt/log2/log10/log256 with a
Rounding direction — so a Solidity port has the same vocabulary. Every
fallible one ships as a checked_ form beside the panicking one.
§System functions
The SDK provides convenient wrappers around Thruput syscalls:
deploy_contract: deploy other contractsContractClient: call other contracts (typically via clients generated bycontract)get_caller,get_current_address,contract_abort,contract_revert: frame context and exit routinescrypto: hash and signature operationsHasher: incremental hashing- Key-value storage primitives, re-exported at the crate root:
delete,delete_exclusive: remove entriesbytestring_set,bytestring_get_sized: byte blobsnon_negative_int_set,non_negative_int_inc: non-negative integersretrocausal_queue_insert,retrocausal_queue_consume_sized: retrocausal queues
- Low-level syscall bindings:
- Emitting events:
Context about the running transaction:
block: the height of the block being executed instats: transaction statistics, includinggas_remaining()log_str,log: contract logging
Other useful modules and types:
§Interfaces And Specs
#[contract] on a trait defines a reusable interface; #[contract] on an
impl of that trait exports an implementation. Callers depend on the interface
crate and get the same generated client either way. That is how the standard
interfaces in standard-interfaces/ (the thruput-*-if crates:
thruput-erc20-if, thruput-erc20-metadata-if, thruput-erc20-pausable-if,
thruput-erc20-permit-if, thruput-erc721-if, thruput-erc165-if,
thruput-access-control-if, thruput-signed-op-if) are consumed.
Every #[contract] trait also carries an InterfaceId as
Trait::INTERFACE_ID, derived from its name and major version, and every
#[contract] impl block leaves a record of its interface’s id in the
contract’s interface table. thruput-erc165 is the
query surface: impl_erc165!() adds a supports_interface entrypoint
answered by implements!(id) from the impls that actually linked, and a
supports_interfaces entrypoint that answers a bounded list of ids in one
call. A contract without it carries no table in its deployed image.
Alongside the entrypoints, the macros emit a machine-readable contract
spec: the interface’s methods, their argument and return types, and the
exceptions it declares. Types reach the spec through
#[contract_type] or
ContractTypeSpec.
§Testing
Three testing lanes, all behind feature dev:
client_test: simplest path for exercising a generated client against a mock registrationTestEnvironment: direct control over environment, blocks, deployment, and multi-contract scenariostest_rv32(): run a built rv32 contract artifact in the test harness
When a test needs one transaction to see another’s committed changes, call
TestEnvironment::advance_block between them. Transactions in the same block
read the same committed snapshot; see TestEnvironment::transact.
Typical native client test, with the contract crate calling
thruput_sdk::declare_mock_contract!(); in its lib.rs to generate
register_mock_contract:
use my_contract::MyContractClient;
thruput_sdk::client_test(
|env| my_contract::register_mock_contract(env),
|client: &MyContractClient| {
// Call methods on `client`
},
);Direct environment control:
use thruput_sdk::{ContractAddress, Named, StorageKey, TestEnvironment};
let env = TestEnvironment::no_cost();
let addr = ContractAddress::named("my_test");
env.transact(|tx| {
tx.call(&addr).run(|| {
let key = StorageKey::default();
thruput_sdk::bytestring_set(&key, b"hello");
})
})
.assert_success();Use the full env.transact form when a test needs multiple transactions,
asserts on aborts or faults, or decodes typed results.
The chain settings an environment runs under – the storage cost model, the
network hash, the genesis root, and the network config parameters – come
from TestEnvironment::builder() when a
test wants something other than the defaults. It is entirely optional; the
constructors above are unaffected by it.
// A contract's behavior at the chain's live-hasher cap, without needing a
// chain configured that way. Every unset parameter keeps its stock value.
let env = TestEnvironment::builder()
.no_cost()
.with_max_sha256_buffers(2)
.build();Advanced helpers are available when you need lower-level control:
Re-exports§
pub use thruput_contract_spec as contract_spec;pub use thruput_u256 as u256;pub use block::*;pub use event::*;pub use exn::*;pub use signer::*;pub use types::*;
Modules§
- base58
- Allocation-free base58 conversion for public identifiers. Allocation-free Bitcoin/Solana base58 conversion for identifier bytes.
- block
- crypto
- System functions: hash and signature
- event
- exn
- Exceptions (part of the SDK’s call-wrapper)
- interface_
table - The interface table: which interfaces this contract implements, collected
by the linker from its
#[contract]impl blocks. - network_
config - The chain’s execution parameters, and a builder for non-default ones.
- read_
xdr - Reading XDR data into Rust types.
- remote
- Off-chain invocation through generated
<Iface>Remoteproxies. Invoking a deployed contract from off-chain code. - signer
- stats
- storage
- Datatypes backed by the key-value store.
- sys_
result - Primitive interfaces for system functions that return
Result. - types
- Types
- write_
xdr - Writing Rust values as XDR data.
- xdr
Macros§
- contract_
local - Use this macro to wrap static definitions in order to make them work correctly in the test environment. The statics are placed in thread-local storage so that concurrently-run tests don’t bash each other.
- contract_
test - Run some code in the test environment, as a single auto-committed transaction at a deterministic per-test address.
- debug_
log - declare_
mock_ contract - export_
interface_ spec - Anchor a
#[contract]trait’s spec for inclusion. Spec shaking drops a trait’s (candidate) interface spec unless something anchors it — normally a#[contract] impl. Use this in an interface crate’s spec-carriermain.rsso building that crate on its own emits the interface’s full spec: - hash_
ident - hash_
to_ array - Compute a
[u8; 32]at compile time: sha256 of the literal’s value (quotes stripped, escapes resolved). Accepts string and byte-string literals:hash_to_array!("foo")== sha256 of the 3 bytesfooand agrees withthruput_sdk::crypto::sha256(b"foo")at runtime and withsha256_static!/static_key!for the same string. - implements
- True if this contract carries a
#[contract]impl of the interface identified by the givenInterfaceId. - match_
exn - Match a caught exception against any exception type, whatever the called
interface declared it
throws. - sha256_
array_ ident - Like
sha256_ident!(sha256 of the bare identifier’s text), but expands to a[u8; 32]array instead of aSHA256Hash. - sha256_
ident - Compute a
SHA256Hashat compile time: sha256 of the bare identifier’s text (no quotes —sha256_ident!(foo)hashes the 3 bytesfoo). - sha256_
static - Compute a
SHA256Hashat compile time: sha256 of the string literal’s value (quotes stripped, escapes resolved). - static_
key - Compute a
StorageKeyat compile time: sha256 of the string literal’s value (quotes stripped, escapes resolved). - storage_
domain_ uniqueness_ test - Declare a native test asserting that no two contract state roots linked into this binary share a storage domain.
- with_
call_ tracking - with_
debug_ context
Structs§
- Auth
Token Preimage - Base58
- Borrowed fixed-size bytes formatted as unprefixed base58.
- Continuable
Frame - A frame that is still open after run_continuable returned FrameAction::Continue. Supports chaining additional run_continuable() calls or finishing.
- Contract
Cell - A wrapped
core::cell::Cellthat implementsSyncso it can be used in statics. Methods of the innerCellare available via this wrapper’sDerefimplementation. The wrapper adds no costs toCell. - Contract
RefCell - A wrapped
core::cell::RefCellthat implementsSyncso it can be used in statics — the by-reference companion toContractCellfor state that must be borrowed in place (e.g. the SDK’s fixed buffers, which would cost a stack copy if moved throughCell). Declare viacontract_local!; the SDK accesses it through a crate-private checkout trait that works identically against the guest static and the test env’s thread-local. - DbConflict
Code - Reason a storage delta could not be applied during two-phase commit. These are the nondeterministic failures of try_push_new_subtransaction: any of them causes ExecResultTxNonDeterministicError, and the transaction is excluded from the block. Codes are intentionally coarse; finer-grained detail may be added later behind a debug-only extension.
- DbConflict
Diagnostic - One conflicting storage op. Fixed-size:
ContractAddress[32]plus a fixed-size StorageKey plus the code — no heap allocation. - Duration
- A span of time, for arithmetic on
TimePoint. - Frame
Builder - Builder for configuring and executing a single invocation frame.
- Frame
Handle - Handle to the current frame, available inside run_continuable closures. Provides child_call() for opening nested frames.
- Frame
Result - Result of executing a single invocation frame. Wraps InvocationFrameOutput + optional trace + per-frame events.
- Hasher
- An incremental hasher, implemented by the VM.
- Hex
- Host
FnError Code - I256
- A 256-bit signed integer.
- Invoke
Config - Invoke
Error - Panic payload classifying how an invocation frame terminated; downcast at the frame’s catch site and mapped to the frame outcome.
- Invoke
Error Code - Invoke
Flag - Flags that modify the behavior of a contract invocation.
- Mock
Contract - Handle to a mock contract registered in a
TestEnvironment: a contract whose entrypoints are native closures instead of rv32 code. - Mock
Transaction Config - Configuration for a mocked transaction, applied when the handler is
created. Build one with
TestEnvironment::transaction, or useMockTransactionConfig::defaultfor the standard setup. - Mock
Transaction Handler - A mocked transaction context: runs one, and only one, transaction, with
exactly one root frame (
call/open_root_framepanic on a second invocation). Nest further calls as child frames, or use a second transaction. - Network
Config Builder - Builder for a
NetworkConfigstating non-default execution parameters. - Panic
Location - Where a contract body panicked.
- Panic
Record - What the harness could see of a contract body’s panic.
- Rv32
Stack Usage - What an rv32 guest did with its stack pointer over one invocation.
- Stats
- Storage
Cost Model - System
Error Code - Test
Environment - An in-process Thruput instance for testing contracts natively.
- Test
Environment Builder - Builder for a
TestEnvironmentthat needs something other than the stock chain settings. - Transact
Result - Result of a full transaction: root frame result + commit outcome. Events are accessed via the root frame’s per-frame events.
- Transaction
Builder - Builder for configuring a mocked transaction before executing it.
- TryFrom
IntError - Returned when an integer conversion in this crate does not fit.
- U256
- A 256-bit unsigned integer.
Enums§
- DbConflict
Result - Conflict diagnostics attached to a failed try_push_new_subtransaction. The discriminant is the DbDiagnosticLevel the database selected from the block’s execution mode, so the variable-length arm is only ever constructed in kDbDiagnosticAll mode (debug-build proposals); prod levels are allocation-free by construction.
- Frame
Action - What an
executeclosure tells the harness to do with its frame. - RawCall
Error - The raw, untyped error from a contract call.
- Read
Error - Errors that can occur when reading XDR data.
- Rounding
- The rounding direction of an inexact result.
- TryCommit
Result - Outcome of a two-phase commit (
try_commit_transaction). - Write
Error - Errors that can occur when writing XDR data.
Constants§
- SP_
UNWRITTEN - The value
Rv32StackUsage::sp_initialandRv32StackUsage::sp_minhold when the guest never wrotesp.
Traits§
- Collect
Auth Handles - Extract the auth-token handles of every
Signedvalue nested inself, in declaration order, so they can travel alongside the XDR payload of a contract call (Signedencodes to zero bytes; the handles are passed out-of-band). - Context
- Contract
Client - Contract
Test - Contract
Type Name - Provides the spec-visible name for a contract type.
- Hash
- SHA-256 of a value’s CXS encoding.
- MapExceptions
- Classify a borrowed exception during a generated call.
- Mintable
- Mintable
Type - Marker trait for types that have a pre-signing (preimage) representation.
- Named
- Create deterministic test addresses from human-readable names.
- OrRe
Throw - Extension trait for transparently propagating a contract error.
- OrSyscall
Throw - Extension trait for turning a failed raw syscall into the SDK’s syscall
exception. A
SysErris only the error code, so the caller names the syscall; the exception carries both (seeSyscallExn). - OrThrow
- Extension trait for replacing an error with a contract exception.
- ReThrow
- A type that can re-throw itself as a contract exception or fault.
- ReadXDR
- Types that can be constructed by reading XDR-encoded data, possibly sharing data from the input.
- ReadXDR
Owned - Types that can be constructed by reading XDR data of any lifetime.
- Reader
- A reader that can produce XDR values, some borrowed with lifetime
'r. - Receive
Auth Handles - Re-attach auth-token handles to every
Signedvalue nested inself, drawing them fromhandlesin declaration order.Signeddecodes from zero XDR bytes with a sentinel handle; this trait fills in the real handles delivered out-of-band. - Test
Register Fn - WriteXDR
- Types that can be written as XDR data.
- Writer
- Something that can write XDR values to a serialization format.
Functions§
- add_
address_ public_ key - Register
public_keyatpk_index. ML-DSA-65 keys need a runtime with ML-DSA-65 support; an older runtime, like any runtime given a scheme it does not know, rejects the key withInvalidSyscallInput. - base58_
encode - Wrap fixed-size identifier bytes for allocation-free base58 formatting.
- bytestring_
exists - Reports whether a bytestring exists at the given key.
- bytestring_
get - bytestring_
get_ len - Returns the length of the bytestring stored at the given key.
- bytestring_
get_ sized - Returns the bytestring contents in a statically-sized array.
- bytestring_
set - Sets the value at the given key to the given bytestring.
- bytestring_
set_ exclusive - Sets the value at the given key to the given bytestring, then requests
ExclusiveLockfor the key. - bytestring_
try_ get - Read the bytestring at
key, reporting failure asErrinstead of aborting (thetry_law; see theexnmodule docs). A missing key is aLibraryExn::Syscallfor whichis_storage_missingis true; a value of another storage type or any other syscall failure is aLibraryExn::Syscallas well. - checked_
mul_ div_ u128 - Computes
a * b / dexactly, returningNoneifdis zero or the quotient does not fit in au128. - clear_
storage_ flags - Removes every flag the current transaction requests for
key. Does nothing if no write tokeyis pending. - client_
test - contract_
abort - contract_
abort_ encoded - contract_
revert - Terminate the current call frame immediately, reverting it.
- delete
- Delete anything stored at the given key.
- delete_
exclusive - delete_
shared - deploy_
address - deploy_
contract - encode_
xdr - encode_
xdr_ into - ensure
- get_
auth_ claim - get_
calldata_ len - get_
caller - get_
current_ address - get_
deploy_ address - get_
deploy_ address_ for_ other - get_
source_ transaction_ hash - The hash of the transaction that initiated the current execution.
- hex_
encode - into_
root_ call_ result - Decode a
TransactResult’s root-frame outcome into the sameResult<T, RawCallError>shape that contract clients produce. Use this when a test asserts on typed exceptions/selectors rather than raw buffers. - load_
rv32_ contract - log
- log_str
- mul_
div_ u128 - Computes
a * b / dexactly, without the intermediate product needing to fit in 128 bits. - non_
negative_ int_ get - Get the current value.
- non_
negative_ int_ inc - Increment the value.
- non_
negative_ int_ set - Set the value.
- non_
negative_ int_ set_ exclusive - Set the value exclusively.
- non_
negative_ int_ strict_ inc - Increment the value.
- non_
negative_ int_ try_ get - Get the current value, reporting failure as
Errinstead of aborting (thetry_law; see theexnmodule docs). - non_
negative_ int_ try_ strict_ inc - Increment the value, like
non_negative_int_strict_inc, but report failure to the caller instead of throwing (thetry_law; see theexnmodule docs), so a contract can raise a domain-specific exception (e.g. an ERC20 “amount too large”). - read_
xdr - Reads an XDR value of type
Tfrom the readerr. - receive_
auth_ handles_ from_ iter - register_
mock_ package - remove_
address_ public_ key - retrocausal_
queue_ consume - retrocausal_
queue_ consume_ sized - retrocausal_
queue_ insert - retrocausal_
queue_ peek - retrocausal_
queue_ peek_ sized - retrocausal_
queue_ try_ consume - Consume the next queue entry into a boxed slice, reporting failure as
Errinstead of aborting (thetry_law). An empty queue is aLibraryExn::Syscallfor whichis_storage_missingis true. - retrocausal_
queue_ try_ consume_ sized - Consume the next queue entry as an
N-byte array, reporting failure asErrinstead of aborting (thetry_law; see theexnmodule docs). - retrocausal_
queue_ try_ peek - Peek at the next queue entry as a boxed slice; the
try_-law counterpart ofretrocausal_queue_peek. Same error contract asretrocausal_queue_try_consume. - retrocausal_
queue_ try_ peek_ sized - Peek at the next queue entry as an
N-byte array; thetry_-law counterpart ofretrocausal_queue_peek_sized. Same error contract asretrocausal_queue_try_consume_sized. - set_
address_ required_ weight - set_
storage_ flags - Adds
flags(a bitwise OR) to the flags the current transaction requests forkey. - storage_
flags - Returns the flags the current transaction requests for
key, as seen by the current call frame. A key with no pending write has none. - test_
network_ hash - The
NetworkHashthatTestEnvironments are created with:sha256(TEST_NETWORK_NAME). - test_
rv32 - throw
- trap
- Abort the current invocation with a deterministic error.
- try_
get_ calldata_ len - with_
debug_ context - Add to the stack of debugging-context values.
- write_
xdr - Writes an XDR value to the writer.
Type Aliases§
- Auth
Handle Buf - BitMap
- A bitmap representing a set of key IDs.
- Call
Error - The error type of ordinary generated
try_*client methods: a call failure that may carry a caught exception, kept untyped. - Calldata
- The calldata buffer — the SDK’s single
ScratchBuf. With theallocfeature this is a heapVecsized exactly to the calldata (any length); without it, a fixedSCRATCH_MAX-byte buffer. - Invoke
Flag Set - A bitset of InvokeFlag values.
- Read
Result - A result type for reader operations.
- Test
Environment Handle - Shared handle to a
TestEnvironment; returned by its constructors. - Weight
- Represents the weight of a signature key in multi-signature schemes.
- Write
Result - A result type for writer operations.
Attribute Macros§
- contract
- Expose methods for cross-contract calls.
- contract_
exception #[contract_exception]or#[contract_exception(version = "1.0.0", name = "...")]— full convenience macro: derives +#[repr(i32)]+impl Exn+impl ContractTypeName.- contract_
type - Make a struct or enum usable as a contract argument, return value, or
auth-token payload: derives XDR codecs, spec registration,
auth-handle walkers, and the
Mintablepreimage machinery. - exn
#[exn]or#[exn(version = "1.0.0")]— emitsimpl Exnwith a computed selector. Use this when you handle your own derives. For the full convenience macro, use#[contract_exception]instead.- storage
- Storage macros and traits for the key-value store.
Derive Macros§
- Contract
Type Spec - Derive
ContractTypeSpec(plusContractTypeRefSpec, a linker anchor, and the raw typedef link-section fragment) for a struct or enum. - Deletable
- Error
- Event
- Derive event encoding, signature and spec metadata.
- ReadXDR
- Derives the
ReadXDRtrait for a struct or enum. - Storage
- WriteXDR
- Derives the
WriteXDRtrait for a struct or enum.