@@ -321,7 +321,7 @@ impl<'a> Runtime<'a> {
321321 if self . gas_counter > self . gas_limit { return Err ( Error :: InvalidGasState ) ; }
322322 Ok ( self . gas_limit - self . gas_counter )
323323 }
324-
324+
325325 /// General gas charging extern.
326326 fn gas ( & mut self , args : RuntimeArgs ) -> Result < ( ) > {
327327 let amount: u32 = args. nth_checked ( 0 ) ?;
@@ -511,29 +511,7 @@ impl<'a> Runtime<'a> {
511511 self . return_u256_ptr ( args. nth_checked ( 0 ) ?, val)
512512 }
513513
514- /// Creates a new contract
515- ///
516- /// Arguments:
517- /// * endowment - how much value (in Wei) transfer to the newly created contract
518- /// * code_ptr - pointer to the code data
519- /// * code_len - lenght of the code data
520- /// * result_ptr - pointer to write an address of the newly created contract
521- pub fn create ( & mut self , args : RuntimeArgs ) -> Result < RuntimeValue >
522- {
523- //
524- // method signature:
525- // fn create(endowment: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32;
526- //
527- trace ! ( target: "wasm" , "runtime: CREATE" ) ;
528- let endowment = self . u256_at ( args. nth_checked ( 0 ) ?) ?;
529- trace ! ( target: "wasm" , " val: {:?}" , endowment) ;
530- let code_ptr: u32 = args. nth_checked ( 1 ) ?;
531- trace ! ( target: "wasm" , " code_ptr: {:?}" , code_ptr) ;
532- let code_len: u32 = args. nth_checked ( 2 ) ?;
533- trace ! ( target: "wasm" , " code_len: {:?}" , code_len) ;
534- let result_ptr: u32 = args. nth_checked ( 3 ) ?;
535- trace ! ( target: "wasm" , "result_ptr: {:?}" , result_ptr) ;
536-
514+ fn do_create ( & mut self , endowment : U256 , code_ptr : u32 , code_len : u32 , result_ptr : u32 , scheme : vm:: CreateContractAddress ) -> Result < RuntimeValue > {
537515 let code = self . memory . get ( code_ptr, code_len as usize ) ?;
538516
539517 self . adjusted_charge ( |schedule| schedule. create_gas as u64 ) ?;
@@ -543,7 +521,7 @@ impl<'a> Runtime<'a> {
543521 * U256 :: from ( self . ext . schedule ( ) . wasm ( ) . opcodes_mul )
544522 / U256 :: from ( self . ext . schedule ( ) . wasm ( ) . opcodes_div ) ;
545523
546- match self . ext . create ( & gas_left, & endowment, & code, vm :: CreateContractAddress :: FromSenderAndCodeHash ) {
524+ match self . ext . create ( & gas_left, & endowment, & code, scheme ) {
547525 vm:: ContractCreateResult :: Created ( address, gas_left) => {
548526 self . memory . set ( result_ptr, & * address) ?;
549527 self . gas_counter = self . gas_limit -
@@ -571,6 +549,59 @@ impl<'a> Runtime<'a> {
571549 }
572550 }
573551
552+ /// Creates a new contract
553+ ///
554+ /// Arguments:
555+ /// * endowment - how much value (in Wei) transfer to the newly created contract
556+ /// * code_ptr - pointer to the code data
557+ /// * code_len - lenght of the code data
558+ /// * result_ptr - pointer to write an address of the newly created contract
559+ pub fn create ( & mut self , args : RuntimeArgs ) -> Result < RuntimeValue > {
560+ //
561+ // method signature:
562+ // fn create(endowment: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32;
563+ //
564+ trace ! ( target: "wasm" , "runtime: CREATE" ) ;
565+ let endowment = self . u256_at ( args. nth_checked ( 0 ) ?) ?;
566+ trace ! ( target: "wasm" , " val: {:?}" , endowment) ;
567+ let code_ptr: u32 = args. nth_checked ( 1 ) ?;
568+ trace ! ( target: "wasm" , " code_ptr: {:?}" , code_ptr) ;
569+ let code_len: u32 = args. nth_checked ( 2 ) ?;
570+ trace ! ( target: "wasm" , " code_len: {:?}" , code_len) ;
571+ let result_ptr: u32 = args. nth_checked ( 3 ) ?;
572+ trace ! ( target: "wasm" , "result_ptr: {:?}" , result_ptr) ;
573+
574+ self . do_create ( endowment, code_ptr, code_len, result_ptr, vm:: CreateContractAddress :: FromSenderAndCodeHash )
575+ }
576+
577+ /// Creates a new contract using FromSenderSaltAndCodeHash scheme
578+ ///
579+ /// Arguments:
580+ /// * endowment - how much value (in Wei) transfer to the newly created contract
581+ /// * salt - salt to be used in contract creation address
582+ /// * code_ptr - pointer to the code data
583+ /// * code_len - lenght of the code data
584+ /// * result_ptr - pointer to write an address of the newly created contract
585+ pub fn create2 ( & mut self , args : RuntimeArgs ) -> Result < RuntimeValue > {
586+ //
587+ // method signature:
588+ // fn create2(endowment: *const u8, salt: *const u8, code_ptr: *const u8, code_len: u32, result_ptr: *mut u8) -> i32;
589+ //
590+ trace ! ( target: "wasm" , "runtime: CREATE2" ) ;
591+ let endowment = self . u256_at ( args. nth_checked ( 0 ) ?) ?;
592+ trace ! ( target: "wasm" , " val: {:?}" , endowment) ;
593+ let salt: H256 = self . u256_at ( args. nth_checked ( 1 ) ?) ?. into ( ) ;
594+ trace ! ( target: "wasm" , " salt: {:?}" , salt) ;
595+ let code_ptr: u32 = args. nth_checked ( 2 ) ?;
596+ trace ! ( target: "wasm" , " code_ptr: {:?}" , code_ptr) ;
597+ let code_len: u32 = args. nth_checked ( 3 ) ?;
598+ trace ! ( target: "wasm" , " code_len: {:?}" , code_len) ;
599+ let result_ptr: u32 = args. nth_checked ( 4 ) ?;
600+ trace ! ( target: "wasm" , "result_ptr: {:?}" , result_ptr) ;
601+
602+ self . do_create ( endowment, code_ptr, code_len, result_ptr, vm:: CreateContractAddress :: FromSenderSaltAndCodeHash ( salt) )
603+ }
604+
574605 fn debug ( & mut self , args : RuntimeArgs ) -> Result < ( ) >
575606 {
576607 trace ! ( target: "wasm" , "Contract debug message: {}" , {
@@ -744,6 +775,7 @@ mod ext_impl {
744775 SENDER_FUNC => void ! ( self . sender( args) ) ,
745776 ORIGIN_FUNC => void ! ( self . origin( args) ) ,
746777 ELOG_FUNC => void ! ( self . elog( args) ) ,
778+ CREATE2_FUNC => some ! ( self . create2( args) ) ,
747779 _ => panic ! ( "env module doesn't provide function at index {}" , index) ,
748780 }
749781 }
0 commit comments