Last active
April 25, 2018 14:48
-
-
Save eira-fransham/faf457970517500a403f8fb81a50440c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Low-level interface, we can implement a higher-level interface as a library | |
mod pwasm { | |
use std::marker::PhantomData; | |
pub struct ContractDef<State> { | |
state: State, | |
iterate: for<'a> fn(&'a EthEnv, State, MessageData) -> (State, ReturnData), | |
} | |
// Will it ever be possible to get arbitrary blocks? | |
pub struct Block(()); | |
impl Block { | |
pub fn beneficiary() -> U256 { | |
unimplemented!(); | |
} | |
pub fn timestamp() -> U256 { | |
unimplemented!(); | |
} | |
pub fn number() -> U256 { | |
unimplemented!(); | |
} | |
pub fn difficulty() -> U256 { | |
unimplemented!(); | |
} | |
pub fn gas_limit() -> U256 { | |
unimplemented!(); | |
} | |
} | |
pub struct EthEnv(()); | |
impl EthEnv { | |
fn blockchain(&self) -> &BlockChain { | |
unimplemented!() | |
} | |
// We use different types for remote vs local contracts since | |
// they require different functions to get the code | |
// `impl Contract` is a `RemoteContract` | |
fn contract_at(&self) -> Result<&impl Contract> { | |
unimplemented!() | |
} | |
// `impl Contract` is a `LocalContract` | |
fn current_contract(&self) -> Result<&impl Contract> { | |
unimplemented!() | |
} | |
} | |
pub struct BlockChain(()); | |
pub impl BlockChain { | |
pub fn current(&self) -> &Block { | |
unimplemented!(); | |
} | |
pub fn block_hash(&self, number: u8) -> U256 { | |
unimplemented!(); | |
} | |
} | |
pub trait Contract { | |
// Compiles to `CODESIZE` + `CODECOPY` (TODO: This should be dynamically-sized but | |
// owned but we can't do that without `alloca`, so we can just write a `Box<[u8]>`- | |
// esque type that allocates on the "heap") | |
fn code(&self) -> &[u8]; | |
fn call(&self, method: &[u8], args: &[u8]) -> &[u8]; | |
} | |
} | |
#[derive(Serialize, Deserialize)] | |
struct Sender(pwasm::Sender); | |
fn make_contract(deploy_data: DeployData) -> ContractDef<Sender> { | |
ContractBuilder::with_data(Sender(deploy_data.sender())) | |
.call(|sender| { | |
let owner = sender.0; | |
Ok(owner.as_ref()) | |
}) | |
.build() | |
} | |
#[derive(Serialize, Deserialize)] | |
struct State { | |
supply: U256, | |
} | |
fn make_contract(deploy_data: DeployData) -> ContractDef<State> { | |
let another_contract: MyType = MyType::at(some_address); | |
ContractBuilder::with_data(State { supply: SUPPLY, ctrct: another_contract }) | |
// Takes a type parameter which is the argument type for | |
// this message. Must implement `Deserialize`. | |
.on_msg::<()>("totalSupply", |this, ()| { | |
ANOTHER_CONTRACT.call("my_msg", MyData); | |
state.supply | |
}) | |
} | |
// The wasm interpreter runs this function and gets the returned `iterate` function, then | |
// "compiles" the deployed contract by removing all code that is not referenced by it. | |
fn deploy(deploy_data: DeployData) -> ContractDef<MyState> { | |
#[derive(Serialize, Deserialize)] | |
struct MyState; | |
ContractDef { | |
state: MyState, | |
iterate: |environment: &EthEnv, state: MyState, _msg: MessageData| state, | |
} | |
} | |
// This takes the `deploy` function and converts the generic `ContractDef` to a monomorphic | |
// type (probably ContractDef<&[u8]>), then exports a `#[no_mangle]` function called | |
// `__ethereum_deploy` or suchlike. | |
eth_deploy!(deploy); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment