example_erc20_gas/
exec.rs

1use crate::handler::Erc20MainnetHandler;
2use revm::{
3    context_interface::{
4        result::{EVMError, ExecutionResult, HaltReason, InvalidTransaction},
5        ContextTr, JournalTr,
6    },
7    database_interface::DatabaseCommit,
8    handler::{
9        instructions::InstructionProvider, ContextTrDbError, EthFrame, EvmTr, Handler,
10        PrecompileProvider,
11    },
12    interpreter::{interpreter::EthInterpreter, InterpreterResult},
13    state::EvmState,
14};
15
16type Erc20Error<CTX> = EVMError<ContextTrDbError<CTX>, InvalidTransaction>;
17
18/// Executes a transaction using ERC20 tokens for gas payment.
19/// Returns the execution result and the finalized state changes.
20/// This function does not commit the state to the database.
21pub fn transact_erc20evm<EVM>(
22    evm: &mut EVM,
23) -> Result<(ExecutionResult<HaltReason>, EvmState), Erc20Error<EVM::Context>>
24where
25    EVM: EvmTr<
26        Context: ContextTr<Journal: JournalTr<State = EvmState>>,
27        Precompiles: PrecompileProvider<EVM::Context, Output = InterpreterResult>,
28        Instructions: InstructionProvider<
29            Context = EVM::Context,
30            InterpreterTypes = EthInterpreter,
31        >,
32        Frame = EthFrame<EthInterpreter>,
33    >,
34{
35    Erc20MainnetHandler::new().run(evm).map(|r| {
36        let state = evm.ctx().journal_mut().finalize();
37        (r, state)
38    })
39}
40
41/// Executes a transaction using ERC20 tokens for gas payment and commits the state.
42/// This is a convenience function that runs the transaction and immediately
43/// commits the resulting state changes to the database.
44pub fn transact_erc20evm_commit<EVM>(
45    evm: &mut EVM,
46) -> Result<ExecutionResult<HaltReason>, Erc20Error<EVM::Context>>
47where
48    EVM: EvmTr<
49        Context: ContextTr<Journal: JournalTr<State = EvmState>, Db: DatabaseCommit>,
50        Precompiles: PrecompileProvider<EVM::Context, Output = InterpreterResult>,
51        Instructions: InstructionProvider<
52            Context = EVM::Context,
53            InterpreterTypes = EthInterpreter,
54        >,
55        Frame = EthFrame<EthInterpreter>,
56    >,
57{
58    transact_erc20evm(evm).map(|(result, state)| {
59        evm.ctx().db_mut().commit(state);
60        result
61    })
62}