diff --git a/substrate/bin/node/executor/tests/basic.rs b/substrate/bin/node/executor/tests/basic.rs
index 3e3b2d1eaaf3f0e1c2fd515b619e7272d6167be2..c18f81bdc07d5a0a4920bc8f907e0e1aaba18671 100644
--- a/substrate/bin/node/executor/tests/basic.rs
+++ b/substrate/bin/node/executor/tests/basic.rs
@@ -17,7 +17,6 @@
 
 use codec::{Encode, Decode, Joiner};
 use frame_support::{
-	StorageMap,
 	traits::Currency,
 	weights::{GetDispatchInfo, DispatchInfo, DispatchClass},
 };
diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index b52b24ed01bc75adba531236c0cf1b50a76801de..c8d7717b4c8fb1bbe81bad9f778e2a9b0d93772e 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -71,7 +71,7 @@ pub use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment, Currency
 use pallet_session::{historical as pallet_session_historical};
 use sp_inherents::{InherentData, CheckInherentsResult};
 use static_assertions::const_assert;
-use pallet_contracts::WeightInfo;
+use pallet_contracts::weights::WeightInfo;
 
 #[cfg(any(feature = "std", test))]
 pub use sp_runtime::BuildStorage;
diff --git a/substrate/frame/contracts/src/benchmarking/mod.rs b/substrate/frame/contracts/src/benchmarking/mod.rs
index b6ff4c04ff7ec4c7b268bad9258e1316b1abbfa4..d01a2bce2c27b6bf837ec4dd69e099e9a2f7f5fe 100644
--- a/substrate/frame/contracts/src/benchmarking/mod.rs
+++ b/substrate/frame/contracts/src/benchmarking/mod.rs
@@ -42,6 +42,7 @@ use parity_wasm::elements::{Instruction, ValueType, BlockType};
 use sp_runtime::traits::{Hash, Bounded, Zero};
 use sp_std::{default::Default, convert::{TryInto}, vec::Vec, vec};
 use pallet_contracts_primitives::RentProjection;
+use frame_support::weights::Weight;
 
 /// How many batches we do per API benchmark.
 const API_BENCHMARK_BATCHES: u32 = 20;
diff --git a/substrate/frame/contracts/src/chain_extension.rs b/substrate/frame/contracts/src/chain_extension.rs
index ef6e034791753cc22a69077a8159bb84a7ee5166..dc6e9771775ca7744da448b7b46039072f0ea301 100644
--- a/substrate/frame/contracts/src/chain_extension.rs
+++ b/substrate/frame/contracts/src/chain_extension.rs
@@ -18,7 +18,7 @@
 //! A mechanism for runtime authors to augment the functionality of contracts.
 //!
 //! The runtime is able to call into any contract and retrieve the result using
-//! [`bare_call`](crate::Module::bare_call). This already allows customization of runtime
+//! [`bare_call`](crate::Pallet::bare_call). This already allows customization of runtime
 //! behaviour by user generated code (contracts). However, often it is more straightforward
 //! to allow the reverse behaviour: The contract calls into the runtime. We call the latter
 //! one a "chain extension" because it allows the chain to extend the set of functions that are
@@ -37,7 +37,7 @@
 //! [`charge_weight`](Environment::charge_weight) function must be called **before**
 //! carrying out any action that causes the consumption of the chargeable weight.
 //! It cannot be overstated how delicate of a process the creation of a chain extension
-//! is. Check whether using [`bare_call`](crate::Module::bare_call) suffices for the
+//! is. Check whether using [`bare_call`](crate::Pallet::bare_call) suffices for the
 //! use case at hand.
 //!
 //! # Benchmarking
@@ -328,7 +328,7 @@ where
 	///
 	/// If the contract supplied buffer is smaller than the passed `buffer` an `Err` is returned.
 	/// If `allow_skip` is set to true the contract is allowed to skip the copying of the buffer
