contract creating contract
This commit is contained in:
		
							parent
							
								
									5ae0f71922
								
							
						
					
					
						commit
						50af19a7c8
					
				@ -7,7 +7,7 @@ use state::*;
 | 
			
		||||
use env_info::*;
 | 
			
		||||
use engine::*;
 | 
			
		||||
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.
 | 
			
		||||
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())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(PartialEq, Debug)]
 | 
			
		||||
pub enum ExecutiveResult {
 | 
			
		||||
	Ok
 | 
			
		||||
	Ok,
 | 
			
		||||
	OutOfGas,
 | 
			
		||||
	InternalError
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
			state: e.state,
 | 
			
		||||
			info: e.info,
 | 
			
		||||
@ -109,14 +112,32 @@ impl<'a> Executive<'a> {
 | 
			
		||||
	fn create(&mut self) -> ExecutiveResult {
 | 
			
		||||
		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();
 | 
			
		||||
			// 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);
 | 
			
		||||
		ExecutiveResult::Ok
 | 
			
		||||
		match code {
 | 
			
		||||
			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] {
 | 
			
		||||
@ -155,11 +176,12 @@ impl<'a> Ext for Executive<'a> {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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),
 | 
			
		||||
			true => {
 | 
			
		||||
				let address = contract_address(&self.params.address, &self.state.nonce(&self.params.address));
 | 
			
		||||
				let params = EvmParams {
 | 
			
		||||
					address: contract_address(&self.params.address, &self.state.nonce(&self.params.address)),
 | 
			
		||||
					address: address.clone(),
 | 
			
		||||
					sender: self.params.address.clone(),
 | 
			
		||||
					origin: self.params.origin.clone(),
 | 
			
		||||
					gas: U256::from(gas),
 | 
			
		||||
@ -169,9 +191,12 @@ impl<'a> Ext for Executive<'a> {
 | 
			
		||||
					data: vec![],
 | 
			
		||||
					kind: ParamsKind::Create
 | 
			
		||||
				};
 | 
			
		||||
				let mut ex = Executive::new_populated_from(self, params);
 | 
			
		||||
				ex.create();
 | 
			
		||||
				unimplemented!()
 | 
			
		||||
				println!("address: {:?}", address);
 | 
			
		||||
				println!("code: {:?}", code);
 | 
			
		||||
				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();
 | 
			
		||||
			unimplemented!();
 | 
			
		||||
			
 | 
			
		||||
@ -251,6 +276,7 @@ mod tests {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#[test]
 | 
			
		||||
	// TODO: replace params with transactions!
 | 
			
		||||
	fn test_executive() {
 | 
			
		||||
		let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
 | 
			
		||||
		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);
 | 
			
		||||
			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(&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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -643,4 +643,28 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
		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());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -13,5 +13,5 @@ pub use self::evm::{Evm, ReturnCode};
 | 
			
		||||
pub use self::ext::{Ext};
 | 
			
		||||
pub use self::logentry::LogEntry;
 | 
			
		||||
pub use self::vmfactory::VmFactory;
 | 
			
		||||
pub use self::executive::Executive;
 | 
			
		||||
pub use self::executive::{Executive, ExecutiveResult};
 | 
			
		||||
pub use self::params::{EvmParams, ParamsKind};
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user