contract creating contract

This commit is contained in:
debris 2016-01-09 13:51:59 +01:00
parent 5ae0f71922
commit 50af19a7c8
3 changed files with 95 additions and 17 deletions

View File

@ -7,7 +7,7 @@ use state::*;
use env_info::*; use env_info::*;
use engine::*; use engine::*;
use transaction::*; use transaction::*;
use evm::{VmFactory, Ext, LogEntry, EvmParams, ParamsKind}; use evm::{VmFactory, Ext, LogEntry, EvmParams, ParamsKind, ReturnCode};
/// Returns new address created from address and given nonce. /// Returns new address created from address and given nonce.
pub fn contract_address(address: &Address, nonce: &U256) -> Address { pub fn contract_address(address: &Address, nonce: &U256) -> Address {
@ -17,8 +17,11 @@ pub fn contract_address(address: &Address, nonce: &U256) -> Address {
From::from(stream.out().sha3()) From::from(stream.out().sha3())
} }
#[derive(PartialEq, Debug)]
pub enum ExecutiveResult { pub enum ExecutiveResult {
Ok Ok,
OutOfGas,
InternalError
} }
pub struct Executive<'a> { pub struct Executive<'a> {
@ -78,7 +81,7 @@ impl<'a> Executive<'a> {
} }
} }
fn new_populated_from(e: &'a mut Executive, params: EvmParams) -> Self { fn from_parent(e: &'a mut Executive, params: EvmParams) -> Self {
Executive { Executive {
state: e.state, state: e.state,
info: e.info, info: e.info,
@ -109,14 +112,32 @@ impl<'a> Executive<'a> {
fn create(&mut self) -> ExecutiveResult { fn create(&mut self) -> ExecutiveResult {
self.state.inc_nonce(&self.params.sender); self.state.inc_nonce(&self.params.sender);
{ //self.state.require_or_from(&self.params.address, false, ||Account::new_contract(U256::from(0)));
self.state.transfer_balance(&self.params.sender, &self.params.address, &self.params.value);
let code = {
let evm = VmFactory::create(); let evm = VmFactory::create();
// TODO: valdidate that exec returns proper code // TODO: valdidate that exec returns proper code
evm.exec(self); evm.exec(self)
} };
self.state.transfer_balance(&self.params.sender, &self.params.address, &self.params.value); match code {
ExecutiveResult::Ok ReturnCode::Stop => { //| ReturnCode::Return => {
//println!("code: {:?}", code);
//self.state.set_code(&self.params.address, self.params.code.clone());
ExecutiveResult::Ok
},
ReturnCode::Return => {
//self.state.transfer_balance(&self.params.sender, &self.params.address, &self.params.value);
//self.state.set_code(&self.params.address, self.params.code.clone());
ExecutiveResult::Ok
},
ReturnCode::OutOfGas => {
ExecutiveResult::OutOfGas
},
err => {
ExecutiveResult::InternalError
}
}
} }
pub fn logs(&self) -> &[LogEntry] { pub fn logs(&self) -> &[LogEntry] {
@ -155,11 +176,12 @@ impl<'a> Ext for Executive<'a> {
} }
fn create(&mut self, gas: u64, endowment: &U256, code: &[u8]) -> (Address, u64) { fn create(&mut self, gas: u64, endowment: &U256, code: &[u8]) -> (Address, u64) {
match self.state.balance(&self.params.address) > *endowment && self.depth < 1024 { match self.state.balance(&self.params.address) >= *endowment && self.depth < 1024 {
false => (Address::new(), gas), false => (Address::new(), gas),
true => { true => {
let address = contract_address(&self.params.address, &self.state.nonce(&self.params.address));
let params = EvmParams { let params = EvmParams {
address: contract_address(&self.params.address, &self.state.nonce(&self.params.address)), address: address.clone(),
sender: self.params.address.clone(), sender: self.params.address.clone(),
origin: self.params.origin.clone(), origin: self.params.origin.clone(),
gas: U256::from(gas), gas: U256::from(gas),
@ -169,9 +191,12 @@ impl<'a> Ext for Executive<'a> {
data: vec![], data: vec![],
kind: ParamsKind::Create kind: ParamsKind::Create
}; };
let mut ex = Executive::new_populated_from(self, params); println!("address: {:?}", address);
ex.create(); println!("code: {:?}", code);
unimplemented!() let mut ex = Executive::from_parent(self, params);
let res = ex.create();
println!("res: {:?}", res);
(address, gas)
} }
} }
} }
@ -192,7 +217,7 @@ impl<'a> Ext for Executive<'a> {
}; };
{ {
let mut ex = Executive::new_populated_from(self, params); let mut ex = Executive::from_parent(self, params);
ex.call(); ex.call();
unimplemented!(); unimplemented!();
@ -251,6 +276,7 @@ mod tests {
} }
#[test] #[test]
// TODO: replace params with transactions!
fn test_executive() { fn test_executive() {
let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let address = contract_address(&sender, &U256::zero()); let address = contract_address(&sender, &U256::zero());
@ -267,11 +293,39 @@ mod tests {
{ {
let mut ex = Executive::new_from_params(&mut state, &info, &engine, params); let mut ex = Executive::new_from_params(&mut state, &info, &engine, params);
ex.exec(); assert_eq!(ex.exec(), ExecutiveResult::Ok);
} }
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0x100u64))); assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0xf9u64)));
assert_eq!(state.balance(&sender), U256::from(0xf9)); assert_eq!(state.balance(&sender), U256::from(0xf9));
assert_eq!(state.balance(&address), U256::from(0x7)); assert_eq!(state.balance(&address), U256::from(0x7));
} }
#[test]
fn test_create_contract() {
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address = contract_address(&sender, &U256::zero());
let next_address = contract_address(&address, &U256::zero());
println!("address: {:?}", address);
println!("next address: {:?}", next_address);
let mut params = EvmParams::new_create();
params.address = address.clone();
params.sender = sender.clone();
params.origin = sender.clone();
params.gas = U256::from(0x174876e800u64);
params.code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036000f0600055".from_hex().unwrap();
let mut state = State::new_temp();
state.add_balance(&sender, &U256::from(0x100u64));
let info = EnvInfo::new();
let engine = TestEngine::new();
{
let mut ex = Executive::new_from_params(&mut state, &info, &engine, params);
assert_eq!(ex.exec(), ExecutiveResult::Ok);
}
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(next_address.clone()));
//assert_eq!(state.code(&next_address).unwrap(), "601080600c6000396000f3006000355415600957005b602035600035".from_hex().unwrap());
//assert!(false);
}
} }

