Skip to main content

Module contract

Module contract 

Source
Expand description

Contract method helpers.

entrypoint_id computes a method selector from an interface identity. Contract binds an address plus that identity and offers typed call/view, encoding arguments and decoding returns with xdrs so tests name methods and pass Rust values instead of hand-building calldata. ContractCall is a prepared, typed call: the building block for typed clients whose methods mirror a contract interface.

Caller implements RemoteInvoker, so an interface’s generated <Iface>Remote proxy (from #[contract] with thruput-sdk/remote) can serve as that typed client. Its methods declared pure or readOnly return a ContractView; all others, including those that declare no effect, return a ContractCall.

Awaiting either gives the decoded return. A ContractCall can instead be awaited with its receipt, submitted without waiting, or simulated. With the Counter interface from the crate docs, plus a peek method that declares no effect:

use thruput_testkit::{AgentContext, Caller, Result, TestkitError};

async fn exercise(ctx: &AgentContext, counter: &CounterRemote<Caller>) -> Result<()> {
    // Submit, require success, and decode the return.
    let count = counter.increment(1).await?;

    // The same, keeping the receipt for its events or gas.
    let (next, receipt) = counter.increment(1).with_receipt().await?;
    assert_eq!(next, count + 1);
    println!("{} events, {} gas", receipt.events.len(), receipt.gas_used);

    // Only the receipt, ignoring the return value.
    let receipt = counter.increment(1).receipt().await?;
    println!("{} gas", receipt.gas_used);

    // Submit now and await later: several calls can land in one block,
    // which a manual block driver produces on request.
    let first = counter.increment(1).submit().await?;
    let second = counter.increment(1).submit().await?;
    first.await_pending().await?;
    second.await_pending().await?;
    ctx.network().produce_block().await?;
    first.await_receipt().await?;
    second.await_receipt().await?;

    // A call that reverts is an error, which a test can expect.
    match counter.increment(u64::MAX).await {
        Err(TestkitError::Reverted { .. }) => {}
        other => panic!("an overflowing increment should revert, got {other:?}"),
    }

    // A method that declares no effect returns a `ContractCall`, even when
    // it only reads: `simulate` it, since awaiting it would submit.
    assert_eq!(counter.peek().simulate().await?, counter.get().await?);
    Ok(())
}

Structs§

Contract
A deployed contract instance bound to its interface identity.
ContractCall
A typed state-changing contract call, prepared but not yet submitted.
ContractEntrypointID
8-byte identifier for a contract method (entrypoint).
ContractView
A typed read-only contract invocation, prepared but not yet simulated.
SubmittedContractCall
A typed contract call submitted without waiting for block production.

Functions§

entrypoint_id
Compute the entrypoint selector for a contract method.
try_entrypoint_id
Fallible form of entrypoint_id for interface identities from untrusted input.