diff --git a/src/executive.rs b/src/executive.rs index b113363fd..039a6007e 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -251,12 +251,13 @@ impl<'a> Executive<'a> { // part of substate that may be reverted let mut unconfirmed_substate = Substate::new(); - // at first create new contract - self.state.new_contract(¶ms.address); - - // then transfer value to it + // create contract and transfer value to it if necessary + let prev_bal = self.state.balance(¶ms.address); if let ActionValue::Transfer(val) = params.value { - self.state.transfer_balance(¶ms.sender, ¶ms.address, &val); + self.state.sub_balance(¶ms.sender, &val); + self.state.new_contract(¶ms.address, val + prev_bal); + } else { + self.state.new_contract(¶ms.address, prev_bal); } let res = { diff --git a/src/state.rs b/src/state.rs index 7310f63a7..9b44d7194 100644 --- a/src/state.rs +++ b/src/state.rs @@ -72,8 +72,8 @@ impl State { /// Create a new contract at address `contract`. If there is already an account at the address /// it will have its code reset, ready for `init_code()`. - pub fn new_contract(&mut self, contract: &Address) { - self.require_or_from(contract, false, || Account::new_contract(U256::from(0u8)), |r| r.reset_code()); + pub fn new_contract(&mut self, contract: &Address, balance: U256) { + self.cache.borrow_mut().insert(contract.clone(), Some(Account::new_contract(balance))); } /// Remove an existing account. diff --git a/src/tests/executive.rs b/src/tests/executive.rs index 1df1b7eec..ab5cdaf98 100644 --- a/src/tests/executive.rs +++ b/src/tests/executive.rs @@ -182,8 +182,7 @@ fn do_json_test_for(vm: &VMType, json_data: &[u8]) -> Vec { let code = xjson!(&s["code"]); let _nonce: U256 = xjson!(&s["nonce"]); - state.new_contract(&address); - state.add_balance(&address, &balance); + state.new_contract(&address, balance); state.init_code(&address, code); BTreeMap::from_json(&s["storage"]).into_iter().foreach(|(k, v)| state.set_storage(&address, k, v)); });