diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index be655691971fd2f4d25fd264fa028282e1b83775..5e35d98feec2b9f769533f697b245d6cd8e61161 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -3233,6 +3233,7 @@ dependencies = [
  "srml-timestamp 1.0.0",
  "substrate-primitives 1.0.0",
  "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -5071,6 +5072,15 @@ dependencies = [
  "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "wasmi-validation"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "websocket"
 version = "0.22.2"
@@ -5603,6 +5613,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
 "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3"
 "checksum wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21ef487a11df1ed468cf613c78798c26282da5c30e9d49f824872d4c77b47d1d"
+"checksum wasmi-validation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab380192444b3e8522ae79c0a1976e42a82920916ccdfbce3def89f456ea33f3"
 "checksum websocket 0.22.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d2c67346c042adbd4f5b2a49700e340befc5b772094fec8d36df6b825523d933"
 "checksum which 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e84a603e7e0b1ce1aa1ee2b109c7be00155ce52df5081590d1ffb93f4f515cb2"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
diff --git a/substrate/node/runtime/Cargo.toml b/substrate/node/runtime/Cargo.toml
index 9cdceb96ac91d36e17347966b1a709ccaa5d6810..f8e0e047bc9b89b2d14bb4f255b75212610f9c23 100644
--- a/substrate/node/runtime/Cargo.toml
+++ b/substrate/node/runtime/Cargo.toml
@@ -41,6 +41,9 @@ consensus_authorities = { package = "substrate-consensus-authorities", path = ".
 
 [features]
 default = ["std"]
+core = [
+	"contract/core",
+]
 std = [
 	"parity-codec/std",
 	"substrate-primitives/std",
diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs
index 7239e14aa1b6ab8e7cd12fd6d5e25b449f315975..3a3ad41c28965db453dcb78634111bf30d46fad0 100644
--- a/substrate/node/runtime/src/lib.rs
+++ b/substrate/node/runtime/src/lib.rs
@@ -59,7 +59,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	spec_name: create_runtime_str!("node"),
 	impl_name: create_runtime_str!("substrate-node"),
 	authoring_version: 10,
-	spec_version: 62,
+	spec_version: 63,
 	impl_version: 65,
 	apis: RUNTIME_API_VERSIONS,
 };
diff --git a/substrate/node/runtime/wasm/Cargo.lock b/substrate/node/runtime/wasm/Cargo.lock
index af4581577764b786f825238dd4471fcb1d3ab7f8..243a60fb254c9d26c4f5327696c4b30691c6f837 100644
--- a/substrate/node/runtime/wasm/Cargo.lock
+++ b/substrate/node/runtime/wasm/Cargo.lock
@@ -2226,6 +2226,7 @@ dependencies = [
  "srml-system 1.0.0",
  "srml-timestamp 1.0.0",
  "substrate-primitives 1.0.0",
+ "wasmi-validation 0.1.0",
 ]
 
 [[package]]
@@ -3203,6 +3204,15 @@ dependencies = [
  "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "wasmi-validation"
+version = "0.1.0"
+dependencies = [
+ "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "winapi"
 version = "0.2.8"
diff --git a/substrate/node/runtime/wasm/Cargo.toml b/substrate/node/runtime/wasm/Cargo.toml
index 8fd90890e95526a0f0aff51f788a10f3ab6d6647..b6490a047ed19c938e5d15fd99bda9eedae90d99 100644
--- a/substrate/node/runtime/wasm/Cargo.toml
+++ b/substrate/node/runtime/wasm/Cargo.toml
@@ -12,7 +12,10 @@ crate-type = ["cdylib"]
 node-runtime = { path = "..", default-features = false }
 
 [features]
-default = []
+default = ["core"]
+core = [
+	"node-runtime/core",
+]
 std = [
 	"node-runtime/std",
 ]
diff --git a/substrate/srml/contract/Cargo.toml b/substrate/srml/contract/Cargo.toml
index 2338aabe0d2f7d54980188ec98934fb933aa4de2..be4034c849ef41658b3a2961a735ebdf91aac997 100644
--- a/substrate/srml/contract/Cargo.toml
+++ b/substrate/srml/contract/Cargo.toml
@@ -10,6 +10,7 @@ serde_derive = { version = "1.0", optional = true }
 pwasm-utils = { version = "0.6.1", default-features = false }
 parity-codec = { version = "3.3", default-features = false, features = ["derive"] }
 parity-wasm = { version = "0.31", default-features = false }
+wasmi-validation = { version = "0.1", default-features = false }
 substrate-primitives = { path = "../../core/primitives", default-features = false }
 runtime-primitives = { package = "sr-primitives", path = "../../core/sr-primitives", default-features = false }
 runtime-io = { package = "sr-io", path = "../../core/sr-io", default-features = false }
@@ -28,6 +29,9 @@ balances = { package = "srml-balances", path = "../balances" }
 
 [features]
 default = ["std"]
+core = [
+	"wasmi-validation/core",
+]
 std = [
 	"serde",
 	"serde_derive",
@@ -42,4 +46,5 @@ std = [
 	"timestamp/std",
 	"parity-wasm/std",
 	"pwasm-utils/std",
+	"wasmi-validation/std",
 ]
diff --git a/substrate/srml/contract/src/wasm/code_cache.rs b/substrate/srml/contract/src/wasm/code_cache.rs
index dab8c4bfa4b04a7ab931688affb74ff807e24af2..0c71fe8cb5b8f9584a86467a01589cca345ea929 100644
--- a/substrate/srml/contract/src/wasm/code_cache.rs
+++ b/substrate/srml/contract/src/wasm/code_cache.rs
@@ -72,8 +72,6 @@ pub fn save<T: Trait>(
 	let prefab_module = prepare::prepare_contract::<T, Env>(&original_code, schedule)?;
 	let code_hash = T::Hashing::hash(&original_code);
 
-	// TODO: #1416 validate the code. If the code is not valid, then don't store it.
-
 	<CodeStorage<T>>::insert(code_hash, prefab_module);
 	<PristineCode<T>>::insert(code_hash, original_code);
 
diff --git a/substrate/srml/contract/src/wasm/prepare.rs b/substrate/srml/contract/src/wasm/prepare.rs
index 15922c3d999592d1753d21d078e7150037f232b5..53883451b4236bb031b90fb3a61ad9d71aede5d9 100644
--- a/substrate/srml/contract/src/wasm/prepare.rs
+++ b/substrate/srml/contract/src/wasm/prepare.rs
@@ -29,20 +29,34 @@ use rstd::prelude::*;
 use runtime_primitives::traits::As;
 
 struct ContractModule<'a, Gas: 'a> {
-	// An `Option` is used here for loaning (`take()`-ing) the module.
-	// Invariant: Can't be `None` (i.e. on enter and on exit from the function
-	// the value *must* be `Some`).
+	/// A deserialized module. The module is valid (this is Guaranteed by `new` method).
+	///
+	/// An `Option` is used here for loaning (`take()`-ing) the module.
+	/// Invariant: Can't be `None` (i.e. on enter and on exit from the function
+	/// the value *must* be `Some`).
 	module: Option<elements::Module>,
 	schedule: &'a Schedule<Gas>,
 }
 
 impl<'a, Gas: 'a + As<u32> + Clone> ContractModule<'a, Gas> {
+	/// Creates a new instance of `ContractModule`.
+	///
+	/// Returns `Err` if the `original_code` couldn't be decoded or
+	/// if it contains an invalid module.
 	fn new(
 		original_code: &[u8],
 		schedule: &'a Schedule<Gas>,
 	) -> Result<ContractModule<'a, Gas>, &'static str> {
+		use wasmi_validation::{validate_module, PlainValidator};
+
 		let module =
-			elements::deserialize_buffer(original_code).map_err(|_| "can't decode wasm code")?;
+			elements::deserialize_buffer(original_code).map_err(|_| "Can't decode wasm code")?;
+
+		// Make sure that the module is valid.
+		validate_module::<PlainValidator>(&module).map_err(|_| "Module is not valid")?;
+
+		// Return a `ContractModule` instance with
+		// __valid__ module.
 		Ok(ContractModule {
 			module: Some(module),
 			schedule,
@@ -270,7 +284,8 @@ impl<'a, Gas: 'a + As<u32> + Clone> ContractModule<'a, Gas> {
 ///
 /// The checks are:
 ///
-/// - module doesn't define an internal memory instance,
+/// - provided code is a valid wasm module.
+/// - the module doesn't define an internal memory instance,
 /// - imported memory (if any) doesn't reserve more memory than permitted by the `schedule`,
 /// - all imported functions from the external environment matches defined by `env` module,
 ///
@@ -438,7 +453,7 @@ mod tests {
 				(func (export "deploy"))
 			)
 			"#,
-			Err("Requested initial number of pages should not exceed the requested maximum")
+			Err("Module is not valid")
 		);
 
 		prepare_test!(no_maximum,
@@ -487,7 +502,7 @@ mod tests {
 				(func (export "deploy"))
 			)
 			"#,
-			Err("Multiple memory imports defined")
+			Err("Module is not valid")
 		);
 
 		prepare_test!(table_import,
@@ -505,7 +520,7 @@ mod tests {
 		prepare_test!(global_import,
 			r#"
 			(module
-				(global $g (import "env" "global") (mut i32))
+				(global $g (import "env" "global") i32)
 				(func (export "call"))
 				(func (export "deploy"))
 			)