diff --git a/substrate/core/executor/wasm/src/lib.rs b/substrate/core/executor/wasm/src/lib.rs
index 842749dd5bbf460f6b2766cf5c90558d2ea3e74c..193ff5c9c0d3cbe9d39122f28126c6b052de55a5 100644
--- a/substrate/core/executor/wasm/src/lib.rs
+++ b/substrate/core/executor/wasm/src/lib.rs
@@ -1,7 +1,6 @@
 #![no_std]
 #![cfg_attr(feature = "strict", deny(warnings))]
 
-#![feature(alloc)]
 extern crate alloc;
 use alloc::vec::Vec;
 use alloc::slice;
diff --git a/substrate/core/finality-grandpa/primitives/src/lib.rs b/substrate/core/finality-grandpa/primitives/src/lib.rs
index 7016a708bd62b8c0f1bc05726d193dd2dc986d1e..869b5e68fd6af5f744d4f9ed34ca77af7545f822 100644
--- a/substrate/core/finality-grandpa/primitives/src/lib.rs
+++ b/substrate/core/finality-grandpa/primitives/src/lib.rs
@@ -17,7 +17,6 @@
 //! Primitives for GRANDPA integration, suitable for WASM compilation.
 
 #![cfg_attr(not(feature = "std"), no_std)]
-#![cfg_attr(not(feature = "std"), feature(alloc))]
 
 #[cfg(not(feature = "std"))]
 extern crate alloc;
diff --git a/substrate/core/primitives/src/lib.rs b/substrate/core/primitives/src/lib.rs
index 97f5480743cef5f397cb13da3b823e54a1fea5f2..c9008171df94376893596b39790d15db3d8bffe4 100644
--- a/substrate/core/primitives/src/lib.rs
+++ b/substrate/core/primitives/src/lib.rs
@@ -19,7 +19,6 @@
 #![warn(missing_docs)]
 
 #![cfg_attr(not(feature = "std"), no_std)]
-#![cfg_attr(not(feature = "std"), feature(alloc))]
 
 /// Initialize a key-value collection from array.
 ///
diff --git a/substrate/core/sr-io/src/lib.rs b/substrate/core/sr-io/src/lib.rs
index 5101d3b2c124b0d23ce02ed2f3e83f5eb1ec63cc..47af4de98ba642133a0069ceccf0e97a90114daa 100644
--- a/substrate/core/sr-io/src/lib.rs
+++ b/substrate/core/sr-io/src/lib.rs
@@ -22,7 +22,6 @@
 #![cfg_attr(not(feature = "std"), feature(lang_items))]
 #![cfg_attr(not(feature = "std"), feature(alloc_error_handler))]
 #![cfg_attr(not(feature = "std"), feature(core_intrinsics))]
-#![cfg_attr(not(feature = "std"), feature(alloc))]
 
 #![cfg_attr(feature = "std", doc = "Substrate runtime standard library as compiled when linked with Rust's standard library.")]
 #![cfg_attr(not(feature = "std"), doc = "Substrate's runtime standard library as compiled without Rust's standard library.")]
diff --git a/substrate/core/sr-sandbox/src/lib.rs b/substrate/core/sr-sandbox/src/lib.rs
index e8bdd5727ea8795ea16efeae71426aecc014e73f..1e8b2b3f1df5e63f76012f7e642f8dd04422aabf 100755
--- a/substrate/core/sr-sandbox/src/lib.rs
+++ b/substrate/core/sr-sandbox/src/lib.rs
@@ -37,7 +37,6 @@
 #![warn(missing_docs)]
 #![cfg_attr(not(feature = "std"), no_std)]
 #![cfg_attr(not(feature = "std"), feature(core_intrinsics))]
-#![cfg_attr(not(feature = "std"), feature(alloc))]
 
 use rstd::prelude::*;
 
diff --git a/substrate/core/sr-std/src/lib.rs b/substrate/core/sr-std/src/lib.rs
index 45857b33eda784a3107bc162a3c12c1b610d0342..b9874bcc2018d5e680fdf51025ffaa77165700ac 100644
--- a/substrate/core/sr-std/src/lib.rs
+++ b/substrate/core/sr-std/src/lib.rs
@@ -19,7 +19,6 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 #![cfg_attr(not(feature = "std"), feature(core_intrinsics))]
-#![cfg_attr(not(feature = "std"), feature(alloc))]
 
 #![cfg_attr(feature = "std", doc = "Substrate runtime standard library as compiled when linked with Rust's standard library.")]
 #![cfg_attr(not(feature = "std"), doc = "Substrate's runtime standard library as compiled without Rust's standard library.")]
diff --git a/substrate/core/trie/src/lib.rs b/substrate/core/trie/src/lib.rs
index da6630e46d47a530cc482b3c08419716808a59b8..1322038d7847cbec83d36349014ba5e0717282e3 100644
--- a/substrate/core/trie/src/lib.rs
+++ b/substrate/core/trie/src/lib.rs
@@ -17,7 +17,6 @@
 //! Utility functions to interact with Substrate's Base-16 Modified Merkle Patricia tree ("trie").
 
 #![cfg_attr(not(feature = "std"), no_std)]
