@@ -321,7 +321,7 @@ impl<'a> Runtime<'a> {
321
321
if self . gas_counter > self . gas_limit { return Err ( Error :: InvalidGasState ) ; }
322
322
Ok ( self . gas_limit - self . gas_counter )
323
323
}
324
-
324
+
325
325
/// General gas charging extern.
326
326
fn gas ( & mut self , args : RuntimeArgs ) -> Result < ( ) > {
327
327
let amount: u32 = args. nth_checked ( 0 ) ?;
@@ -511,29 +511,7 @@ impl<'a> Runtime<'a> {
511
511
self . return_u256_ptr ( args. nth_checked ( 0 ) ?, val)
512
512
}
513
513
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 > {
537
515
let code = self . memory . get ( code_ptr, code_len as usize ) ?;
538
516
539
517
self . adjusted_charge ( |schedule| schedule. create_gas as u64 ) ?;
@@ -543,7 +521,7 @@ impl<'a> Runtime<'a> {
543
521
* U256 :: from ( self . ext . schedule ( ) . wasm ( ) . opcodes_mul )
544
522
/ U256 :: from ( self . ext . schedule ( ) . wasm ( ) . opcodes_div ) ;
545
523
546
- match self . ext . create ( & gas_left, & endowment, & code, vm :: CreateContractAddress :: FromSenderAndCodeHash ) {
524
+ match self . ext . create ( & gas_left, & endowment, & code, scheme ) {
547
525
vm:: ContractCreateResult :: Created ( address, gas_left) => {
548
526
self . memory . set ( result_ptr, & * address) ?;
549
527
self . gas_counter = self . gas_limit -
@@ -571,6 +549,59 @@ impl<'a> Runtime<'a> {
571
549
}
572
550
}
573
551
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
+
574
605
fn debug ( & mut self , args : RuntimeArgs ) -> Result < ( ) >
575
606
{
576
607
trace ! ( target: "wasm" , "Contract debug message: {}" , {
@@ -744,6 +775,7 @@ mod ext_impl {
744
775
SENDER_FUNC => void ! ( self . sender( args) ) ,
745
776
ORIGIN_FUNC => void ! ( self . origin( args) ) ,
746
777
ELOG_FUNC => void ! ( self . elog( args) ) ,
778
+ CREATE2_FUNC => some ! ( self . create2( args) ) ,
747
779
_ => panic ! ( "env module doesn't provide function at index {}" , index) ,
748
780
}
749
781
}
0 commit comments