contract creating contract
This commit is contained in:
parent
5ae0f71922
commit
50af19a7c8
@ -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 {
|
||||||
|
ReturnCode::Stop => { //| ReturnCode::Return => {
|
||||||
|
//println!("code: {:?}", code);
|
||||||
|
//self.state.set_code(&self.params.address, self.params.code.clone());
|
||||||
ExecutiveResult::Ok
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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};
|
||||||
|
Loading…
Reference in New Issue
Block a user