openethereum/src/evm/ext.rs

127 lines
3.0 KiB
Rust
Raw Normal View History

2015-12-30 12:46:10 +01:00
//! Contract execution environment.
2016-01-06 13:00:14 +01:00
use std::collections::HashSet;
2015-12-23 13:02:01 +01:00
use util::hash::*;
2015-12-29 12:04:03 +01:00
use util::uint::*;
2016-01-06 13:00:14 +01:00
use util::bytes::*;
2015-12-30 12:03:40 +01:00
use state::*;
use env_info::*;
2016-01-06 13:00:14 +01:00
use evm::LogEntry;
struct SubState {
// any accounts that have suicided
suicides: HashSet<Address>,
// any logs
logs: Vec<LogEntry>,
// refund counter of SSTORE nonzero->zero
refunds: U256
}
impl SubState {
fn new() -> SubState {
SubState {
suicides: HashSet::new(),
logs: vec![],
refunds: U256::zero()
}
}
}
2015-12-23 13:02:01 +01:00
2016-01-07 21:29:36 +01:00
/// Externality interface for the Virtual Machine providing access to
/// world state.
2015-12-30 12:46:10 +01:00
///
/// ```markdown
/// extern crate ethcore_util as util;
/// extern crate ethcore;
/// use util::hash::*;
/// use ethcore::state::*;
/// use ethcore::env_info::*;
2015-12-30 12:46:10 +01:00
/// use ethcore::evm::*;
///
/// fn main() {
/// let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
/// let mut data = RuntimeData::new();
2016-01-07 21:29:36 +01:00
/// let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address);
2015-12-30 12:46:10 +01:00
/// }
/// ```
2016-01-07 19:20:23 +01:00
pub struct Ext {
info: EnvInfo,
2015-12-30 12:03:40 +01:00
state: State,
2016-01-06 13:00:14 +01:00
address: Address,
substate: SubState
2015-12-30 12:03:40 +01:00
}
2015-12-23 13:02:01 +01:00
2016-01-07 19:20:23 +01:00
impl Ext {
2015-12-30 12:46:10 +01:00
/// Creates new evm environment object with backing state.
2016-01-07 19:20:23 +01:00
pub fn new(info: EnvInfo, state: State, address: Address) -> Ext {
Ext {
info: info,
2015-12-30 12:03:40 +01:00
state: state,
2016-01-06 13:00:14 +01:00
address: address,
substate: SubState::new()
2015-12-30 12:03:40 +01:00
}
2015-12-23 13:02:01 +01:00
}
2015-12-30 12:46:10 +01:00
/// Returns a value for given key.
pub fn sload(&self, key: &H256) -> H256 {
self.state.storage_at(&self.address, key)
2015-12-23 13:02:01 +01:00
}
2015-12-30 12:46:10 +01:00
/// Stores a value for given key.
pub fn sstore(&mut self, key: H256, value: H256) {
self.state.set_storage(&self.address, key, value)
2015-12-23 13:02:01 +01:00
}
2015-12-29 12:04:03 +01:00
2015-12-30 12:46:10 +01:00
/// Returns address balance.
pub fn balance(&self, address: &Address) -> U256 {
self.state.balance(address)
2015-12-29 12:04:03 +01:00
}
/// Returns the hash of one of the 256 most recent complete blocks.
pub fn blockhash(&self, number: &U256) -> H256 {
match *number < self.info.number {
false => H256::from(&U256::zero()),
true => {
let index = self.info.number - *number - U256::one();
self.info.last_hashes[index.low_u32() as usize].clone()
}
}
2015-12-29 12:04:03 +01:00
}
2016-01-06 20:00:32 +01:00
/// Creates new contract.
/// Returns new contract address and gas used.
2015-12-29 12:04:03 +01:00
pub fn create(&self, _gas: u64, _endowment: &U256, _code: &[u8]) -> (Address, u64) {
unimplemented!();
}
2016-01-06 20:00:32 +01:00
/// Calls existing contract.
/// Returns call output and gas used.
pub fn call(&self, _gas: u64, _call_gas: u64, _receive_address: &Address, _value: &U256, _data: &[u8], _code_address: &Address) -> Option<(Vec<u8>, u64)>{
2015-12-29 12:04:03 +01:00
unimplemented!();
}
/// Returns code at given address
2016-01-05 18:43:46 +01:00
pub fn extcode(&self, address: &Address) -> Vec<u8> {
self.state.code(address).unwrap_or(vec![])
2015-12-29 12:04:03 +01:00
}
2016-01-06 13:00:14 +01:00
/// Creates log entry with given topics and data
pub fn log(&mut self, topics: Vec<H256>, data: Bytes) {
let address = self.address.clone();
self.substate.logs.push(LogEntry::new(address, topics, data));
2015-12-29 12:04:03 +01:00
}
2015-12-30 12:03:40 +01:00
2016-01-06 13:00:14 +01:00
/// Returns state
2015-12-30 12:03:40 +01:00
// not sure if this is the best solution, but seems to be the easiest one, mk
2016-01-06 13:00:14 +01:00
pub fn state(&self) -> &State {
&self.state
}
/// Returns substate
pub fn logs(&self) -> &[LogEntry] {
&self.substate.logs
2015-12-30 12:03:40 +01:00
}
2015-12-23 13:02:01 +01:00
}