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