-#![cfg_attr(not(feature = "std"), feature(alloc))]
 
 mod error;
 mod node_header;
diff --git a/substrate/node-template/runtime/src/lib.rs b/substrate/node-template/runtime/src/lib.rs
index f7325923c7641f3b6180eb1a5090a242728d27fd..81adf200d05f405eedbfa3dd1d9d7b29e5a25abc 100644
--- a/substrate/node-template/runtime/src/lib.rs
+++ b/substrate/node-template/runtime/src/lib.rs
@@ -1,7 +1,6 @@
 //! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.
 
 #![cfg_attr(not(feature = "std"), no_std)]
-#![cfg_attr(not(feature = "std"), feature(alloc))]
 // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
 #![recursion_limit="256"]
 
diff --git a/substrate/node/primitives/src/lib.rs b/substrate/node/primitives/src/lib.rs
index 0d8906c47df817f4c6c62c2a3b6d54365b47bb77..4dde59296f4980c6ec4a0b3bf6734609de6405bf 100644
--- a/substrate/node/primitives/src/lib.rs
+++ b/substrate/node/primitives/src/lib.rs
@@ -19,7 +19,6 @@
 #![warn(missing_docs)]
 
 #![cfg_attr(not(feature = "std"), no_std)]
-#![cfg_attr(not(feature = "std"), feature(alloc))]
 
 use runtime_primitives::{
 	generic, traits::{Verify, BlakeTwo256}, OpaqueExtrinsic, AnySignature
diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs
index 748b5c63928c4ff0be6e81343cf9cf568cb0ff5b..d0d603bb10d33f216169389e9b150f38abc1db24 100644
--- a/substrate/node/runtime/src/lib.rs
+++ b/substrate/node/runtime/src/lib.rs
@@ -58,8 +58,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	spec_name: create_runtime_str!("node"),
 	impl_name: create_runtime_str!("substrate-node"),
 	authoring_version: 10,
-	spec_version: 71,
-	impl_version: 71,
+	spec_version: 72,
+	impl_version: 72,
 	apis: RUNTIME_API_VERSIONS,
 };
 
