diff --git a/Cargo.lock b/Cargo.lock index 28e420e88cb40..6b6ab1bb6d980 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/demo/runtime/Cargo.toml b/demo/runtime/Cargo.toml index cb263af8b1e11..3bf3b5af928db 100644 --- a/demo/runtime/Cargo.toml +++ b/demo/runtime/Cargo.toml @@ -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", diff --git a/demo/runtime/src/lib.rs b/demo/runtime/src/lib.rs index 23984f16f3287..60c8c1167ec55 100644 --- a/demo/runtime/src/lib.rs +++ b/demo/runtime/src/lib.rs @@ -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; +/// 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 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; + 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; /// Executive: handles dispatch to the various modules. pub type Executive = executive::Executive; + ((((((((), Treasury), Council), Democracy), Staking), Session), Timestamp), Contract)>; impl_json_metadata!( for Runtime with modules diff --git a/demo/runtime/wasm/Cargo.lock b/demo/runtime/wasm/Cargo.lock index 333c02b898cb9..ec034f0999f74 100644 --- a/demo/runtime/wasm/Cargo.lock +++ b/demo/runtime/wasm/Cargo.lock @@ -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" diff --git a/demo/runtime/wasm/Cargo.toml b/demo/runtime/wasm/Cargo.toml index 18285b648f736..198e8c6280ad9 100644 --- a/demo/runtime/wasm/Cargo.toml +++ b/demo/runtime/wasm/Cargo.toml @@ -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", diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm index 04e6d8dddfd6b..feed783fad5c1 100644 Binary files a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm and b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm differ diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm index 6a5fdb99d0087..2bfdb71e81182 100755 Binary files a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm and b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm differ diff --git a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 1794012886159..7e39d224b35d0 100644 Binary files a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm and b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm differ diff --git a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm index 31e382242fb91..6474b594e17de 100755 Binary files a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm and b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm differ diff --git a/substrate/runtime-std/with_std.rs b/substrate/runtime-std/with_std.rs index 0e809e67d8896..443fea1a61717 100644 --- a/substrate/runtime-std/with_std.rs +++ b/substrate/runtime-std/with_std.rs @@ -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; diff --git a/substrate/runtime-std/without_std.rs b/substrate/runtime-std/without_std.rs index b7fbf03a35a32..5219cba062703 100644 --- a/substrate/runtime-std/without_std.rs +++ b/substrate/runtime-std/without_std.rs @@ -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; diff --git a/substrate/runtime/contract/src/exec.rs b/substrate/runtime/contract/src/exec.rs index f7673d49b0fcf..ba3e0ff9676ec 100644 --- a/substrate/runtime/contract/src/exec.rs +++ b/substrate/runtime/contract/src/exec.rs @@ -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 >::exists(&dest) { // TODO: Is it enough? return Err("contract already exists"); diff --git a/substrate/runtime/contract/src/genesis_config.rs b/substrate/runtime/contract/src/genesis_config.rs index 08f09324a5ad7..dc2019d882400 100644 --- a/substrate/runtime/contract/src/genesis_config.rs +++ b/substrate/runtime/contract/src/genesis_config.rs @@ -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; diff --git a/substrate/runtime/contract/src/lib.rs b/substrate/runtime/contract/src/lib.rs index cb5697cd89910..8114d2651607e 100644 --- a/substrate/runtime/contract/src/lib.rs +++ b/substrate/runtime/contract/src/lib.rs @@ -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 { - fn contract_address_for(code: &[u8], origin: &AccountId) -> AccountId; + fn contract_address_for(code: &[u8], data: &[u8], origin: &AccountId) -> AccountId; } decl_module! { diff --git a/substrate/runtime/contract/src/tests.rs b/substrate/runtime/contract/src/tests.rs index 9968f804c7b24..4456bf1972c6b 100644 --- a/substrate/runtime/contract/src/tests.rs +++ b/substrate/runtime/contract/src/tests.rs @@ -61,7 +61,7 @@ type Contract = Module; pub struct DummyContractAddressFor; impl ContractAddressFor 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 = ::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 = ::DetermineContractAddress::contract_address_for( &code_ctor_transfer, + &[], &0, ); diff --git a/substrate/runtime/contract/src/vm/env_def/macros.rs b/substrate/runtime/contract/src/vm/env_def/macros.rs index b6b2cdb2ba344..40651749eb55b 100644 --- a/substrate/runtime/contract/src/vm/env_def/macros.rs +++ b/substrate/runtime/contract/src/vm/env_def/macros.rs @@ -137,7 +137,7 @@ macro_rules! define_env { $( env.funcs.insert( - stringify!( $name ).to_string(), + stringify!( $name ).into(), HostFunction::new( gen_signature!( ( $( $params ),* ) $( -> $returns )* ), { diff --git a/substrate/runtime/contract/src/vm/env_def/mod.rs b/substrate/runtime/contract/src/vm/env_def/mod.rs index eb6c16ca8a07e..dbdda705d3326 100644 --- a/substrate/runtime/contract/src/vm/env_def/mod.rs +++ b/substrate/runtime/contract/src/vm/env_def/mod.rs @@ -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}; diff --git a/substrate/runtime/contract/src/vm/prepare.rs b/substrate/runtime/contract/src/vm/prepare.rs index 4e77fef6b0a5a..b15f9cbc3a977 100644 --- a/substrate/runtime/contract/src/vm/prepare.rs +++ b/substrate/runtime/contract/src/vm/prepare.rs @@ -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; diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index 1ea084433d1a5..f973ad7f37279 100644 Binary files a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm index ae7e0e7a50fbf..63669ed93ae09 100755 Binary files a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm and b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm differ