Skip to content

Instantly share code, notes, and snippets.

@pepyakin
Created April 12, 2018 13:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pepyakin/530a77925c5ada4bceb0e74c6c1b3d0d to your computer and use it in GitHub Desktop.
Save pepyakin/530a77925c5ada4bceb0e74c6c1b3d0d to your computer and use it in GitHub Desktop.
// Copyright 2018 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
//! Smart-contract execution functions.
use rstd::prelude::*;
use std::any::Any;
use {AccountDb, Trait};
use sandbox;
struct Ext<T: Trait, DB: AccountDb<T>> {
account_db: DB,
account: T::AccountId,
memory: sandbox::Memory,
}
impl<T: Trait, DB: AccountDb<T>> Ext<T, DB> {
fn memory(&self) -> &sandbox::Memory {
&self.memory
}
fn account(&self) -> &T::AccountId {
&self.account
}
fn account_db(&self) -> &DB {
&self.account_db
}
}
fn ext_stuff<T: Trait + 'static, DB: AccountDb<T> + 'static>(args: &[sandbox::TypedValue]) {
let location_ptr = args[0].as_i32().unwrap() as u32;
let mut location = [0; 32];
ext::with(|e| {
let e = e.downcast_mut::<Ext<T, DB>>().unwrap();
e.memory().get(location_ptr, &mut location).unwrap();
e.account_db()
.set_storage(e.account(), location.to_vec(), None);
});
}
environmental!(ext: Box<Any>);
pub(crate) fn execute<T: Trait + 'static, DB: AccountDb<T> + 'static>(
code: &[u8],
account: T::AccountId,
account_db: DB,
) -> bool {
let memory = sandbox::Memory::new(1, None);
// TODO: Signatures.
let mut imports = sandbox::EnvironmentDefinitionBuilder::new();
imports.add_host_func("env", "ext_stuff", ext_stuff::<T, DB>);
imports.add_memory("env", "memory", memory.clone());
let mut instance = sandbox::Instance::new(code, &imports).unwrap();
let mut ext_any = Box::new(Ext {
account,
account_db,
memory,
}) as Box<Any>;
ext::using(&mut ext_any, || {
instance.invoke(b"call", &[]);
});
true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment