Skip to content

Commit e81732d

Browse files
TarekkMAlibrelois
andauthored
add transact_create_force_address (#309)
* add fn transact_create_force_address * fmt * add allow_explicit_address feature * add info about allow_explicit_address in the README.md --------- Co-authored-by: Éloïs <[email protected]>
1 parent 6d86fe2 commit e81732d

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ std = [
5050
"evm-gasometer/std",
5151
"evm-runtime/std",
5252
]
53+
allow_explicit_address = []
5354
with-codec = [
5455
"scale-codec",
5556
"scale-info",

README.md

+11
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@
1919
* written in Rust, can be used as a binary, cargo crate or shared
2020
library
2121

22+
### Feature Flags
23+
24+
SputnikVM provides optional feature flags to enable specific functionalities:
25+
26+
- `allow_explicit_address`
27+
Enables the `transact_create_force_address` method, allowing contract creation with a predefined address.
28+
- `with-codec`
29+
- `with-serde`
30+
- `tracing`
31+
- `force-debug`
32+
2233
## Dependencies
2334

2435
Ensure you have at least `rustc 1.51.0 (2fd73fabe 2021-03-23)`. Rust 1.50.0 and

src/executor/stack/executor.rs

+49
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,55 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet>
550550
}
551551
}
552552

553+
/// Execute a `CREATE` transaction that force the contract address
554+
#[cfg(feature = "allow_explicit_address")]
555+
pub fn transact_create_force_address(
556+
&mut self,
557+
caller: H160,
558+
value: U256,
559+
init_code: Vec<u8>,
560+
gas_limit: u64,
561+
access_list: Vec<(H160, Vec<H256>)>, // See EIP-2930
562+
contract_address: H160,
563+
) -> (ExitReason, Vec<u8>) {
564+
event!(TransactCreate {
565+
caller,
566+
value,
567+
init_code: &init_code,
568+
gas_limit,
569+
address: self.create_address(CreateScheme::Fixed(contract_address)),
570+
});
571+
572+
if let Some(limit) = self.config.max_initcode_size {
573+
if init_code.len() > limit {
574+
self.state.metadata_mut().gasometer.fail();
575+
return emit_exit!(ExitError::CreateContractLimit.into(), Vec::new());
576+
}
577+
}
578+
579+
if let Err(e) = self.record_create_transaction_cost(&init_code, &access_list) {
580+
return emit_exit!(e.into(), Vec::new());
581+
}
582+
self.initialize_with_access_list(access_list);
583+
584+
match self.create_inner(
585+
caller,
586+
CreateScheme::Fixed(contract_address),
587+
value,
588+
init_code,
589+
Some(gas_limit),
590+
false,
591+
) {
592+
Capture::Exit((s, _, v)) => emit_exit!(s, v),
593+
Capture::Trap(rt) => {
594+
let mut cs = Vec::with_capacity(DEFAULT_CALL_STACK_CAPACITY);
595+
cs.push(rt.0);
596+
let (s, _, v) = self.execute_with_call_stack(&mut cs);
597+
emit_exit!(s, v)
598+
}
599+
}
600+
}
601+
553602
/// Execute a `CALL` transaction with a given caller, address, value and
554603
/// gas limit and data.
555604
///

0 commit comments

Comments
 (0)