Integrate contracts into substrate-demo runtime (#675)

* Introduce data and salt into ContractAddressFor

* Accept salt arg in ext_create.

* Integrate contracts into the demo runtime

* Make libcontract compile to wasm

* Remove salt parameter.

This now is concern of userspace.

* Rebuild binaries.
This commit is contained in:
Sergey Pepyakin
2018-09-10 20:45:19 +03:00
committed by Gav Wood
parent 0e1023ae42
commit 6c1b2c27d1
20 changed files with 83 additions and 6 deletions
+1
View File
@@ -523,6 +523,7 @@ dependencies = [
"substrate-primitives 0.1.0",
"substrate-runtime-balances 0.1.0",
"substrate-runtime-consensus 0.1.0",
"substrate-runtime-contract 0.1.0",
"substrate-runtime-council 0.1.0",
"substrate-runtime-democracy 0.1.0",
"substrate-runtime-executive 0.1.0",
+2
View File
@@ -19,6 +19,7 @@ substrate-primitives = { path = "../../substrate/primitives" }
substrate-keyring = { path = "../../substrate/keyring" }
substrate-runtime-balances = { path = "../../substrate/runtime/balances" }
substrate-runtime-consensus = { path = "../../substrate/runtime/consensus" }
substrate-runtime-contract = { path = "../../substrate/runtime/contract" }
substrate-runtime-council = { path = "../../substrate/runtime/council" }
substrate-runtime-democracy = { path = "../../substrate/runtime/democracy" }
substrate-runtime-executive = { path = "../../substrate/runtime/executive" }
@@ -41,6 +42,7 @@ std = [
"substrate-runtime-support/std",
"substrate-runtime-balances/std",
"substrate-runtime-consensus/std",
"substrate-runtime-contract/std",
"substrate-runtime-council/std",
"substrate-runtime-democracy/std",
"substrate-runtime-executive/std",
+30 -1
View File
@@ -44,6 +44,7 @@ extern crate substrate_codec_derive;
extern crate substrate_runtime_std as rstd;
extern crate substrate_runtime_balances as balances;
extern crate substrate_runtime_consensus as consensus;
extern crate substrate_runtime_contract as contract;
extern crate substrate_runtime_council as council;
extern crate substrate_runtime_democracy as democracy;
extern crate substrate_runtime_executive as executive;
@@ -196,6 +197,33 @@ impl treasury::Trait for Runtime {
/// Treasury module for this concrete runtime.
pub type Treasury = treasury::Module<Runtime>;
/// Address calculated from the code (of the constructor), input data to the constructor
/// and account id which requested the account creation.
///
/// Formula: `blake2_256(blake2_256(code) + blake2_256(data) + origin)`
pub struct DetermineContractAddress;
impl contract::ContractAddressFor<AccountId> for DetermineContractAddress {
fn contract_address_for(code: &[u8], data: &[u8], origin: &AccountId) -> AccountId {
use runtime_primitives::traits::Hash;
let code_hash = BlakeTwo256::hash(code);
let data_hash = BlakeTwo256::hash(data);
let mut buf = [0u8, 32 + 32 + 32];
&mut buf[0..32].copy_from_slice(&code_hash);
&mut buf[32..64].copy_from_slice(&data_hash);
&mut buf[64..96].copy_from_slice(origin);
AccountId::from(BlakeTwo256::hash(&buf[..]))
}
}
impl contract::Trait for Runtime {
type Gas = u64;
type DetermineContractAddress = DetermineContractAddress;
}
/// Contract module for this concrete runtime.
pub type Contract = contract::Module<Runtime>;
impl_outer_event! {
pub enum Event for Runtime {
balances, session, staking, democracy, treasury, council_motions
@@ -226,6 +254,7 @@ impl_outer_dispatch! {
CouncilVoting,
CouncilMotions,
Treasury,
Contract,
}
}
@@ -269,7 +298,7 @@ pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Index, Call,
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Index, Call>;
/// Executive: handles dispatch to the various modules.
pub type Executive = executive::Executive<Runtime, Block, Balances, Balances,
(((((((), Treasury), Council), Democracy), Staking), Session), Timestamp)>;
((((((((), Treasury), Council), Democracy), Staking), Session), Timestamp), Contract)>;
impl_json_metadata!(
for Runtime with modules
+31
View File
@@ -101,6 +101,7 @@ dependencies = [
"substrate-primitives 0.1.0",
"substrate-runtime-balances 0.1.0",
"substrate-runtime-consensus 0.1.0",
"substrate-runtime-contract 0.1.0",
"substrate-runtime-council 0.1.0",
"substrate-runtime-democracy 0.1.0",
"substrate-runtime-executive 0.1.0",
@@ -411,6 +412,16 @@ dependencies = [
name = "pwasm-libc"
version = "0.1.0"
[[package]]
name = "pwasm-utils"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "0.6.3"
@@ -640,6 +651,25 @@ dependencies = [
"substrate-runtime-system 0.1.0",
]
[[package]]
name = "substrate-runtime-contract"
version = "0.1.0"
dependencies = [
"parity-wasm 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pwasm-utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-codec 0.1.0",
"substrate-primitives 0.1.0",
"substrate-runtime-balances 0.1.0",
"substrate-runtime-io 0.1.0",
"substrate-runtime-primitives 0.1.0",
"substrate-runtime-sandbox 0.1.0",
"substrate-runtime-std 0.1.0",
"substrate-runtime-support 0.1.0",
"substrate-runtime-system 0.1.0",
]
[[package]]
name = "substrate-runtime-council"
version = "0.1.0"
@@ -1040,6 +1070,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba8d4f9257b85eb6cdf13f055cea3190520aab1409ca2ab43493ea4820c25f0"
"checksum proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5cb6f960ad471404618e9817c0e5d10b1ae74cfdf01fab89ea0641fe7fb2892"
"checksum proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1fa93823f53cfd0f5ac117b189aed6cfdfb2cfc0a9d82e956dd7927595ed7d46"
"checksum pwasm-utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd695333cfae6e9dbe2703a6d040e252b57a6fc3b9a65c712615ac042b2e0c5"
"checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035"
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
+2
View File
@@ -17,6 +17,7 @@ substrate-runtime-io = { path = "../../../substrate/runtime-io", default-feature
substrate-runtime-support = { path = "../../../substrate/runtime-support", default-features = false }
substrate-runtime-balances = { path = "../../../substrate/runtime/balances", default-features = false }
substrate-runtime-consensus = { path = "../../../substrate/runtime/consensus", default-features = false }
substrate-runtime-contract = { path = "../../../substrate/runtime/contract", default-features = false }
substrate-runtime-council = { path = "../../../substrate/runtime/council", default-features = false }
substrate-runtime-democracy = { path = "../../../substrate/runtime/democracy", default-features = false }
substrate-runtime-executive = { path = "../../../substrate/runtime/executive", default-features = false }
@@ -40,6 +41,7 @@ std = [
"substrate-runtime-support/std",
"substrate-runtime-balances/std",
"substrate-runtime-consensus/std",
"substrate-runtime-contract/std",
"substrate-runtime-council/std",
"substrate-runtime-democracy/std",
"substrate-runtime-executive/std",
@@ -29,6 +29,7 @@ pub use std::ops;
pub use std::ptr;
pub use std::rc;
pub use std::slice;
pub use std::string;
pub use std::vec;
pub use std::result;
@@ -24,6 +24,7 @@ extern crate pwasm_alloc;
pub use alloc::boxed;
pub use alloc::rc;
pub use alloc::vec;
pub use alloc::string;
pub use core::borrow;
pub use core::cell;
pub use core::clone;
@@ -123,7 +123,7 @@ impl<'a, T: Trait> ExecutionContext<'a, T> {
return Err("not enough gas to pay base create fee");
}
let dest = T::DetermineContractAddress::contract_address_for(ctor, &self.self_account);
let dest = T::DetermineContractAddress::contract_address_for(ctor, data, &self.self_account);
if <CodeOf<T>>::exists(&dest) {
// TODO: Is it enough?
return Err("contract already exists");
@@ -16,6 +16,8 @@
//! Build the contract module part of the genesis block storage.
#![cfg(feature = "std")]
use {Trait, ContractFee, CallBaseFee, CreateBaseFee, GasPrice, MaxDepth, BlockGasLimit};
use runtime_primitives;
@@ -66,7 +66,7 @@ extern crate substrate_codec as codec;
extern crate substrate_runtime_io as runtime_io;
extern crate substrate_runtime_sandbox as sandbox;
#[cfg_attr(feature = "std", macro_use)]
#[macro_use]
extern crate substrate_runtime_std as rstd;
extern crate substrate_runtime_balances as balances;
@@ -90,16 +90,19 @@ mod double_map;
mod exec;
mod vm;
mod gas;
mod genesis_config;
#[cfg(test)]
mod tests;
#[cfg(feature = "std")]
pub use genesis_config::GenesisConfig;
use exec::ExecutionContext;
use account_db::{AccountDb, OverlayAccountDb};
use double_map::StorageDoubleMap;
use rstd::prelude::*;
use codec::Codec;
use runtime_primitives::traits::{As, SimpleArithmetic, OnFinalise};
use runtime_support::dispatch::Result;
@@ -115,7 +118,7 @@ pub trait Trait: balances::Trait {
}
pub trait ContractAddressFor<AccountId: Sized> {
fn contract_address_for(code: &[u8], origin: &AccountId) -> AccountId;
fn contract_address_for(code: &[u8], data: &[u8], origin: &AccountId) -> AccountId;
}
decl_module! {
@@ -61,7 +61,7 @@ type Contract = Module<Test>;
pub struct DummyContractAddressFor;
impl ContractAddressFor<u64> for DummyContractAddressFor {
fn contract_address_for(_code: &[u8], origin: &u64) -> u64 {
fn contract_address_for(_code: &[u8], _data: &[u8], origin: &u64) -> u64 {
origin + 1
}
}
@@ -357,6 +357,7 @@ fn contract_create() {
let derived_address = <Test as Trait>::DetermineContractAddress::contract_address_for(
&code_ctor_transfer,
&[],
&1,
);
@@ -395,6 +396,7 @@ fn top_level_create() {
with_externalities(&mut ExtBuilder::default().gas_price(3).build(), || {
let derived_address = <Test as Trait>::DetermineContractAddress::contract_address_for(
&code_ctor_transfer,
&[],
&0,
);
@@ -137,7 +137,7 @@ macro_rules! define_env {
$(
env.funcs.insert(
stringify!( $name ).to_string(),
stringify!( $name ).into(),
HostFunction::new(
gen_signature!( ( $( $params ),* ) $( -> $returns )* ),
{
@@ -17,6 +17,8 @@
use super::{BalanceOf, CallReceipt, CreateReceipt, Ext, GasMeterResult, Runtime};
use codec::Decode;
use parity_wasm::elements::{FunctionType, ValueType};
use rstd::prelude::*;
use rstd::string::String;
use rstd::collections::btree_map::BTreeMap;
use runtime_primitives::traits::As;
use sandbox::{self, TypedValue};
@@ -19,6 +19,7 @@
use super::env_def::HostFunctionSet;
use super::{Config, Error, Ext};
use rstd::prelude::*;
use parity_wasm::elements::{self, External, MemoryType, Type};
use pwasm_utils;
use pwasm_utils::rules;