diff --git a/substrate/srml/executive/src/lib.rs b/substrate/srml/executive/src/lib.rs
index 6ca10bed2d5c73b7cb4f4344d64faaf1d3ae8cfb..f6dcae4a4c9293df00afea416cc6c260fccde3ae 100644
--- a/substrate/srml/executive/src/lib.rs
+++ b/substrate/srml/executive/src/lib.rs
@@ -443,7 +443,7 @@ mod tests {
 				header: Header {
 					parent_hash: [69u8; 32].into(),
 					number: 1,
-					state_root: hex!("4c10fddf15e63c91ff2aa13ab3a9b7f6b19938d533829489e72ba40278a08fac").into(),
+					state_root: hex!("ac2840371d51ff2e036c8fc05af7313b7a030f735c38b2f03b94cbe87bfbb7c9").into(),
 					extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(),
 					digest: Digest { logs: vec![], },
 				},
diff --git a/substrate/srml/support/src/lib.rs b/substrate/srml/support/src/lib.rs
index 78edc361d5e67ffea6952f3a6d4f30041ba0566c..b0fe28c63c5b9fdc2b6ad7a2c4c121cfd06f72d2 100644
--- a/substrate/srml/support/src/lib.rs
+++ b/substrate/srml/support/src/lib.rs
@@ -17,7 +17,6 @@
 //! Support code for the runtime.
 
 #![cfg_attr(not(feature = "std"), no_std)]
-#![cfg_attr(not(feature = "std"), feature(alloc))]
 
 #[macro_use]
 extern crate bitmask;
diff --git a/substrate/srml/system/src/lib.rs b/substrate/srml/system/src/lib.rs
index e3d77438f9c27f94ceb213a2ad309956f8043797..0d3264c5ab04e990eb2127600eae3bacd1df7277 100644
--- a/substrate/srml/system/src/lib.rs
+++ b/substrate/srml/system/src/lib.rs
@@ -302,8 +302,9 @@ decl_storage! {
 		pub BlockHash get(block_hash) build(|_| vec![(T::BlockNumber::zero(), hash69())]): map T::BlockNumber => T::Hash;
 		/// Extrinsics data for the current block (maps an extrinsic's index to its data).
 		ExtrinsicData get(extrinsic_data): map u32 => Vec<u8>;
-		/// Random seed of the current block.
-		RandomSeed get(random_seed) build(|_| T::Hash::default()): T::Hash;
+		/// Series of block headers from the last 81 blocks that acts as random seed material. This is arranged as a
+		/// ring buffer with the `i8` prefix being the index into the `Vec` of the oldest hash.
+		RandomMaterial get(random_material): (i8, Vec<T::Hash>);
 		/// The current block number being processed. Set by `execute_block`.
 		Number get(block_number) build(|_| T::BlockNumber::sa(1u64)): T::BlockNumber;
 		/// Hash of the previous block.
@@ -395,13 +396,17 @@ impl<T: Trait> Module<T> {
 		<ParentHash<T>>::put(parent_hash);
 		<BlockHash<T>>::insert(*number - One::one(), parent_hash);
 		<ExtrinsicsRoot<T>>::put(txs_root);
-		<RandomSeed<T>>::put(Self::calculate_random());
+		<RandomMaterial<T>>::mutate(|&mut(ref mut index, ref mut values)| if values.len() < 81 {
+			values.push(parent_hash.clone())
+		} else {
+			values[*index as usize] = parent_hash.clone();
+			*index = (*index + 1) % 81;
+		});
 		<Events<T>>::kill();
 	}
 
 	/// Remove temporary "environment" entries in storage.
 	pub fn finalize() -> T::Header {
-		<RandomSeed<T>>::kill();
 		<ExtrinsicCount<T>>::kill();
 		<AllExtrinsicsLen<T>>::kill();
 
@@ -432,26 +437,13 @@ impl<T: Trait> Module<T> {
 		<Digest<T>>::put(l);
 	}
 
-	/// Calculate the current block's random seed.
-	fn calculate_random() -> T::Hash {
-		assert!(Self::block_number() > Zero::zero(), "Block number may never be zero");
-		(0..81)
-			.scan(
-				Self::block_number() - One::one(),
-				|c, _| { if *c > Zero::zero() { *c -= One::one() }; Some(*c)
-			})
-			.map(Self::block_hash)
-			.triplet_mix()
-	}
-
 	/// Get the basic externalities for this module, useful for tests.
 	#[cfg(any(feature = "std", test))]
 	pub fn externalities() -> TestExternalities<Blake2Hasher> {
 		TestExternalities::new(map![
 			twox_128(&<BlockHash<T>>::key_for(T::BlockNumber::zero())).to_vec() => [69u8; 32].encode(),
 			twox_128(<Number<T>>::key()).to_vec() => T::BlockNumber::one().encode(),
-			twox_128(<ParentHash<T>>::key()).to_vec() => [69u8; 32].encode(),
-			twox_128(<RandomSeed<T>>::key()).to_vec() => T::Hash::default().encode()
+			twox_128(<ParentHash<T>>::key()).to_vec() => [69u8; 32].encode()
 		])
 	}
 
@@ -475,11 +467,54 @@ impl<T: Trait> Module<T> {
 		<ParentHash<T>>::put(n);
 	}
 
-	/// Set the random seed to something in particular. Can be used as an alternative to
-	/// `initialize` for tests that don't need to bother with the other environment entries.
-	#[cfg(any(feature = "std", test))]
-	pub fn set_random_seed(seed: T::Hash) {
-		<RandomSeed<T>>::put(seed);
+	/// Get the basic random seed.
+	///
+	/// In general you won't want to use this, but rather `Self::random` which allows you to give a subject for the
+	/// random result and whose value will be independently low-influence random from any other such seeds.
+	pub fn random_seed() -> T::Hash {
+		Self::random(&[][..])
+	}
+
+	/// Get a low-influence "random" value.
+	///
+	/// Being a deterministic block chain, real randomness is difficult to come by. This gives you something that
+	/// approximates it. `subject` is a context identifier and allows you to get a different result to other callers
+	/// of this function; use it like `random(&b"my context"[..])`.
+	///
+	/// This is initially implemented through a low-influence "triplet mix" convolution of previous block hash values.
+	/// In the future it will be generated from a secure "VRF".
+	///
+	/// ### Security Notes
+	/// This randomness uses a low-influence function, drawing upon the block hashes from the previous 81 blocks. Its
+	/// result for any given subject will be known in advance by the block producer of this block (and, indeed, anyone
+	/// who knows the block's `parent_hash`). However, it is mostly impossible for the producer of this block *alone*
+	/// to influence the value of this hash. A sizable minority of dishonest and coordinating block producers would be
+	/// required in order to affect this value. If that is an insufficient security guarantee then two things can be
+	/// used to improve this randomness:
+	/// - Name, in advance, the block number whose random value will be used; ensure your module retains a buffer of
+	/// previous random values for its subject and then index into these in order to obviate the ability of your user
+	/// to look up the parent hash and choose when to transact based upon it.
+	/// - Require your user to first commit to an additional value by first posting its hash. Require them to reveal
+	/// the value to determine the final result, hashing it with the output of this random function. This reduces the
+	/// ability of a cabal of block producers from conspiring against individuals.
+	///
+	/// WARNING: Hashing the result of this function will remove any low-infleunce properties it has and mean that
+	/// all bits of the resulting value are entirely manipulatable by the author of the parent block, who can determine
+	/// the value of `parent_hash`.
+	pub fn random(subject: &[u8]) -> T::Hash {
+		let (index, hash_series) = <RandomMaterial<T>>::get();
+		if hash_series.len() > 0 {
+			// Always the case after block 1 is initialised.
+			hash_series.iter()
+				.cycle()
+				.skip(index as usize)
+				.take(81)
+				.enumerate()
+				.map(|(i, h)| (i as i8, subject, h).using_encoded(T::Hashing::hash))
+				.triplet_mix()
+		} else {
+			T::Hash::default()
+		}
 	}
 
 	/// Increment a particular account's nonce by 1.