revm_interpreter/interpreter_action/
create_inputs.rs

1use context_interface::CreateScheme;
2use core::cell::OnceCell;
3use primitives::{Address, Bytes, U256};
4
5/// Inputs for a create call
6#[derive(Clone, Debug, Default, PartialEq, Eq)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct CreateInputs {
9    /// Caller address of the EVM
10    caller: Address,
11    /// The create scheme
12    scheme: CreateScheme,
13    /// The value to transfer
14    value: U256,
15    /// The init code of the contract
16    init_code: Bytes,
17    /// The gas limit of the call
18    gas_limit: u64,
19    /// Cached created address. This is computed lazily and cached to avoid
20    /// redundant keccak computations when inspectors call `created_address`.
21    #[cfg_attr(feature = "serde", serde(skip))]
22    cached_address: OnceCell<Address>,
23}
24
25impl CreateInputs {
26    /// Creates a new `CreateInputs` instance.
27    pub fn new(
28        caller: Address,
29        scheme: CreateScheme,
30        value: U256,
31        init_code: Bytes,
32        gas_limit: u64,
33    ) -> Self {
34        Self {
35            caller,
36            scheme,
37            value,
38            init_code,
39            gas_limit,
40            cached_address: OnceCell::new(),
41        }
42    }
43
44    /// Returns the address that this create call will create.
45    ///
46    /// The result is cached to avoid redundant keccak computations.
47    pub fn created_address(&self, nonce: u64) -> Address {
48        *self.cached_address.get_or_init(|| match self.scheme {
49            CreateScheme::Create => self.caller.create(nonce),
50            CreateScheme::Create2 { salt } => self
51                .caller
52                .create2_from_code(salt.to_be_bytes(), &self.init_code),
53            CreateScheme::Custom { address } => address,
54        })
55    }
56
57    /// Returns the caller address of the EVM.
58    pub fn caller(&self) -> Address {
59        self.caller
60    }
61
62    /// Returns the create scheme of the EVM.
63    pub fn scheme(&self) -> CreateScheme {
64        self.scheme
65    }
66
67    /// Returns the value to transfer.
68    pub fn value(&self) -> U256 {
69        self.value
70    }
71
72    /// Returns the init code of the contract.
73    pub fn init_code(&self) -> &Bytes {
74        &self.init_code
75    }
76
77    /// Returns the gas limit of the call.
78    pub fn gas_limit(&self) -> u64 {
79        self.gas_limit
80    }
81
82    /// Set call
83    pub fn set_call(&mut self, caller: Address) {
84        self.caller = caller;
85        self.cached_address = OnceCell::new();
86    }
87
88    /// Set scheme
89    pub fn set_scheme(&mut self, scheme: CreateScheme) {
90        self.scheme = scheme;
91        self.cached_address = OnceCell::new();
92    }
93
94    /// Set value
95    pub fn set_value(&mut self, value: U256) {
96        self.value = value;
97    }
98
99    /// Set init code
100    pub fn set_init_code(&mut self, init_code: Bytes) {
101        self.init_code = init_code;
102        self.cached_address = OnceCell::new();
103    }
104
105    /// Set gas limit
106    pub fn set_gas_limit(&mut self, gas_limit: u64) {
107        self.gas_limit = gas_limit;
108    }
109}