View File

@ -643,4 +643,28 @@ mod tests {
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(address.clone())); assert_eq!(state.storage_at(&address, &H256::new()), H256::from(address.clone()));
} }
#[test]
fn test_calldataload() {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let mut params = EvmParams::new_create();
params.address = address.clone();
params.gas = U256::from(0x174876e800u64);
params.code = "600135600055".from_hex().unwrap();
params.data = "0123ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23".from_hex().unwrap();
let mut state = State::new_temp();
let mut info = EnvInfo::new();
info.number = U256::one();
info.last_hashes.push(H256::from(address.clone()));
let engine = TestEngine::new();
{
let mut ext = Executive::new_from_params(&mut state, &info, &engine, params);
let evm = JitEvm;
assert_eq!(evm.exec(&mut ext), ReturnCode::Stop);
}
assert_eq!(state.storage_at(&address, &H256::new()), H256::from_str("23ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23").unwrap());
}
} }

View File

@ -13,5 +13,5 @@ pub use self::evm::{Evm, ReturnCode};
pub use self::ext::{Ext}; pub use self::ext::{Ext};
pub use self::logentry::LogEntry; pub use self::logentry::LogEntry;
pub use self::vmfactory::VmFactory; pub use self::vmfactory::VmFactory;
pub use self::executive::Executive; pub use self::executive::{Executive, ExecutiveResult};
pub use self::params::{EvmParams, ParamsKind}; pub use self::params::{EvmParams, ParamsKind};