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