pub struct Contract<E> { /* private fields */ }Expand description
Represents a contract instance for interacting with EVM environments.
This struct provides a way to interact with a deployed smart contract
at a specific address within a given EVM environment E.
Note: This contract interaction is not type-safe regarding the ABI.
Ensure the deployed contract at address matches the ABI used for calls (S: SolCall).
§Usage Scenarios
- Host (Preflight): Use Contract::preflight to set up calls on the host environment. The
environment can be initialized using the EthEvmEnv::builder or EvmEnv::builder. This
fetches necessary state and prepares proofs for guest execution.
- Consider CallBuilder::call_with_prefetch for calls with many storage accesses to potentially optimize preflight time by reducing RPC calls.
- Guest: Use Contract::new within the guest environment, typically initialized from EvmInput::into_env.
§Making Contract Calls (Host Preflight or Guest Execution)
To interact with the contract’s functions, you use the Contract::call_builder method to prepare a call. This follows a specific workflow:
-
Create Builder: Call Contract::call_builder with a specific Solidity function call object (e.g.,
MyCall { arg1: ..., arg2: ... }derived usingalloy_sol_types::sol!). This returns a CallBuilder instance, initializing its internal transaction environment (tx) with the contract address and call data. -
Configure Transaction: Because the underlying transaction type (
EvmFactory::Tx) is generic, configuration parameters (like caller address, value, gas limit, nonce) are set by directly modifying the public.txfield of the returned CallBuilder instance.let mut builder = contract.call_builder(&my_call); builder.tx.caller = Address::ZERO; builder.tx.value = U256::from(0); // Set value if payable builder.tx.gas_limit = 100_000; // ... set other fields like gas_price, nonce as neededNote: Fluent configuration methods like
.from(address)or.value(amount)are not available directly on theCallBuilderdue to this generic design. You must use direct field access on.tx. Consult the documentation of the specificTxtype provided by your chosenEvmFactoryfor available fields (e.g.,revm::primitives::TxEnv). -
Execute Call: Once configured, execute the call using the appropriate method on the
CallBuilderinstance. Common methods include:.call(): Executes in the guest, panicking on EVM errors..try_call(): Executes in the guest, returning aResultfor error handling..call().await: Executes preflight on the host (requireshostfeature)..call_with_prefetch().await: Executes preflight on the host, potentially optimizing state loading (requireshostfeature).
See the CallBuilder documentation for more details on execution methods.
§Examples
const CONTRACT_ADDRESS: Address = address!("dAC17F958D2ee523a2206206994597C13D831ec7"); // USDT
const ACCOUNT_TO_QUERY: Address = address!("F977814e90dA44bFA03b6295A0616a897441aceC"); // Binance
sol! {
interface IERC20 {
function balanceOf(address account) external view returns (uint);
}
}
const CALL: IERC20::balanceOfCall = IERC20::balanceOfCall { account: ACCOUNT_TO_QUERY };
// === Host Setup ===
let rpc_url = "https://ethereum-rpc.publicnode.com".parse()?;
let mut host_env = EthEvmEnv::builder().rpc(rpc_url).chain_spec(Ð_MAINNET_CHAIN_SPEC).build().await?;
// Preflight the call on the host
let mut contract_host = Contract::preflight(CONTRACT_ADDRESS, &mut host_env);
let mut builder = contract_host.call_builder(&CALL);
// Configure via builder.tx
builder.tx.caller = Address::default();
builder.tx.gas_limit = 10_000;
// Execute
let balance_result = builder.call().await?;
println!("Host preflight balance: {}", balance_result);
// Generate input for the guest
let evm_input = host_env.into_input().await?;
// === Guest Setup & Execution ===
// (Inside the RISC Zero guest)
let guest_env = evm_input.into_env(Ð_MAINNET_CHAIN_SPEC);
let contract_guest = Contract::new(CONTRACT_ADDRESS, &guest_env);
// Execute the same call in the guest
let mut builder = contract_guest.call_builder(&CALL);
builder.tx.caller = Address::default();
builder.tx.gas_limit = 10_000;
let guest_balance_result = builder.call();
println!("Guest execution balance: {}", guest_balance_result);Implementations§
Source§impl<'a, F, D, C> Contract<&'a mut EvmEnv<ProofDb<D>, F, HostCommit<C>>>where
F: EvmFactory,
impl<'a, F, D, C> Contract<&'a mut EvmEnv<ProofDb<D>, F, HostCommit<C>>>where
F: EvmFactory,
Sourcepub fn preflight(
address: Address,
env: &'a mut EvmEnv<ProofDb<D>, F, HostCommit<C>>,
) -> Self
Available on crate feature host only.
pub fn preflight( address: Address, env: &'a mut EvmEnv<ProofDb<D>, F, HostCommit<C>>, ) -> Self
host only.Creates a Contract instance for use on the host for preflighting calls.
This prepares the environment for simulating the call, fetching necessary
state via the Provider within env, and enabling proof generation
via HostEvmEnv::into_input.
Sourcepub fn call_builder<S: SolCall>(
&mut self,
call: &S,
) -> CallBuilder<F::Tx, S, &mut EvmEnv<ProofDb<D>, F, HostCommit<C>>>
Available on crate feature host only.
pub fn call_builder<S: SolCall>( &mut self, call: &S, ) -> CallBuilder<F::Tx, S, &mut EvmEnv<ProofDb<D>, F, HostCommit<C>>>
host only.Initializes a builder for preflighting a specific contract call (S) on the host.
Source§impl<'a, F: EvmFactory> Contract<&'a EvmEnv<StateDb, F, Commitment>>
impl<'a, F: EvmFactory> Contract<&'a EvmEnv<StateDb, F, Commitment>>
Sourcepub fn new(address: Address, env: &'a EvmEnv<StateDb, F, Commitment>) -> Self
pub fn new(address: Address, env: &'a EvmEnv<StateDb, F, Commitment>) -> Self
Creates a Contract instance for use within the guest environment.
The env should typically be obtained via EvmInput::into_env.
Sourcepub fn call_builder<S: SolCall>(
&self,
call: &S,
) -> CallBuilder<F::Tx, S, &EvmEnv<StateDb, F, Commitment>>
pub fn call_builder<S: SolCall>( &self, call: &S, ) -> CallBuilder<F::Tx, S, &EvmEnv<StateDb, F, Commitment>>
Initializes a builder for executing a specific contract call (S) in the guest.
Auto Trait Implementations§
impl<E> Freeze for Contract<E>where
E: Freeze,
impl<E> RefUnwindSafe for Contract<E>where
E: RefUnwindSafe,
impl<E> Send for Contract<E>where
E: Send,
impl<E> Sync for Contract<E>where
E: Sync,
impl<E> Unpin for Contract<E>where
E: Unpin,
impl<E> UnwindSafe for Contract<E>where
E: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<TxEnv, T> FromRecoveredTx<&T> for TxEnvwhere
TxEnv: FromRecoveredTx<T>,
impl<TxEnv, T> FromRecoveredTx<&T> for TxEnvwhere
TxEnv: FromRecoveredTx<T>,
§fn from_recovered_tx(tx: &&T, sender: Address) -> TxEnv
fn from_recovered_tx(tx: &&T, sender: Address) -> TxEnv
TxEnv] from a transaction and a sender address.§impl<TxEnv, T> FromTxWithEncoded<&T> for TxEnvwhere
TxEnv: FromTxWithEncoded<T>,
impl<TxEnv, T> FromTxWithEncoded<&T> for TxEnvwhere
TxEnv: FromTxWithEncoded<T>,
§fn from_encoded_tx(tx: &&T, sender: Address, encoded: Bytes) -> TxEnv
fn from_encoded_tx(tx: &&T, sender: Address, encoded: Bytes) -> TxEnv
TxEnv] from a transaction, its sender, and encoded transaction bytes.§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.