@@ -550,6 +550,55 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet>
550
550
}
551
551
}
552
552
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
+
553
602
/// Execute a `CALL` transaction with a given caller, address, value and
554
603
/// gas limit and data.
555
604
///
0 commit comments