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