arb_stylus/
evm_api.rs

1use alloy_primitives::{Address, B256, U256};
2
3use crate::ink::{Gas, Ink};
4
5/// Status codes returned by EVM API operations.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7#[repr(u8)]
8pub enum EvmApiStatus {
9    Success = 0,
10    Failure = 1,
11    OutOfGas = 2,
12    WriteProtection = 3,
13}
14
15/// Outcome kind from a user program or call.
16#[derive(Clone, Copy, Debug, PartialEq, Eq)]
17#[repr(u8)]
18pub enum UserOutcomeKind {
19    Success = 0,
20    Revert = 1,
21    Failure = 2,
22    OutOfInk = 3,
23    OutOfStack = 4,
24}
25
26/// Response from a CREATE operation.
27pub enum CreateResponse {
28    Success(Address),
29    Fail(String),
30}
31
32/// The EVM API trait that Stylus programs use to interact with EVM state.
33///
34/// This is the bridge between the WASM runtime and the EVM execution environment.
35/// Implementations are provided by the block executor.
36pub trait EvmApi: Send + 'static {
37    /// Read a storage slot. Returns the value and access cost.
38    fn get_bytes32(&mut self, key: B256, evm_api_gas_to_use: Gas) -> eyre::Result<(B256, Gas)>;
39
40    /// Cache a storage value for later flushing.
41    fn cache_bytes32(&mut self, key: B256, value: B256) -> eyre::Result<Gas>;
42
43    /// Flush the storage cache to EVM state.
44    fn flush_storage_cache(
45        &mut self,
46        clear: bool,
47        gas_left: Gas,
48    ) -> eyre::Result<(Gas, UserOutcomeKind)>;
49
50    /// Read a transient storage slot.
51    fn get_transient_bytes32(&mut self, key: B256) -> eyre::Result<B256>;
52
53    /// Write a transient storage slot.
54    fn set_transient_bytes32(&mut self, key: B256, value: B256) -> eyre::Result<UserOutcomeKind>;
55
56    /// Execute a CALL. Returns return data length, gas cost, outcome, and the
57    /// updated page counters following the sub-call.
58    fn contract_call(
59        &mut self,
60        contract: Address,
61        calldata: &[u8],
62        gas_left: Gas,
63        gas_req: Gas,
64        value: U256,
65        pages: (u16, u16),
66    ) -> eyre::Result<(u32, Gas, UserOutcomeKind, (u16, u16))>;
67
68    /// Execute a DELEGATECALL.
69    fn delegate_call(
70        &mut self,
71        contract: Address,
72        calldata: &[u8],
73        gas_left: Gas,
74        gas_req: Gas,
75        pages: (u16, u16),
76    ) -> eyre::Result<(u32, Gas, UserOutcomeKind, (u16, u16))>;
77
78    /// Execute a STATICCALL.
79    fn static_call(
80        &mut self,
81        contract: Address,
82        calldata: &[u8],
83        gas_left: Gas,
84        gas_req: Gas,
85        pages: (u16, u16),
86    ) -> eyre::Result<(u32, Gas, UserOutcomeKind, (u16, u16))>;
87
88    /// Deploy via CREATE.
89    fn create1(
90        &mut self,
91        code: Vec<u8>,
92        endowment: U256,
93        gas: Gas,
94        pages: (u16, u16),
95    ) -> eyre::Result<(CreateResponse, u32, Gas, (u16, u16))>;
96
97    /// Deploy via CREATE2.
98    fn create2(
99        &mut self,
100        code: Vec<u8>,
101        endowment: U256,
102        salt: B256,
103        gas: Gas,
104        pages: (u16, u16),
105    ) -> eyre::Result<(CreateResponse, u32, Gas, (u16, u16))>;
106
107    /// Get the return data from the last call.
108    fn get_return_data(&self) -> Vec<u8>;
109
110    /// Emit a log with the given data and number of topics.
111    fn emit_log(&mut self, data: Vec<u8>, topics: u32) -> eyre::Result<()>;
112
113    /// Get an account's balance. Returns balance and access cost.
114    fn account_balance(&mut self, address: Address) -> eyre::Result<(U256, Gas)>;
115
116    /// Get an account's code. Returns code and access cost.
117    fn account_code(
118        &mut self,
119        arbos_version: u64,
120        address: Address,
121        gas_left: Gas,
122    ) -> eyre::Result<(Vec<u8>, Gas)>;
123
124    /// Get an account's code hash. Returns hash and access cost.
125    fn account_codehash(&mut self, address: Address) -> eyre::Result<(B256, Gas)>;
126
127    /// Capture tracing information for host I/O calls.
128    fn capture_hostio(
129        &mut self,
130        name: &str,
131        args: &[u8],
132        outs: &[u8],
133        start_ink: Ink,
134        end_ink: Ink,
135    );
136}