-	/// by supplying the guard value of [`u32::max_value()`] as `out_ptr`. The
+	/// by supplying the guard value of `u32::max_value()` as `out_ptr`. The
 	/// `weight_per_byte` is only charged when the write actually happens and is not skipped or
 	/// failed due to a too small output buffer.
 	pub fn write(
diff --git a/substrate/frame/contracts/src/exec.rs b/substrate/frame/contracts/src/exec.rs
index bf9efddc6166f349992a59851281fb9e0631e9e6..745384a8674bc51e5273e6c54ee6303faecded58 100644
--- a/substrate/frame/contracts/src/exec.rs
+++ b/substrate/frame/contracts/src/exec.rs
@@ -16,7 +16,7 @@
 // limitations under the License.
 
 use crate::{
-	CodeHash, Event, RawEvent, Config, Module as Contracts,
+	CodeHash, Event, Config, Module as Contracts,
 	TrieId, BalanceOf, ContractInfo, gas::GasMeter, rent::Rent, storage::{self, Storage},
 	Error, ContractInfoOf, Schedule,
 };
@@ -30,7 +30,7 @@ use frame_support::{
 	dispatch::{DispatchResult, DispatchError},
 	traits::{ExistenceRequirement, Currency, Time, Randomness, Get},
 	weights::Weight,
-	ensure, StorageMap,
+	ensure,
 };
 use pallet_contracts_primitives::{ErrorOrigin, ExecError, ExecReturnValue, ExecResult, ReturnFlags};
 
@@ -57,7 +57,11 @@ pub enum TransactorKind {
 ///
 /// This interface is specialized to an account of the executing code, so all
 /// operations are implicitly performed on that account.
-pub trait Ext {
+///
+/// # Note
+///
+/// This trait is sealed and cannot be implemented by downstream crates.
+pub trait Ext: sealing::Sealed {
 	type T: Config;
 
 	/// Returns the storage entry of the executing account by the given `key`.
@@ -446,7 +450,7 @@ where
 					.ok_or(Error::<T>::NewContractNotFunded)?;
 
 				// Deposit an instantiation event.
-				deposit_event::<T>(vec![], RawEvent::Instantiated(caller.clone(), dest.clone()));
+				deposit_event::<T>(vec![], Event::Instantiated(caller.clone(), dest.clone()));
 
 				Ok(output)
 			});
@@ -664,7 +668,7 @@ where
 		if let Some(ContractInfo::Alive(info)) = ContractInfoOf::<T>::take(&self_id) {
 			Storage::<T>::queue_trie_for_deletion(&info).map_err(|e| (e, 0))?;
 			let code_len = E::remove_user(info.code_hash);
-			Contracts::<T>::deposit_event(RawEvent::Terminated(self_id, beneficiary.clone()));
+			Contracts::<T>::deposit_event(Event::Terminated(self_id, beneficiary.clone()));
 			Ok(code_len)
 		} else {
 			panic!(
@@ -708,7 +712,7 @@ where
 		if let Ok(_) = result {
 			deposit_event::<Self::T>(
 				vec![],
-				RawEvent::Restored(
+				Event::Restored(
 					self.ctx.self_account.clone(),
 					dest,
 					code_hash,
@@ -754,7 +758,7 @@ where
 	fn deposit_event(&mut self, topics: Vec<T::Hash>, data: Vec<u8>) {
 		deposit_event::<Self::T>(
 			topics,
-			RawEvent::ContractEmitted(self.ctx.self_account.clone(), data)
+			Event::ContractEmitted(self.ctx.self_account.clone(), data)
 		);
 	}
 
@@ -799,6 +803,20 @@ fn deposit_event<T: Config>(
 	)
 }
 
+mod sealing {
+	use super::*;
+
+	pub trait Sealed {}
+
+	impl<'a, 'b: 'a, T: Config, E> Sealed for CallContext<'a, 'b, T, E> {}
+
+	#[cfg(test)]
+	impl Sealed for crate::wasm::MockExt {}
+
+	#[cfg(test)]
+	impl Sealed for &mut crate::wasm::MockExt {}
+}
+
 /// These tests exercise the executive layer.
 ///
 /// In these tests the VM/loader are mocked. Instead of dealing with wasm bytecode they use simple closures.
@@ -809,13 +827,12 @@ mod tests {
 	use super::*;
 	use crate::{
 		gas::GasMeter, tests::{ExtBuilder, Test, Event as MetaEvent},
-		gas::Gas,
 		storage::Storage,
 		tests::{
 			ALICE, BOB, CHARLIE,
 			test_utils::{place_contract, set_balance, get_balance},
 		},
-		Error,
+		Error, Weight,
 	};
 	use sp_runtime::DispatchError;
 	use assert_matches::assert_matches;
@@ -823,7 +840,7 @@ mod tests {
 
 	type MockContext<'a> = ExecutionContext<'a, Test, MockExecutable>;
 
-	const GAS_LIMIT: Gas = 10_000_000_000;
+	const GAS_LIMIT: Weight = 10_000_000_000;
 
 	thread_local! {
 		static LOADER: RefCell<MockLoader> = RefCell::new(MockLoader::default());
@@ -1334,7 +1351,7 @@ mod tests {
 			// there are instantiation event.
 			assert_eq!(Storage::<Test>::code_hash(&instantiated_contract_address).unwrap(), dummy_ch);
 			assert_eq!(&events(), &[
-				RawEvent::Instantiated(ALICE, instantiated_contract_address)
+				Event::Instantiated(ALICE, instantiated_contract_address)
 			]);
 		});
 	}
@@ -1410,7 +1427,7 @@ mod tests {
 			// there are instantiation event.
 			assert_eq!(Storage::<Test>::code_hash(&instantiated_contract_address).unwrap(), dummy_ch);
 			assert_eq!(&events(), &[
-				RawEvent::Instantiated(BOB, instantiated_contract_address)
+				Event::Instantiated(BOB, instantiated_contract_address)
 			]);
 		});
 	}
diff --git a/substrate/frame/contracts/src/gas.rs b/substrate/frame/contracts/src/gas.rs
index 2737f351a50de75c902c27dc946a6f896690fb58..80e608b217bd32377125c8e847d7ccfd19d228dd 100644
--- a/substrate/frame/contracts/src/gas.rs
+++ b/substrate/frame/contracts/src/gas.rs
@@ -30,14 +30,11 @@ use sp_core::crypto::UncheckedFrom;
 #[cfg(test)]
 use std::{any::Any, fmt::Debug};
 
-// Gas is essentially the same as weight. It is a 1 to 1 correspondence.
-pub type Gas = Weight;
-
 #[derive(Debug, PartialEq, Eq)]
-pub struct ChargedAmount(Gas);
+pub struct ChargedAmount(Weight);
 
 impl ChargedAmount {
-	pub fn amount(&self) -> Gas {
+	pub fn amount(&self) -> Weight {
 		self.0
 	}
 }
@@ -72,7 +69,7 @@ pub trait Token<T: Config>: Copy + Clone + TestAuxiliaries {
 	/// That said, implementors of this function still can run into overflows
 	/// while calculating the amount. In this case it is ok to use saturating operations
 	/// since on overflow they will return `max_value` which should consume all gas.
-	fn calculate_amount(&self, metadata: &Self::Metadata) -> Gas;
+	fn calculate_amount(&self, metadata: &Self::Metadata) -> Weight;
 }
 
 /// A wrapper around a type-erased trait object of what used to be a `Token`.
@@ -83,9 +80,9 @@ pub struct ErasedToken {
 }
 
 pub struct GasMeter<T: Config> {
-	gas_limit: Gas,
+	gas_limit: Weight,
 	/// Amount of gas left from initial gas limit. Can reach zero.
-	gas_left: Gas,
+	gas_left: Weight,
 	_phantom: PhantomData<T>,
 	#[cfg(test)]
 	tokens: Vec<ErasedToken>,
@@ -95,7 +92,7 @@ impl<T: Config> GasMeter<T>
 where
 	T::AccountId: UncheckedFrom<<T as frame_system::Config>::Hash> + AsRef<[u8]>
 {
-	pub fn new(gas_limit: Gas) -> Self {
+	pub fn new(gas_limit: Weight) -> Self {
 		GasMeter {
 			gas_limit,
 			gas_left: gas_limit,
@@ -177,7 +174,7 @@ where
 	/// All unused gas in the nested gas meter is returned to this gas meter.
 	pub fn with_nested<R, F: FnOnce(Option<&mut GasMeter<T>>) -> R>(
 		&mut self,
-		amount: Gas,
+		amount: Weight,
 		f: F,
 	) -> R {
 		// NOTE that it is ok to allocate all available gas since it still ensured
@@ -197,12 +194,12 @@ where
 	}
 
 	/// Returns how much gas was used.
-	pub fn gas_spent(&self) -> Gas {
+	pub fn gas_spent(&self) -> Weight {
 		self.gas_limit - self.gas_left
 	}
 
 	/// Returns how much gas left from the initial budget.
-	pub fn gas_left(&self) -> Gas {
+	pub fn gas_left(&self) -> Weight {
 		self.gas_left
 	}
 
@@ -230,49 +227,48 @@ where
 	}
 }
 
-/// A simple utility macro that helps to match against a
-/// list of tokens.
-#[macro_export]
-macro_rules! match_tokens {
-	($tokens_iter:ident,) => {
-	};
-	($tokens_iter:ident, $x:expr, $($rest:tt)*) => {
-		{
-			let next = ($tokens_iter).next().unwrap();
-			let pattern = $x;
-
-			// Note that we don't specify the type name directly in this macro,
-			// we only have some expression $x of some type. At the same time, we
-			// have an iterator of Box<dyn Any> and to downcast we need to specify
-			// the type which we want downcast to.
-			//
-			// So what we do is we assign `_pattern_typed_next_ref` to a variable which has
-			// the required type.
-			//
-			// Then we make `_pattern_typed_next_ref = token.downcast_ref()`. This makes
-			// rustc infer the type `T` (in `downcast_ref<T: Any>`) to be the same as in $x.
-
-			let mut _pattern_typed_next_ref = &pattern;
-			_pattern_typed_next_ref = match next.token.downcast_ref() {
-				Some(p) => {
-					assert_eq!(p, &pattern);
-					p
-				}
-				None => {
-					panic!("expected type {} got {}", stringify!($x), next.description);
-				}
-			};
-		}
-
-		match_tokens!($tokens_iter, $($rest)*);
-	};
-}
-
 #[cfg(test)]
 mod tests {
 	use super::{GasMeter, Token};
 	use crate::tests::Test;
 
+	/// A simple utility macro that helps to match against a
+	/// list of tokens.
+	macro_rules! match_tokens {
+		($tokens_iter:ident,) => {
+		};
+		($tokens_iter:ident, $x:expr, $($rest:tt)*) => {
+			{
+				let next = ($tokens_iter).next().unwrap();
+				let pattern = $x;
+
+				// Note that we don't specify the type name directly in this macro,
+				// we only have some expression $x of some type. At the same time, we
+				// have an iterator of Box<dyn Any> and to downcast we need to specify
+				// the type which we want downcast to.
+				//
+				// So what we do is we assign `_pattern_typed_next_ref` to a variable which has
+				// the required type.
+				//
+				// Then we make `_pattern_typed_next_ref = token.downcast_ref()`. This makes
+				// rustc infer the type `T` (in `downcast_ref<T: Any>`) to be the same as in $x.
+
+				let mut _pattern_typed_next_ref = &pattern;
+				_pattern_typed_next_ref = match next.token.downcast_ref() {
+					Some(p) => {
+						assert_eq!(p, &pattern);
+						p
+					}
+					None => {
+						panic!("expected type {} got {}", stringify!($x), next.description);
+					}
+				};
+			}
+
+			match_tokens!($tokens_iter, $($rest)*);
+		};
+	}
+
 	/// A trivial token that charges the specified number of gas units.
 	#[derive(Copy, Clone, PartialEq, Eq, Debug)]
 	struct SimpleToken(u64);
diff --git a/substrate/frame/contracts/src/lib.rs b/substrate/frame/contracts/src/lib.rs
index 4e56230e93f3a046037660744d855115846df995..1f21a59e61584bdf68a74f6531c156b631ab08c5 100644
--- a/substrate/frame/contracts/src/lib.rs
+++ b/substrate/frame/contracts/src/lib.rs
@@ -98,368 +98,80 @@ pub mod weights;
 mod tests;
 
 pub use crate::{
-	gas::{Gas, GasMeter},
-	wasm::{ReturnCode as RuntimeReturnCode, PrefabWasmModule},
-	weights::WeightInfo,
+	wasm::PrefabWasmModule,
 	schedule::{Schedule, HostFnWeights, InstructionWeights, Limits},
+	pallet::*,
 };
 use crate::{
+	gas::GasMeter,
 	exec::{ExecutionContext, Executable},
 	rent::Rent,
-	storage::Storage,
+	storage::{Storage, DeletedContract},
+	weights::WeightInfo,
 };
 use sp_core::crypto::UncheckedFrom;
 use sp_std::{prelude::*, marker::PhantomData, fmt::Debug};
 use codec::{Codec, Encode, Decode};
 use sp_runtime::{
 	traits::{
-		Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member, Convert, Saturating,
+		Hash, StaticLookup, MaybeSerializeDeserialize, Member, Convert, Saturating, Zero,
 	},
 	RuntimeDebug, Perbill,
 };
 use frame_support::{
-	decl_module, decl_event, decl_storage, decl_error, ensure,
 	storage::child::ChildInfo,
-	dispatch::{DispatchResult, DispatchResultWithPostInfo},
 	traits::{OnUnbalanced, Currency, Get, Time, Randomness},
-	weights::Pays,
+	weights::{Weight, PostDispatchInfo, WithPostDispatchInfo},
 };
-use frame_system::{ensure_signed, ensure_root, Module as System};
+use frame_system::Module as System;
 use pallet_contracts_primitives::{
 	RentProjectionResult, GetStorageResult, ContractAccessError, ContractExecResult,
 };
-use frame_support::weights::{Weight, PostDispatchInfo, WithPostDispatchInfo};
 
 pub type CodeHash<T> = <T as frame_system::Config>::Hash;
 pub type TrieId = Vec<u8>;
-
-/// Information for managing an account and its sub trie abstraction.
-/// This is the required info to cache for an account
-#[derive(Encode, Decode, RuntimeDebug)]
-pub enum ContractInfo<T: Config> {
-	Alive(AliveContractInfo<T>),
-	Tombstone(TombstoneContractInfo<T>),
-}
-
-impl<T: Config> ContractInfo<T> {
-	/// If contract is alive then return some alive info
-	pub fn get_alive(self) -> Option<AliveContractInfo<T>> {
-		if let ContractInfo::Alive(alive) = self {
-			Some(alive)
-		} else {
-			None
-		}
-	}
-	/// If contract is alive then return some reference to alive info
-	pub fn as_alive(&self) -> Option<&AliveContractInfo<T>> {
-		if let ContractInfo::Alive(ref alive) = self {
-			Some(alive)
-		} else {
-			None
-		}
-	}
-	/// If contract is alive then return some mutable reference to alive info
-	pub fn as_alive_mut(&mut self) -> Option<&mut AliveContractInfo<T>> {
-		if let ContractInfo::Alive(ref mut alive) = self {
-			Some(alive)
-		} else {
-			None
-		}
-	}
-
-	/// If contract is tombstone then return some tombstone info
-	pub fn get_tombstone(self) -> Option<TombstoneContractInfo<T>> {
-		if let ContractInfo::Tombstone(tombstone) = self {
-			Some(tombstone)
-		} else {
-			None
-		}
-	}
-	/// If contract is tombstone then return some reference to tombstone info
-	pub fn as_tombstone(&self) -> Option<&TombstoneContractInfo<T>> {
-		if let ContractInfo::Tombstone(ref tombstone) = self {
-			Some(tombstone)
-		} else {
-			None
-		}
-	}
-	/// If contract is tombstone then return some mutable reference to tombstone info
-	pub fn as_tombstone_mut(&mut self) -> Option<&mut TombstoneContractInfo<T>> {
-		if let ContractInfo::Tombstone(ref mut tombstone) = self {
-			Some(tombstone)
-		} else {
-			None
-		}
-	}
-}
-
-pub type AliveContractInfo<T> =
-	RawAliveContractInfo<CodeHash<T>, BalanceOf<T>, <T as frame_system::Config>::BlockNumber>;
-
-/// Information for managing an account and its sub trie abstraction.
-/// This is the required info to cache for an account.
-#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)]
-pub struct RawAliveContractInfo<CodeHash, Balance, BlockNumber> {
-	/// Unique ID for the subtree encoded as a bytes vector.
-	pub trie_id: TrieId,
-	/// The total number of bytes used by this contract.
-	///
-	/// It is a sum of each key-value pair stored by this contract.
-	pub storage_size: u32,
-	/// The total number of key-value pairs in storage of this contract.
-	pub pair_count: u32,
-	/// The code associated with a given account.
-	pub code_hash: CodeHash,
-	/// Pay rent at most up to this value.
-	pub rent_allowance: Balance,
-	/// The amount of rent that was payed by the contract over its whole lifetime.
-	///
-	/// A restored contract starts with a value of zero just like a new contract.
-	pub rent_payed: Balance,
-	/// Last block rent has been payed.
-	pub deduct_block: BlockNumber,
-	/// Last block child storage has been written.
-	pub last_write: Option<BlockNumber>,
-}
-
-impl<CodeHash, Balance, BlockNumber> RawAliveContractInfo<CodeHash, Balance, BlockNumber> {
-	/// Associated child trie unique id is built from the hash part of the trie id.
-	pub fn child_trie_info(&self) -> ChildInfo {
-		child_trie_info(&self.trie_id[..])
-	}
-}
-
-/// Associated child trie unique id is built from the hash part of the trie id.
-pub(crate) fn child_trie_info(trie_id: &[u8]) -> ChildInfo {
-	ChildInfo::new_default(trie_id)
-}
-
-pub type TombstoneContractInfo<T> =
-	RawTombstoneContractInfo<<T as frame_system::Config>::Hash, <T as frame_system::Config>::Hashing>;
-
-#[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)]
-pub struct RawTombstoneContractInfo<H, Hasher>(H, PhantomData<Hasher>);
-
-impl<H, Hasher> RawTombstoneContractInfo<H, Hasher>
-where
-	H: Member + MaybeSerializeDeserialize+ Debug
-		+ AsRef<[u8]> + AsMut<[u8]> + Copy + Default
-		+ sp_std::hash::Hash + Codec,
-	Hasher: Hash<Output=H>,
-{
-	fn new(storage_root: &[u8], code_hash: H) -> Self {
-		let mut buf = Vec::new();
-		storage_root.using_encoded(|encoded| buf.extend_from_slice(encoded));
-		buf.extend_from_slice(code_hash.as_ref());
-		RawTombstoneContractInfo(<Hasher as Hash>::hash(&buf[..]), PhantomData)
-	}
-}
-
-impl<T: Config> From<AliveContractInfo<T>> for ContractInfo<T> {
-	fn from(alive_info: AliveContractInfo<T>) -> Self {
-		Self::Alive(alive_info)
-	}
-}
-
 pub type BalanceOf<T> =
 	<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
 pub type NegativeImbalanceOf<T> =
 	<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;
+pub type AliveContractInfo<T> =
+	RawAliveContractInfo<CodeHash<T>, BalanceOf<T>, <T as frame_system::Config>::BlockNumber>;
+pub type TombstoneContractInfo<T> =
+	RawTombstoneContractInfo<<T as frame_system::Config>::Hash, <T as frame_system::Config>::Hashing>;
 
-pub trait Config: frame_system::Config {
-	type Time: Time;
-	type Randomness: Randomness<Self::Hash>;
-
-	/// The currency in which fees are paid and contract balances are held.
-	type Currency: Currency<Self::AccountId>;
-
-	/// The overarching event type.
-	type Event: From<Event<Self>> + Into<<Self as frame_system::Config>::Event>;
-
-	/// Handler for rent payments.
-	type RentPayment: OnUnbalanced<NegativeImbalanceOf<Self>>;
-
-	/// Number of block delay an extrinsic claim surcharge has.
-	///
-	/// When claim surcharge is called by an extrinsic the rent is checked
-	/// for current_block - delay
-	type SignedClaimHandicap: Get<Self::BlockNumber>;
-
-	/// The minimum amount required to generate a tombstone.
-	type TombstoneDeposit: Get<BalanceOf<Self>>;
-
-	/// The balance every contract needs to deposit to stay alive indefinitely.
-	///
-	/// This is different from the [`Self::TombstoneDeposit`] because this only needs to be
-	/// deposited while the contract is alive. Costs for additional storage are added to
-	/// this base cost.
-	///
-	/// This is a simple way to ensure that contracts with empty storage eventually get deleted by
-	/// making them pay rent. This creates an incentive to remove them early in order to save rent.
-	type DepositPerContract: Get<BalanceOf<Self>>;
-
-	/// The balance a contract needs to deposit per storage byte to stay alive indefinitely.
-	///
-	/// Let's suppose the deposit is 1,000 BU (balance units)/byte and the rent is 1 BU/byte/day,
-	/// then a contract with 1,000,000 BU that uses 1,000 bytes of storage would pay no rent.
-	/// But if the balance reduced to 500,000 BU and the storage stayed the same at 1,000,
-	/// then it would pay 500 BU/day.
-	type DepositPerStorageByte: Get<BalanceOf<Self>>;
-
-	/// The balance a contract needs to deposit per storage item to stay alive indefinitely.
-	///
-	/// It works the same as [`Self::DepositPerStorageByte`] but for storage items.
-	type DepositPerStorageItem: Get<BalanceOf<Self>>;
-
-	/// The fraction of the deposit that should be used as rent per block.
-	///
-	/// When a contract hasn't enough balance deposited to stay alive indefinitely it needs
-	/// to pay per block for the storage it consumes that is not covered by the deposit.
-	/// This determines how high this rent payment is per block as a fraction of the deposit.
-	type RentFraction: Get<Perbill>;
-
-	/// Reward that is received by the party whose touch has led
-	/// to removal of a contract.
-	type SurchargeReward: Get<BalanceOf<Self>>;
-
-	/// The maximum nesting level of a call/instantiate stack.
-	type MaxDepth: Get<u32>;
-
-	/// The maximum size of a storage value and event payload in bytes.
-	type MaxValueSize: Get<u32>;
-
-	/// Used to answer contracts's queries regarding the current weight price. This is **not**
-	/// used to calculate the actual fee and is only for informational purposes.
-	type WeightPrice: Convert<Weight, BalanceOf<Self>>;
-
-	/// Describes the weights of the dispatchables of this module and is also used to
-	/// construct a default cost schedule.
-	type WeightInfo: WeightInfo;
-
-	/// Type that allows the runtime authors to add new host functions for a contract to call.
-	type ChainExtension: chain_extension::ChainExtension<Self>;
+#[frame_support::pallet]
+pub mod pallet {
+	use frame_support::pallet_prelude::*;
+	use frame_system::pallet_prelude::*;
+	use super::*;
 
-	/// The maximum number of tries that can be queued for deletion.
-	type DeletionQueueDepth: Get<u32>;
+	#[pallet::config]
+	pub trait Config: frame_system::Config {
+		/// The time implementation used to supply timestamps to conntracts through `seal_now`.
+		type Time: Time;
 
-	/// The maximum amount of weight that can be consumed per block for lazy trie removal.
-	type DeletionWeightLimit: Get<Weight>;
+		/// The generator used to supply randomness to contracts through `seal_random`.
+		type Randomness: Randomness<Self::Hash>;
 
-	/// The maximum length of a contract code in bytes. This limit applies to the instrumented
-	/// version of the code. Therefore `instantiate_with_code` can fail even when supplying
-	/// a wasm binary below this maximum size.
-	type MaxCodeSize: Get<u32>;
-}
+		/// The currency in which fees are paid and contract balances are held.
+		type Currency: Currency<Self::AccountId>;
 
-decl_error! {
-	/// Error for the contracts module.
-	pub enum Error for Module<T: Config>
-	where
-		T::AccountId: UncheckedFrom<T::Hash>,
-		T::AccountId: AsRef<[u8]>,
-	{
-		/// A new schedule must have a greater version than the current one.
-		InvalidScheduleVersion,
-		/// An origin must be signed or inherent and auxiliary sender only provided on inherent.
-		InvalidSurchargeClaim,
-		/// Cannot restore from nonexisting or tombstone contract.
-		InvalidSourceContract,
-		/// Cannot restore to nonexisting or alive contract.
-		InvalidDestinationContract,
-		/// Tombstones don't match.
-		InvalidTombstone,
-		/// An origin TrieId written in the current block.
-		InvalidContractOrigin,
-		/// The executed contract exhausted its gas limit.
-		OutOfGas,
-		/// The output buffer supplied to a contract API call was too small.
-		OutputBufferTooSmall,
-		/// Performing the requested transfer would have brought the contract below
-		/// the subsistence threshold. No transfer is allowed to do this in order to allow
-		/// for a tombstone to be created. Use `seal_terminate` to remove a contract without
-		/// leaving a tombstone behind.
-		BelowSubsistenceThreshold,
-		/// The newly created contract is below the subsistence threshold after executing
-		/// its contructor. No contracts are allowed to exist below that threshold.
-		NewContractNotFunded,
-		/// Performing the requested transfer failed for a reason originating in the
-		/// chosen currency implementation of the runtime. Most probably the balance is
-		/// too low or locks are placed on it.
-		TransferFailed,
-		/// Performing a call was denied because the calling depth reached the limit
-		/// of what is specified in the schedule.
-		MaxCallDepthReached,
-		/// The contract that was called is either no contract at all (a plain account)
-		/// or is a tombstone.
-		NotCallable,
-		/// The code supplied to `instantiate_with_code` exceeds the limit specified in the
-		/// current schedule.
-		CodeTooLarge,
-		/// No code could be found at the supplied code hash.
-		CodeNotFound,
-		/// A buffer outside of sandbox memory was passed to a contract API function.
-		OutOfBounds,
-		/// Input passed to a contract API function failed to decode as expected type.
-		DecodingFailed,
-		/// Contract trapped during execution.
-		ContractTrapped,
-		/// The size defined in `T::MaxValueSize` was exceeded.
-		ValueTooLarge,
-		/// The action performed is not allowed while the contract performing it is already
-		/// on the call stack. Those actions are contract self destruction and restoration
-		/// of a tombstone.
-		ReentranceDenied,
-		/// `seal_input` was called twice from the same contract execution context.
-		InputAlreadyRead,
-		/// The subject passed to `seal_random` exceeds the limit.
-		RandomSubjectTooLong,
-		/// The amount of topics passed to `seal_deposit_events` exceeds the limit.
-		TooManyTopics,
-		/// The topics passed to `seal_deposit_events` contains at least one duplicate.
-		DuplicateTopics,
-		/// The chain does not provide a chain extension. Calling the chain extension results
-		/// in this error. Note that this usually  shouldn't happen as deploying such contracts
-		/// is rejected.
-		NoChainExtension,
-		/// Removal of a contract failed because the deletion queue is full.
-		///
-		/// This can happen when either calling [`Module::claim_surcharge`] or `seal_terminate`.
-		/// The queue is filled by deleting contracts and emptied by a fixed amount each block.
-		/// Trying again during another block is the only way to resolve this issue.
-		DeletionQueueFull,
-		/// A contract could not be evicted because it has enough balance to pay rent.
-		///
-		/// This can be returned from [`Module::claim_surcharge`] because the target
-		/// contract has enough balance to pay for its rent.
-		ContractNotEvictable,
-		/// A storage modification exhausted the 32bit type that holds the storage size.
-		///
-		/// This can either happen when the accumulated storage in bytes is too large or
-		/// when number of storage items is too large.
-		StorageExhausted,
-		/// A contract with the same AccountId already exists.
-		DuplicateContract,
-	}
-}
+		/// The overarching event type.
+		type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
 
-decl_module! {
-	/// Contracts module.
-	pub struct Module<T: Config> for enum Call
-	where
-		origin: T::Origin,
-		T::AccountId: UncheckedFrom<T::Hash>,
-		T::AccountId: AsRef<[u8]>,
-	{
-		type Error = Error<T>;
+		/// Handler for rent payments.
+		type RentPayment: OnUnbalanced<NegativeImbalanceOf<Self>>;
 
 		/// Number of block delay an extrinsic claim surcharge has.
 		///
 		/// When claim surcharge is called by an extrinsic the rent is checked
 		/// for current_block - delay
-		const SignedClaimHandicap: T::BlockNumber = T::SignedClaimHandicap::get();
+		#[pallet::constant]
+		type SignedClaimHandicap: Get<Self::BlockNumber>;
 
 		/// The minimum amount required to generate a tombstone.
-		const TombstoneDeposit: BalanceOf<T> = T::TombstoneDeposit::get();
+		#[pallet::constant]
+		type TombstoneDeposit: Get<BalanceOf<Self>>;
 
 		/// The balance every contract needs to deposit to stay alive indefinitely.
 		///
@@ -469,7 +181,8 @@ decl_module! {
 		///
 		/// This is a simple way to ensure that contracts with empty storage eventually get deleted by
 		/// making them pay rent. This creates an incentive to remove them early in order to save rent.
-		const DepositPerContract: BalanceOf<T> = T::DepositPerContract::get();
+		#[pallet::constant]
+		type DepositPerContract: Get<BalanceOf<Self>>;
 
 		/// The balance a contract needs to deposit per storage byte to stay alive indefinitely.
 		///
@@ -477,40 +190,73 @@ decl_module! {
 		/// then a contract with 1,000,000 BU that uses 1,000 bytes of storage would pay no rent.
 		/// But if the balance reduced to 500,000 BU and the storage stayed the same at 1,000,
 		/// then it would pay 500 BU/day.
-		const DepositPerStorageByte: BalanceOf<T> = T::DepositPerStorageByte::get();
+		#[pallet::constant]
+		type DepositPerStorageByte: Get<BalanceOf<Self>>;
 
 		/// The balance a contract needs to deposit per storage item to stay alive indefinitely.
 		///
 		/// It works the same as [`Self::DepositPerStorageByte`] but for storage items.
-		const DepositPerStorageItem: BalanceOf<T> = T::DepositPerStorageItem::get();
+		#[pallet::constant]
+		type DepositPerStorageItem: Get<BalanceOf<Self>>;
 
 		/// The fraction of the deposit that should be used as rent per block.
 		///
 		/// When a contract hasn't enough balance deposited to stay alive indefinitely it needs
 		/// to pay per block for the storage it consumes that is not covered by the deposit.
 		/// This determines how high this rent payment is per block as a fraction of the deposit.
-		const RentFraction: Perbill = T::RentFraction::get();
+		#[pallet::constant]
+		type RentFraction: Get<Perbill>;
 
 		/// Reward that is received by the party whose touch has led
 		/// to removal of a contract.
-		const SurchargeReward: BalanceOf<T> = T::SurchargeReward::get();
+		#[pallet::constant]
+		type SurchargeReward: Get<BalanceOf<Self>>;
+
+		/// The maximum nesting level of a call/instantiate stack.
+		#[pallet::constant]
+		type MaxDepth: Get<u32>;
+
+		/// The maximum size of a storage value and event payload in bytes.
+		#[pallet::constant]
+		type MaxValueSize: Get<u32>;
 
-		/// The maximum nesting level of a call/instantiate stack. A reasonable default
-		/// value is 100.
-		const MaxDepth: u32 = T::MaxDepth::get();
+		/// Used to answer contracts's queries regarding the current weight price. This is **not**
+		/// used to calculate the actual fee and is only for informational purposes.
+		type WeightPrice: Convert<Weight, BalanceOf<Self>>;
 
-		/// The maximum size of a storage value in bytes. A reasonable default is 16 KiB.
-		const MaxValueSize: u32 = T::MaxValueSize::get();
+		/// Describes the weights of the dispatchables of this module and is also used to
+		/// construct a default cost schedule.
+		type WeightInfo: WeightInfo;
+
+		/// Type that allows the runtime authors to add new host functions for a contract to call.
+		type ChainExtension: chain_extension::ChainExtension<Self>;
 
 		/// The maximum number of tries that can be queued for deletion.
-		const DeletionQueueDepth: u32 = T::DeletionQueueDepth::get();
+		#[pallet::constant]
+		type DeletionQueueDepth: Get<u32>;
 
 		/// The maximum amount of weight that can be consumed per block for lazy trie removal.
-		const DeletionWeightLimit: Weight = T::DeletionWeightLimit::get();
+		#[pallet::constant]
+		type DeletionWeightLimit: Get<Weight>;
+
+		/// The maximum length of a contract code in bytes. This limit applies to the instrumented
+		/// version of the code. Therefore `instantiate_with_code` can fail even when supplying
+		/// a wasm binary below this maximum size.
+		#[pallet::constant]
+		type MaxCodeSize: Get<u32>;
+	}
 
-		fn deposit_event() = default;
+	#[pallet::pallet]
+	#[pallet::generate_store(pub(super) trait Store)]
+	pub struct Pallet<T>(PhantomData<T>);
 
-		fn on_initialize() -> Weight {
+	#[pallet::hooks]
+	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T>
+	where
+		T::AccountId: UncheckedFrom<T::Hash>,
+		T::AccountId: AsRef<[u8]>,
+	{
+		fn on_initialize(_block: T::BlockNumber) -> Weight {
 			// We do not want to go above the block limit and rather avoid lazy deletion
 			// in that case. This should only happen on runtime upgrades.
 			let weight_limit = T::BlockWeights::get().max_block
@@ -519,21 +265,29 @@ decl_module! {
 			Storage::<T>::process_deletion_queue_batch(weight_limit)
 				.saturating_add(T::WeightInfo::on_initialize())
 		}
+	}
 
+	#[pallet::call]
+	impl<T: Config> Pallet<T>
+	where
+		T::AccountId: UncheckedFrom<T::Hash>,
+		T::AccountId: AsRef<[u8]>,
+	{
 		/// Updates the schedule for metering contracts.
 		///
 		/// The schedule must have a greater version than the stored schedule.
-		#[weight = T::WeightInfo::update_schedule()]
-		pub fn update_schedule(origin, schedule: Schedule<T>) -> DispatchResult {
+		#[pallet::weight(T::WeightInfo::update_schedule())]
+		pub fn update_schedule(
+			origin: OriginFor<T>,
+			schedule: Schedule<T>
+		) -> DispatchResultWithPostInfo {
 			ensure_root(origin)?;
 			if <Module<T>>::current_schedule().version >= schedule.version {
 				Err(Error::<T>::InvalidScheduleVersion)?
 			}
-
-			Self::deposit_event(RawEvent::ScheduleUpdated(schedule.version));
+			Self::deposit_event(Event::ScheduleUpdated(schedule.version));
 			CurrentSchedule::put(schedule);
-
-			Ok(())
+			Ok(().into())
 		}
 
 		/// Makes a call to an account, optionally transferring some balance.
@@ -543,12 +297,12 @@ decl_module! {
 		/// * If the account is a regular account, any value will be transferred.
 		/// * If no account exists and the call value is not less than `existential_deposit`,
 		/// a regular account will be created and any value will be transferred.
-		#[weight = T::WeightInfo::call(T::MaxCodeSize::get() / 1024).saturating_add(*gas_limit)]
+		#[pallet::weight(T::WeightInfo::call(T::MaxCodeSize::get() / 1024).saturating_add(*gas_limit))]
 		pub fn call(
-			origin,
+			origin: OriginFor<T>,
 			dest: <T::Lookup as StaticLookup>::Source,
-			#[compact] value: BalanceOf<T>,
-			#[compact] gas_limit: Gas,
+			#[pallet::compact] value: BalanceOf<T>,
+			#[pallet::compact] gas_limit: Weight,
 			data: Vec<u8>
 		) -> DispatchResultWithPostInfo {
 			let origin = ensure_signed(origin)?;
@@ -584,17 +338,17 @@ decl_module! {
 		/// - The smart-contract account is created at the computed address.
 		/// - The `endowment` is transferred to the new account.
 		/// - The `deploy` function is executed in the context of the newly-created account.
-		#[weight =
+		#[pallet::weight(
 			T::WeightInfo::instantiate_with_code(
 				code.len() as u32 / 1024,
 				salt.len() as u32 / 1024,
 			)
 			.saturating_add(*gas_limit)
-		]
+		)]
 		pub fn instantiate_with_code(
-			origin,
-			#[compact] endowment: BalanceOf<T>,
-			#[compact] gas_limit: Gas,
+			origin: OriginFor<T>,
+			#[pallet::compact] endowment: BalanceOf<T>,
+			#[pallet::compact] gas_limit: Weight,
 			code: Vec<u8>,
 			data: Vec<u8>,
 			salt: Vec<u8>,
@@ -618,89 +372,289 @@ decl_module! {
 
 		/// Instantiates a contract from a previously deployed wasm binary.
 		///
-		/// This function is identical to [`Self::instantiate_with_code`] but without the
-		/// code deployment step. Instead, the `code_hash` of an on-chain deployed wasm binary
-		/// must be supplied.
-		#[weight =
-			T::WeightInfo::instantiate(T::MaxCodeSize::get() / 1024, salt.len() as u32 / 1024)
-				.saturating_add(*gas_limit)
-		]
-		pub fn instantiate(
-			origin,
-			#[compact] endowment: BalanceOf<T>,
-			#[compact] gas_limit: Gas,
-			code_hash: CodeHash<T>,
-			data: Vec<u8>,
-			salt: Vec<u8>,
-		) -> DispatchResultWithPostInfo {
-			let origin = ensure_signed(origin)?;
-			let mut gas_meter = GasMeter::new(gas_limit);
-			let schedule = <Module<T>>::current_schedule();
-			let executable = PrefabWasmModule::from_storage(code_hash, &schedule, &mut gas_meter)?;
-			let mut ctx = ExecutionContext::<T, PrefabWasmModule<T>>::top_level(origin, &schedule);
-			let code_len = executable.code_len();
-			let result = ctx.instantiate(endowment, &mut gas_meter, executable, data, &salt)
-				.map(|(_address, output)| output);
-			gas_meter.into_dispatch_result(
-				result,
-				T::WeightInfo::instantiate(code_len / 1024, salt.len() as u32 / 1024),
-			)
-		}
-
-		/// Allows block producers to claim a small reward for evicting a contract. If a block
-		/// producer fails to do so, a regular users will be allowed to claim the reward.
+		/// This function is identical to [`Self::instantiate_with_code`] but without the
+		/// code deployment step. Instead, the `code_hash` of an on-chain deployed wasm binary
+		/// must be supplied.
+		#[pallet::weight(
+			T::WeightInfo::instantiate(T::MaxCodeSize::get() / 1024, salt.len() as u32 / 1024)
+				.saturating_add(*gas_limit)
+		)]
+		pub fn instantiate(
+			origin: OriginFor<T>,
+			#[pallet::compact] endowment: BalanceOf<T>,
+			#[pallet::compact] gas_limit: Weight,
+			code_hash: CodeHash<T>,
+			data: Vec<u8>,
+			salt: Vec<u8>,
+		) -> DispatchResultWithPostInfo {
+			let origin = ensure_signed(origin)?;
+			let mut gas_meter = GasMeter::new(gas_limit);
+			let schedule = <Module<T>>::current_schedule();
+			let executable = PrefabWasmModule::from_storage(code_hash, &schedule, &mut gas_meter)?;
+			let mut ctx = ExecutionContext::<T, PrefabWasmModule<T>>::top_level(origin, &schedule);
+			let code_len = executable.code_len();
+			let result = ctx.instantiate(endowment, &mut gas_meter, executable, data, &salt)
+				.map(|(_address, output)| output);
+			gas_meter.into_dispatch_result(
+				result,
+				T::WeightInfo::instantiate(code_len / 1024, salt.len() as u32 / 1024),
+			)
+		}
+
+		/// Allows block producers to claim a small reward for evicting a contract. If a block
+		/// producer fails to do so, a regular users will be allowed to claim the reward.
+		///
+		/// In case of a successful eviction no fees are charged from the sender. However, the
+		/// reward is capped by the total amount of rent that was payed by the contract while
+		/// it was alive.
+		///
+		/// If contract is not evicted as a result of this call, [`Error::ContractNotEvictable`]
+		/// is returned and the sender is not eligible for the reward.
+		#[pallet::weight(T::WeightInfo::claim_surcharge(T::MaxCodeSize::get() / 1024))]
+		pub fn claim_surcharge(
+			origin: OriginFor<T>,
+			dest: T::AccountId,
+			aux_sender: Option<T::AccountId>
+		) -> DispatchResultWithPostInfo {
+			let origin = origin.into();
+			let (signed, rewarded) = match (origin, aux_sender) {
+				(Ok(frame_system::RawOrigin::Signed(account)), None) => {
+					(true, account)
+				},
+				(Ok(frame_system::RawOrigin::None), Some(aux_sender)) => {
+					(false, aux_sender)
+				},
+				_ => Err(Error::<T>::InvalidSurchargeClaim)?,
+			};
+
+			// Add some advantage for block producers (who send unsigned extrinsics) by
+			// adding a handicap: for signed extrinsics we use a slightly older block number
+			// for the eviction check. This can be viewed as if we pushed regular users back in past.
+			let handicap = if signed {
+				T::SignedClaimHandicap::get()
+			} else {
+				Zero::zero()
+			};
+
+			// If poking the contract has lead to eviction of the contract, give out the rewards.
+			match Rent::<T, PrefabWasmModule<T>>::try_eviction(&dest, handicap)? {
+				(Some(rent_payed), code_len) => {
+					T::Currency::deposit_into_existing(
+						&rewarded,
+						T::SurchargeReward::get().min(rent_payed),
+					)
+					.map(|_| PostDispatchInfo {
+						actual_weight: Some(T::WeightInfo::claim_surcharge(code_len / 1024)),
+						pays_fee: Pays::No,
+					})
+					.map_err(Into::into)
+				}
+				(None, code_len) => Err(Error::<T>::ContractNotEvictable.with_weight(
+					T::WeightInfo::claim_surcharge(code_len / 1024)
+				)),
+			}
+		}
+	}
+
+	#[pallet::event]
+	#[pallet::generate_deposit(pub(super) fn deposit_event)]
+	#[pallet::metadata(T::AccountId = "AccountId", T::Hash = "Hash", BalanceOf<T> = "Balance")]
+	pub enum Event<T: Config> {
+		/// Contract deployed by address at the specified address. \[deployer, contract\]
+		Instantiated(T::AccountId, T::AccountId),
+
+		/// Contract has been evicted and is now in tombstone state. \[contract\]
+		Evicted(T::AccountId),
+
+		/// Contract has been terminated without leaving a tombstone.
+		/// \[contract, beneficiary\]
+		///
+		/// # Params
+		///
+		/// - `contract`: The contract that was terminated.
+		/// - `beneficiary`: The account that received the contracts remaining balance.
+		///
+		/// # Note
+		///
+		/// The only way for a contract to be removed without a tombstone and emitting
+		/// this event is by calling `seal_terminate`.
+		Terminated(T::AccountId, T::AccountId),
+
+		/// Restoration of a contract has been successful.
+		/// \[restorer, dest, code_hash, rent_allowance\]
+		///
+		/// # Params
+		///
+		/// - `restorer`: Account ID of the restoring contract.
+		/// - `dest`: Account ID of the restored contract.
+		/// - `code_hash`: Code hash of the restored contract.
+		/// - `rent_allowance`: Rent allowance of the restored contract.
+		Restored(T::AccountId, T::AccountId, T::Hash, BalanceOf<T>),
+
+		/// Code with the specified hash has been stored. \[code_hash\]
+		CodeStored(T::Hash),
+
+		/// Triggered when the current schedule is updated.
+		/// \[version\]
+		///
+		/// # Params
+		///
+		/// - `version`: The version of the newly set schedule.
+		ScheduleUpdated(u32),
+
+		/// A custom event emitted by the contract.
+		/// \[contract, data\]
+		///
+		/// # Params
+		///
+		/// - `contract`: The contract that emitted the event.
+		/// - `data`: Data supplied by the contract. Metadata generated during contract
+		///           compilation is needed to decode it.
+		ContractEmitted(T::AccountId, Vec<u8>),
+
+		/// A code with the specified hash was removed.
+		/// \[code_hash\]
+		///
+		/// This happens when the last contract that uses this code hash was removed or evicted.
+		CodeRemoved(T::Hash),
+	}
+
+	#[pallet::error]
+	pub enum Error<T> {
+		/// A new schedule must have a greater version than the current one.
+		InvalidScheduleVersion,
+		/// An origin must be signed or inherent and auxiliary sender only provided on inherent.
+		InvalidSurchargeClaim,
+		/// Cannot restore from nonexisting or tombstone contract.
+		InvalidSourceContract,
+		/// Cannot restore to nonexisting or alive contract.
+		InvalidDestinationContract,
+		/// Tombstones don't match.
+		InvalidTombstone,
+		/// An origin TrieId written in the current block.
+		InvalidContractOrigin,
+		/// The executed contract exhausted its gas limit.
+		OutOfGas,
+		/// The output buffer supplied to a contract API call was too small.
+		OutputBufferTooSmall,
+		/// Performing the requested transfer would have brought the contract below
+		/// the subsistence threshold. No transfer is allowed to do this in order to allow
+		/// for a tombstone to be created. Use `seal_terminate` to remove a contract without
+		/// leaving a tombstone behind.
+		BelowSubsistenceThreshold,
+		/// The newly created contract is below the subsistence threshold after executing
+		/// its contructor. No contracts are allowed to exist below that threshold.
+		NewContractNotFunded,
+		/// Performing the requested transfer failed for a reason originating in the
+		/// chosen currency implementation of the runtime. Most probably the balance is
+		/// too low or locks are placed on it.
+		TransferFailed,
+		/// Performing a call was denied because the calling depth reached the limit
+		/// of what is specified in the schedule.
+		MaxCallDepthReached,
+		/// The contract that was called is either no contract at all (a plain account)
+		/// or is a tombstone.
+		NotCallable,
+		/// The code supplied to `instantiate_with_code` exceeds the limit specified in the
+		/// current schedule.
+		CodeTooLarge,
+		/// No code could be found at the supplied code hash.
+		CodeNotFound,
+		/// A buffer outside of sandbox memory was passed to a contract API function.
+		OutOfBounds,
+		/// Input passed to a contract API function failed to decode as expected type.
+		DecodingFailed,
+		/// Contract trapped during execution.
+		ContractTrapped,
+		/// The size defined in `T::MaxValueSize` was exceeded.
+		ValueTooLarge,
+		/// The action performed is not allowed while the contract performing it is already
+		/// on the call stack. Those actions are contract self destruction and restoration
+		/// of a tombstone.
+		ReentranceDenied,
+		/// `seal_input` was called twice from the same contract execution context.
+		InputAlreadyRead,
+		/// The subject passed to `seal_random` exceeds the limit.
+		RandomSubjectTooLong,
+		/// The amount of topics passed to `seal_deposit_events` exceeds the limit.
+		TooManyTopics,
+		/// The topics passed to `seal_deposit_events` contains at least one duplicate.
+		DuplicateTopics,
+		/// The chain does not provide a chain extension. Calling the chain extension results
+		/// in this error. Note that this usually  shouldn't happen as deploying such contracts
+		/// is rejected.
+		NoChainExtension,
+		/// Removal of a contract failed because the deletion queue is full.
+		///
+		/// This can happen when either calling [`Pallet::claim_surcharge`] or `seal_terminate`.
+		/// The queue is filled by deleting contracts and emptied by a fixed amount each block.
+		/// Trying again during another block is the only way to resolve this issue.
+		DeletionQueueFull,
+		/// A contract could not be evicted because it has enough balance to pay rent.
 		///
-		/// In case of a successful eviction no fees are charged from the sender. However, the
-		/// reward is capped by the total amount of rent that was payed by the contract while
-		/// it was alive.
+		/// This can be returned from [`Pallet::claim_surcharge`] because the target
+		/// contract has enough balance to pay for its rent.
+		ContractNotEvictable,
+		/// A storage modification exhausted the 32bit type that holds the storage size.
 		///
-		/// If contract is not evicted as a result of this call, [`Error::ContractNotEvictable`]
-		/// is returned and the sender is not eligible for the reward.
-		#[weight = T::WeightInfo::claim_surcharge(T::MaxCodeSize::get() / 1024)]
-		pub fn claim_surcharge(
-			origin,
-			dest: T::AccountId,
-			aux_sender: Option<T::AccountId>
-		) -> DispatchResultWithPostInfo {
-			let origin = origin.into();
-			let (signed, rewarded) = match (origin, aux_sender) {
-				(Ok(frame_system::RawOrigin::Signed(account)), None) => {
-					(true, account)
-				},
-				(Ok(frame_system::RawOrigin::None), Some(aux_sender)) => {
-					(false, aux_sender)
-				},
-				_ => Err(Error::<T>::InvalidSurchargeClaim)?,
-			};
+		/// This can either happen when the accumulated storage in bytes is too large or
+		/// when number of storage items is too large.
+		StorageExhausted,
+		/// A contract with the same AccountId already exists.
+		DuplicateContract,
+	}
 
-			// Add some advantage for block producers (who send unsigned extrinsics) by
-			// adding a handicap: for signed extrinsics we use a slightly older block number
-			// for the eviction check. This can be viewed as if we pushed regular users back in past.
-			let handicap = if signed {
-				T::SignedClaimHandicap::get()
-			} else {
-				Zero::zero()
-			};
+	/// Current cost schedule for contracts.
+	#[pallet::storage]
+	#[pallet::getter(fn current_schedule)]
+	pub(super) type CurrentSchedule<T: Config> = StorageValue<_, Schedule<T>, ValueQuery>;
 
-			// If poking the contract has lead to eviction of the contract, give out the rewards.
-			match Rent::<T, PrefabWasmModule<T>>::try_eviction(&dest, handicap)? {
-				(Some(rent_payed), code_len) => {
-					T::Currency::deposit_into_existing(
-						&rewarded,
-						T::SurchargeReward::get().min(rent_payed),
-					)
-					.map(|_| PostDispatchInfo {
-						actual_weight: Some(T::WeightInfo::claim_surcharge(code_len / 1024)),
-						pays_fee: Pays::No,
-					})
-					.map_err(Into::into)
-				}
-				(None, code_len) => Err(Error::<T>::ContractNotEvictable.with_weight(
-					T::WeightInfo::claim_surcharge(code_len / 1024)
-				)),
+	/// A mapping from an original code hash to the original code, untouched by instrumentation.
+	#[pallet::storage]
+	pub type PristineCode<T: Config> = StorageMap<_, Identity, CodeHash<T>, Vec<u8>>;
+
+	/// A mapping between an original code hash and instrumented wasm code, ready for execution.
+	#[pallet::storage]
+	pub type CodeStorage<T: Config> = StorageMap<_, Identity, CodeHash<T>, PrefabWasmModule<T>>;
+
+	/// The subtrie counter.
+	#[pallet::storage]
+	pub type AccountCounter<T: Config> = StorageValue<_, u64, ValueQuery>;
+
+	/// The code associated with a given account.
+	///
+	/// TWOX-NOTE: SAFE since `AccountId` is a secure hash.
+	#[pallet::storage]
+	pub type ContractInfoOf<T: Config> = StorageMap<_, Twox64Concat, T::AccountId, ContractInfo<T>>;
+
+	/// Evicted contracts that await child trie deletion.
+	///
+	/// Child trie deletion is a heavy operation depending on the amount of storage items
+	/// stored in said trie. Therefore this operation is performed lazily in `on_initialize`.
+	#[pallet::storage]
+	pub type DeletionQueue<T: Config> = StorageValue<_, Vec<DeletedContract>, ValueQuery>;
+
+	#[pallet::genesis_config]
+	pub struct GenesisConfig<T: Config> {
+		#[doc = "Current cost schedule for contracts."]
+		pub current_schedule: Schedule<T>,
+	}
+
+	#[cfg(feature = "std")]
+	impl<T: Config> Default for GenesisConfig<T> {
+		fn default() -> Self {
+			Self {
+				current_schedule: Default::default(),
 			}
 		}
 	}
+
+	#[pallet::genesis_build]
+	impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
+		fn build(&self) {
+			<CurrentSchedule<T>>::put(&self.current_schedule);
+		}
+	}
 }
 
 impl<T: Config> Module<T>
@@ -717,7 +671,7 @@ where
 		origin: T::AccountId,
 		dest: T::AccountId,
 		value: BalanceOf<T>,
-		gas_limit: Gas,
+		gas_limit: Weight,
 		input_data: Vec<u8>,
 	) -> ContractExecResult {
 		let mut gas_meter = GasMeter::new(gas_limit);
@@ -783,7 +737,7 @@ where
 
 	/// Store code for benchmarks which does not check nor instrument the code.
 	#[cfg(feature = "runtime-benchmarks")]
-	fn store_code_raw(code: Vec<u8>) -> DispatchResult {
+	fn store_code_raw(code: Vec<u8>) -> frame_support::dispatch::DispatchResult {
 		let schedule = <Module<T>>::current_schedule();
 		PrefabWasmModule::store_code_unchecked(code, &schedule)?;
 		Ok(())
@@ -794,99 +748,129 @@ where
 	fn reinstrument_module(
 		module: &mut PrefabWasmModule<T>,
 		schedule: &Schedule<T>
-	) -> DispatchResult {
+	) -> frame_support::dispatch::DispatchResult {
 		self::wasm::reinstrument(module, schedule)
 	}
 }
 
-decl_event! {
-	pub enum Event<T>
-	where
-		Balance = BalanceOf<T>,
-		<T as frame_system::Config>::AccountId,
-		<T as frame_system::Config>::Hash
-	{
-		/// Contract deployed by address at the specified address. \[deployer, contract\]
-		Instantiated(AccountId, AccountId),
+/// Information for managing an account and its sub trie abstraction.
+/// This is the required info to cache for an account
+#[derive(Encode, Decode, RuntimeDebug)]
+pub enum ContractInfo<T: Config> {
+	Alive(AliveContractInfo<T>),
+	Tombstone(TombstoneContractInfo<T>),
+}
 
-		/// Contract has been evicted and is now in tombstone state. \[contract\]
-		Evicted(AccountId),
+impl<T: Config> ContractInfo<T> {
+	/// If contract is alive then return some alive info
+	pub fn get_alive(self) -> Option<AliveContractInfo<T>> {
+		if let ContractInfo::Alive(alive) = self {
+			Some(alive)
+		} else {
+			None
+		}
+	}
+	/// If contract is alive then return some reference to alive info
+	pub fn as_alive(&self) -> Option<&AliveContractInfo<T>> {
+		if let ContractInfo::Alive(ref alive) = self {
+			Some(alive)
+		} else {
+			None
+		}
+	}
+	/// If contract is alive then return some mutable reference to alive info
+	pub fn as_alive_mut(&mut self) -> Option<&mut AliveContractInfo<T>> {
+		if let ContractInfo::Alive(ref mut alive) = self {
+			Some(alive)
+		} else {
+			None
+		}
+	}
 
-		/// Contract has been terminated without leaving a tombstone.
-		/// \[contract, beneficiary\]
-		///
-		/// # Params
-		///
-		/// - `contract`: The contract that was terminated.
-		/// - `beneficiary`: The account that received the contracts remaining balance.
-		///
-		/// # Note
-		///
-		/// The only way for a contract to be removed without a tombstone and emitting
-		/// this event is by calling `seal_terminate`.
-		Terminated(AccountId, AccountId),
+	/// If contract is tombstone then return some tombstone info
+	pub fn get_tombstone(self) -> Option<TombstoneContractInfo<T>> {
+		if let ContractInfo::Tombstone(tombstone) = self {
+			Some(tombstone)
+		} else {
+			None
+		}
+	}
+	/// If contract is tombstone then return some reference to tombstone info
+	pub fn as_tombstone(&self) -> Option<&TombstoneContractInfo<T>> {
+		if let ContractInfo::Tombstone(ref tombstone) = self {
+			Some(tombstone)
+		} else {
+			None
+		}
+	}
+	/// If contract is tombstone then return some mutable reference to tombstone info
+	pub fn as_tombstone_mut(&mut self) -> Option<&mut TombstoneContractInfo<T>> {
+		if let ContractInfo::Tombstone(ref mut tombstone) = self {
+			Some(tombstone)
+		} else {
+			None
+		}
+	}
+}
 
-		/// Restoration of a contract has been successful.
-		/// \[restorer, dest, code_hash, rent_allowance\]
-		///
-		/// # Params
-		///
-		/// - `restorer`: Account ID of the restoring contract.
-		/// - `dest`: Account ID of the restored contract.
-		/// - `code_hash`: Code hash of the restored contract.
-		/// - `rent_allowance`: Rent allowance of the restored contract.
-		Restored(AccountId, AccountId, Hash, Balance),
+/// Information for managing an account and its sub trie abstraction.
+/// This is the required info to cache for an account.
+#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)]
+pub struct RawAliveContractInfo<CodeHash, Balance, BlockNumber> {
+	/// Unique ID for the subtree encoded as a bytes vector.
+	pub trie_id: TrieId,
+	/// The total number of bytes used by this contract.
+	///
+	/// It is a sum of each key-value pair stored by this contract.
+	pub storage_size: u32,
+	/// The total number of key-value pairs in storage of this contract.
+	pub pair_count: u32,
+	/// The code associated with a given account.
+	pub code_hash: CodeHash,
+	/// Pay rent at most up to this value.
+	pub rent_allowance: Balance,
+	/// The amount of rent that was payed by the contract over its whole lifetime.
+	///
+	/// A restored contract starts with a value of zero just like a new contract.
+	pub rent_payed: Balance,
+	/// Last block rent has been payed.
+	pub deduct_block: BlockNumber,
+	/// Last block child storage has been written.
+	pub last_write: Option<BlockNumber>,
+}
 
-		/// Code with the specified hash has been stored. \[code_hash\]
-		CodeStored(Hash),
+impl<CodeHash, Balance, BlockNumber> RawAliveContractInfo<CodeHash, Balance, BlockNumber> {
+	/// Associated child trie unique id is built from the hash part of the trie id.
+	pub fn child_trie_info(&self) -> ChildInfo {
+		child_trie_info(&self.trie_id[..])
+	}
+}
 
-		/// Triggered when the current schedule is updated.
-		/// \[version\]
-		///
-		/// # Params
-		///
-		/// - `version`: The version of the newly set schedule.
-		ScheduleUpdated(u32),
+/// Associated child trie unique id is built from the hash part of the trie id.
+pub(crate) fn child_trie_info(trie_id: &[u8]) -> ChildInfo {
+	ChildInfo::new_default(trie_id)
+}
 
-		/// A custom event emitted by the contract.
-		/// \[contract, data\]
-		///
-		/// # Params
-		///
-		/// - `contract`: The contract that emitted the event.
-		/// - `data`: Data supplied by the contract. Metadata generated during contract
-		///           compilation is needed to decode it.
-		ContractEmitted(AccountId, Vec<u8>),
+#[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)]
+pub struct RawTombstoneContractInfo<H, Hasher>(H, PhantomData<Hasher>);
 
-		/// A code with the specified hash was removed.
-		/// \[code_hash\]
-		///
-		/// This happens when the last contract that uses this code hash was removed or evicted.
-		CodeRemoved(Hash),
+impl<H, Hasher> RawTombstoneContractInfo<H, Hasher>
+where
+	H: Member + MaybeSerializeDeserialize+ Debug
+		+ AsRef<[u8]> + AsMut<[u8]> + Copy + Default
+		+ sp_std::hash::Hash + Codec,
+	Hasher: Hash<Output=H>,
+{
+	fn new(storage_root: &[u8], code_hash: H) -> Self {
+		let mut buf = Vec::new();
+		storage_root.using_encoded(|encoded| buf.extend_from_slice(encoded));
+		buf.extend_from_slice(code_hash.as_ref());
+		RawTombstoneContractInfo(<Hasher as Hash>::hash(&buf[..]), PhantomData)
 	}
 }
 
-decl_storage! {
-	trait Store for Module<T: Config> as Contracts
-	where
-		T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>
-	{
-		/// Current cost schedule for contracts.
-		CurrentSchedule get(fn current_schedule) config(): Schedule<T> = Default::default();
-		/// A mapping from an original code hash to the original code, untouched by instrumentation.
-		pub PristineCode: map hasher(identity) CodeHash<T> => Option<Vec<u8>>;
-		/// A mapping between an original code hash and instrumented wasm code, ready for execution.
-		pub CodeStorage: map hasher(identity) CodeHash<T> => Option<PrefabWasmModule<T>>;
-		/// The subtrie counter.
-		pub AccountCounter: u64 = 0;
-		/// The code associated with a given account.
-		///
-		/// TWOX-NOTE: SAFE since `AccountId` is a secure hash.
-		pub ContractInfoOf: map hasher(twox_64_concat) T::AccountId => Option<ContractInfo<T>>;
-		/// Evicted contracts that await child trie deletion.
-		///
-		/// Child trie deletion is a heavy operation depending on the amount of storage items
-		/// stored in said trie. Therefore this operation is performed lazily in `on_initialize`.
-		pub DeletionQueue: Vec<storage::DeletedContract>;
+impl<T: Config> From<AliveContractInfo<T>> for ContractInfo<T> {
+	fn from(alive_info: AliveContractInfo<T>) -> Self {
+		Self::Alive(alive_info)
 	}
 }
diff --git a/substrate/frame/contracts/src/rent.rs b/substrate/frame/contracts/src/rent.rs
index 087c6c518300ba368907685152a426b3ebbe98fe..85b8eff9893196e540138ae170a09286f37b7951 100644
--- a/substrate/frame/contracts/src/rent.rs
+++ b/substrate/frame/contracts/src/rent.rs
@@ -18,7 +18,7 @@
 //! A module responsible for computing the right amount of weight and charging it.
 
 use crate::{
-	AliveContractInfo, BalanceOf, ContractInfo, ContractInfoOf, Module, RawEvent,
+	AliveContractInfo, BalanceOf, ContractInfo, ContractInfoOf, Module, Event,
 	TombstoneContractInfo, Config, CodeHash, Error,
 	storage::Storage, wasm::PrefabWasmModule, exec::Executable,
 };
@@ -26,7 +26,7 @@ use sp_std::prelude::*;
 use sp_io::hashing::blake2_256;
 use sp_core::crypto::UncheckedFrom;
 use frame_support::{
-	debug, StorageMap,
+	debug,
 	storage::child,
 	traits::{Currency, ExistenceRequirement, Get, OnUnbalanced, WithdrawReasons},
 };
@@ -268,7 +268,7 @@ where
 				let tombstone_info = ContractInfo::Tombstone(tombstone);
 				<ContractInfoOf<T>>::insert(account, &tombstone_info);
 				code.drop_from_storage();
-				<Module<T>>::deposit_event(RawEvent::Evicted(account.clone()));
+				<Module<T>>::deposit_event(Event::Evicted(account.clone()));
 				Ok(None)
 			}
 			(Verdict::Evict { amount: _ }, None) => {
diff --git a/substrate/frame/contracts/src/storage.rs b/substrate/frame/contracts/src/storage.rs
index 2a2d5da225d61b018695c255dbf840744cca46fb..244ab3788979a29d09101b8bb9c57ae2f78de543 100644
--- a/substrate/frame/contracts/src/storage.rs
+++ b/substrate/frame/contracts/src/storage.rs
@@ -31,9 +31,8 @@ use sp_runtime::traits::{Bounded, Saturating, Zero};
 use sp_core::crypto::UncheckedFrom;
 use frame_support::{
 	dispatch::DispatchResult,
-	StorageMap,
 	debug,
-	storage::{child::{self, KillOutcome}, StorageValue},
+	storage::child::{self, KillOutcome},
 	traits::Get,
 	weights::Weight,
 };
@@ -196,10 +195,10 @@ where
 	/// You must make sure that the contract is also removed or converted into a tombstone
 	/// when queuing the trie for deletion.
 	pub fn queue_trie_for_deletion(contract: &AliveContractInfo<T>) -> DispatchResult {
-		if DeletionQueue::decode_len().unwrap_or(0) >= T::DeletionQueueDepth::get() as usize {
+		if <DeletionQueue<T>>::decode_len().unwrap_or(0) >= T::DeletionQueueDepth::get() as usize {
 			Err(Error::<T>::DeletionQueueFull.into())
 		} else {
-			DeletionQueue::append(DeletedContract {
+			<DeletionQueue<T>>::append(DeletedContract {
 				pair_count: contract.pair_count,
 				trie_id: contract.trie_id.clone(),
 			});
@@ -234,7 +233,7 @@ where
 	/// It returns the amount of weight used for that task or `None` when no weight was used
 	/// apart from the base weight.
 	pub fn process_deletion_queue_batch(weight_limit: Weight) -> Weight {
-		let queue_len = DeletionQueue::decode_len().unwrap_or(0);
+		let queue_len = <DeletionQueue<T>>::decode_len().unwrap_or(0);
 		if queue_len == 0 {
 			return weight_limit;
 		}
@@ -251,7 +250,7 @@ where
 			return weight_limit;
 		}
 
-		let mut queue = DeletionQueue::get();
+		let mut queue = <DeletionQueue<T>>::get();
 
 		while !queue.is_empty() && remaining_key_budget > 0 {
 			// Cannot panic due to loop condition
@@ -283,7 +282,7 @@ where
 				.saturating_sub(remaining_key_budget.min(pair_count));
 		}
 
-		DeletionQueue::put(queue);
+		<DeletionQueue<T>>::put(queue);
 		weight_limit.saturating_sub(weight_per_key.saturating_mul(remaining_key_budget as Weight))
 	}
 
@@ -293,7 +292,7 @@ where
 		use sp_runtime::traits::Hash;
 		// Note that skipping a value due to error is not an issue here.
 		// We only need uniqueness, not sequence.
-		let new_seed = AccountCounter::mutate(|v| {
+		let new_seed = <AccountCounter<T>>::mutate(|v| {
 			*v = v.wrapping_add(1);
 			*v
 		});
@@ -322,6 +321,6 @@ where
 			trie_id: vec![],
 		})
 		.collect();
-		DeletionQueue::put(queue);
+		<DeletionQueue<T>>::put(queue);
 	}
 }
diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs
index f10cd2882ace454066828b4ca4a3adae82f2ab1b..3fa806799e95c7e9babccae65ae6329b3025a8a5 100644
--- a/substrate/frame/contracts/src/tests.rs
+++ b/substrate/frame/contracts/src/tests.rs
@@ -17,14 +17,15 @@
 
 use crate::{
 	BalanceOf, ContractInfo, ContractInfoOf, Module,
-	RawAliveContractInfo, RawEvent, Config, Schedule, gas::Gas,
-	Error, RuntimeReturnCode, storage::Storage,
+	RawAliveContractInfo, Config, Schedule,
+	Error, storage::Storage,
 	chain_extension::{
 		Result as ExtensionResult, Environment, ChainExtension, Ext, SysConfig, RetVal,
 		UncheckedFrom, InitState, ReturnFlags,
 	},
 	exec::{AccountIdOf, Executable}, wasm::PrefabWasmModule,
 	weights::WeightInfo,
+	wasm::ReturnCode as RuntimeReturnCode,
 };
 use assert_matches::assert_matches;
 use codec::Encode;
@@ -36,8 +37,8 @@ use sp_runtime::{
 use sp_io::hashing::blake2_256;
 use frame_support::{
 	assert_ok, assert_err, assert_err_ignore_postinfo,
-	parameter_types, StorageMap, StorageValue, assert_storage_noop,
-	traits::{Currency, ReservableCurrency, OnInitialize},
+	parameter_types, assert_storage_noop,
+	traits::{Currency, ReservableCurrency, OnInitialize, GenesisBuild},
 	weights::{Weight, PostDispatchInfo, DispatchClass, constants::WEIGHT_PER_SECOND},
 	dispatch::DispatchErrorWithPostInfo,
 	storage::child,
@@ -73,7 +74,7 @@ pub mod test_utils {
 		exec::{StorageKey, AccountIdOf},
 		Module as Contracts,
 	};
-	use frame_support::{StorageMap, traits::Currency};
+	use frame_support::traits::Currency;
 
 	pub fn set_storage(addr: &AccountIdOf<Test>, key: &StorageKey, value: Option<Vec<u8>>) {
 		let contract_info = <ContractInfoOf::<Test>>::get(&addr).unwrap().get_alive().unwrap();
@@ -292,7 +293,7 @@ pub const BOB: AccountId32 = AccountId32::new([2u8; 32]);
 pub const CHARLIE: AccountId32 = AccountId32::new([3u8; 32]);
 pub const DJANGO: AccountId32 = AccountId32::new([4u8; 32]);
 
-const GAS_LIMIT: Gas = 10_000_000_000;
+const GAS_LIMIT: Weight = 10_000_000_000;
 
 pub struct ExtBuilder {
 	existential_deposit: u64,
@@ -501,19 +502,19 @@ fn instantiate_and_call_and_deposit_event() {
 				},
 				EventRecord {
 					phase: Phase::Initialization,
-					event: Event::pallet_contracts(RawEvent::CodeStored(code_hash.into())),
+					event: Event::pallet_contracts(crate::Event::CodeStored(code_hash.into())),
 					topics: vec![],
 				},
 				EventRecord {
 					phase: Phase::Initialization,
 					event: Event::pallet_contracts(
-						RawEvent::ContractEmitted(addr.clone(), vec![1, 2, 3, 4])
+						crate::Event::ContractEmitted(addr.clone(), vec![1, 2, 3, 4])
 					),
 					topics: vec![],
 				},
 				EventRecord {
 					phase: Phase::Initialization,
-					event: Event::pallet_contracts(RawEvent::Instantiated(ALICE, addr.clone())),
+					event: Event::pallet_contracts(crate::Event::Instantiated(ALICE, addr.clone())),
 					topics: vec![],
 				},
 			]);
@@ -1230,12 +1231,16 @@ fn restoration(
 				},
 				EventRecord {
 					phase: Phase::Initialization,
-					event: Event::pallet_contracts(RawEvent::CodeStored(set_rent_code_hash.into())),
+					event: Event::pallet_contracts(
+						crate::Event::CodeStored(set_rent_code_hash.into())
+					),
 					topics: vec![],
 				},
 				EventRecord {
 					phase: Phase::Initialization,
-					event: Event::pallet_contracts(RawEvent::Instantiated(ALICE, addr_bob.clone())),
+					event: Event::pallet_contracts(
+						crate::Event::Instantiated(ALICE, addr_bob.clone())
+					),
 					topics: vec![],
 				},
 			];
@@ -1275,7 +1280,9 @@ fn restoration(
 					},
 					EventRecord {
 						phase: Phase::Initialization,
-						event: Event::pallet_contracts(RawEvent::Instantiated(ALICE, addr_dummy.clone())),
+						event: Event::pallet_contracts(
+							crate::Event::Instantiated(ALICE, addr_dummy.clone())
+						),
 						topics: vec![],
 					},
 				].iter().cloned());
@@ -1401,7 +1408,7 @@ fn restoration(
 						assert_eq!(System::events(), vec![
 							EventRecord {
 								phase: Phase::Initialization,
-								event: Event::pallet_contracts(RawEvent::Evicted(addr_bob)),
+								event: Event::pallet_contracts(crate::Event::Evicted(addr_bob)),
 								topics: vec![],
 							},
 							EventRecord {
@@ -1433,12 +1440,16 @@ fn restoration(
 							},
 							EventRecord {
 								phase: Phase::Initialization,
-								event: Event::pallet_contracts(RawEvent::CodeStored(restoration_code_hash)),
+								event: Event::pallet_contracts(
+									crate::Event::CodeStored(restoration_code_hash)
+								),
 								topics: vec![],
 							},
 							EventRecord {
 								phase: Phase::Initialization,
-								event: Event::pallet_contracts(RawEvent::Instantiated(CHARLIE, addr_django.clone())),
+								event: Event::pallet_contracts(
+									crate::Event::Instantiated(CHARLIE, addr_django.clone())
+								),
 								topics: vec![],
 							},
 
@@ -1470,7 +1481,7 @@ fn restoration(
 				assert_eq!(System::events(), vec![
 					EventRecord {
 						phase: Phase::Initialization,
-						event: Event::pallet_contracts(RawEvent::CodeRemoved(restoration_code_hash)),
+						event: Event::pallet_contracts(crate::Event::CodeRemoved(restoration_code_hash)),
 						topics: vec![],
 					},
 					EventRecord {
@@ -1481,7 +1492,9 @@ fn restoration(
 					EventRecord {
 						phase: Phase::Initialization,
 						event: Event::pallet_contracts(
-							RawEvent::Restored(addr_django, addr_bob, bob_contract.code_hash, 50)
+							crate::Event::Restored(
+								addr_django, addr_bob, bob_contract.code_hash, 50
+							)
 						),
 						topics: vec![],
 					},
@@ -1720,13 +1733,13 @@ fn self_destruct_works() {
 				},
 				EventRecord {
 					phase: Phase::Initialization,
-					event: Event::pallet_contracts(RawEvent::CodeRemoved(code_hash)),
+					event: Event::pallet_contracts(crate::Event::CodeRemoved(code_hash)),
 					topics: vec![],
 				},
 				EventRecord {
 					phase: Phase::Initialization,
 					event: Event::pallet_contracts(
-						RawEvent::Terminated(addr.clone(), DJANGO)
+						crate::Event::Terminated(addr.clone(), DJANGO)
 					),
 					topics: vec![],
 				},
diff --git a/substrate/frame/contracts/src/wasm/code_cache.rs b/substrate/frame/contracts/src/wasm/code_cache.rs
index 1132d31776db61f617deca13ca623775e3a71e78..0b2512f17f594b5da8cbd2088de0475a3deee7ad 100644
--- a/substrate/frame/contracts/src/wasm/code_cache.rs
+++ b/substrate/frame/contracts/src/wasm/code_cache.rs
@@ -28,13 +28,13 @@
 //! Thus, before executing a contract it should be reinstrument with new schedule.
 
 use crate::{
-	CodeHash, CodeStorage, PristineCode, Schedule, Config, Error,
-	wasm::{prepare, PrefabWasmModule}, Module as Contracts, RawEvent,
-	gas::{Gas, GasMeter, Token},
+	CodeHash, CodeStorage, PristineCode, Schedule, Config, Error, Weight,
+	wasm::{prepare, PrefabWasmModule}, Module as Contracts, Event,
+	gas::{GasMeter, Token},
 	weights::WeightInfo,
 };
 use sp_core::crypto::UncheckedFrom;
-use frame_support::{StorageMap, dispatch::DispatchError};
+use frame_support::dispatch::DispatchError;
 #[cfg(feature = "runtime-benchmarks")]
 pub use self::private::reinstrument as reinstrument;
 
@@ -58,7 +58,7 @@ where
 			Some(module) => increment_64(&mut module.refcount),
 			None => {
 				*existing = Some(prefab_module);
-				Contracts::<T>::deposit_event(RawEvent::CodeStored(code_hash))
+				Contracts::<T>::deposit_event(Event::CodeStored(code_hash))
 			}
 		}
 	});
@@ -170,7 +170,7 @@ where
 	T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>
 {
 	<PristineCode<T>>::remove(code_hash);
-	Contracts::<T>::deposit_event(RawEvent::CodeRemoved(code_hash))
+	Contracts::<T>::deposit_event(Event::CodeRemoved(code_hash))
 }
 
 /// Increment the refcount panicking if it should ever overflow (which will not happen).
@@ -196,7 +196,7 @@ struct InstrumentToken(u32);
 impl<T: Config> Token<T> for InstrumentToken {
 	type Metadata = ();
 
-	fn calculate_amount(&self, _metadata: &Self::Metadata) -> Gas {
+	fn calculate_amount(&self, _metadata: &Self::Metadata) -> Weight {
 		T::WeightInfo::instrument(self.0 / 1024)
 	}
 }
diff --git a/substrate/frame/contracts/src/wasm/env_def/macros.rs b/substrate/frame/contracts/src/wasm/env_def/macros.rs
index dbb6705e9722d7d257ed034e944932b5dc240297..3c10d3225e43094b9bbb322eca52c5da7dd0e5e3 100644
--- a/substrate/frame/contracts/src/wasm/env_def/macros.rs
+++ b/substrate/frame/contracts/src/wasm/env_def/macros.rs
@@ -20,13 +20,11 @@
 //!
 //! Most likely you should use `define_env` macro.
 
-#[macro_export]
 macro_rules! convert_args {
 	() => (vec![]);
 	( $( $t:ty ),* ) => ( vec![ $( { use $crate::wasm::env_def::ConvertibleToWasm; <$t>::VALUE_TYPE }, )* ] );
 }
 
-#[macro_export]
 macro_rules! gen_signature {
 	( ( $( $params: ty ),* ) ) => (
 		{
@@ -43,7 +41,6 @@ macro_rules! gen_signature {
 	);
 }
 
-#[macro_export]
 macro_rules! gen_signature_dispatch {
 	(
 		$needle_name:ident,
@@ -102,7 +99,6 @@ where
 	f
 }
 
-#[macro_export]
 macro_rules! unmarshall_then_body_then_marshall {
 	( $args_iter:ident, $ctx:ident, ( $( $names:ident : $params:ty ),* ) -> $returns:ty => $body:tt ) => ({
 		let body = $crate::wasm::env_def::macros::constrain_closure::<
@@ -128,7 +124,6 @@ macro_rules! unmarshall_then_body_then_marshall {
 	})
 }
 
-#[macro_export]
 macro_rules! define_func {
 	( < E: $seal_ty:tt > $name:ident ( $ctx: ident $(, $names:ident : $params:ty)*) $(-> $returns:ty)* => $body:tt ) => {
 		fn $name< E: $seal_ty >(
@@ -152,7 +147,6 @@ macro_rules! define_func {
 	};
 }
 
-#[macro_export]
 macro_rules! register_func {
 	( $reg_cb:ident, < E: $seal_ty:tt > ; ) => {};
 
@@ -215,9 +209,9 @@ mod tests {
 	use sp_runtime::traits::Zero;
 	use sp_sandbox::{ReturnValue, Value};
 	use crate::{
+		Weight,
 		wasm::{Runtime, runtime::TrapReason, tests::MockExt},
 		exec::Ext,
-		gas::Gas,
 	};
 
 	struct TestRuntime {
@@ -282,7 +276,7 @@ mod tests {
 	#[test]
 	fn macro_define_func() {
 		define_func!( <E: Ext> seal_gas (_ctx, amount: u32) => {
-			let amount = Gas::from(amount);
+			let amount = Weight::from(amount);
 			if !amount.is_zero() {
 				Ok(())
 			} else {
@@ -334,7 +328,7 @@ mod tests {
 
 		define_env!(Env, <E: Ext>,
 			seal_gas( _ctx, amount: u32 ) => {
-				let amount = Gas::from(amount);
+				let amount = Weight::from(amount);
 				if !amount.is_zero() {
 					Ok(())
 				} else {
diff --git a/substrate/frame/contracts/src/wasm/env_def/mod.rs b/substrate/frame/contracts/src/wasm/env_def/mod.rs
index 0d9ceeee02373ec81c41eb501272741334566f36..997ec29e028d5df029243dcaa651c7c98477527e 100644
--- a/substrate/frame/contracts/src/wasm/env_def/mod.rs
+++ b/substrate/frame/contracts/src/wasm/env_def/mod.rs
@@ -22,7 +22,7 @@ use sp_sandbox::Value;
 use parity_wasm::elements::{FunctionType, ValueType};
 
 #[macro_use]
-pub(crate) mod macros;
+pub mod macros;
 
 pub trait ConvertibleToWasm: Sized {
 	const VALUE_TYPE: ValueType;
@@ -67,13 +67,13 @@ impl ConvertibleToWasm for u64 {
 	}
 }
 
-pub(crate) type HostFunc<E> =
+pub type HostFunc<E> =
 	fn(
 		&mut Runtime<E>,
 		&[sp_sandbox::Value]
 	) -> Result<sp_sandbox::ReturnValue, sp_sandbox::HostError>;
 
-pub(crate) trait FunctionImplProvider<E: Ext> {
+pub trait FunctionImplProvider<E: Ext> {
 	fn impls<F: FnMut(&[u8], HostFunc<E>)>(f: &mut F);
 }
 
diff --git a/substrate/frame/contracts/src/wasm/mod.rs b/substrate/frame/contracts/src/wasm/mod.rs
index c6970b2b1eb060d239a067d096618a7a8f01288a..9001e2b8e92d713f873031572157c7cd043223e3 100644
--- a/substrate/frame/contracts/src/wasm/mod.rs
+++ b/substrate/frame/contracts/src/wasm/mod.rs
@@ -38,6 +38,8 @@ use pallet_contracts_primitives::ExecResult;
 pub use self::runtime::{ReturnCode, Runtime, RuntimeToken};
 #[cfg(feature = "runtime-benchmarks")]
 pub use self::code_cache::reinstrument;
+#[cfg(test)]
+pub use tests::MockExt;
 
 /// A prepared wasm module ready for execution.
 ///
@@ -237,7 +239,7 @@ mod tests {
 	use crate::{
 		CodeHash, BalanceOf, Error, Module as Contracts,
 		exec::{Ext, StorageKey, AccountIdOf, Executable},
-		gas::{Gas, GasMeter},
+		gas::GasMeter,
 		tests::{Test, Call, ALICE, BOB},
 	};
 	use std::collections::HashMap;
@@ -248,7 +250,7 @@ mod tests {
 	use assert_matches::assert_matches;
 	use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags, ExecError, ErrorOrigin};
 
-	const GAS_LIMIT: Gas = 10_000_000_000;
+	const GAS_LIMIT: Weight = 10_000_000_000;
 
 	#[derive(Debug, PartialEq, Eq)]
 	struct DispatchEntry(Call);
@@ -1202,7 +1204,7 @@ mod tests {
 			&mut gas_meter,
 		).unwrap();
 
-		let gas_left = Gas::decode(&mut output.data.as_slice()).unwrap();
+		let gas_left = Weight::decode(&mut output.data.as_slice()).unwrap();
 		assert!(gas_left < GAS_LIMIT, "gas_left must be less than initial");
 		assert!(gas_left > gas_meter.gas_left(), "gas_left must be greater than final");
 	}
diff --git a/substrate/frame/contracts/src/wasm/runtime.rs b/substrate/frame/contracts/src/wasm/runtime.rs
index 020be381851f8131974e3b5538a4ee97593929e8..e0f7626b95a9fb5a3db780f442fe293869f4f558 100644
--- a/substrate/frame/contracts/src/wasm/runtime.rs
+++ b/substrate/frame/contracts/src/wasm/runtime.rs
@@ -20,11 +20,11 @@
 use crate::{
 	HostFnWeights, Config, CodeHash, BalanceOf, Error,
 	exec::{Ext, StorageKey, TopicOf},
-	gas::{Gas, GasMeter, Token, ChargedAmount},
+	gas::{GasMeter, Token, ChargedAmount},
 	wasm::env_def::ConvertibleToWasm,
 };
 use parity_wasm::elements::ValueType;
-use frame_support::{dispatch::DispatchError, ensure, traits::Get};
+use frame_support::{dispatch::DispatchError, ensure, traits::Get, weights::Weight};
 use sp_std::prelude::*;
 use codec::{Decode, DecodeAll, Encode};
 use sp_runtime::traits::SaturatedConversion;
@@ -223,7 +223,7 @@ where
 {
 	type Metadata = HostFnWeights<T>;
 
-	fn calculate_amount(&self, s: &Self::Metadata) -> Gas {
+	fn calculate_amount(&self, s: &Self::Metadata) -> Weight {
 		use self::RuntimeToken::*;
 		match *self {
 			MeteringBlock(amount) => s.gas.saturating_add(amount.into()),