diff --git a/substrate/demo/executor/src/lib.rs b/substrate/demo/executor/src/lib.rs
index 6e07f3c5fbf0216066a1602816cffb5adab4c1c1..5c6b2748d7a769eb5df74a29afaade15d8e656bb 100644
--- a/substrate/demo/executor/src/lib.rs
+++ b/substrate/demo/executor/src/lib.rs
@@ -38,15 +38,15 @@ mod tests {
 	use runtime_io;
 	use super::Executor;
 	use substrate_executor::WasmExecutor;
-	use codec::{KeyedVec, Slicable, Joiner};
+	use codec::{Slicable, Joiner};
 	use keyring::Keyring::{self, Alice, Bob};
-	use runtime_support::Hashable;
+	use runtime_support::{Hashable, StorageValue, StorageMap};
 	use state_machine::{CodeExecutor, TestExternalities};
 	use primitives::twox_128;
 	use demo_primitives::{Hash, Header, BlockNumber, Digest};
 	use demo_runtime::transaction::{Transaction, UncheckedTransaction};
 	use demo_runtime::block::Block;
-	use demo_runtime::runtime::staking::{self, balance, BALANCE_OF};
+	use demo_runtime::runtime::staking::{self, FreeBalanceOf, balance};
 	use demo_runtime::dispatch;
 	use ed25519::{Public, Pair};
 
@@ -75,8 +75,8 @@ mod tests {
 	#[test]
 	fn panic_execution_with_foreign_code_gives_error() {
 		let mut t: TestExternalities = map![
-			twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0],
-			twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8]
+			twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0],
+			twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8]
 		];
 
 		let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
@@ -86,8 +86,8 @@ mod tests {
 	#[test]
 	fn panic_execution_with_native_equivalent_code_gives_error() {
 		let mut t: TestExternalities = map![
-			twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0],
-			twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8]
+			twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0],
+			twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8]
 		];
 
 		let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
@@ -97,8 +97,8 @@ mod tests {
 	#[test]
 	fn successful_execution_with_native_equivalent_code_gives_ok() {
 		let mut t: TestExternalities = map![
-			twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0],
-			twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8]
+			twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0],
+			twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8]
 		];
 
 		let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
@@ -113,8 +113,8 @@ mod tests {
 	#[test]
 	fn successful_execution_with_foreign_code_gives_ok() {
 		let mut t: TestExternalities = map![
-			twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0],
-			twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8]
+			twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0],
+			twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8]
 		];
 
 		let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
@@ -158,7 +158,7 @@ mod tests {
 		construct_block(
 			1,
 			[69u8; 32].into(),
-			hex!("cfb76a83e40aa6a0d3f92255e6229e74808cae31d9f46053f31129b797540d03").into(),
+			hex!("7a388ce5b4eeadbb9268ae96e8822b223f4fd1841327d99f4e1c21fad81f97f2").into(),
 			vec![Transaction {
 				signed: Alice.into(),
 				nonce: 0,
@@ -171,7 +171,7 @@ mod tests {
 		construct_block(
 			2,
 			block1().1,
-			hex!("c713bd003e303648e8d904bcfa44084865c9b70c398547e678028cc7cf60907f").into(),
+			hex!("e4eb71be8b816f2061f32f284e9b429562cdc1b82f11725e5f965ff23439f5e9").into(),
 			vec![
 				Transaction {
 					signed: Bob.into(),
@@ -228,8 +228,8 @@ mod tests {
 	#[test]
 	fn panic_execution_gives_error() {
 		let mut t: TestExternalities = map![
-			twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0],
-			twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8]
+			twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0],
+			twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8]
 		];
 
 		let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm");
@@ -240,8 +240,8 @@ mod tests {
 	#[test]
 	fn successful_execution_gives_ok() {
 		let mut t: TestExternalities = map![
-			twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0],
-			twox_128(staking::TRANSACTION_FEE).to_vec() => vec![0u8; 8]
+			twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0],
+			twox_128(staking::TransactionFee::key()).to_vec() => vec![0u8; 8]
 		];
 
 		let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm");
diff --git a/substrate/demo/runtime/src/genesismap.rs b/substrate/demo/runtime/src/genesismap.rs
index c3b7da1b7d8c2f4e2ffe84f6b63d6a727af1270a..5fa83499b335a4f51a99819bacba784c6c232c77 100644
--- a/substrate/demo/runtime/src/genesismap.rs
+++ b/substrate/demo/runtime/src/genesismap.rs
@@ -19,7 +19,7 @@
 use codec::{KeyedVec, Joiner};
 use std::collections::HashMap;
 use runtime_io::twox_128;
-use runtime_support::Hashable;
+use runtime_support::{Hashable, StorageMap, StorageList, StorageValue};
 use primitives::Block;
 use demo_primitives::{BlockNumber, AccountId};
 use runtime::staking::Balance;
@@ -80,40 +80,37 @@ impl GenesisConfig {
 	pub fn genesis_map(&self) -> HashMap<Vec<u8>, Vec<u8>> {
 		let wasm_runtime = include_bytes!("../wasm/genesis.wasm").to_vec();
 		vec![
-			(&session::SESSION_LENGTH[..], vec![].and(&self.session_length)),
-			(&session::VALIDATOR_COUNT[..], vec![].and(&(self.validators.len() as u32))),
+			(session::SessionLength::key(), vec![].and(&self.session_length)),
+			(session::Validators::key(), vec![].and(&self.validators)),
 
-			(&staking::INTENTION_COUNT[..], vec![].and(&0u32)),
-			(&staking::SESSIONS_PER_ERA[..], vec![].and(&self.sessions_per_era)),
-			(&staking::CURRENT_ERA[..], vec![].and(&0u64)),
+			(&staking::Intention::len_key()[..], vec![].and(&0u32)),
+			(&staking::SessionsPerEra::key()[..], vec![].and(&self.sessions_per_era)),
+			(&staking::CurrentEra::key()[..], vec![].and(&0u64)),
 
-			(&democracy::LAUNCH_PERIOD[..], vec![].and(&self.launch_period)),
-			(&democracy::VOTING_PERIOD[..], vec![].and(&self.voting_period)),
-			(&democracy::MINIMUM_DEPOSIT[..], vec![].and(&self.minimum_deposit)),
+			(democracy::LaunchPeriod::key(), vec![].and(&self.launch_period)),
+			(democracy::VotingPeriod::key(), vec![].and(&self.voting_period)),
+			(democracy::MinimumDeposit::key(), vec![].and(&self.minimum_deposit)),
 
-			(&council::CANDIDACY_BOND[..], vec![].and(&self.candidacy_bond)),
-			(&council::VOTING_BOND[..], vec![].and(&self.voter_bond)),
-			(&council::PRESENT_SLASH_PER_VOTER[..], vec![].and(&self.present_slash_per_voter)),
-			(&council::CARRY_COUNT[..], vec![].and(&self.carry_count)),
-			(&council::PRESENTATION_DURATION[..], vec![].and(&self.presentation_duration)),
-			(&council::VOTING_PERIOD[..], vec![].and(&self.council_election_voting_period)),
-			(&council::TERM_DURATION[..], vec![].and(&self.council_term_duration)),
-			(&council::DESIRED_SEATS[..], vec![].and(&self.desired_seats)),
-			(&council::INACTIVE_GRACE_PERIOD[..], vec![].and(&self.inactive_grace_period)),
+			(council::CandidacyBond::key(), vec![].and(&self.candidacy_bond)),
+			(council::VotingBond::key(), vec![].and(&self.voter_bond)),
+			(council::PresentSlashPerVoter::key(), vec![].and(&self.present_slash_per_voter)),
+			(council::CarryCount::key(), vec![].and(&self.carry_count)),
+			(council::PresentationDuration::key(), vec![].and(&self.presentation_duration)),
+			(council::VotingPeriod::key(), vec![].and(&self.council_election_voting_period)),
+			(council::TermDuration::key(), vec![].and(&self.council_term_duration)),
+			(council::DesiredSeats::key(), vec![].and(&self.desired_seats)),
+			(council::InactiveGracePeriod::key(), vec![].and(&self.inactive_grace_period)),
 
-			(&council_vote::COOLOFF_PERIOD[..], vec![].and(&self.cooloff_period)),
-			(&council_vote::VOTING_PERIOD[..], vec![].and(&self.council_proposal_voting_period))
+			(council_vote::CooloffPeriod::key(), vec![].and(&self.cooloff_period)),
+			(council_vote::VotingPeriod::key(), vec![].and(&self.council_proposal_voting_period))
 		].into_iter()
 			.map(|(k, v)| (k.into(), v))
-			.chain(self.validators.iter()
-				.enumerate()
-				.map(|(i, account)| ((i as u32).to_keyed_vec(session::VALIDATOR_AT), vec![].and(account)))
-			).chain(self.balances.iter()
-				.map(|&(account, balance)| (account.to_keyed_vec(staking::BALANCE_OF), vec![].and(&balance)))
+			.chain(self.balances.iter()
+				.map(|&(account, balance)| (staking::FreeBalanceOf::key_for(&account), vec![].and(&balance)))
 			)
 			.map(|(k, v)| (twox_128(&k[..])[..].to_vec(), v.to_vec()))
 			.chain(vec![
-				(system::CODE[..].into(), wasm_runtime),
+				(system::CODE.to_vec(), wasm_runtime),
 				(consensus::AUTHORITY_COUNT[..].into(), vec![].and(&(self.authorities.len() as u32))),
 			].into_iter())
 			.chain(self.authorities.iter()
@@ -127,6 +124,6 @@ impl GenesisConfig {
 pub fn additional_storage_with_genesis(genesis_block: &Block) -> HashMap<Vec<u8>, Vec<u8>> {
 	use codec::Slicable;
 	map![
-		twox_128(&0u64.to_keyed_vec(system::BLOCK_HASH_AT)).to_vec() => genesis_block.header.blake2_256().encode()
+		system::BlockHashAt::key_for(&0) => genesis_block.header.blake2_256().encode()
 	]
 }
diff --git a/substrate/demo/runtime/src/lib.rs b/substrate/demo/runtime/src/lib.rs
index 1df77cc8cb925331be6373624fc11e262c859cf4..b9769af20924881cf2451b8c813acc63a35054e9 100644
--- a/substrate/demo/runtime/src/lib.rs
+++ b/substrate/demo/runtime/src/lib.rs
@@ -20,7 +20,7 @@
 
 #[allow(unused_imports)] #[macro_use] extern crate substrate_runtime_std as rstd;
 #[macro_use] extern crate substrate_runtime_io as runtime_io;
-extern crate substrate_runtime_support as runtime_support;
+#[macro_use] extern crate substrate_runtime_support as runtime_support;
 #[cfg(any(feature = "std", test))] extern crate substrate_keyring as keyring;
 
 #[cfg(feature = "std")] #[macro_use] extern crate serde_derive;
diff --git a/substrate/demo/runtime/src/runtime/council.rs b/substrate/demo/runtime/src/runtime/council.rs
index 504461cf19add715291b29b741b03fc814be02a5..3e64e231d8b351dfd7d733ce15250479a7b738f9 100644
--- a/substrate/demo/runtime/src/runtime/council.rs
+++ b/substrate/demo/runtime/src/runtime/council.rs
@@ -18,7 +18,7 @@
 
 use rstd::prelude::*;
 use codec::KeyedVec;
-use runtime_support::storage;
+use runtime_support::{StorageMap, StorageValue};
 use demo_primitives::{AccountId, Hash, BlockNumber};
 use runtime::{staking, system, session};
 use runtime::democracy::PrivPass;
@@ -80,103 +80,66 @@ use runtime::staking::{PublicPass, Balance};
 
 pub type VoteIndex = u32;
 
-// parameters
-pub const CANDIDACY_BOND: &[u8] = b"cou:cbo";
-pub const VOTING_BOND: &[u8] = b"cou:vbo";
-pub const PRESENT_SLASH_PER_VOTER: &[u8] = b"cou:pss";
-pub const CARRY_COUNT: &[u8] = b"cou:cco";
-pub const PRESENTATION_DURATION: &[u8] = b"cou:pdu";
-pub const INACTIVE_GRACE_PERIOD: &[u8] = b"cou:vgp";
-pub const VOTING_PERIOD: &[u8] = b"cou:per";
-pub const TERM_DURATION: &[u8] = b"cou:trm";
-pub const DESIRED_SEATS: &[u8] = b"cou:sts";
-
-// permanent state (always relevant, changes only at the finalisation of voting)
-pub const ACTIVE_COUNCIL: &[u8] = b"cou:act";		// Vec<(AccountId, expiry: BlockNumber)>
-pub const VOTE_COUNT: &[u8] = b"cou:vco";			// VoteIndex
-
-// persistent state (always relevant, changes constantly)
-pub const APPROVALS_OF: &[u8] = b"cou:apr:";		// Vec<bool>
-pub const REGISTER_INFO_OF: &[u8] = b"cou:reg:";	// Candidate -> (VoteIndex, u32)
-pub const LAST_ACTIVE_OF: &[u8] = b"cou:lac:";		// Voter -> VoteIndex
-pub const VOTERS: &[u8] = b"cou:vrs";				// Vec<AccountId>
-pub const CANDIDATES: &[u8] = b"cou:can";			// Vec<AccountId>, has holes
-pub const CANDIDATE_COUNT: &[u8] = b"cou:cnc";		// u32
-
-// temporary state (only relevant during finalisation/presentation)
-pub const NEXT_FINALISE: &[u8] = b"cou:nxt";
-pub const SNAPSHOTED_STAKES: &[u8] = b"cou:sss";		// Vec<Balance>
-pub const LEADERBOARD: &[u8] = b"cou:win";				// Vec<(Balance, AccountId)> ORDERED low -> high
-
-/// How much should be locked up in order to submit one's candidacy.
-pub fn candidacy_bond() -> Balance {
-	storage::get(CANDIDACY_BOND)
-		.expect("all core parameters of council module must be in place")
-}
-
-/// How much should be locked up in order to be able to submit votes.
-pub fn voting_bond() -> Balance {
-	storage::get(VOTING_BOND)
-		.expect("all core parameters of council module must be in place")
-}
-
-/// How long to give each top candidate to present themselves after the vote ends.
-pub fn presentation_duration() -> BlockNumber {
-	storage::get(PRESENTATION_DURATION)
-		.expect("all core parameters of council module must be in place")
-}
-
-/// How often (in blocks) to check for new votes.
-pub fn voting_period() -> BlockNumber {
-	storage::get(VOTING_PERIOD)
-		.expect("all core parameters of council module must be in place")
-}
-
-/// How many votes need to go by after a voter's last vote before they can be reaped if their
-/// approvals are moot.
-pub fn inactivity_grace_period() -> VoteIndex {
-	storage::get(INACTIVE_GRACE_PERIOD)
-		.expect("all core parameters of council module must be in place")
-}
-
-/// How long each position is active for.
-pub fn term_duration() -> BlockNumber {
-	storage::get(TERM_DURATION)
-		.expect("all core parameters of council module must be in place")
-}
-
-/// The punishment, per voter, if you provide an invalid presentation.
-pub fn present_slash_per_voter() -> Balance {
-	storage::get(PRESENT_SLASH_PER_VOTER)
-		.expect("all core parameters of council module must be in place")
-}
-
-/// Number of accounts that should be sitting on the council.
-pub fn desired_seats() -> u32 {
-	storage::get(DESIRED_SEATS)
-		.expect("all core parameters of council module must be in place")
-}
-
-/// How many runners-up should have their approvals persist until the next vote.
-pub fn carry_count() -> u32 {
-	storage::get(CARRY_COUNT)
-		.expect("all core parameters of council module must be in place")
+storage_items! {
+	// parameters
+	// How much should be locked up in order to submit one's candidacy.
+	pub CandidacyBond get(candidacy_bond): b"cou:cbo" => required Balance;
+	// How much should be locked up in order to be able to submit votes.
+	pub VotingBond get(voting_bond): b"cou:vbo" => required Balance;
+	// The punishment, per voter, if you provide an invalid presentation.
+	pub PresentSlashPerVoter get(present_slash_per_voter): b"cou:pss" => required Balance;
+	// How many runners-up should have their approvals persist until the next vote.
+	pub CarryCount get(carry_count): b"cou:cco" => required u32;
+	// How long to give each top candidate to present themselves after the vote ends.
+	pub PresentationDuration get(presentation_duration): b"cou:pdu" => required BlockNumber;
+	// How many votes need to go by after a voter's last vote before they can be reaped if their
+	// approvals are moot.
+	pub InactiveGracePeriod get(inactivity_grace_period): b"cou:vgp" => required VoteIndex;
+	// How often (in blocks) to check for new votes.
+	pub VotingPeriod get(voting_period): b"cou:per" => required BlockNumber;
+	// How long each position is active for.
+	pub TermDuration get(term_duration): b"cou:trm" => required BlockNumber;
+	// Number of accounts that should be sitting on the council.
+	pub DesiredSeats get(desired_seats): b"cou:sts" => required u32;
+
+	// permanent state (always relevant, changes only at the finalisation of voting)
+	// The current council. When there's a vote going on, this should still be used for executive
+	// matters.
+	pub ActiveCouncil get(active_council): b"cou:act" => default Vec<(AccountId, BlockNumber)>;
+	// The total number of votes that have happened or are in progress.
+	pub VoteCount get(vote_index): b"cou:vco" => default VoteIndex;
+
+	// persistent state (always relevant, changes constantly)
+	// The last cleared vote index that this voter was last active at.
+	pub ApprovalsOf get(approvals_of): b"cou:apr" => default map [ AccountId => Vec<bool> ];
+	// The vote index and list slot that the candidate `who` was registered or `None` if they are not
+	// currently registered.
+	pub RegisterInfoOf get(candidate_reg_info): b"cou:reg" => map [ AccountId => (VoteIndex, u32) ];
+	// The last cleared vote index that this voter was last active at.
+	pub LastActiveOf get(voter_last_active): b"cou:lac" => map [ AccountId => VoteIndex ];
+	// The present voter list.
+	pub Voters get(voters): b"cou:vrs" => default Vec<AccountId>;
+	// The present candidate list.
+	pub Candidates get(candidates): b"cou:can" => default Vec<AccountId>; // has holes
+	pub CandidateCount get(candidate_count): b"cou:cnc" => default u32;
+
+	// temporary state (only relevant during finalisation/presentation)
+	// The accounts holding the seats that will become free on the next tally.
+	pub NextFinalise get(next_finalise): b"cou:nxt" => (BlockNumber, u32, Vec<AccountId>);
+	// The stakes as they were at the point that the vote ended.
+	pub SnapshotedStakes get(snapshoted_stakes): b"cou:sss" => required Vec<Balance>;
+	// Get the leaderboard if we;re in the presentation phase.
+	pub Leaderboard get(leaderboard): b"cou:win" => Vec<(Balance, AccountId)>; // ORDERED low -> high
 }
 
 /// True if we're currently in a presentation period.
 pub fn presentation_active() -> bool {
-	storage::exists(NEXT_FINALISE)
-}
-
-/// The current council. When there's a vote going on, this should still be used for executive
-/// matters.
-pub fn active_council() -> Vec<(AccountId, BlockNumber)> {
-	storage::get_or_default(ACTIVE_COUNCIL)
+	NextFinalise::exists()
 }
 
 /// If `who` a candidate at the moment?
 pub fn is_a_candidate(who: &AccountId) -> bool {
-	storage::exists(&who.to_keyed_vec(REGISTER_INFO_OF))
+	RegisterInfoOf::exists(who)
 }
 
 /// Determine the block that a vote can happen on which is no less than `n`.
@@ -215,47 +178,6 @@ pub fn next_tally() -> Option<BlockNumber> {
 	}
 }
 
-/// The accounts holding the seats that will become free on the next tally.
-pub fn next_finalise() -> Option<(BlockNumber, u32, Vec<AccountId>)> {
-	storage::get(NEXT_FINALISE)
-}
-
-/// The total number of votes that have happened or are in progress.
-pub fn vote_index() -> VoteIndex {
-	storage::get_or_default(VOTE_COUNT)
-}
-
-/// The present candidate list.
-pub fn candidates() -> Vec<AccountId> {
-	storage::get_or_default(CANDIDATES)
-}
-
-/// The present voter list.
-pub fn voters() -> Vec<AccountId> {
-	storage::get_or_default(VOTERS)
-}
-
-/// The vote index and list slot that the candidate `who` was registered or `None` if they are not
-/// currently registered.
-pub fn candidate_reg_info(who: &AccountId) -> Option<(VoteIndex, u32)> {
-	storage::get(&who.to_keyed_vec(REGISTER_INFO_OF))
-}
-
-/// The last cleared vote index that this voter was last active at.
-pub fn voter_last_active(voter: &AccountId) -> Option<VoteIndex> {
-	storage::get(&voter.to_keyed_vec(LAST_ACTIVE_OF))
-}
-
-/// The last cleared vote index that this voter was last active at.
-pub fn approvals_of(voter: &AccountId) -> Vec<bool> {
-	storage::get_or_default(&voter.to_keyed_vec(APPROVALS_OF))
-}
-
-/// Get the leaderboard if we;re in the presentation phase.
-pub fn leaderboard() -> Option<Vec<(Balance, AccountId)>> {
-	storage::get(LEADERBOARD)
-}
-
 impl_dispatch! {
 	pub mod public;
 	fn set_approvals(votes: Vec<bool>, index: VoteIndex) = 0;
@@ -271,17 +193,17 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 	fn set_approvals(self, votes: Vec<bool>, index: VoteIndex) {
 		assert!(!presentation_active());
 		assert_eq!(index, vote_index());
-		if !storage::exists(&self.to_keyed_vec(LAST_ACTIVE_OF)) {
+		if !LastActiveOf::exists(*self) {
 			// not yet a voter - deduct bond.
 			staking::internal::reserve_balance(&self, voting_bond());
-			storage::put(VOTERS, &{
-				let mut v: Vec<AccountId> = storage::get_or_default(VOTERS);
+			Voters::put({
+				let mut v = Voters::get();
 				v.push(self.clone());
 				v
 			});
 		}
-		storage::put(&self.to_keyed_vec(APPROVALS_OF), &votes);
-		storage::put(&self.to_keyed_vec(LAST_ACTIVE_OF), &index);
+		ApprovalsOf::insert(*self, votes);
+		LastActiveOf::insert(*self, index);
 	}
 
 	/// Remove a voter. For it not to be a bond-consuming no-op, all approved candidate indices
@@ -291,7 +213,7 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 	/// May be called by anyone. Returns the voter deposit to `signed`.
 	fn reap_inactive_voter(self, signed_index: u32, who: AccountId, who_index: u32, assumed_vote_index: VoteIndex) {
 		assert!(!presentation_active(), "cannot reap during presentation period");
-		assert!(voter_last_active(&self).is_some(), "reaper must be a voter");
+		assert!(voter_last_active(*self).is_some(), "reaper must be a voter");
 		let last_active = voter_last_active(&who).expect("target for inactivity cleanup must be active");
 		assert!(assumed_vote_index == vote_index(), "vote index not current");
 		assert!(last_active < assumed_vote_index - inactivity_grace_period(), "cannot reap during grace perid");
@@ -326,7 +248,7 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 	/// Remove a voter. All votes are cancelled and the voter deposit is returned.
 	fn retract_voter(self, index: u32) {
 		assert!(!presentation_active(), "cannot retract when presenting");
-		assert!(storage::exists(&self.to_keyed_vec(LAST_ACTIVE_OF)), "cannot retract non-voter");
+		assert!(LastActiveOf::exists(*self), "cannot retract non-voter");
 		let voters = voters();
 		let index = index as usize;
 		assert!(index < voters.len(), "retraction index invalid");
@@ -343,8 +265,8 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 		assert!(staking::internal::deduct_unbonded(&self, candidacy_bond()), "candidate has not enough funds");
 
 		let slot = slot as usize;
-		let count = storage::get_or_default::<u32>(CANDIDATE_COUNT) as usize;
-		let candidates: Vec<AccountId> = storage::get_or_default(CANDIDATES);
+		let count = CandidateCount::get() as usize;
+		let candidates = Candidates::get();
 		assert!(
 			(slot == count && count == candidates.len()) ||
 			(slot < candidates.len() && candidates[slot] == AccountId::default()),
@@ -357,20 +279,20 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 		} else {
 			candidates[slot] = self.clone();
 		}
-		storage::put(CANDIDATES, &candidates);
-		storage::put(CANDIDATE_COUNT, &(count as u32 + 1));
-		storage::put(&self.to_keyed_vec(REGISTER_INFO_OF), &(vote_index(), slot));
+		Candidates::put(candidates);
+		CandidateCount::put(count as u32 + 1);
+		RegisterInfoOf::insert(*self, (vote_index(), slot as u32));
 	}
 
 	/// Claim that `signed` is one of the top carry_count() + current_vote().1 candidates.
-	/// Only works if the block number >= current_vote().0 and < current_vote().0 + presentation_duration()
+	/// Only works if the `block_number >= current_vote().0` and `< current_vote().0 + presentation_duration()``
 	/// `signed` should have at least
 	fn present_winner(self, candidate: AccountId, total: Balance, index: VoteIndex) {
 		assert_eq!(index, vote_index(), "index not current");
-		let (_, _, expiring): (BlockNumber, u32, Vec<AccountId>) = storage::get(NEXT_FINALISE)
+		let (_, _, expiring) = NextFinalise::get()
 			.expect("cannot present outside of presentation period");
-		let stakes: Vec<Balance> = storage::get_or_default(SNAPSHOTED_STAKES);
-		let voters: Vec<AccountId> = storage::get_or_default(VOTERS);
+		let stakes = SnapshotedStakes::get();
+		let voters = Voters::get();
 		let bad_presentation_punishment = present_slash_per_voter() * voters.len() as Balance;
 		assert!(staking::can_slash(&self, bad_presentation_punishment), "presenter must have sufficient slashable funds");
 
@@ -382,14 +304,14 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 		}
 
 		let (registered_since, candidate_index): (VoteIndex, u32) =
-			storage::get(&candidate.to_keyed_vec(REGISTER_INFO_OF)).expect("presented candidate must be current");
+			RegisterInfoOf::get(candidate).expect("presented candidate must be current");
 		let actual_total = voters.iter()
 			.zip(stakes.iter())
 			.filter_map(|(voter, stake)|
 				match voter_last_active(voter) {
 					Some(b) if b >= registered_since =>
 						approvals_of(voter).get(candidate_index as usize)
-							.and_then(|approved| if *approved { Some(stake) } else { None }),
+							.and_then(|approved| if *approved { Some(*stake) } else { None }),
 					_ => None,
 				})
 			.sum();
@@ -398,7 +320,7 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 			// insert into leaderboard
 			leaderboard[0] = (total, candidate.clone());
 			leaderboard.sort_by_key(|&(t, _)| t);
-			storage::put(LEADERBOARD, &leaderboard);
+			Leaderboard::put(leaderboard);
 		} else {
 			staking::internal::slash(&self, bad_presentation_punishment);
 		}
@@ -418,7 +340,7 @@ impl privileged::Dispatch for PrivPass {
 	/// election when they expire. If more, then a new vote will be started if one is not already
 	/// in progress.
 	fn set_desired_seats(self, count: u32) {
-		storage::put(DESIRED_SEATS, &count);
+		DesiredSeats::put(count);
 	}
 
 	/// Remove a particular member. A tally will happen instantly (if not already in a presentation
@@ -429,19 +351,19 @@ impl privileged::Dispatch for PrivPass {
 			.into_iter()
 			.filter(|i| i.0 != who)
 			.collect();
-		storage::put(ACTIVE_COUNCIL, &new_council);
+		ActiveCouncil::put(new_council);
 	}
 
 	/// Set the presentation duration. If there is current a vote being presented for, will
 	/// invoke `finalise_vote`.
 	fn set_presentation_duration(self, count: BlockNumber) {
-		storage::put(PRESENTATION_DURATION, &count);
+		PresentationDuration::put(count);
 	}
 
 	/// Set the presentation duration. If there is current a vote being presented for, will
 	/// invoke `finalise_vote`.
 	fn set_term_duration(self, count: BlockNumber) {
-		storage::put(TERM_DURATION, &count);
+		TermDuration::put(count);
 	}
 }
 
@@ -468,9 +390,9 @@ pub mod internal {
 
 /// Remove a voter from the system. Trusts that voters()[index] != voter.
 fn remove_voter(voter: &AccountId, index: usize, mut voters: Vec<AccountId>) {
-	storage::put(VOTERS, &{ voters.swap_remove(index); voters });
-	storage::kill(&voter.to_keyed_vec(APPROVALS_OF));
-	storage::kill(&voter.to_keyed_vec(LAST_ACTIVE_OF));
+	Voters::put({ voters.swap_remove(index); voters });
+	ApprovalsOf::remove(voter);
+	LastActiveOf::remove(voter);
 }
 
 /// Close the voting, snapshot the staking and the number of seats that are actually up for grabs.
@@ -478,18 +400,18 @@ fn start_tally() {
 	let active_council = active_council();
 	let desired_seats = desired_seats() as usize;
 	let number = system::block_number();
-	let expiring = active_council.iter().take_while(|i| i.1 == number).cloned().collect::<Vec<_>>();
+	let expiring = active_council.iter().take_while(|i| i.1 == number).map(|i| i.0).collect::<Vec<_>>();
 	if active_council.len() - expiring.len() < desired_seats {
 		let empty_seats = desired_seats - (active_council.len() - expiring.len());
-		storage::put(NEXT_FINALISE, &(number + presentation_duration(), empty_seats as u32, expiring));
+		NextFinalise::put((number + presentation_duration(), empty_seats as u32, expiring));
 
-		let voters: Vec<AccountId> = storage::get_or_default(VOTERS);
-		let votes: Vec<Balance> = voters.iter().map(staking::balance).collect();
-		storage::put(SNAPSHOTED_STAKES, &votes);
+		let voters = Voters::get();
+		let votes = voters.iter().map(staking::balance).collect::<Vec<_>>();
+		SnapshotedStakes::put(votes);
 
 		// initialise leaderboard.
 		let leaderboard_size = empty_seats + carry_count() as usize;
-		storage::put(LEADERBOARD, &vec![(0 as Balance, AccountId::default()); leaderboard_size]);
+		Leaderboard::put(vec![(0 as Balance, AccountId::default()); leaderboard_size]);
 	}
 }
 
@@ -498,10 +420,10 @@ fn start_tally() {
 /// a new vote is started.
 /// Clears all presented candidates, returning the bond of the elected ones.
 fn finalise_tally() {
-	storage::kill(SNAPSHOTED_STAKES);
-	let (_, coming, expiring): (BlockNumber, u32, Vec<AccountId>) = storage::take(NEXT_FINALISE)
+	SnapshotedStakes::kill();
+	let (_, coming, expiring): (BlockNumber, u32, Vec<AccountId>) = NextFinalise::take()
 		.expect("finalise can only be called after a tally is started.");
-	let leaderboard: Vec<(Balance, AccountId)> = storage::take(LEADERBOARD).unwrap_or_default();
+	let leaderboard: Vec<(Balance, AccountId)> = Leaderboard::take().unwrap_or_default();
 	let new_expiry = system::block_number() + term_duration();
 
 	// return bond to winners.
@@ -526,10 +448,10 @@ fn finalise_tally() {
 			.map(|(_, a)| (a, new_expiry)))
 		.collect();
 	new_council.sort_by_key(|&(_, expiry)| expiry);
-	storage::put(ACTIVE_COUNCIL, &new_council);
+	ActiveCouncil::put(new_council);
 
 	// clear all except runners-up from candidate list.
-	let candidates: Vec<AccountId> = storage::get_or_default(CANDIDATES);
+	let candidates = Candidates::get();
 	let mut new_candidates = vec![AccountId::default(); candidates.len()];	// shrink later.
 	let runners_up = leaderboard.into_iter()
 		.rev()
@@ -544,16 +466,16 @@ fn finalise_tally() {
 	for (old, new) in candidates.iter().zip(new_candidates.iter()) {
 		if old != new {
 			// removed - kill it
-			storage::kill(&old.to_keyed_vec(REGISTER_INFO_OF));
+			RegisterInfoOf::remove(old);
 		}
 	}
 	// discard any superfluous slots.
 	if let Some(last_index) = new_candidates.iter().rposition(|c| *c != AccountId::default()) {
 		new_candidates.truncate(last_index + 1);
 	}
-	storage::put(CANDIDATES, &(new_candidates));
-	storage::put(CANDIDATE_COUNT, &count);
-	storage::put(VOTE_COUNT, &(vote_index() + 1));
+	Candidates::put(new_candidates);
+	CandidateCount::put(count);
+	VoteCount::put(vote_index() + 1);
 }
 
 #[cfg(test)]
@@ -565,15 +487,15 @@ pub mod testing {
 
 	pub fn externalities() -> TestExternalities {
 		let extras: TestExternalities = map![
-			twox_128(CANDIDACY_BOND).to_vec() => vec![].and(&9u64),
-			twox_128(VOTING_BOND).to_vec() => vec![].and(&3u64),
-			twox_128(PRESENT_SLASH_PER_VOTER).to_vec() => vec![].and(&1u64),
-			twox_128(CARRY_COUNT).to_vec() => vec![].and(&2u32),
-			twox_128(PRESENTATION_DURATION).to_vec() => vec![].and(&2u64),
-			twox_128(VOTING_PERIOD).to_vec() => vec![].and(&4u64),
-			twox_128(TERM_DURATION).to_vec() => vec![].and(&5u64),
-			twox_128(DESIRED_SEATS).to_vec() => vec![].and(&2u32),
-			twox_128(INACTIVE_GRACE_PERIOD).to_vec() => vec![].and(&1u32)
+			twox_128(CandidacyBond::key()).to_vec() => vec![].and(&9u64),
+			twox_128(VotingBond::key()).to_vec() => vec![].and(&3u64),
+			twox_128(PresentSlashPerVoter::key()).to_vec() => vec![].and(&1u64),
+			twox_128(CarryCount::key()).to_vec() => vec![].and(&2u32),
+			twox_128(PresentationDuration::key()).to_vec() => vec![].and(&2u64),
+			twox_128(VotingPeriod::key()).to_vec() => vec![].and(&4u64),
+			twox_128(TermDuration::key()).to_vec() => vec![].and(&5u64),
+			twox_128(DesiredSeats::key()).to_vec() => vec![].and(&2u32),
+			twox_128(InactiveGracePeriod::key()).to_vec() => vec![].and(&1u32)
 		];
 		democracy::testing::externalities()
 			.into_iter().chain(extras.into_iter()).collect()
@@ -621,11 +543,11 @@ mod tests {
 
 			assert_eq!(candidates(), Vec::<AccountId>::new());
 			assert_eq!(is_a_candidate(&Alice), false);
-			assert_eq!(candidate_reg_info(&Alice), None);
+			assert_eq!(candidate_reg_info(*Alice), None);
 
 			assert_eq!(voters(), Vec::<AccountId>::new());
-			assert_eq!(voter_last_active(&Alice), None);
-			assert_eq!(approvals_of(&Alice), vec![]);
+			assert_eq!(voter_last_active(*Alice), None);
+			assert_eq!(approvals_of(*Alice), vec![]);
 		});
 	}
 
@@ -634,22 +556,22 @@ mod tests {
 		with_externalities(&mut new_test_ext(), || {
 			with_env(|e| e.block_number = 1);
 			assert_eq!(candidates(), Vec::<AccountId>::new());
-			assert_eq!(candidate_reg_info(&Alice), None);
-			assert_eq!(candidate_reg_info(&Bob), None);
+			assert_eq!(candidate_reg_info(*Alice), None);
+			assert_eq!(candidate_reg_info(*Bob), None);
 			assert_eq!(is_a_candidate(&Alice), false);
 			assert_eq!(is_a_candidate(&Bob), false);
 
 			PublicPass::test(&Alice).submit_candidacy(0);
 			assert_eq!(candidates(), vec![Alice.to_raw_public()]);
-			assert_eq!(candidate_reg_info(&Alice), Some((0 as VoteIndex, 0u32)));
-			assert_eq!(candidate_reg_info(&Bob), None);
+			assert_eq!(candidate_reg_info(*Alice), Some((0 as VoteIndex, 0u32)));
+			assert_eq!(candidate_reg_info(*Bob), None);
 			assert_eq!(is_a_candidate(&Alice), true);
 			assert_eq!(is_a_candidate(&Bob), false);
 
 			PublicPass::test(&Bob).submit_candidacy(1);
 			assert_eq!(candidates(), vec![Alice.to_raw_public(), Bob.into()]);
-			assert_eq!(candidate_reg_info(&Alice), Some((0 as VoteIndex, 0u32)));
-			assert_eq!(candidate_reg_info(&Bob), Some((0 as VoteIndex, 1u32)));
+			assert_eq!(candidate_reg_info(*Alice), Some((0 as VoteIndex, 0u32)));
+			assert_eq!(candidate_reg_info(*Bob), Some((0 as VoteIndex, 1u32)));
 			assert_eq!(is_a_candidate(&Alice), true);
 			assert_eq!(is_a_candidate(&Bob), true);
 		});
@@ -657,9 +579,9 @@ mod tests {
 
 	fn new_test_ext_with_candidate_holes() -> TestExternalities {
 		let mut t = new_test_ext();
-		t.insert(twox_128(CANDIDATES).to_vec(), vec![].and(&vec![AccountId::default(), AccountId::default(), Alice.to_raw_public()]));
-		t.insert(twox_128(CANDIDATE_COUNT).to_vec(), vec![].and(&1u32));
-		t.insert(twox_128(&Alice.to_raw_public().to_keyed_vec(REGISTER_INFO_OF)).to_vec(), vec![].and(&(0 as VoteIndex, 2u32)));
+		t.insert(twox_128(Candidates::key()).to_vec(), vec![].and(&vec![AccountId::default(), AccountId::default(), Alice.to_raw_public()]));
+		t.insert(twox_128(CandidateCount::key()).to_vec(), vec![].and(&1u32));
+		t.insert(twox_128(&RegisterInfoOf::key_for(*Alice)).to_vec(), vec![].and(&(0 as VoteIndex, 2u32)));
 		t
 	}
 
@@ -758,8 +680,8 @@ mod tests {
 			PublicPass::test(&Alice).set_approvals(vec![true], 0);
 			PublicPass::test(&Dave).set_approvals(vec![true], 0);
 
-			assert_eq!(approvals_of(&Alice), vec![true]);
-			assert_eq!(approvals_of(&Dave), vec![true]);
+			assert_eq!(approvals_of(*Alice), vec![true]);
+			assert_eq!(approvals_of(*Dave), vec![true]);
 			assert_eq!(voters(), vec![Alice.to_raw_public(), Dave.into()]);
 
 			PublicPass::test(&Bob).submit_candidacy(1);
@@ -768,10 +690,10 @@ mod tests {
 			PublicPass::test(&Bob).set_approvals(vec![false, true, true], 0);
 			PublicPass::test(&Charlie).set_approvals(vec![false, true, true], 0);
 
-			assert_eq!(approvals_of(&Alice), vec![true]);
-			assert_eq!(approvals_of(&Dave), vec![true]);
-			assert_eq!(approvals_of(&Bob), vec![false, true, true]);
-			assert_eq!(approvals_of(&Charlie), vec![false, true, true]);
+			assert_eq!(approvals_of(*Alice), vec![true]);
+			assert_eq!(approvals_of(*Dave), vec![true]);
+			assert_eq!(approvals_of(*Bob), vec![false, true, true]);
+			assert_eq!(approvals_of(*Charlie), vec![false, true, true]);
 
 			assert_eq!(voters(), vec![Alice.to_raw_public(), Dave.into(), Bob.into(), Charlie.into()]);
 		});
@@ -785,13 +707,13 @@ mod tests {
 			PublicPass::test(&Eve).submit_candidacy(0);
 			PublicPass::test(&Dave).set_approvals(vec![true], 0);
 
-			assert_eq!(approvals_of(&Dave), vec![true]);
+			assert_eq!(approvals_of(*Dave), vec![true]);
 
 			PublicPass::test(&Bob).submit_candidacy(1);
 			PublicPass::test(&Charlie).submit_candidacy(2);
 			PublicPass::test(&Dave).set_approvals(vec![true, false, true], 0);
 
-			assert_eq!(approvals_of(&Dave), vec![true, false, true]);
+			assert_eq!(approvals_of(*Dave), vec![true, false, true]);
 		});
 	}
 
@@ -810,34 +732,34 @@ mod tests {
 			PublicPass::test(&Dave).set_approvals(vec![true, false, true], 0);
 
 			assert_eq!(voters(), vec![Alice.to_raw_public(), Bob.into(), Charlie.into(), Dave.into()]);
-			assert_eq!(approvals_of(&Alice), vec![true]);
-			assert_eq!(approvals_of(&Bob), vec![false, true, true]);
-			assert_eq!(approvals_of(&Charlie), vec![false, true, true]);
-			assert_eq!(approvals_of(&Dave), vec![true, false, true]);
+			assert_eq!(approvals_of(*Alice), vec![true]);
+			assert_eq!(approvals_of(*Bob), vec![false, true, true]);
+			assert_eq!(approvals_of(*Charlie), vec![false, true, true]);
+			assert_eq!(approvals_of(*Dave), vec![true, false, true]);
 
 			PublicPass::test(&Alice).retract_voter(0);
 
 			assert_eq!(voters(), vec![Dave.to_raw_public(), Bob.into(), Charlie.into()]);
-			assert_eq!(approvals_of(&Alice), Vec::<bool>::new());
-			assert_eq!(approvals_of(&Bob), vec![false, true, true]);
-			assert_eq!(approvals_of(&Charlie), vec![false, true, true]);
-			assert_eq!(approvals_of(&Dave), vec![true, false, true]);
+			assert_eq!(approvals_of(*Alice), Vec::<bool>::new());
+			assert_eq!(approvals_of(*Bob), vec![false, true, true]);
+			assert_eq!(approvals_of(*Charlie), vec![false, true, true]);
+			assert_eq!(approvals_of(*Dave), vec![true, false, true]);
 
 			PublicPass::test(&Bob).retract_voter(1);
 
 			assert_eq!(voters(), vec![Dave.to_raw_public(), Charlie.into()]);
-			assert_eq!(approvals_of(&Alice), Vec::<bool>::new());
-			assert_eq!(approvals_of(&Bob), Vec::<bool>::new());
-			assert_eq!(approvals_of(&Charlie), vec![false, true, true]);
-			assert_eq!(approvals_of(&Dave), vec![true, false, true]);
+			assert_eq!(approvals_of(*Alice), Vec::<bool>::new());
+			assert_eq!(approvals_of(*Bob), Vec::<bool>::new());
+			assert_eq!(approvals_of(*Charlie), vec![false, true, true]);
+			assert_eq!(approvals_of(*Dave), vec![true, false, true]);
 
 			PublicPass::test(&Charlie).retract_voter(1);
 
 			assert_eq!(voters(), vec![Dave.to_raw_public()]);
-			assert_eq!(approvals_of(&Alice), Vec::<bool>::new());
-			assert_eq!(approvals_of(&Bob), Vec::<bool>::new());
-			assert_eq!(approvals_of(&Charlie), Vec::<bool>::new());
-			assert_eq!(approvals_of(&Dave), vec![true, false, true]);
+			assert_eq!(approvals_of(*Alice), Vec::<bool>::new());
+			assert_eq!(approvals_of(*Bob), Vec::<bool>::new());
+			assert_eq!(approvals_of(*Charlie), Vec::<bool>::new());
+			assert_eq!(approvals_of(*Dave), vec![true, false, true]);
 		});
 	}
 
@@ -901,8 +823,8 @@ mod tests {
 			assert!(!is_a_candidate(&Bob));
 			assert!(!is_a_candidate(&Eve));
 			assert_eq!(vote_index(), 1);
-			assert_eq!(voter_last_active(&Bob), Some(0));
-			assert_eq!(voter_last_active(&Eve), Some(0));
+			assert_eq!(voter_last_active(*Bob), Some(0));
+			assert_eq!(voter_last_active(*Eve), Some(0));
 		});
 	}
 
@@ -957,7 +879,7 @@ mod tests {
 			);
 
 			assert_eq!(voters(), vec![Eve.to_raw_public()]);
-			assert_eq!(approvals_of(&Bob).len(), 0);
+			assert_eq!(approvals_of(*Bob).len(), 0);
 			assert_eq!(staking::balance(&Bob), 17);
 			assert_eq!(staking::balance(&Eve), 53);
 		});
@@ -1017,7 +939,7 @@ mod tests {
 			);
 
 			assert_eq!(voters(), vec![Eve.to_raw_public()]);
-			assert_eq!(approvals_of(&Bob).len(), 0);
+			assert_eq!(approvals_of(*Bob).len(), 0);
 			assert_eq!(staking::balance(&Bob), 17);
 			assert_eq!(staking::balance(&Eve), 53);
 		});
@@ -1120,7 +1042,7 @@ mod tests {
 			);
 
 			assert_eq!(voters(), vec![Bob.to_raw_public(), Charlie.into(), Eve.into()]);
-			assert_eq!(approvals_of(&Dave).len(), 0);
+			assert_eq!(approvals_of(*Dave).len(), 0);
 			assert_eq!(staking::balance(&Dave), 37);
 		});
 	}
@@ -1327,13 +1249,13 @@ mod tests {
 			assert!(is_a_candidate(&Charlie));
 			assert!(is_a_candidate(&Dave));
 			assert_eq!(vote_index(), 1);
-			assert_eq!(voter_last_active(&Bob), Some(0));
-			assert_eq!(voter_last_active(&Charlie), Some(0));
-			assert_eq!(voter_last_active(&Dave), Some(0));
-			assert_eq!(voter_last_active(&Eve), Some(0));
-			assert_eq!(voter_last_active(&Ferdie), Some(0));
-			assert_eq!(candidate_reg_info(&Charlie), Some((0, 2)));
-			assert_eq!(candidate_reg_info(&Dave), Some((0, 3)));
+			assert_eq!(voter_last_active(*Bob), Some(0));
+			assert_eq!(voter_last_active(*Charlie), Some(0));
+			assert_eq!(voter_last_active(*Dave), Some(0));
+			assert_eq!(voter_last_active(*Eve), Some(0));
+			assert_eq!(voter_last_active(*Ferdie), Some(0));
+			assert_eq!(candidate_reg_info(*Charlie), Some((0, 2)));
+			assert_eq!(candidate_reg_info(*Dave), Some((0, 3)));
 		});
 	}
 
@@ -1379,13 +1301,13 @@ mod tests {
 			assert!(!is_a_candidate(&Eve));
 			assert!(is_a_candidate(&Dave));
 			assert_eq!(vote_index(), 2);
-			assert_eq!(voter_last_active(&Bob), Some(0));
-			assert_eq!(voter_last_active(&Charlie), Some(0));
-			assert_eq!(voter_last_active(&Dave), Some(0));
-			assert_eq!(voter_last_active(&Eve), Some(0));
-			assert_eq!(voter_last_active(&Ferdie), Some(1));
+			assert_eq!(voter_last_active(*Bob), Some(0));
+			assert_eq!(voter_last_active(*Charlie), Some(0));
+			assert_eq!(voter_last_active(*Dave), Some(0));
+			assert_eq!(voter_last_active(*Eve), Some(0));
+			assert_eq!(voter_last_active(*Ferdie), Some(1));
 
-			assert_eq!(candidate_reg_info(&Dave), Some((0, 3)));
+			assert_eq!(candidate_reg_info(*Dave), Some((0, 3)));
 		});
 	}
 }
diff --git a/substrate/demo/runtime/src/runtime/council_vote.rs b/substrate/demo/runtime/src/runtime/council_vote.rs
index 9b58c7eeb4f9a502df69d39b56620fbdfcdcecca..763a35f1d26838905c21da1ec2e56ec3d9784a90 100644
--- a/substrate/demo/runtime/src/runtime/council_vote.rs
+++ b/substrate/demo/runtime/src/runtime/council_vote.rs
@@ -17,9 +17,10 @@
 //! Council voting system.
 
 use rstd::prelude::*;
+use rstd::borrow::Borrow;
 use codec::{KeyedVec, Slicable, Input, NonTrivialSlicable};
 use runtime_support::Hashable;
-use runtime_support::storage;
+use runtime_support::{StorageValue, StorageMap};
 use demo_primitives::{AccountId, Hash, BlockNumber};
 use runtime::{system, democracy, council};
 use runtime::staking::{PublicPass, Balance};
@@ -28,43 +29,28 @@ use dispatch::PrivCall as Proposal;
 
 type ProposalHash = [u8; 32];
 
-pub const COOLOFF_PERIOD: &[u8] = b"cov:cooloff";		// BlockNumber
-pub const VOTING_PERIOD: &[u8] = b"cov:period";			// BlockNumber
-
-pub const PROPOSALS: &[u8] = b"cov:prs";				// Vec<(expiry: BlockNumber, ProposalHash)> ordered by expiry.
-pub const PROPOSAL_OF: &[u8] = b"cov:pro";				// ProposalHash -> Proposal
-pub const PROPOSAL_VOTERS: &[u8] = b"cov:voters:";		// ProposalHash -> Vec<AccountId>
-pub const COUNCIL_VOTE_OF: &[u8] = b"cov:vote:";		// (ProposalHash, AccountId) -> bool
-pub const VETOED_PROPOSAL: &[u8] = b"cov:veto:";		// ProposalHash -> (BlockNumber, sorted_vetoers: Vec<AccountId>)
-
-pub fn cooloff_period() -> BlockNumber {
-	storage::get(COOLOFF_PERIOD).expect("all parameters must be defined")
-}
-
-pub fn voting_period() -> BlockNumber {
-	storage::get(VOTING_PERIOD).expect("all parameters must be defined")
-}
-
-pub fn proposals() -> Vec<(BlockNumber, ProposalHash)> {
-	storage::get_or_default(PROPOSALS)
+storage_items! {
+	pub CooloffPeriod get(cooloff_period): b"cov:cooloff" => required BlockNumber;
+	pub VotingPeriod get(voting_period): b"cov:period" => required BlockNumber;
+	pub Proposals get(proposals): b"cov:prs" => default Vec<(BlockNumber, ProposalHash)>; // ordered by expiry.
+	pub ProposalOf get(proposal_of): b"cov:pro" => map [ ProposalHash => Proposal ];
+	pub ProposalVoters get(proposal_voters): b"cov:voters:" => default map [ ProposalHash => Vec<AccountId> ];
+	pub CouncilVoteOf get(vote_of): b"cov:vote:" => map [ (ProposalHash, AccountId) => bool ];
+	pub VetoedProposal get(veto_of): b"cov:veto:" => map [ ProposalHash => (BlockNumber, Vec<AccountId>) ];
 }
 
-pub fn is_vetoed(proposal: &ProposalHash) -> bool {
-	storage::get(&proposal.to_keyed_vec(VETOED_PROPOSAL))
+pub fn is_vetoed<B: Borrow<ProposalHash>>(proposal: B) -> bool {
+	VetoedProposal::get(proposal.borrow())
 		.map(|(expiry, _): (BlockNumber, Vec<AccountId>)| system::block_number() < expiry)
 		.unwrap_or(false)
 }
 
-pub fn veto_of(proposal: &ProposalHash) -> Option<(BlockNumber, Vec<AccountId>)> {
-	storage::get(&proposal.to_keyed_vec(VETOED_PROPOSAL))
-}
-
 fn set_veto_of(proposal: &ProposalHash, expiry: BlockNumber, vetoers: Vec<AccountId>) {
-	storage::put(&proposal.to_keyed_vec(VETOED_PROPOSAL), &(expiry, vetoers))
+	VetoedProposal::insert(proposal, (expiry, vetoers));
 }
 
 fn kill_veto_of(proposal: &ProposalHash) {
-	storage::kill(&proposal.to_keyed_vec(VETOED_PROPOSAL))
+	VetoedProposal::remove(proposal);
 }
 
 pub fn will_still_be_councillor_at(who: &AccountId, n: BlockNumber) -> bool {
@@ -79,20 +65,12 @@ pub fn is_councillor(who: &AccountId) -> bool {
 		.any(|&(ref a, _)| a == who)
 }
 
-pub fn vote_of(who: &AccountId, proposal: &ProposalHash) -> Option<bool> {
-	storage::get(&(*proposal, *who).to_keyed_vec(COUNCIL_VOTE_OF))
-}
-
-pub fn proposal_voters(proposal: &ProposalHash) -> Vec<AccountId> {
-	storage::get_or_default(&proposal.to_keyed_vec(PROPOSAL_VOTERS))
-}
-
 pub fn tally(proposal_hash: &ProposalHash) -> (u32, u32, u32) {
-	generic_tally(proposal_hash, |w: &AccountId, p: &ProposalHash| storage::get(&(*p, *w).to_keyed_vec(COUNCIL_VOTE_OF)))
+	generic_tally(proposal_hash, |w: &AccountId, p: &ProposalHash| CouncilVoteOf::get((*p, *w)))
 }
 
 fn take_tally(proposal_hash: &ProposalHash) -> (u32, u32, u32) {
-	generic_tally(proposal_hash, |w: &AccountId, p: &ProposalHash| storage::get(&(*p, *w).to_keyed_vec(COUNCIL_VOTE_OF)))
+	generic_tally(proposal_hash, |w: &AccountId, p: &ProposalHash| CouncilVoteOf::take((*p, *w)))
 }
 
 fn generic_tally<F: Fn(&AccountId, &ProposalHash) -> Option<bool>>(proposal_hash: &ProposalHash, vote_of: F) -> (u32, u32, u32) {
@@ -105,7 +83,7 @@ fn generic_tally<F: Fn(&AccountId, &ProposalHash) -> Option<bool>>(proposal_hash
 }
 
 fn set_proposals(p: &Vec<(BlockNumber, ProposalHash)>) {
-	storage::put(PROPOSALS, p)
+	Proposals::put(p);
 }
 
 fn take_proposal_if_expiring_at(n: BlockNumber) -> Option<(Proposal, ProposalHash)> {
@@ -114,7 +92,7 @@ fn take_proposal_if_expiring_at(n: BlockNumber) -> Option<(Proposal, ProposalHas
 		Some(&(expiry, hash)) if expiry == n => {
 			// yes this is horrible, but fixing it will need substantial work in storage.
 			set_proposals(&proposals[1..].to_vec());
-			let proposal = storage::take(&hash.to_keyed_vec(PROPOSAL_OF)).expect("all queued proposal hashes must have associated proposals");
+			let proposal = ProposalOf::take(hash).expect("all queued proposal hashes must have associated proposals");
 			Some((proposal, hash))
 		}
 		_ => None,
@@ -142,23 +120,23 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 		proposals.sort_by_key(|&(expiry, _)| expiry);
 		set_proposals(&proposals);
 
-		storage::put(&proposal_hash.to_keyed_vec(PROPOSAL_OF), &proposal);
-		storage::put(&proposal_hash.to_keyed_vec(PROPOSAL_VOTERS), &vec![*self]);
-		storage::put(&(proposal_hash, *self).to_keyed_vec(COUNCIL_VOTE_OF), &true);
+		ProposalOf::insert(proposal_hash, *proposal);
+		ProposalVoters::insert(proposal_hash, vec![*self]);
+		CouncilVoteOf::insert((proposal_hash, *self), true);
 	}
 
 	fn vote(self, proposal: ProposalHash, approve: bool) {
-		if vote_of(&self, &proposal).is_none() {
+		if vote_of((*self, proposal)).is_none() {
 			let mut voters = proposal_voters(&proposal);
 			voters.push(*self);
-			storage::put(&proposal.to_keyed_vec(PROPOSAL_VOTERS), &voters);
+			ProposalVoters::insert(proposal, voters);
 		}
-		storage::put(&(proposal, *self).to_keyed_vec(COUNCIL_VOTE_OF), &approve);
+		CouncilVoteOf::insert((proposal, *self), approve);
 	}
 
 	fn veto(self, proposal_hash: ProposalHash) {
 		assert!(is_councillor(&self), "only councillors may veto council proposals");
-		assert!(storage::exists(&proposal_hash.to_keyed_vec(PROPOSAL_VOTERS)), "proposal must exist to be vetoed");
+		assert!(ProposalVoters::exists(&proposal_hash), "proposal must exist to be vetoed");
 
 		let mut existing_vetoers = veto_of(&proposal_hash)
 			.map(|pair| pair.1)
@@ -169,10 +147,10 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 		set_veto_of(&proposal_hash, system::block_number() + cooloff_period(), existing_vetoers);
 
 		set_proposals(&proposals().into_iter().filter(|&(_, h)| h != proposal_hash).collect::<Vec<_>>());
-		storage::kill(&proposal_hash.to_keyed_vec(PROPOSAL_VOTERS));
-		storage::kill(&proposal_hash.to_keyed_vec(PROPOSAL_OF));
+		ProposalVoters::remove(proposal_hash);
+		ProposalOf::remove(proposal_hash);
 		for (c, _) in council::active_council() {
-			storage::kill(&(proposal_hash, c).to_keyed_vec(COUNCIL_VOTE_OF));
+			CouncilVoteOf::remove((proposal_hash, c));
 		}
 	}
 }
@@ -185,11 +163,11 @@ impl_dispatch! {
 
 impl privileged::Dispatch for PrivPass {
 	fn set_cooloff_period(self, blocks: BlockNumber) {
-		storage::put(COOLOFF_PERIOD, &blocks);
+		CooloffPeriod::put(blocks);
 	}
 
 	fn set_voting_period(self, blocks: BlockNumber) {
-		storage::put(VOTING_PERIOD, &blocks);
+		VotingPeriod::put(blocks);
 	}
 }
 
@@ -230,14 +208,14 @@ pub mod testing {
 	pub fn externalities() -> TestExternalities {
 		let expiry: BlockNumber = 10;
 		let extras: TestExternalities = map![
-			twox_128(council::ACTIVE_COUNCIL).to_vec() => vec![].and(&vec![
+			twox_128(council::ActiveCouncil::key()).to_vec() => vec![].and(&vec![
 				(Alice.to_raw_public(), expiry),
 				(Bob.into(), expiry),
 				(Charlie.into(), expiry)
 			]),
-			twox_128(COOLOFF_PERIOD).to_vec() => vec![].and(&2u64),
-			twox_128(VOTING_PERIOD).to_vec() => vec![].and(&1u64),
-			twox_128(democracy::VOTING_PERIOD).to_vec() => vec![].and(&3u64)
+			twox_128(CooloffPeriod::key()).to_vec() => vec![].and(&2u64),
+			twox_128(VotingPeriod::key()).to_vec() => vec![].and(&1u64),
+			twox_128(democracy::VotingPeriod::key()).to_vec() => vec![].and(&3u64)
 		];
 		council::testing::externalities()
 			.into_iter().chain(extras.into_iter()).collect()
@@ -274,9 +252,9 @@ mod tests {
 			assert_eq!(is_councillor(&Alice), true);
 			assert_eq!(is_councillor(&Dave), false);
 			assert_eq!(proposals(), Vec::<(BlockNumber, ProposalHash)>::new());
-			assert_eq!(proposal_voters(&ProposalHash::default()), Vec::<AccountId>::new());
+			assert_eq!(proposal_voters(ProposalHash::default()), Vec::<AccountId>::new());
 			assert_eq!(is_vetoed(&ProposalHash::default()), false);
-			assert_eq!(vote_of(&Alice, &ProposalHash::default()), None);
+			assert_eq!(vote_of((*Alice, ProposalHash::default())), None);
 			assert_eq!(tally(&ProposalHash::default()), (0, 0, 3));
 		});
 	}
@@ -447,7 +425,7 @@ mod tests {
 			PublicPass::new(&Alice).propose(Box::new(proposal.clone()));
 			assert_eq!(proposals().len(), 1);
 			assert_eq!(proposal_voters(&hash), vec![Alice.to_raw_public()]);
-			assert_eq!(vote_of(&Alice, &hash), Some(true));
+			assert_eq!(vote_of((hash, *Alice)), Some(true));
 			assert_eq!(tally(&hash), (1, 0, 2));
 		});
 	}
diff --git a/substrate/demo/runtime/src/runtime/democracy.rs b/substrate/demo/runtime/src/runtime/democracy.rs
index ea945245e70e454a5e7e45413c56ed57f0e023c1..7146a05833901380b19b60d20c3e9fafe20169d3 100644
--- a/substrate/demo/runtime/src/runtime/democracy.rs
+++ b/substrate/demo/runtime/src/runtime/democracy.rs
@@ -19,7 +19,7 @@
 use rstd::prelude::*;
 use integer_sqrt::IntegerSquareRoot;
 use codec::{KeyedVec, Slicable, Input, NonTrivialSlicable};
-use runtime_support::storage;
+use runtime_support::{StorageValue, StorageMap};
 use demo_primitives::{AccountId, Hash, BlockNumber};
 use dispatch::PrivCall as Proposal;
 use runtime::{staking, system, session};
@@ -95,48 +95,36 @@ impl Approved for VoteThreshold {
 	}
 }
 
-// public proposals
-pub const PUBLIC_PROP_COUNT: &[u8] = b"dem:ppc";	// PropIndex
-pub const PUBLIC_PROPS: &[u8] = b"dem:pub";			// Vec<(PropIndex, Proposal)>
-pub const DEPOSIT_OF: &[u8] = b"dem:dep:";			// PropIndex -> (Balance, Vec<AccountId>)
-pub const LAUNCH_PERIOD: &[u8] = b"dem:lau";		// BlockNumber
-pub const MINIMUM_DEPOSIT: &[u8] = b"dem:min";		// Balance
-
-// referenda
-pub const VOTING_PERIOD: &[u8] = b"dem:per";		// BlockNumber
-pub const REFERENDUM_COUNT: &[u8] = b"dem:rco";		// ReferendumIndex
-pub const NEXT_TALLY: &[u8] = b"dem:nxt";			// ReferendumIndex
-pub const REFERENDUM_INFO_OF: &[u8] = b"dem:pro:";	// ReferendumIndex -> (BlockNumber, Proposal, VoteThreshold)
-pub const VOTERS_FOR: &[u8] = b"dem:vtr:";			// ReferendumIndex -> Vec<AccountId>
-pub const VOTE_OF: &[u8] = b"dem:vot:";				// (ReferendumIndex, AccountId) -> bool
-
-/// The minimum amount to be used as a deposit for a public referendum proposal.
-pub fn minimum_deposit() -> Balance {
-	storage::get(MINIMUM_DEPOSIT)
-		.expect("all core parameters of council module must be in place")
-}
-
-/// How often (in blocks) to check for new votes.
-pub fn voting_period() -> BlockNumber {
-	storage::get(VOTING_PERIOD)
-		.expect("all core parameters of council module must be in place")
-}
-
-/// How often (in blocks) new public referenda are launched.
-pub fn launch_period() -> BlockNumber {
-	storage::get(LAUNCH_PERIOD)
-		.expect("all core parameters of council module must be in place")
+storage_items! {
+	// The number of (public) proposals that have been made so far.
+	pub PublicPropCount get(public_prop_count): b"dem:ppc" => default PropIndex;
+	// The public proposals. Unsorted.
+	pub PublicProps get(public_props): b"dem:pub" => default Vec<(PropIndex, Proposal, AccountId)>;
+	// Those who have locked a deposit.
+	pub DepositOf get(deposit_lockers): b"dem:dep:" => map [ PropIndex => (Balance, Vec<AccountId>) ];
+	// How often (in blocks) new public referenda are launched.
+	pub LaunchPeriod get(launch_period): b"dem:lau" => required BlockNumber;
+	// The minimum amount to be used as a deposit for a public referendum proposal.
+	pub MinimumDeposit get(minimum_deposit): b"dem:min" => required Balance;
+
+	// How often (in blocks) to check for new votes.
+	pub VotingPeriod get(voting_period): b"dem:per" => required BlockNumber;
+
+	// The next free referendum index, aka the number of referendums started so far.
+	pub ReferendumCount get(next_free_ref_index): b"dem:rco" => default ReferendumIndex;
+	// The next referendum index that should be tallied.
+	pub NextTally get(next_tally): b"dem:nxt" => default ReferendumIndex;
+	// Information concerning any given referendum.
+	pub ReferendumInfoOf get(referendum_info): b"dem:pro:" => map [ ReferendumIndex => (BlockNumber, Proposal, VoteThreshold) ];
+
+	// Get the voters for the current proposal.
+	pub VotersFor get(voters_for): b"dem:vtr:" => default map [ ReferendumIndex => Vec<AccountId> ];
+
+	// Get the vote, if Some, of `who`.
+	pub VoteOf get(vote_of): b"dem:vot:" => map [ (ReferendumIndex, AccountId) => bool ];
 }
 
-/// The public proposals. Unsorted.
-pub fn public_props() -> Vec<(PropIndex, Proposal, AccountId)> {
-	storage::get_or_default(PUBLIC_PROPS)
-}
-
-/// Those who have locked a deposit.
-pub fn deposit_lockers(proposal: PropIndex) -> Option<(Balance, Vec<AccountId>)> {
-	storage::get(&proposal.to_keyed_vec(DEPOSIT_OF))
-}
+// public proposals
 
 /// Get the amount locked in support of `proposal`; false if proposal isn't a valid proposal
 /// index.
@@ -146,28 +134,13 @@ pub fn locked_for(proposal: PropIndex) -> Option<Balance> {
 
 /// Return true if `ref_index` is an on-going referendum.
 pub fn is_active_referendum(ref_index: ReferendumIndex) -> bool {
-	storage::exists(&ref_index.to_keyed_vec(REFERENDUM_INFO_OF))
-}
-
-/// Get the voters for the current proposal.
-pub fn voters_for(ref_index: ReferendumIndex) -> Vec<AccountId> {
-	storage::get_or_default(&ref_index.to_keyed_vec(VOTERS_FOR))
-}
-
-/// Get the vote, if Some, of `who`.
-pub fn vote_of(who: &AccountId, ref_index: ReferendumIndex) -> Option<bool> {
-	storage::get(&(*who, ref_index).to_keyed_vec(VOTE_OF))
-}
-
-/// Get the info concerning the next referendum.
-pub fn referendum_info(ref_index: ReferendumIndex) -> Option<(BlockNumber, Proposal, VoteThreshold)> {
-	storage::get(&ref_index.to_keyed_vec(REFERENDUM_INFO_OF))
+	ReferendumInfoOf::exists(ref_index)
 }
 
 /// Get all referendums currently active.
 pub fn active_referendums() -> Vec<(ReferendumIndex, BlockNumber, Proposal, VoteThreshold)> {
-	let next: ReferendumIndex = storage::get_or_default(NEXT_TALLY);
-	let last: ReferendumIndex = storage::get_or_default(REFERENDUM_COUNT);
+	let next = NextTally::get();
+	let last = ReferendumCount::get();
 	(next..last).into_iter()
 		.filter_map(|i| referendum_info(i).map(|(n, p, t)| (i, n, p, t)))
 		.collect()
@@ -175,8 +148,8 @@ pub fn active_referendums() -> Vec<(ReferendumIndex, BlockNumber, Proposal, Vote
 
 /// Get all referendums ready for tally at block `n`.
 pub fn maturing_referendums_at(n: BlockNumber) -> Vec<(ReferendumIndex, BlockNumber, Proposal, VoteThreshold)> {
-	let next: ReferendumIndex = storage::get_or_default(NEXT_TALLY);
-	let last: ReferendumIndex = storage::get_or_default(REFERENDUM_COUNT);
+	let next = NextTally::get();
+	let last = ReferendumCount::get();
 	(next..last).into_iter()
 		.filter_map(|i| referendum_info(i).map(|(n, p, t)| (i, n, p, t)))
 		.take_while(|&(_, block_number, _, _)| block_number == n)
@@ -186,16 +159,11 @@ pub fn maturing_referendums_at(n: BlockNumber) -> Vec<(ReferendumIndex, BlockNum
 /// Get the voters for the current proposal.
 pub fn tally(ref_index: ReferendumIndex) -> (staking::Balance, staking::Balance) {
 	voters_for(ref_index).iter()
-		.map(|a| (staking::balance(a), vote_of(a, ref_index).expect("all items come from `voters`; for an item to be in `voters` there must be a vote registered; qed")))
+		.map(|a| (staking::balance(a), vote_of((ref_index, *a)).expect("all items come from `voters`; for an item to be in `voters` there must be a vote registered; qed")))
 		.map(|(bal, vote)| if vote { (bal, 0) } else { (0, bal) })
 		.fold((0, 0), |(a, b), (c, d)| (a + c, b + d))
 }
 
-/// Get the next free referendum index, aka the number of referendums started so far.
-pub fn next_free_ref_index() -> ReferendumIndex {
-	storage::get_or_default(REFERENDUM_COUNT)
-}
-
 impl_dispatch! {
 	pub mod public;
 	fn propose(proposal: Box<Proposal>, value: Balance) = 0;
@@ -209,24 +177,22 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 		assert!(value >= minimum_deposit());
 		assert!(staking::internal::deduct_unbonded(&self, value));
 
-		let index: PropIndex = storage::get_or_default(PUBLIC_PROP_COUNT);
-		storage::put(PUBLIC_PROP_COUNT, &(index + 1));
-		storage::put(&index.to_keyed_vec(DEPOSIT_OF), &(value, vec![*self]));
+		let index = PublicPropCount::get();
+		PublicPropCount::put(index + 1);
+		DepositOf::insert(index, (value, vec![*self]));
 
 		let mut props = public_props();
 		props.push((index, (*proposal).clone(), *self));
-		storage::put(PUBLIC_PROPS, &props);
+		PublicProps::put(props);
 	}
 
 	/// Propose a sensitive action to be taken.
 	fn second(self, proposal: PropIndex) {
-		let key = proposal.to_keyed_vec(DEPOSIT_OF);
-		let mut deposit: (Balance, Vec<AccountId>) =
-			storage::get(&key).expect("can only second an existing proposal");
+		let mut deposit = DepositOf::get(proposal).expect("can only second an existing proposal");
 		assert!(staking::internal::deduct_unbonded(&self, deposit.0));
 
 		deposit.1.push(*self);
-		storage::put(&key, &deposit);
+		DepositOf::insert(proposal, deposit);
 	}
 
 	/// Vote in a referendum. If `approve_proposal` is true, the vote is to enact the proposal;
@@ -238,13 +204,12 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 		if staking::balance(&self) == 0 {
 			panic!("transactor must have balance to signal approval.");
 		}
-		let key = (*self, ref_index).to_keyed_vec(VOTE_OF);
-		if !storage::exists(&key) {
+		if !VoteOf::exists(&(ref_index, *self)) {
 			let mut voters = voters_for(ref_index);
 			voters.push(self.clone());
-			storage::put(&ref_index.to_keyed_vec(VOTERS_FOR), &voters);
+			VotersFor::insert(ref_index, voters);
 		}
-		storage::put(&key, &approve_proposal);
+		VoteOf::insert(&(ref_index, *self), approve_proposal);
 	}
 }
 
@@ -291,13 +256,12 @@ pub mod internal {
 			{
 				let (prop_index, proposal, _) = public_props.swap_remove(winner_index);
 				let (deposit, depositors): (Balance, Vec<AccountId>) =
-					storage::take(&prop_index.to_keyed_vec(DEPOSIT_OF))
-						.expect("depositors always exist for current proposals");
+					DepositOf::take(prop_index).expect("depositors always exist for current proposals");
 				// refund depositors
 				for d in &depositors {
 					staking::internal::refund(d, deposit);
 				}
-				storage::put(PUBLIC_PROPS, &public_props);
+				PublicProps::put(public_props);
 				inject_referendum(now + voting_period(), proposal, VoteThreshold::SuperMajorityApprove);
 			}
 		}
@@ -310,7 +274,7 @@ pub mod internal {
 			if vote_threshold.approved(approve, against, total_stake) {
 				proposal.dispatch(PrivPass::new());
 			}
-			storage::put(NEXT_TALLY, &(index + 1));
+			NextTally::put(index + 1);
 		}
 	}
 }
@@ -326,17 +290,17 @@ fn inject_referendum(
 		panic!("Cannot inject a referendum that ends earlier than preceeding referendum");
 	}
 
-	storage::put(REFERENDUM_COUNT, &(ref_index + 1));
-	storage::put(&ref_index.to_keyed_vec(REFERENDUM_INFO_OF), &(end, proposal, vote_threshold));
+	ReferendumCount::put(ref_index + 1);
+	ReferendumInfoOf::insert(ref_index, (end, proposal, vote_threshold));
 	ref_index
 }
 
 /// Remove all info on a referendum.
 fn clear_referendum(ref_index: ReferendumIndex) {
-	storage::kill(&ref_index.to_keyed_vec(REFERENDUM_INFO_OF));
-	storage::kill(&ref_index.to_keyed_vec(VOTERS_FOR));
+	ReferendumInfoOf::remove(ref_index);
+	VotersFor::remove(ref_index);
 	for v in voters_for(ref_index) {
-		storage::kill(&(v, ref_index).to_keyed_vec(VOTE_OF));
+		VoteOf::remove((ref_index, v));
 	}
 }
 
@@ -344,37 +308,36 @@ fn clear_referendum(ref_index: ReferendumIndex) {
 pub mod testing {
 	use super::*;
 	use runtime_io::{twox_128, TestExternalities};
+	use runtime_support::{StorageList, StorageValue, StorageMap};
 	use codec::Joiner;
 	use keyring::Keyring::*;
 	use runtime::{session, staking};
 
 	pub fn externalities() -> TestExternalities {
 		map![
-			twox_128(session::SESSION_LENGTH).to_vec() => vec![].and(&1u64),
-			twox_128(session::VALIDATOR_COUNT).to_vec() => vec![].and(&3u32),
-			twox_128(&0u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => Alice.to_raw_public_vec(),
-			twox_128(&1u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => Bob.to_raw_public_vec(),
-			twox_128(&2u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => Charlie.to_raw_public_vec(),
-			twox_128(staking::INTENTION_COUNT).to_vec() => vec![].and(&3u32),
-			twox_128(&0u32.to_keyed_vec(staking::INTENTION_AT)).to_vec() => Alice.to_raw_public_vec(),
-			twox_128(&1u32.to_keyed_vec(staking::INTENTION_AT)).to_vec() => Bob.to_raw_public_vec(),
-			twox_128(&2u32.to_keyed_vec(staking::INTENTION_AT)).to_vec() => Charlie.to_raw_public_vec(),
-			twox_128(&Alice.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&10u64),
-			twox_128(&Bob.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&20u64),
-			twox_128(&Charlie.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&30u64),
-			twox_128(&Dave.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&40u64),
-			twox_128(&Eve.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&50u64),
-			twox_128(&Ferdie.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&60u64),
-			twox_128(&One.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![].and(&1u64),
-			twox_128(staking::TOTAL_STAKE).to_vec() => vec![].and(&210u64),
-			twox_128(staking::SESSIONS_PER_ERA).to_vec() => vec![].and(&1u64),
-			twox_128(staking::VALIDATOR_COUNT).to_vec() => vec![].and(&3u64),
-			twox_128(staking::CURRENT_ERA).to_vec() => vec![].and(&1u64),
-			twox_128(staking::TRANSACTION_FEE).to_vec() => vec![].and(&1u64),
-
-			twox_128(LAUNCH_PERIOD).to_vec() => vec![].and(&1u64),
-			twox_128(VOTING_PERIOD).to_vec() => vec![].and(&1u64),
-			twox_128(MINIMUM_DEPOSIT).to_vec() => vec![].and(&1u64)
+			twox_128(session::SessionLength::key()).to_vec() => vec![].and(&1u64),
+			twox_128(session::Validators::key()).to_vec() => vec![].and(&vec![Alice.to_raw_public(), Bob.into(), Charlie.into()]),
+			twox_128(&staking::Intention::len_key()).to_vec() => vec![].and(&3u32),
+			twox_128(&staking::Intention::key_for(0)).to_vec() => Alice.to_raw_public_vec(),
+			twox_128(&staking::Intention::key_for(1)).to_vec() => Bob.to_raw_public_vec(),
+			twox_128(&staking::Intention::key_for(2)).to_vec() => Charlie.to_raw_public_vec(),
+			twox_128(&staking::FreeBalanceOf::key_for(*Alice)).to_vec() => vec![].and(&10u64),
+			twox_128(&staking::FreeBalanceOf::key_for(*Bob)).to_vec() => vec![].and(&20u64),
+			twox_128(&staking::FreeBalanceOf::key_for(*Charlie)).to_vec() => vec![].and(&30u64),
+			twox_128(&staking::FreeBalanceOf::key_for(*Dave)).to_vec() => vec![].and(&40u64),
+			twox_128(&staking::FreeBalanceOf::key_for(*Eve)).to_vec() => vec![].and(&50u64),
+			twox_128(&staking::FreeBalanceOf::key_for(*Ferdie)).to_vec() => vec![].and(&60u64),
+			twox_128(&staking::FreeBalanceOf::key_for(*One)).to_vec() => vec![].and(&1u64),
+			twox_128(staking::TotalStake::key()).to_vec() => vec![].and(&210u64),
+			twox_128(staking::SessionsPerEra::key()).to_vec() => vec![].and(&1u64),
+			twox_128(staking::ValidatorCount::key()).to_vec() => vec![].and(&3u64),
+			twox_128(staking::CurrentEra::key()).to_vec() => vec![].and(&1u64),
+			twox_128(staking::TransactionFee::key()).to_vec() => vec![].and(&1u64),
+			twox_128(staking::BondingDuration::key()).to_vec() => vec![].and(&0u64),
+
+			twox_128(LaunchPeriod::key()).to_vec() => vec![].and(&1u64),
+			twox_128(VotingPeriod::key()).to_vec() => vec![].and(&1u64),
+			twox_128(MinimumDeposit::key()).to_vec() => vec![].and(&1u64)
 		]
 	}
 }
@@ -442,7 +405,7 @@ mod tests {
 
 			assert_eq!(next_free_ref_index(), 1);
 			assert_eq!(voters_for(r), vec![Alice.to_raw_public()]);
-			assert_eq!(vote_of(&Alice, r), Some(true));
+			assert_eq!(vote_of((r, *Alice)), Some(true));
 			assert_eq!(tally(r), (10, 0));
 
 			democracy::internal::end_block(system::block_number());
@@ -557,7 +520,7 @@ mod tests {
 			PublicPass::test(&Alice).vote(r, true);
 
 			assert_eq!(voters_for(r), vec![Alice.to_raw_public()]);
-			assert_eq!(vote_of(&Alice, r), Some(true));
+			assert_eq!(vote_of((r, *Alice)), Some(true));
 			assert_eq!(tally(r), (10, 0));
 
 			democracy::internal::end_block(system::block_number());
@@ -590,7 +553,7 @@ mod tests {
 			PublicPass::test(&Alice).vote(r, false);
 
 			assert_eq!(voters_for(r), vec![Alice.to_raw_public()]);
-			assert_eq!(vote_of(&Alice, r), Some(false));
+			assert_eq!(vote_of((r, *Alice)), Some(false));
 			assert_eq!(tally(r), (0, 10));
 
 			democracy::internal::end_block(system::block_number());
diff --git a/substrate/demo/runtime/src/runtime/session.rs b/substrate/demo/runtime/src/runtime/session.rs
index a0983c160801b1cb9f38dbc976f3406c8676b3be..f7fc68f83c6908e765163068d998b944f2c02727 100644
--- a/substrate/demo/runtime/src/runtime/session.rs
+++ b/substrate/demo/runtime/src/runtime/session.rs
@@ -19,49 +19,31 @@
 
 use rstd::prelude::*;
 use codec::KeyedVec;
-use runtime_support::{storage, StorageVec};
+use runtime_support::{storage, StorageValue, StorageMap};
 use demo_primitives::{AccountId, SessionKey, BlockNumber};
 use runtime::{system, staking, consensus};
 use runtime::democracy::PrivPass;
 use runtime::staking::PublicPass;
 
-pub const SESSION_LENGTH: &[u8] = b"ses:len";
-pub const CURRENT_INDEX: &[u8] = b"ses:ind";
-pub const LAST_LENGTH_CHANGE: &[u8] = b"ses:llc";
-pub const NEXT_KEY_FOR: &[u8] = b"ses:nxt:";
-pub const NEXT_SESSION_LENGTH: &[u8] = b"ses:nln";
-pub const VALIDATOR_AT: &[u8] = b"ses:val:";
-pub const VALIDATOR_COUNT: &[u8] = b"ses:val:len";
-
-struct ValidatorStorageVec {}
-impl StorageVec for ValidatorStorageVec {
-	type Item = AccountId;
-	const PREFIX: &'static[u8] = VALIDATOR_AT;
-}
-
-/// Get the current set of validators.
-pub fn validators() -> Vec<AccountId> {
-	ValidatorStorageVec::items()
-}
-
-/// The number of blocks in each session.
-pub fn length() -> BlockNumber {
-	storage::get_or(SESSION_LENGTH, 0)
+storage_items!{
+	// The current set of validators.
+	pub Validators get(validators): b"ses:val" => required Vec<AccountId>;
+	// Current length of the session.
+	pub SessionLength get(length): b"ses:len" => required BlockNumber;
+	// Current index of the session.
+	pub CurrentIndex get(current_index): b"ses:ind" => required BlockNumber;
+
+	// Block at which the session length last changed.
+	LastLengthChange: b"ses:llc" => default BlockNumber;
+	// The next key for a given validator.
+	NextKeyFor: b"ses:nxt:" => map [ AccountId => SessionKey ];
+	// The next session length.
+	NextSessionLength: b"ses:nln" => BlockNumber;
 }
 
 /// The number of validators currently.
 pub fn validator_count() -> u32 {
-	ValidatorStorageVec::count() as u32
-}
-
-/// The current era index.
-pub fn current_index() -> BlockNumber {
-	storage::get_or(CURRENT_INDEX, 0)
-}
-
-/// The block number at which the era length last changed.
-pub fn last_length_change() -> BlockNumber {
-	storage::get_or(LAST_LENGTH_CHANGE, 0)
+	Validators::get().len() as u32	// TODO: can probably optimised
 }
 
 impl_dispatch! {
@@ -74,7 +56,7 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 	/// session.
 	fn set_key(self, key: SessionKey) {
 		// set new value for next session
-		storage::put(&self.to_keyed_vec(NEXT_KEY_FOR), &key);
+		NextKeyFor::insert(*self, key)
 	}
 }
 
@@ -87,7 +69,7 @@ impl_dispatch! {
 impl privileged::Dispatch for PrivPass {
 	/// Set a new era length. Won't kick in until the next era change (at current length).
 	fn set_length(self, new: BlockNumber) {
-		storage::put(NEXT_SESSION_LENGTH, &new);
+		NextSessionLength::put(new);
 	}
 
 	/// Forces a new session.
@@ -103,10 +85,10 @@ pub mod internal {
 
 	/// Set the current set of validators.
 	///
-	/// Called by staking::next_era() only. `next_session` should be called after this in order to
+	/// Called by `staking::next_era()` only. `next_session` should be called after this in order to
 	/// update the session keys to the next validator set.
 	pub fn set_validators(new: &[AccountId]) {
-		ValidatorStorageVec::set_items(new);
+		Validators::put(&new.to_vec());			// TODO: optimise.
 		consensus::internal::set_authorities(new);
 	}
 
@@ -115,7 +97,7 @@ pub mod internal {
 		// do this last, after the staking system has had chance to switch out the authorities for the
 		// new set.
 		// check block number and call next_session if necessary.
-		if (system::block_number() - last_length_change()) % length() == 0 {
+		if (system::block_number() - LastLengthChange::get()) % length() == 0 {
 			rotate_session();
 		}
 	}
@@ -123,19 +105,17 @@ pub mod internal {
 	/// Move onto next session: register the new authority set.
 	pub fn rotate_session() {
 		// Increment current session index.
-		storage::put(CURRENT_INDEX, &(current_index() + 1));
+		CurrentIndex::put(CurrentIndex::get() + 1);
 
 		// Enact era length change.
-		if let Some(next_len) = storage::get::<u64>(NEXT_SESSION_LENGTH) {
-			storage::put(SESSION_LENGTH, &next_len);
-			storage::put(LAST_LENGTH_CHANGE, &system::block_number());
-			storage::kill(NEXT_SESSION_LENGTH);
+		if let Some(next_len) = NextSessionLength::take() {
+			SessionLength::put(next_len);
+			LastLengthChange::put(system::block_number());
 		}
 
 		// Update any changes in session keys.
 		validators().iter().enumerate().for_each(|(i, v)| {
-			let k = v.to_keyed_vec(NEXT_KEY_FOR);
-			if let Some(n) = storage::take(&k) {
+			if let Some(n) = NextKeyFor::take(v) {
 				consensus::internal::set_authority(i as u32, &n);
 			}
 		});
@@ -147,20 +127,16 @@ pub mod testing {
 	use super::*;
 	use runtime_io::{twox_128, TestExternalities};
 	use codec::{Joiner, KeyedVec};
-	use keyring::Keyring;
+	use keyring::Keyring::*;
 	use runtime::system;
 
 	pub fn externalities(session_length: u64) -> TestExternalities {
-		let one = Keyring::One.to_raw_public();
-		let two = Keyring::Two.to_raw_public();
 		let three = [3u8; 32];
 
 		let extras: TestExternalities = map![
-			twox_128(SESSION_LENGTH).to_vec() => vec![].and(&session_length),
-			twox_128(VALIDATOR_COUNT).to_vec() => vec![].and(&3u32),
-			twox_128(&0u32.to_keyed_vec(VALIDATOR_AT)).to_vec() => one.to_vec(),
-			twox_128(&1u32.to_keyed_vec(VALIDATOR_AT)).to_vec() => two.to_vec(),
-			twox_128(&2u32.to_keyed_vec(VALIDATOR_AT)).to_vec() => three.to_vec()
+			twox_128(SessionLength::key()).to_vec() => vec![].and(&session_length),
+			twox_128(CurrentIndex::key()).to_vec() => vec![].and(&0u64),
+			twox_128(Validators::key()).to_vec() => vec![].and(&vec![One.into(), Two.into(), three])
 		];
 		system::testing::externalities().into_iter().chain(extras.into_iter()).collect()
 	}
@@ -181,11 +157,10 @@ mod tests {
 
 	fn simple_setup() -> TestExternalities {
 		map![
-			twox_128(SESSION_LENGTH).to_vec() => vec![].and(&2u64),
+			twox_128(SessionLength::key()).to_vec() => vec![].and(&2u64),
+			twox_128(CurrentIndex::key()).to_vec() => vec![].and(&0u64),
 			// the validators (10, 20, ...)
-			twox_128(b"ses:val:len").to_vec() => vec![].and(&2u32),
-			twox_128(&0u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![10; 32],
-			twox_128(&1u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![20; 32],
+			twox_128(Validators::key()).to_vec() => vec![].and(&vec![[10u8; 32], [20; 32]]),
 			// initial session keys (11, 21, ...)
 			b":auth:len".to_vec() => vec![].and(&2u32),
 			0u32.to_keyed_vec(b":auth:") => vec![11; 32],
diff --git a/substrate/demo/runtime/src/runtime/staking.rs b/substrate/demo/runtime/src/runtime/staking.rs
index 629700503f9933f2b16960481241a689bbdd438a..f863e8d4242685de2a1710037d4e98700d6397a1 100644
--- a/substrate/demo/runtime/src/runtime/staking.rs
+++ b/substrate/demo/runtime/src/runtime/staking.rs
@@ -22,7 +22,7 @@ use rstd::cell::RefCell;
 use rstd::collections::btree_map::{BTreeMap, Entry};
 use runtime_io::{print, blake2_256};
 use codec::{Slicable, Input, KeyedVec};
-use runtime_support::{storage, StorageVec};
+use runtime_support::{storage, StorageValue, StorageList, StorageMap};
 use demo_primitives::{BlockNumber, AccountId};
 use runtime::{system, session, democracy};
 
@@ -32,78 +32,52 @@ pub type Balance = u64;
 /// The amount of bonding period left in an account. Measured in eras.
 pub type Bondage = u64;
 
-pub const BONDING_DURATION: &[u8] = b"sta:loc";
-pub const VALIDATOR_COUNT: &[u8] = b"sta:vac";
-pub const SESSIONS_PER_ERA: &[u8] = b"sta:spe";
-pub const NEXT_SESSIONS_PER_ERA: &[u8] = b"sta:nse";
-pub const CURRENT_ERA: &[u8] = b"sta:era";
-pub const LAST_ERA_LENGTH_CHANGE: &[u8] = b"sta:lec";
-pub const TOTAL_STAKE: &[u8] = b"sta:tot";
-pub const INTENTION_AT: &[u8] = b"sta:wil:";
-pub const INTENTION_COUNT: &[u8] = b"sta:wil:len";
-pub const TRANSACTION_FEE: &[u8] = b"sta:fee";
-
-pub const BALANCE_OF: &[u8] = b"sta:bal:";
-pub const RESERVED_BALANCE_OF: &[u8] = b"sta:lbo:";
-pub const BONDAGE_OF: &[u8] = b"sta:bon:";
-pub const CODE_OF: &[u8] = b"sta:cod:";
-pub const STORAGE_OF: &[u8] = b"sta:sto:";
-
-pub struct IntentionStorageVec {}
-impl StorageVec for IntentionStorageVec {
-	type Item = AccountId;
-	const PREFIX: &'static[u8] = INTENTION_AT;
-}
-
-/// The fee to be paid for making a transaction.
-pub fn transaction_fee() -> Balance {
-	storage::get(TRANSACTION_FEE).expect("All basic parameters should be defined")
-}
-
-/// The length of the bonding duration in eras.
-pub fn bonding_duration() -> BlockNumber {
-	storage::get_or_default(BONDING_DURATION)
-}
-
-/// The length of a staking era in sessions.
-pub fn validator_count() -> usize {
-	storage::get_or_default::<u32>(VALIDATOR_COUNT) as usize
+storage_items! {
+	// The length of the bonding duration in eras.
+	pub BondingDuration get(bonding_duration): b"sta:loc" => required BlockNumber;
+	// The length of a staking era in sessions.
+	pub ValidatorCount get(validator_count): b"sta:vac" => required u32;
+	// The length of a staking era in sessions.
+	pub SessionsPerEra get(sessions_per_era): b"sta:spe" => required BlockNumber;
+	// The total amount of stake on the system.
+	pub TotalStake get(total_stake): b"sta:tot" => required Balance;
+	// The fee to be paid for making a transaction.
+	pub TransactionFee get(transaction_fee): b"sta:fee" => required Balance;
+
+	// The current era index.
+	pub CurrentEra get(current_era): b"sta:era" => required BlockNumber;
+	// All the accounts with a desire to stake.
+	pub Intention: b"sta:wil:" => list [ AccountId ];
+	// The next value of sessions per era.
+	pub NextSessionsPerEra get(next_sessions_per_era): b"sta:nse" => BlockNumber;
+	// The block number at which the era length last changed.
+	pub LastEraLengthChange get(last_era_length_change): b"sta:lec" => default BlockNumber;
+
+	// The balance of a given account.
+	pub FreeBalanceOf get(free_balance_of): b"sta:bal:" => default map [ AccountId => Balance ];
+
+	// The amount of the balance of a given account that is exterally reserved; this can still get
+	// slashed, but gets slashed last of all.
+	pub ReservedBalanceOf get(reserved_balance_of): b"sta:lbo:" => default map [ AccountId => Balance ];
+
+	// The block at which the `who`'s funds become entirely liquid.
+	pub BondageOf get(bondage_of): b"sta:bon:" => default map [ AccountId => Bondage ];
+
+	// The code associated with an account.
+	pub CodeOf: b"sta:cod:" => default map [ AccountId => Vec<u8> ];	// TODO Vec<u8> values should be optimised to not do a length prefix.
+
+	// The storage items associated with an account/key.
+	pub StorageOf: b"sta:sto:" => map [ (AccountId, Vec<u8>) => Vec<u8> ];	// TODO: keys should also be able to take AsRef<KeyType> to ensure Vec<u8>s can be passed as &[u8]
 }
 
 /// The length of a staking era in blocks.
 pub fn era_length() -> BlockNumber {
-	sessions_per_era() * session::length()
+	SessionsPerEra::get() * session::length()
 }
 
-/// The length of a staking era in sessions.
-pub fn sessions_per_era() -> BlockNumber {
-	storage::get_or_default(SESSIONS_PER_ERA)
-}
-
-/// The current era index.
-pub fn current_era() -> BlockNumber {
-	storage::get_or_default(CURRENT_ERA)
-}
-
-/// The block number at which the era length last changed.
-pub fn last_era_length_change() -> BlockNumber {
-	storage::get_or_default(LAST_ERA_LENGTH_CHANGE)
-}
-
-/// The balance of a given account.
+/// The combined balance of `who`.
 pub fn balance(who: &AccountId) -> Balance {
-	free_balance(who) + reserved_balance(who)
-}
-
-/// The balance of a given account.
-pub fn free_balance(who: &AccountId) -> Balance {
-	storage::get_or_default(&who.to_keyed_vec(BALANCE_OF))
-}
-
-/// The amount of the balance of a given account that is exterally reserved; this can still get
-/// slashed, but gets slashed last of all.
-pub fn reserved_balance(who: &AccountId) -> Balance {
-	storage::get_or_default(&who.to_keyed_vec(RESERVED_BALANCE_OF))
+	FreeBalanceOf::get(who) + ReservedBalanceOf::get(who)
 }
 
 /// Some result as `slash(who, value)` (but without the side-effects) asuming there are no
@@ -112,11 +86,6 @@ pub fn can_slash(who: &AccountId, value: Balance) -> bool {
 	balance(who) >= value
 }
 
-/// The block at which the `who`'s funds become entirely liquid.
-pub fn bondage(who: &AccountId) -> Bondage {
-	storage::get_or_default(&who.to_keyed_vec(BONDAGE_OF))
-}
-
 #[derive(PartialEq, Copy, Clone)]
 #[cfg_attr(test, derive(Debug))]
 pub enum LockStatus {
@@ -127,28 +96,23 @@ pub enum LockStatus {
 
 /// The block at which the `who`'s funds become entirely liquid.
 pub fn unlock_block(who: &AccountId) -> LockStatus {
-	match bondage(who) {
+	match BondageOf::get(who) {
 		i if i == Bondage::max_value() => LockStatus::Staked,
 		i if i <= system::block_number() => LockStatus::Liquid,
 		i => LockStatus::LockedUntil(i),
 	}
 }
 
-/// The total amount of stake on the system.
-pub fn total_stake() -> Balance {
-	storage::get_or(TOTAL_STAKE, 0)
-}
-
 pub struct PublicPass<'a> (&'a AccountId);
 
 const NOBODY: AccountId = [0u8; 32];
 
 impl<'a> PublicPass<'a> {
 	pub fn new(transactor: &AccountId) -> PublicPass {
-		let b = free_balance(&transactor);
-		let transaction_fee = transaction_fee();
+		let b = FreeBalanceOf::get(transactor);
+		let transaction_fee = TransactionFee::get();
 		assert!(b >= transaction_fee, "attempt to transact without enough funds to pay fee");
-		internal::set_free_balance(&transactor, b - transaction_fee);
+		FreeBalanceOf::insert(transactor, b - transaction_fee);
 		PublicPass(transactor)
 	}
 
@@ -199,26 +163,26 @@ impl<'a> public::Dispatch for PublicPass<'a> {
 	///
 	/// Effects will be felt at the beginning of the next era.
 	fn stake(self) {
-		let mut intentions = IntentionStorageVec::items();
+		let mut intentions = Intention::items();
 		// can't be in the list twice.
 		assert!(intentions.iter().find(|&t| *t == *self).is_none(), "Cannot stake if already staked.");
 		intentions.push(self.clone());
-		IntentionStorageVec::set_items(&intentions);
-		storage::put(&self.to_keyed_vec(BONDAGE_OF), &u64::max_value());
+		Intention::set_items(&intentions);
+		BondageOf::insert(*self, u64::max_value());
 	}
 
 	/// Retract the desire to stake for the transactor.
 	///
 	/// Effects will be felt at the beginning of the next era.
 	fn unstake(self) {
-		let mut intentions = IntentionStorageVec::items();
+		let mut intentions = Intention::items();
 		if let Some(position) = intentions.iter().position(|&t| t == *self) {
 			intentions.swap_remove(position);
 		} else {
 			panic!("Cannot unstake if not already staked.");
 		}
-		IntentionStorageVec::set_items(&intentions);
-		storage::put(&self.to_keyed_vec(BONDAGE_OF), &(current_era() + bonding_duration()));
+		Intention::set_items(&intentions);
+		BondageOf::insert(*self, CurrentEra::get() + BondingDuration::get());
 	}
 }
 
@@ -233,17 +197,17 @@ impl_dispatch! {
 impl privileged::Dispatch for democracy::PrivPass {
 	/// Set the number of sessions in an era.
 	fn set_sessions_per_era(self, new: BlockNumber) {
-		storage::put(NEXT_SESSIONS_PER_ERA, &new);
+		NextSessionsPerEra::put(&new);
 	}
 
 	/// The length of the bonding duration in eras.
 	fn set_bonding_duration(self, new: BlockNumber) {
-		storage::put(BONDING_DURATION, &new);
+		BondingDuration::put(&new);
 	}
 
 	/// The length of a staking era in sessions.
 	fn set_validator_count(self, new: u32) {
-		storage::put(VALIDATOR_COUNT, &new);
+		ValidatorCount::put(&new);
 	}
 
 	/// Force there to be a new era. This also forces a new session immediately after.
@@ -254,9 +218,9 @@ impl privileged::Dispatch for democracy::PrivPass {
 }
 
 // Each identity's stake may be in one of three bondage states, given by an integer:
-// - n | n <= current_era(): inactive: free to be transferred.
+// - n | n <= CurrentEra::get(): inactive: free to be transferred.
 // - ~0: active: currently representing a validator.
-// - n | n > current_era(): deactivating: recently representing a validator and not yet
+// - n | n > CurrentEra::get(): deactivating: recently representing a validator and not yet
 //   ready for transfer.
 
 mod private {
@@ -296,15 +260,13 @@ mod private {
 	pub struct DirectExt;
 	impl Externalities for DirectExt {
 		fn get_storage(&self, account: &AccountId, location: &[u8]) -> Option<Vec<u8>> {
-			let mut v = account.to_keyed_vec(STORAGE_OF);
-			v.extend(location);
-			storage::get_raw(&v)
+			StorageOf::get(&(*account, location.to_vec()))
 		}
 		fn get_code(&self, account: &AccountId) -> Vec<u8> {
-			storage::get_raw(&account.to_keyed_vec(CODE_OF)).unwrap_or_default()
+			CodeOf::get(account)
 		}
 		fn get_balance(&self, account: &AccountId) -> Balance {
-			storage::get_or_default::<Balance>(&account.to_keyed_vec(BALANCE_OF))
+			FreeBalanceOf::get(account)
 		}
 	}
 
@@ -327,19 +289,16 @@ mod private {
 	pub fn commit_state(s: State) {
 		for (address, changed) in s.into_iter() {
 			if let Some(balance) = changed.balance {
-				storage::put(&address.to_keyed_vec(BALANCE_OF), &balance);
+				FreeBalanceOf::insert(address, balance);
 			}
 			if let Some(code) = changed.code {
-				storage::put(&address.to_keyed_vec(CODE_OF), &code);
+				CodeOf::insert(&address, &code);
 			}
-			let storage_key = address.to_keyed_vec(STORAGE_OF);
 			for (k, v) in changed.storage.into_iter() {
-				let mut key = storage_key.clone();
-				key.extend(k);
 				if let Some(value) = v {
-					storage::put_raw(&key, &value);
+					StorageOf::insert(&(address, k), &value);
 				} else {
-					storage::kill(&key);
+					StorageOf::remove(&(address, k));
 				}
 			}
 		}
@@ -404,7 +363,7 @@ mod private {
 		assert!(from_balance >= value);
 
 		let to_balance = ext.get_balance(dest);
-		assert!(bondage(transactor) <= bondage(dest));
+		assert!(BondageOf::get(transactor) <= BondageOf::get(dest));
 		assert!(to_balance + value > to_balance);	// no overflow
 
 		// TODO: a fee, based upon gaslimit/gasprice.
@@ -470,17 +429,10 @@ mod private {
 pub mod internal {
 	use super::*;
 
-	/// Set the balance of an account.
-	/// Needless to say, this is super low-level and accordingly dangerous. Ensure any modules that
-	/// use it are auditted to the hilt.
-	pub fn set_free_balance(who: &AccountId, value: Balance) {
-		storage::put(&who.to_keyed_vec(BALANCE_OF), &value);
-	}
-
 	/// Hook to be called after to transaction processing.
 	pub fn check_new_era() {
 		// check block number and call new_era if necessary.
-		if (system::block_number() - last_era_length_change()) % era_length() == 0 {
+		if (system::block_number() - LastEraLengthChange::get()) % era_length() == 0 {
 			new_era();
 		}
 	}
@@ -488,9 +440,9 @@ pub mod internal {
 	/// Deduct from an unbonded balance. true if it happened.
 	pub fn deduct_unbonded(who: &AccountId, value: Balance) -> bool {
 		if let LockStatus::Liquid = unlock_block(who) {
-			let b = free_balance(who);
+			let b = FreeBalanceOf::get(who);
 			if b >= value {
-				set_free_balance(who, b - value);
+				FreeBalanceOf::insert(who, &(b - value));
 				return true;
 			}
 		}
@@ -499,14 +451,14 @@ pub mod internal {
 
 	/// Refund some balance.
 	pub fn refund(who: &AccountId, value: Balance) {
-		set_free_balance(who, free_balance(who) + value)
+		FreeBalanceOf::insert(who, &(FreeBalanceOf::get(who) + value))
 	}
 
 	/// Will slash any balance, but prefer free over reserved.
 	pub fn slash(who: &AccountId, value: Balance) -> bool {
-		let free_balance = free_balance(who);
+		let free_balance = FreeBalanceOf::get(who);
 		let free_slash = cmp::min(free_balance, value);
-		set_free_balance(who, free_balance - free_slash);
+		FreeBalanceOf::insert(who, &(free_balance - free_slash));
 		if free_slash < value {
 			slash_reserved(who, value - free_slash)
 		} else {
@@ -516,63 +468,59 @@ pub mod internal {
 
 	/// Moves `value` from balance to reserved balance.
 	pub fn reserve_balance(who: &AccountId, value: Balance) {
-		let b = free_balance(who);
+		let b = FreeBalanceOf::get(who);
 		assert!(b >= value);
-		set_free_balance(who, b - value);
-		set_reserved_balance(who, reserved_balance(who) + value);
+		FreeBalanceOf::insert(who, &(b - value));
+		ReservedBalanceOf::insert(who, &(ReservedBalanceOf::get(who) + value));
 	}
 
 	/// Moves `value` from reserved balance to balance.
 	pub fn unreserve_balance(who: &AccountId, value: Balance) {
-		let b = reserved_balance(who);
+		let b = ReservedBalanceOf::get(who);
 		let value = cmp::min(b, value);
-		set_reserved_balance(who, b - value);
-		set_free_balance(who, free_balance(who) + value);
+		ReservedBalanceOf::insert(who, &(b - value));
+		FreeBalanceOf::insert(who, &(FreeBalanceOf::get(who) + value));
 	}
 
 	/// Moves `value` from reserved balance to balance.
 	pub fn slash_reserved(who: &AccountId, value: Balance) -> bool {
-		let b = reserved_balance(who);
+		let b = ReservedBalanceOf::get(who);
 		let slash = cmp::min(b, value);
-		set_reserved_balance(who, b - slash);
+		ReservedBalanceOf::insert(who, &(b - slash));
 		value == slash
 	}
 
 	/// Moves `value` from reserved balance to balance.
 	pub fn transfer_reserved_balance(slashed: &AccountId, beneficiary: &AccountId, value: Balance) -> bool {
-		let b = reserved_balance(slashed);
+		let b = ReservedBalanceOf::get(slashed);
 		let slash = cmp::min(b, value);
-		set_reserved_balance(slashed, b - slash);
-		set_free_balance(beneficiary, free_balance(beneficiary) + slash);
+		ReservedBalanceOf::insert(slashed, &(b - slash));
+		FreeBalanceOf::insert(beneficiary, &(FreeBalanceOf::get(beneficiary) + slash));
 		slash == value
 	}
 }
 
-/// Set the reserved portion of `who`'s balance.
-fn set_reserved_balance(who: &AccountId, value: Balance) {
-	storage::put(&who.to_keyed_vec(RESERVED_BALANCE_OF), &value);
-}
-
 /// The era has changed - enact new staking set.
 ///
 /// NOTE: This always happens immediately before a session change to ensure that new validators
 /// get a chance to set their session keys.
 fn new_era() {
 	// Increment current era.
-	storage::put(CURRENT_ERA, &(current_era() + 1));
+	CurrentEra::put(&(CurrentEra::get() + 1));
 
 	// Enact era length change.
-	let next_spe: u64 = storage::get_or_default(NEXT_SESSIONS_PER_ERA);
-	if next_spe > 0 && next_spe != sessions_per_era() {
-		storage::put(SESSIONS_PER_ERA, &next_spe);
-		storage::put(LAST_ERA_LENGTH_CHANGE, &system::block_number());
+	if let Some(next_spe) = NextSessionsPerEra::get() {
+		if next_spe != SessionsPerEra::get() {
+			SessionsPerEra::put(&next_spe);
+			LastEraLengthChange::put(&system::block_number());
+		}
 	}
 
 	// evaluate desired staking amounts and nominations and optimise to find the best
 	// combination of validators, then use session::internal::set_validators().
 	// for now, this just orders would-be stakers by their balances and chooses the top-most
-	// validator_count() of them.
-	let mut intentions = IntentionStorageVec::items()
+	// ValidatorCount::get() of them.
+	let mut intentions = Intention::items()
 		.into_iter()
 		.map(|v| (balance(&v), v))
 		.collect::<Vec<_>>();
@@ -580,7 +528,7 @@ fn new_era() {
 	session::internal::set_validators(
 		&intentions.into_iter()
 			.map(|(_, v)| v)
-			.take(validator_count())
+			.take(ValidatorCount::get() as usize)
 			.collect::<Vec<_>>()
 	);
 }
@@ -597,15 +545,16 @@ pub mod testing {
 
 	pub fn externalities(session_length: u64, sessions_per_era: u64, current_era: u64) -> TestExternalities {
 		let extras: TestExternalities = map![
-			twox_128(INTENTION_COUNT).to_vec() => vec![].and(&3u32),
-			twox_128(&0u32.to_keyed_vec(INTENTION_AT)).to_vec() => Alice.to_raw_public_vec(),
-			twox_128(&1u32.to_keyed_vec(INTENTION_AT)).to_vec() => Bob.to_raw_public_vec(),
-			twox_128(&2u32.to_keyed_vec(INTENTION_AT)).to_vec() => Charlie.to_raw_public_vec(),
-			twox_128(SESSIONS_PER_ERA).to_vec() => vec![].and(&sessions_per_era),
-			twox_128(VALIDATOR_COUNT).to_vec() => vec![].and(&3u64),
-			twox_128(TRANSACTION_FEE).to_vec() => vec![].and(&1u64),
-			twox_128(CURRENT_ERA).to_vec() => vec![].and(&current_era),
-			twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
+			twox_128(&Intention::len_key()).to_vec() => vec![].and(&3u32),
+			twox_128(&Intention::key_for(0)).to_vec() => Alice.to_raw_public_vec(),
+			twox_128(&Intention::key_for(1)).to_vec() => Bob.to_raw_public_vec(),
+			twox_128(&Intention::key_for(2)).to_vec() => Charlie.to_raw_public_vec(),
+			twox_128(SessionsPerEra::key()).to_vec() => vec![].and(&sessions_per_era),
+			twox_128(ValidatorCount::key()).to_vec() => vec![].and(&3u64),
+			twox_128(BondingDuration::key()).to_vec() => vec![].and(&0u64),
+			twox_128(TransactionFee::key()).to_vec() => vec![].and(&1u64),
+			twox_128(CurrentEra::key()).to_vec() => vec![].and(&current_era),
+			twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
 		];
 		session::testing::externalities(session_length).into_iter().chain(extras.into_iter()).collect()
 	}
@@ -630,25 +579,24 @@ mod tests {
 	#[test]
 	fn staking_should_work() {
 		let mut t: TestExternalities = map![
-			twox_128(session::SESSION_LENGTH).to_vec() => vec![].and(&1u64),
-			twox_128(session::VALIDATOR_COUNT).to_vec() => vec![].and(&2u32),
-			twox_128(&0u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => vec![10; 32],
-			twox_128(&1u32.to_keyed_vec(session::VALIDATOR_AT)).to_vec() => vec![20; 32],
-			twox_128(SESSIONS_PER_ERA).to_vec() => vec![].and(&2u64),
-			twox_128(VALIDATOR_COUNT).to_vec() => vec![].and(&2u32),
-			twox_128(BONDING_DURATION).to_vec() => vec![].and(&3u64),
-			twox_128(TOTAL_STAKE).to_vec() => vec![].and(&100u64),
-			twox_128(TRANSACTION_FEE).to_vec() => vec![].and(&0u64),
-			twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&10u64),
-			twox_128(&Bob.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&20u64),
-			twox_128(&Charlie.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&30u64),
-			twox_128(&Dave.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&40u64)
+			twox_128(session::SessionLength::key()).to_vec() => vec![].and(&1u64),
+			twox_128(session::Validators::key()).to_vec() => vec![].and(&vec![[10u8; 32], [20; 32]]),
+			twox_128(CurrentEra::key()).to_vec() => vec![].and(&0u64),
+			twox_128(SessionsPerEra::key()).to_vec() => vec![].and(&2u64),
+			twox_128(ValidatorCount::key()).to_vec() => vec![].and(&2u32),
+			twox_128(BondingDuration::key()).to_vec() => vec![].and(&3u64),
+			twox_128(TotalStake::key()).to_vec() => vec![].and(&100u64),
+			twox_128(TransactionFee::key()).to_vec() => vec![].and(&0u64),
+			twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![].and(&10u64),
+			twox_128(&FreeBalanceOf::key_for(*Bob)).to_vec() => vec![].and(&20u64),
+			twox_128(&FreeBalanceOf::key_for(*Charlie)).to_vec() => vec![].and(&30u64),
+			twox_128(&FreeBalanceOf::key_for(*Dave)).to_vec() => vec![].and(&40u64)
 		];
 
 		with_externalities(&mut t, || {
 			assert_eq!(era_length(), 2u64);
-			assert_eq!(validator_count(), 2usize);
-			assert_eq!(bonding_duration(), 3u64);
+			assert_eq!(ValidatorCount::get(), 2);
+			assert_eq!(BondingDuration::get(), 3);
 			assert_eq!(session::validators(), vec![[10u8; 32], [20u8; 32]]);
 
 			// Block 1: Add three validators. No obvious change.
@@ -701,76 +649,78 @@ mod tests {
 	#[test]
 	fn staking_eras_work() {
 		let mut t: TestExternalities = map![
-			twox_128(session::SESSION_LENGTH).to_vec() => vec![].and(&1u64),
-			twox_128(SESSIONS_PER_ERA).to_vec() => vec![].and(&2u64)
+			twox_128(session::SessionLength::key()).to_vec() => vec![].and(&1u64),
+			twox_128(SessionsPerEra::key()).to_vec() => vec![].and(&2u64),
+			twox_128(ValidatorCount::key()).to_vec() => vec![].and(&2u32),
+			twox_128(CurrentEra::key()).to_vec() => vec![].and(&0u64)
 		];
 		with_externalities(&mut t, || {
 			assert_eq!(era_length(), 2u64);
-			assert_eq!(sessions_per_era(), 2u64);
-			assert_eq!(last_era_length_change(), 0u64);
-			assert_eq!(current_era(), 0u64);
+			assert_eq!(SessionsPerEra::get(), 2u64);
+			assert_eq!(LastEraLengthChange::get(), 0u64);
+			assert_eq!(CurrentEra::get(), 0u64);
 
 			// Block 1: No change.
 			with_env(|e| e.block_number = 1);
 			check_new_era();
-			assert_eq!(sessions_per_era(), 2u64);
-			assert_eq!(last_era_length_change(), 0u64);
-			assert_eq!(current_era(), 0u64);
+			assert_eq!(SessionsPerEra::get(), 2u64);
+			assert_eq!(LastEraLengthChange::get(), 0u64);
+			assert_eq!(CurrentEra::get(), 0u64);
 
 			// Block 2: Simple era change.
 			with_env(|e| e.block_number = 2);
 			check_new_era();
-			assert_eq!(sessions_per_era(), 2u64);
-			assert_eq!(last_era_length_change(), 0u64);
-			assert_eq!(current_era(), 1u64);
+			assert_eq!(SessionsPerEra::get(), 2u64);
+			assert_eq!(LastEraLengthChange::get(), 0u64);
+			assert_eq!(CurrentEra::get(), 1u64);
 
 			// Block 3: Schedule an era length change; no visible changes.
 			with_env(|e| e.block_number = 3);
 			PrivPass::test().set_sessions_per_era(3);
 			check_new_era();
-			assert_eq!(sessions_per_era(), 2u64);
-			assert_eq!(last_era_length_change(), 0u64);
-			assert_eq!(current_era(), 1u64);
+			assert_eq!(SessionsPerEra::get(), 2u64);
+			assert_eq!(LastEraLengthChange::get(), 0u64);
+			assert_eq!(CurrentEra::get(), 1u64);
 
 			// Block 4: Era change kicks in.
 			with_env(|e| e.block_number = 4);
 			check_new_era();
-			assert_eq!(sessions_per_era(), 3u64);
-			assert_eq!(last_era_length_change(), 4u64);
-			assert_eq!(current_era(), 2u64);
+			assert_eq!(SessionsPerEra::get(), 3u64);
+			assert_eq!(LastEraLengthChange::get(), 4u64);
+			assert_eq!(CurrentEra::get(), 2u64);
 
 			// Block 5: No change.
 			with_env(|e| e.block_number = 5);
 			check_new_era();
-			assert_eq!(sessions_per_era(), 3u64);
-			assert_eq!(last_era_length_change(), 4u64);
-			assert_eq!(current_era(), 2u64);
+			assert_eq!(SessionsPerEra::get(), 3u64);
+			assert_eq!(LastEraLengthChange::get(), 4u64);
+			assert_eq!(CurrentEra::get(), 2u64);
 
 			// Block 6: No change.
 			with_env(|e| e.block_number = 6);
 			check_new_era();
-			assert_eq!(sessions_per_era(), 3u64);
-			assert_eq!(last_era_length_change(), 4u64);
-			assert_eq!(current_era(), 2u64);
+			assert_eq!(SessionsPerEra::get(), 3u64);
+			assert_eq!(LastEraLengthChange::get(), 4u64);
+			assert_eq!(CurrentEra::get(), 2u64);
 
 			// Block 7: Era increment.
 			with_env(|e| e.block_number = 7);
 			check_new_era();
-			assert_eq!(sessions_per_era(), 3u64);
-			assert_eq!(last_era_length_change(), 4u64);
-			assert_eq!(current_era(), 3u64);
+			assert_eq!(SessionsPerEra::get(), 3u64);
+			assert_eq!(LastEraLengthChange::get(), 4u64);
+			assert_eq!(CurrentEra::get(), 3u64);
 		});
 	}
 
 	#[test]
 	fn staking_balance_works() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 42);
-			assert_eq!(free_balance(&Alice), 42);
-			assert_eq!(reserved_balance(&Alice), 0);
+			FreeBalanceOf::insert(*Alice, 42);
+			assert_eq!(FreeBalanceOf::get(*Alice), 42);
+			assert_eq!(ReservedBalanceOf::get(*Alice), 0);
 			assert_eq!(balance(&Alice), 42);
-			assert_eq!(free_balance(&Bob), 0);
-			assert_eq!(reserved_balance(&Bob), 0);
+			assert_eq!(FreeBalanceOf::get(*Bob), 0);
+			assert_eq!(ReservedBalanceOf::get(*Bob), 0);
 			assert_eq!(balance(&Bob), 0);
 		});
 	}
@@ -778,7 +728,7 @@ mod tests {
 	#[test]
 	fn staking_balance_transfer_works() {
 		with_externalities(&mut testing::externalities(1, 3, 1), || {
-			set_free_balance(&Alice, 112);
+			FreeBalanceOf::insert(*Alice, 112);
 			PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69);
 			assert_eq!(balance(&Alice), 42);
 			assert_eq!(balance(&Bob), 69);
@@ -789,7 +739,7 @@ mod tests {
 	#[should_panic]
 	fn staking_balance_transfer_when_bonded_panics() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 111);
+			FreeBalanceOf::insert(*Alice, 111);
 			PublicPass::new(&Alice).stake();
 			PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69);
 		});
@@ -798,17 +748,17 @@ mod tests {
 	#[test]
 	fn reserving_balance_should_work() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 111);
+			FreeBalanceOf::insert(*Alice, 111);
 
 			assert_eq!(balance(&Alice), 111);
-			assert_eq!(free_balance(&Alice), 111);
-			assert_eq!(reserved_balance(&Alice), 0);
+			assert_eq!(FreeBalanceOf::get(*Alice), 111);
+			assert_eq!(ReservedBalanceOf::get(*Alice), 0);
 
 			reserve_balance(&Alice, 69);
 
 			assert_eq!(balance(&Alice), 111);
-			assert_eq!(free_balance(&Alice), 42);
-			assert_eq!(reserved_balance(&Alice), 69);
+			assert_eq!(FreeBalanceOf::get(*Alice), 42);
+			assert_eq!(ReservedBalanceOf::get(*Alice), 69);
 		});
 	}
 
@@ -816,7 +766,7 @@ mod tests {
 	#[should_panic]
 	fn staking_balance_transfer_when_reserved_panics() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 111);
+			FreeBalanceOf::insert(*Alice, 111);
 			reserve_balance(&Alice, 69);
 			PublicPass::new(&Alice).transfer(Bob.to_raw_public(), 69);
 		});
@@ -825,17 +775,17 @@ mod tests {
 	#[test]
 	fn deducting_balance_should_work() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 111);
+			FreeBalanceOf::insert(*Alice, 111);
 			assert!(deduct_unbonded(&Alice, 69));
-			assert_eq!(free_balance(&Alice), 42);
+			assert_eq!(FreeBalanceOf::get(*Alice), 42);
 		});
 	}
 
 	#[test]
 	fn deducting_balance_should_fail_when_bonded() {
 		let mut t: TestExternalities = map![
-			twox_128(&Alice.to_raw_public().to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64),
-			twox_128(&Alice.to_raw_public().to_keyed_vec(BONDAGE_OF)).to_vec() => vec![].and(&2u64)
+			twox_128(&FreeBalanceOf::key_for(*Alice)).to_vec() => vec![].and(&111u64),
+			twox_128(&BondageOf::key_for(*Alice)).to_vec() => vec![].and(&2u64)
 		];
 		with_externalities(&mut t, || {
 			with_env(|e| e.block_number = 1);
@@ -847,90 +797,90 @@ mod tests {
 	#[test]
 	fn refunding_balance_should_work() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 42);
+			FreeBalanceOf::insert(*Alice, 42);
 			refund(&Alice, 69);
-			assert_eq!(free_balance(&Alice), 111);
+			assert_eq!(FreeBalanceOf::get(*Alice), 111);
 		});
 	}
 
 	#[test]
 	fn slashing_balance_should_work() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 111);
+			FreeBalanceOf::insert(*Alice, 111);
 			reserve_balance(&Alice, 69);
 			assert!(slash(&Alice, 69));
-			assert_eq!(free_balance(&Alice), 0);
-			assert_eq!(reserved_balance(&Alice), 42);
+			assert_eq!(FreeBalanceOf::get(*Alice), 0);
+			assert_eq!(ReservedBalanceOf::get(*Alice), 42);
 		});
 	}
 
 	#[test]
 	fn slashing_incomplete_balance_should_work() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 42);
+			FreeBalanceOf::insert(*Alice, 42);
 			reserve_balance(&Alice, 21);
 			assert!(!slash(&Alice, 69));
-			assert_eq!(free_balance(&Alice), 0);
-			assert_eq!(reserved_balance(&Alice), 0);
+			assert_eq!(FreeBalanceOf::get(*Alice), 0);
+			assert_eq!(ReservedBalanceOf::get(*Alice), 0);
 		});
 	}
 
 	#[test]
 	fn unreserving_balance_should_work() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 111);
+			FreeBalanceOf::insert(*Alice, 111);
 			reserve_balance(&Alice, 111);
 			unreserve_balance(&Alice, 42);
-			assert_eq!(reserved_balance(&Alice), 69);
-			assert_eq!(free_balance(&Alice), 42);
+			assert_eq!(ReservedBalanceOf::get(*Alice), 69);
+			assert_eq!(FreeBalanceOf::get(*Alice), 42);
 		});
 	}
 
 	#[test]
 	fn slashing_reserved_balance_should_work() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 111);
+			FreeBalanceOf::insert(*Alice, 111);
 			reserve_balance(&Alice, 111);
 			assert!(slash_reserved(&Alice, 42));
-			assert_eq!(reserved_balance(&Alice), 69);
-			assert_eq!(free_balance(&Alice), 0);
+			assert_eq!(ReservedBalanceOf::get(*Alice), 69);
+			assert_eq!(FreeBalanceOf::get(*Alice), 0);
 		});
 	}
 
 	#[test]
 	fn slashing_incomplete_reserved_balance_should_work() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 111);
+			FreeBalanceOf::insert(*Alice, 111);
 			reserve_balance(&Alice, 42);
 			assert!(!slash_reserved(&Alice, 69));
-			assert_eq!(free_balance(&Alice), 69);
-			assert_eq!(reserved_balance(&Alice), 0);
+			assert_eq!(FreeBalanceOf::get(*Alice), 69);
+			assert_eq!(ReservedBalanceOf::get(*Alice), 0);
 		});
 	}
 
 	#[test]
 	fn transferring_reserved_balance_should_work() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 111);
+			FreeBalanceOf::insert(*Alice, 111);
 			reserve_balance(&Alice, 111);
 			assert!(transfer_reserved_balance(&Alice, &Bob, 42));
-			assert_eq!(reserved_balance(&Alice), 69);
-			assert_eq!(free_balance(&Alice), 0);
-			assert_eq!(reserved_balance(&Bob), 0);
-			assert_eq!(free_balance(&Bob), 42);
+			assert_eq!(ReservedBalanceOf::get(*Alice), 69);
+			assert_eq!(FreeBalanceOf::get(*Alice), 0);
+			assert_eq!(ReservedBalanceOf::get(*Bob), 0);
+			assert_eq!(FreeBalanceOf::get(*Bob), 42);
 		});
 	}
 
 	#[test]
 	fn transferring_incomplete_reserved_balance_should_work() {
 		with_externalities(&mut TestExternalities::default(), || {
-			set_free_balance(&Alice, 111);
+			FreeBalanceOf::insert(*Alice, 111);
 			reserve_balance(&Alice, 42);
 			assert!(!transfer_reserved_balance(&Alice, &Bob, 69));
-			assert_eq!(reserved_balance(&Alice), 0);
-			assert_eq!(free_balance(&Alice), 69);
-			assert_eq!(reserved_balance(&Bob), 0);
-			assert_eq!(free_balance(&Bob), 42);
+			assert_eq!(ReservedBalanceOf::get(*Alice), 0);
+			assert_eq!(FreeBalanceOf::get(*Alice), 69);
+			assert_eq!(ReservedBalanceOf::get(*Bob), 0);
+			assert_eq!(FreeBalanceOf::get(*Bob), 42);
 		});
 	}
 }
diff --git a/substrate/demo/runtime/src/runtime/system.rs b/substrate/demo/runtime/src/runtime/system.rs
index e3a6e19ef51f00537871d8b1b5e995d1194fe2c3..5469d6aa9bfc8b81219d0d008adb92f25067c653 100644
--- a/substrate/demo/runtime/src/runtime/system.rs
+++ b/substrate/demo/runtime/src/runtime/system.rs
@@ -21,7 +21,7 @@ use rstd::prelude::*;
 use rstd::mem;
 use runtime_io::{print, storage_root, enumerated_trie_root};
 use codec::{KeyedVec, Slicable};
-use runtime_support::{Hashable, storage};
+use runtime_support::{Hashable, storage, StorageValue, StorageMap};
 use environment::with_env;
 use demo_primitives::{AccountId, Hash, TxOrder, BlockNumber, Header, Log};
 use block::Block;
@@ -30,9 +30,12 @@ use runtime::{staking, session};
 use runtime::democracy::PrivPass;
 use dispatch;
 
-pub const NONCE_OF: &[u8] = b"sys:non:";
-pub const BLOCK_HASH_AT: &[u8] = b"sys:old:";
-pub const CODE: &[u8] = b"sys:cod";
+storage_items! {
+	pub Nonce: b"sys:non" => default map [ AccountId => TxOrder ];
+	pub BlockHashAt: b"sys:old" => required map [ BlockNumber => Hash ];
+}
+
+pub const CODE: &'static[u8] = b":code";
 
 
 /// The current block number being processed. Set by `execute_block`.
@@ -40,11 +43,6 @@ pub fn block_number() -> BlockNumber {
 	with_env(|e| e.block_number)
 }
 
-/// Get the block hash of a given block (uses storage).
-pub fn block_hash(number: BlockNumber) -> Hash {
-	storage::get_or_default(&number.to_keyed_vec(BLOCK_HASH_AT))
-}
-
 impl_dispatch! {
 	pub mod privileged;
 	fn set_code(new: Vec<u8>) = 0;
@@ -145,12 +143,11 @@ fn execute_transaction(utx: UncheckedTransaction) {
 
 	{
 		// check nonce
-		let nonce_key = tx.signed.to_keyed_vec(NONCE_OF);
-		let expected_nonce: TxOrder = storage::get_or(&nonce_key, 0);
+		let expected_nonce: TxOrder = Nonce::get(&tx.signed);
 		assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce");
 
 		// increment nonce in storage
-		storage::put(&nonce_key, &(expected_nonce + 1));
+		Nonce::insert(&tx.signed, &(expected_nonce + 1));
 	}
 
 	// decode parameters and dispatch
@@ -163,7 +160,7 @@ fn initial_checks(block: &Block) {
 
 	// check parent_hash is correct.
 	assert!(
-		header.number > 0 && block_hash(header.number - 1) == header.parent_hash,
+		header.number > 0 && BlockHashAt::get(&(header.number - 1)) == header.parent_hash,
 		"Parent hash should be valid."
 	);
 
@@ -192,7 +189,7 @@ fn final_checks(block: &Block) {
 fn post_finalise(header: &Header) {
 	// store the header hash in storage; we can't do it before otherwise there would be a
 	// cyclic dependency.
-	storage::put(&header.number.to_keyed_vec(BLOCK_HASH_AT), &header.blake2_256());
+	BlockHashAt::insert(&header.number, &header.blake2_256().into());
 }
 
 #[cfg(feature = "std")]
@@ -220,7 +217,7 @@ pub mod testing {
 
 	pub fn externalities() -> TestExternalities {
 		map![
-			twox_128(&0u64.to_keyed_vec(BLOCK_HASH_AT)).to_vec() => [69u8; 32].encode()
+			twox_128(&BlockHashAt::key_for(&0)).to_vec() => [69u8; 32].encode()
 		]
 	}
 }
@@ -231,6 +228,7 @@ mod tests {
 	use super::internal::*;
 
 	use runtime_io::{with_externalities, twox_128, TestExternalities};
+	use runtime_support::StorageValue;
 	use codec::{Joiner, KeyedVec, Slicable};
 	use keyring::Keyring::*;
 	use environment::with_env;
@@ -244,8 +242,8 @@ mod tests {
 	#[test]
 	fn staking_balance_transfer_dispatch_works() {
 		let mut t: TestExternalities = map![
-			twox_128(&One.to_raw_public().to_keyed_vec(staking::BALANCE_OF)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0],
-			twox_128(staking::TRANSACTION_FEE).to_vec() => vec![10u8, 0, 0, 0, 0, 0, 0, 0]
+			twox_128(&staking::FreeBalanceOf::key_for(*One)).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0],
+			twox_128(staking::TransactionFee::key()).to_vec() => vec![10u8, 0, 0, 0, 0, 0, 0, 0]
 		];
 
 		let tx = UncheckedTransaction {
@@ -275,7 +273,7 @@ mod tests {
 		let h = Header {
 			parent_hash: [69u8; 32].into(),
 			number: 1,
-			state_root: hex!("584e0c1f4d4b96153591e3906d756762493dffeb5fa7159e7107014aec8d9c3d").into(),
+			state_root: hex!("cc3f1f5db826013193e502c76992b5e933b12367e37a269a9822b89218323e9f").into(),
 			transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(),
 			digest: Digest { logs: vec![], },
 		};
diff --git a/substrate/demo/runtime/src/runtime/timestamp.rs b/substrate/demo/runtime/src/runtime/timestamp.rs
index ff2c18b9bd4bab247b006289685c73adce7f8d56..ed51ebabc72795126ff49dce3622744458c200c5 100644
--- a/substrate/demo/runtime/src/runtime/timestamp.rs
+++ b/substrate/demo/runtime/src/runtime/timestamp.rs
@@ -16,16 +16,13 @@
 
 //! Timestamp manager: just handles the current timestamp.
 
-use runtime_support::storage;
+use runtime_support::storage::StorageValue;
 use runtime::staking::PublicPass;
 
 pub type Timestamp = u64;
 
-pub const CURRENT_TIMESTAMP: &[u8] = b"tim:val";
-
-/// Get the current time.
-pub fn get() -> Timestamp {
-	storage::get_or_default(CURRENT_TIMESTAMP)
+storage_items! {
+	pub Now: b"tim:val" => required Timestamp;
 }
 
 impl_dispatch! {
@@ -36,7 +33,7 @@ impl_dispatch! {
 impl<'a> public::Dispatch for PublicPass<'a> {
 	/// Set the current time.
 	fn set(self, now: Timestamp) {
-		storage::put(CURRENT_TIMESTAMP, &now);
+		Now::put(&now);
 	}
 }
 
@@ -46,6 +43,7 @@ mod tests {
 	use super::public::*;
 
 	use runtime_io::{with_externalities, twox_128, TestExternalities};
+	use runtime_support::storage::StorageValue;
 	use runtime::timestamp;
 	use codec::{Joiner, KeyedVec};
 	use demo_primitives::AccountId;
@@ -54,13 +52,13 @@ mod tests {
 	#[test]
 	fn timestamp_works() {
 		let mut t: TestExternalities = map![
-			twox_128(CURRENT_TIMESTAMP).to_vec() => vec![].and(&42u64)
+			twox_128(Now::key()).to_vec() => vec![].and(&42u64)
 		];
 
 		with_externalities(&mut t, || {
-			assert_eq!(get(), 42);
+			assert_eq!(Now::get(), 42);
 			PublicPass::nobody().set(69);
-			assert_eq!(get(), 69);
+			assert_eq!(Now::get(), 69);
 		});
 	}
 }
diff --git a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm
index 8d4177558c879383d18ca9954e22d0c54b394113..00854daf6fc89be40cfe268dfed20d17bb68e871 100644
Binary files a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm and b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm differ
diff --git a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm
index 43f146e82f7b5fed169d463fa837a22d4712c589..b033a3c8809c99b3a5aa7d2d45948d9e184d34fb 100644
Binary files a/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm and b/substrate/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm differ
diff --git a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm
index 68f8fe0114541bf47fc02b224d5c1450d506c2ed..7072339a0712581faa3d0d6c6370673df0ff70de 100644
Binary files a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm and b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm differ
diff --git a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm
index 06caf6119bea69b895da6b8f025f0147d66db725..57be0867032a5e1ffdb5b49e77ebcd77c8ceaa5a 100644
Binary files a/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm and b/substrate/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm differ
diff --git a/substrate/substrate/runtime-support/src/lib.rs b/substrate/substrate/runtime-support/src/lib.rs
index 6e946ce6c798881fb5b2b761c633e0a52109b494..b3aea78cbc6e62754b4d3d9ae5ab9d59305ae1bb 100644
--- a/substrate/substrate/runtime-support/src/lib.rs
+++ b/substrate/substrate/runtime-support/src/lib.rs
@@ -29,5 +29,5 @@ pub use self::storage::generator::Storage as GenericStorage;
 pub mod storage;
 mod hashable;
 
-pub use self::storage::StorageVec;
+pub use self::storage::{StorageVec, StorageList, StorageValue, StorageMap};
 pub use self::hashable::Hashable;
diff --git a/substrate/substrate/runtime-support/src/storage/generator.rs b/substrate/substrate/runtime-support/src/storage/generator.rs
index ce02a4e099264c549670ffc312dd0063502c41ee..b77b58d418124f2469697ce595e36b77e2ac0ea4 100644
--- a/substrate/substrate/runtime-support/src/storage/generator.rs
+++ b/substrate/substrate/runtime-support/src/storage/generator.rs
@@ -36,7 +36,7 @@
 //!
 //! storage_items! {
 //!     // public value
-//!     pub Value: b"stored_key" => SessionKey;
+//!     pub Value: b"putd_key" => SessionKey;
 //!     // private map.
 //!     Balances: b"private_map:" => map [AuthorityId => Balance];
 //!     // private list.
@@ -48,38 +48,73 @@
 
 use codec;
 use rstd::vec::Vec;
+#[doc(hidden)]
+pub use rstd::borrow::Borrow;
 
 /// Abstraction around storage.
 pub trait Storage {
+	/// true if the key exists in storage.
+	fn exists(&self, key: &[u8]) -> bool;
+
 	/// Load the bytes of a key from storage. Can panic if the type is incorrect.
-	fn load<T: codec::Slicable>(&self, key: &[u8]) -> Option<T>;
+	fn get<T: codec::Slicable>(&self, key: &[u8]) -> Option<T>;
+
+	/// Load the bytes of a key from storage. Can panic if the type is incorrect. Will panic if
+	/// it's not there.
+	fn require<T: codec::Slicable>(&self, key: &[u8]) -> T { self.get(key).expect("Required values must be in storage") }
+
+	/// Load the bytes of a key from storage. Can panic if the type is incorrect. The type's
+	/// default is returned if it's not there.
+	fn get_or_default<T: codec::Slicable + Default>(&self, key: &[u8]) -> T { self.get(key).unwrap_or_default() }
 
 	/// Put a value in under a key.
-	fn store<T: codec::Slicable>(&self, key: &[u8], val: &T);
+	fn put<T: codec::Slicable>(&self, key: &[u8], val: &T);
 
 	/// Remove the bytes of a key from storage.
 	fn kill(&self, key: &[u8]);
 
 	/// Take a value from storage, deleting it after reading.
 	fn take<T: codec::Slicable>(&self, key: &[u8]) -> Option<T> {
-		let value = self.load(key);
+		let value = self.get(key);
 		self.kill(key);
 		value
 	}
+
+	/// Take a value from storage, deleting it after reading.
+	fn take_or_panic<T: codec::Slicable>(&self, key: &[u8]) -> T { self.take(key).expect("Required values must be in storage") }
+
+	/// Take a value from storage, deleting it after reading.
+	fn take_or_default<T: codec::Slicable + Default>(&self, key: &[u8]) -> T { self.take(key).unwrap_or_default() }
 }
 
 /// A strongly-typed value kept in storage.
 pub trait StorageValue<T: codec::Slicable> {
+	/// The type that get/take returns.
+	type Query;
+
 	/// Get the storage key.
 	fn key() -> &'static [u8];
+
+	/// true if the value is defined in storage.
+	fn exists<S: Storage>(storage: &S) -> bool {
+		storage.exists(Self::key())
+	}
+
 	/// Load the value from the provided storage instance.
-	fn load<S: Storage>(storage: &S) -> Option<T>;
+	fn get<S: Storage>(storage: &S) -> Self::Query;
+
+	/// Take a value from storage, removing it afterwards.
+	fn take<S: Storage>(storage: &S) -> Self::Query;
+
 	/// Store a value under this key into the provded storage instance.
-	fn store<S: Storage>(val: &T, storage: &S);
+	fn put<S: Storage>(val: &T, storage: &S) {
+		storage.put(Self::key(), val)
+	}
+
 	/// Clear the storage value.
-	fn kill<S: Storage>(storage: &S);
-	/// Take a value from storage, removing it afterwards.
-	fn take<S: Storage>(storage: &S) -> Option<T>;
+	fn kill<S: Storage>(storage: &S) {
+		storage.kill(Self::key())
+	}
 }
 
 /// A strongly-typed list in storage.
@@ -87,7 +122,7 @@ pub trait StorageList<T: codec::Slicable> {
 	/// Get the prefix key in storage.
 	fn prefix() -> &'static [u8];
 
-	/// Get the key used to store the length field.
+	/// Get the key used to put the length field.
 	fn len_key() -> Vec<u8>;
 
 	/// Get the storage key used to fetch a value at a given index.
@@ -114,225 +149,119 @@ pub trait StorageList<T: codec::Slicable> {
 
 /// A strongly-typed map in storage.
 pub trait StorageMap<K: codec::Slicable, V: codec::Slicable> {
+	/// The type that get/take returns.
+	type Query;
+
 	/// Get the prefix key in storage.
 	fn prefix() -> &'static [u8];
 
 	/// Get the storage key used to fetch a value corresponding to a specific key.
 	fn key_for(x: &K) -> Vec<u8>;
 
+	/// true if the value is defined in storage.
+	fn exists<S: Storage>(key: &K, storage: &S) -> bool {
+		storage.exists(&Self::key_for(key)[..])
+	}
+
 	/// Load the value associated with the given key from the map.
-	fn get<S: Storage>(key: &K, storage: &S) -> Option<V>;
+	fn get<S: Storage>(key: &K, storage: &S) -> Self::Query;
+
+	/// Take the value under a key.
+	fn take<S: Storage>(key: &K, storage: &S) -> Self::Query;
 
 	/// Store a value to be associated with the given key from the map.
-	fn insert<S: Storage>(key: &K, val: &V, storage: &S);
+	fn insert<S: Storage>(key: &K, val: &V, storage: &S) {
+		storage.put(&Self::key_for(key)[..], val);
+	}
 
 	/// Remove the value under a key.
-	fn remove<S: Storage>(key: &K, storage: &S);
-
-	/// Take the value under a key.
-	fn take<S: Storage>(key: &K, storage: &S) -> Option<V>;
+	fn remove<S: Storage>(key: &K, storage: &S) {
+		storage.kill(&Self::key_for(key)[..]);
+	}
 }
 
 #[macro_export]
 #[doc(hidden)]
 macro_rules! __storage_items_internal {
 	// generator for values.
-	(($($vis:tt)*) $name: ident: $key: expr => $ty:ty) => {
+	(($($vis:tt)*) ($get_fn:ident) ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => {
+		__storage_items_internal!{ ($($vis)*) () ($gettype) ($getter) ($taker) $name : $key => $ty }
+		pub fn $get_fn() -> $gettype { <$name as $crate::storage::generator::StorageValue<$ty>> :: get(&$crate::storage::RuntimeStorage) }
+	};
+	(($($vis:tt)*) () ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $key:expr => $ty:ty) => {
 		$($vis)* struct $name;
 
-		#[allow(unused)]
-		impl $name {
-			/// Get the storage key.
-			$($vis)* fn key() -> &'static [u8] {
-				$key
-			}
-
-			/// Load the value from the provided storage instance.
-			$($vis)* fn load<S: $crate::GenericStorage>(storage: &S) -> Option<$ty> {
-				storage.load($key)
-			}
-
-			/// Store a value under this key into the provded storage instance.
-			$($vis)* fn store<S: $crate::GenericStorage>(val: &$ty, storage: &S) {
-				storage.store($key, val)
-			}
-
-			/// Kill the value.
-			$($vis)* fn kill<S: $crate::GenericStorage>(storage: &S) {
-				storage.kill($key)
-			}
-
-			/// Take and remove the value from the provided storage instance.
-			$($vis)* fn take<S: $crate::GenericStorage>(storage: &S) -> Option<$ty> {
-				storage.take($key)
-			}
-		}
-
 		impl $crate::storage::generator::StorageValue<$ty> for $name {
+			type Query = $gettype;
+
+			/// Get the storage key.
 			fn key() -> &'static [u8] {
 				$key
 			}
 
-			fn load<S: $crate::GenericStorage>(storage: &S) -> Option<$ty> {
-				$name::load(storage)
-			}
-
-			fn store<S: $crate::GenericStorage>(val: &$ty, storage: &S) {
-				$name::store(val, storage)
-			}
-
-			fn kill<S: $crate::GenericStorage>(storage: &S) {
-				$name::kill(storage)
+			/// Load the value from the provided storage instance.
+			fn get<S: $crate::GenericStorage>(storage: &S) -> Self::Query {
+				storage.$getter($key)
 			}
 
-			fn take<S: $crate::GenericStorage>(storage: &S) -> Option<$ty> {
-				$name::take(storage)
+			/// Take a value from storage, removing it afterwards.
+			fn take<S: $crate::GenericStorage>(storage: &S) -> Self::Query {
+				storage.$taker($key)
 			}
 		}
 	};
 	// generator for maps.
-	(($($vis:tt)*) $name: ident: $prefix: expr => map [$kty: ty => $ty:ty]) => {
+	(($($vis:tt)*) ($get_fn:ident) ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => {
+		__storage_items_internal!{ ($($vis)*) () ($gettype) ($getter) ($taker) $name : $prefix => map [$kty => $ty] }
+		pub fn $get_fn<K: $crate::storage::generator::Borrow<$kty>>(key: K) -> $gettype {
+			<$name as $crate::storage::generator::StorageMap<$kty, $ty>> :: get(key.borrow(), &$crate::storage::RuntimeStorage)
+		}
+	};
+	(($($vis:tt)*) () ($gettype:ty) ($getter:ident) ($taker:ident) $name:ident : $prefix:expr => map [$kty:ty => $ty:ty]) => {
 		$($vis)* struct $name;
 
-		#[allow(unused)]
-		impl $name {
+		impl $crate::storage::generator::StorageMap<$kty, $ty> for $name {
+			type Query = $gettype;
+
 			/// Get the prefix key in storage.
-			$($vis)* fn prefix() -> &'static [u8] {
+			fn prefix() -> &'static [u8] {
 				$prefix
 			}
 
 			/// Get the storage key used to fetch a value corresponding to a specific key.
-			$($vis)* fn key_for(x: &$kty) -> Vec<u8> {
+			fn key_for(x: &$kty) -> Vec<u8> {
 				let mut key = $prefix.to_vec();
 				key.extend($crate::codec::Slicable::encode(x));
 				key
 			}
 
 			/// Load the value associated with the given key from the map.
-			$($vis)* fn get<S: $crate::GenericStorage>(key: &$kty, storage: &S) -> Option<$ty> {
-				let key = $name::key_for(key);
-				storage.load(&key[..])
-			}
-
-			/// Store a value to be associated with the given key from the map.
-			$($vis)* fn insert<S: $crate::GenericStorage>(key: &$kty, val: &$ty, storage: &S) {
-				let key = $name::key_for(key);
-				storage.store(&key[..], val);
-			}
-
-			/// Remove the value from storage.
-			$($vis)* fn remove<S: $crate::GenericStorage>(key: &$kty, storage: &S) {
-				storage.kill(&$name::key_for(key)[..]);
+			fn get<S: $crate::GenericStorage>(key: &$kty, storage: &S) -> Self::Query {
+				let key = <$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key);
+				storage.$getter(&key[..])
 			}
 
 			/// Take the value, reading and removing it.
-			$($vis)* fn take<S: $crate::GenericStorage>(key: &$kty, storage: &S) -> Option<$ty> {
-				let key = $name::key_for(key);
-				storage.take(&key[..])
-			}
-		}
-
-		impl $crate::storage::generator::StorageMap<$kty, $ty> for $name {
-			fn prefix() -> &'static [u8] {
-				$prefix
-			}
-
-			fn key_for(x: &$kty) -> Vec<u8> {
-				$name::key_for(x)
-			}
-
-			fn get<S: $crate::GenericStorage>(key: &$kty, storage: &S) -> Option<$ty> {
-				$name::get(key, storage)
-			}
-
-			fn insert<S: $crate::GenericStorage>(key: &$kty, val: &$ty, storage: &S) {
-				$name::insert(key, val, storage)
-			}
-
-			fn remove<S: $crate::GenericStorage>(key: &$kty, storage: &S) {
-				$name::remove(key, storage)
-			}
-
-			fn take<S: $crate::GenericStorage>(key: &$kty, storage: &S) -> Option<$ty> {
-				$name::take(key, storage)
+			fn take<S: $crate::GenericStorage>(key: &$kty, storage: &S) -> Self::Query {
+				let key = <$name as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key);
+				storage.$taker(&key[..])
 			}
 		}
 	};
 	// generator for lists.
-	(($($vis:tt)*) $name: ident: $prefix: expr => list [$ty:ty]) => {
+	(($($vis:tt)*) $name:ident : $prefix:expr => list [$ty:ty]) => {
 		$($vis)* struct $name;
 
-		#[allow(unused)]
 		impl $name {
-			/// Get the prefix key in storage.
-			$($vis)* fn prefix() -> &'static [u8] {
-				$prefix
-			}
-
-			/// Get the key used to store the length field.
-			// TODO: concat macro should accept byte literals.
-			$($vis)* fn len_key() -> Vec<u8> {
-				let mut key = $prefix.to_vec();
-				key.extend(b"len");
-				key
-			}
-
-			/// Get the storage key used to fetch a value at a given index.
-			$($vis)* fn key_for(index: u32) -> Vec<u8> {
-				let mut key = $prefix.to_vec();
-				key.extend($crate::codec::Slicable::encode(&index));
-				key
-			}
-
-			/// Read out all the items.
-			$($vis)* fn items<S: $crate::GenericStorage>(storage: &S) -> Vec<$ty> {
-				(0..$name::len(storage))
-					.map(|i| $name::get(i, storage).expect("all items within length are set; qed"))
-					.collect()
-			}
-
-			/// Set the current set of items.
-			$($vis)* fn set_items<S: $crate::GenericStorage>(items: &[$ty], storage: &S) {
-				$name::set_len(items.len() as u32, storage);
-				items.iter()
-					.enumerate()
-					.for_each(|(i, item)| $name::set_item(i as u32, item, storage));
-			}
-
-			$($vis)* fn set_item<S: $crate::GenericStorage>(index: u32, item: &$ty, storage: &S) {
-				if index < $name::len(storage) {
-					storage.store(&$name::key_for(index)[..], item);
-				}
-			}
-
-			/// Load the value at given index. Returns `None` if the index is out-of-bounds.
-			$($vis)* fn get<S: $crate::GenericStorage>(index: u32, storage: &S) -> Option<$ty> {
-				storage.load(&$name::key_for(index)[..])
-			}
-
-			/// Load the length of the list.
-			$($vis)* fn len<S: $crate::GenericStorage>(storage: &S) -> u32 {
-				storage.load(&$name::len_key()).unwrap_or_default()
-			}
-
-			/// Clear the list.
-			$($vis)* fn clear<S: $crate::GenericStorage>(storage: &S) {
-				for i in 0..$name::len(storage) {
-					$name::clear_item(i, storage);
-				}
-
-				storage.kill(&$name::len_key()[..])
-			}
-
 			fn clear_item<S: $crate::GenericStorage>(index: u32, storage: &S) {
-				if index < $name::len(storage) {
-					storage.kill(&$name::key_for(index));
+				if index < <$name as $crate::storage::generator::StorageList<$ty>>::len(storage) {
+					storage.kill(&<$name as $crate::storage::generator::StorageList<$ty>>::key_for(index));
 				}
 			}
 
 			fn set_len<S: $crate::GenericStorage>(count: u32, storage: &S) {
-				(count..$name::len(storage)).for_each(|i| $name::clear_item(i, storage));
-				storage.store(&$name::len_key(), &count);
+				(count..<$name as $crate::storage::generator::StorageList<$ty>>::len(storage)).for_each(|i| $name::clear_item(i, storage));
+				storage.put(&<$name as $crate::storage::generator::StorageList<$ty>>::len_key(), &count);
 			}
 		}
 
@@ -342,42 +271,59 @@ macro_rules! __storage_items_internal {
 				$prefix
 			}
 
-			/// Get the key used to store the length field.
+			/// Get the key used to put the length field.
 			// TODO: concat macro should accept byte literals.
 			fn len_key() -> Vec<u8> {
-				$name::len_key()
+				let mut key = $prefix.to_vec();
+				key.extend(b"len");
+				key
 			}
 
 			/// Get the storage key used to fetch a value at a given index.
 			fn key_for(index: u32) -> Vec<u8> {
-				$name::key_for(index)
+				let mut key = $prefix.to_vec();
+				key.extend($crate::codec::Slicable::encode(&index));
+				key
 			}
 
 			/// Read out all the items.
 			fn items<S: $crate::GenericStorage>(storage: &S) -> Vec<$ty> {
-				$name::items(storage)
+				(0..<$name as $crate::storage::generator::StorageList<$ty>>::len(storage))
+					.map(|i| <$name as $crate::storage::generator::StorageList<$ty>>::get(i, storage).expect("all items within length are set; qed"))
+					.collect()
 			}
 
 			/// Set the current set of items.
 			fn set_items<S: $crate::GenericStorage>(items: &[$ty], storage: &S) {
-				$name::set_items(items, storage)
+				$name::set_len(items.len() as u32, storage);
+				items.iter()
+					.enumerate()
+					.for_each(|(i, item)| <$name as $crate::storage::generator::StorageList<$ty>>::set_item(i as u32, item, storage));
 			}
 
 			fn set_item<S: $crate::GenericStorage>(index: u32, item: &$ty, storage: &S) {
-				$name::set_item(index, item, storage)
+				if index < <$name as $crate::storage::generator::StorageList<$ty>>::len(storage) {
+					storage.put(&<$name as $crate::storage::generator::StorageList<$ty>>::key_for(index)[..], item);
+				}
 			}
 
 			/// Load the value at given index. Returns `None` if the index is out-of-bounds.
 			fn get<S: $crate::GenericStorage>(index: u32, storage: &S) -> Option<$ty> {
-				$name::get(index, storage)
+				storage.get(&<$name as $crate::storage::generator::StorageList<$ty>>::key_for(index)[..])
 			}
 
+			/// Load the length of the list.
 			fn len<S: $crate::GenericStorage>(storage: &S) -> u32 {
-				$name::len(storage)
+				storage.get(&<$name as $crate::storage::generator::StorageList<$ty>>::len_key()).unwrap_or_default()
 			}
 
+			/// Clear the list.
 			fn clear<S: $crate::GenericStorage>(storage: &S) {
-				$name::clear(storage)
+				for i in 0..<$name as $crate::storage::generator::StorageList<$ty>>::len(storage) {
+					$name::clear_item(i, storage);
+				}
+
+				storage.kill(&<$name as $crate::storage::generator::StorageList<$ty>>::len_key()[..])
 			}
 		}
 	};
@@ -387,29 +333,114 @@ macro_rules! __storage_items_internal {
 #[macro_export]
 macro_rules! storage_items {
 	// simple values
-	($name: ident: $key: expr => $ty:ty; $($t:tt)*) => {
-		__storage_items_internal!(() $name: $key => $ty);
+	($name:ident : $key:expr => $ty:ty; $($t:tt)*) => {
+		__storage_items_internal!(() () (Option<$ty>) (get) (take) $name: $key => $ty);
+		storage_items!($($t)*);
+	};
+	(pub $name:ident : $key:expr => $ty:ty; $($t:tt)*) => {
+		__storage_items_internal!((pub) () (Option<$ty>) (get) (take) $name: $key => $ty);
 		storage_items!($($t)*);
 	};
-	(pub $name: ident: $key: expr => $ty:ty; $($t:tt)*) => {
-		__storage_items_internal!((pub) $name: $key => $ty);
+	($name:ident : $key:expr => default $ty:ty; $($t:tt)*) => {
+		__storage_items_internal!(() () ($ty) (get_or_default) (take_or_default) $name: $key => $ty);
 		storage_items!($($t)*);
 	};
+	(pub $name:ident : $key:expr => default $ty:ty; $($t:tt)*) => {
+		__storage_items_internal!((pub) () ($ty) (get_or_default) (take_or_default) $name: $key => $ty);
+		storage_items!($($t)*);
+	};
+	($name:ident : $key:expr => required $ty:ty; $($t:tt)*) => {
+		__storage_items_internal!(() () ($ty) (require) (take_or_panic) $name: $key => $ty);
+		storage_items!($($t)*);
+	};
+	(pub $name:ident : $key:expr => required $ty:ty; $($t:tt)*) => {
+		__storage_items_internal!((pub) () ($ty) (require) (take_or_panic) $name: $key => $ty);
+		storage_items!($($t)*);
+	};
+
+	($name:ident get($getfn:ident) : $key:expr => $ty:ty; $($t:tt)*) => {
+		__storage_items_internal!(() ($getfn) (Option<$ty>) (get) (take) $name: $key => $ty);
+		storage_items!($($t)*);
+	};
+	(pub $name:ident get($getfn:ident) : $key:expr => $ty:ty; $($t:tt)*) => {
+		__storage_items_internal!((pub) ($getfn) (Option<$ty>) (get) (take) $name: $key => $ty);
+		storage_items!($($t)*);
+	};
+	($name:ident get($getfn:ident) : $key:expr => default $ty:ty; $($t:tt)*) => {
+		__storage_items_internal!(() ($getfn) ($ty) (get_or_default) (take_or_default) $name: $key => $ty);
+		storage_items!($($t)*);
+	};
+	(pub $name:ident get($getfn:ident) : $key:expr => default $ty:ty; $($t:tt)*) => {
+		__storage_items_internal!((pub) ($getfn) ($ty) (get_or_default) (take_or_default) $name: $key => $ty);
+		storage_items!($($t)*);
+	};
+	($name:ident get($getfn:ident) : $key:expr => required $ty:ty; $($t:tt)*) => {
+		__storage_items_internal!(() ($getfn) ($ty) (require) (take_or_panic) $name: $key => $ty);
+		storage_items!($($t)*);
+	};
+	(pub $name:ident get($getfn:ident) : $key:expr => required $ty:ty; $($t:tt)*) => {
+		__storage_items_internal!((pub) ($getfn) ($ty) (require) (take_or_panic) $name: $key => $ty);
+		storage_items!($($t)*);
+	};
+
 	// maps
-	($name: ident: $prefix: expr => map [$kty: ty => $ty:ty]; $($t:tt)*) => {
-		__storage_items_internal!(() $name: $prefix => map [$kty => $ty]);
+	($name:ident : $prefix:expr => map [$kty: ty => $ty:ty]; $($t:tt)*) => {
+		__storage_items_internal!(() () (Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]);
+		storage_items!($($t)*);
+	};
+	(pub $name:ident : $prefix:expr => map [$kty: ty => $ty:ty]; $($t:tt)*) => {
+		__storage_items_internal!((pub) () (Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]);
+		storage_items!($($t)*);
+	};
+	($name:ident : $prefix:expr => default map [$kty: ty => $ty:ty]; $($t:tt)*) => {
+		__storage_items_internal!(() () ($ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]);
+		storage_items!($($t)*);
+	};
+	(pub $name:ident : $prefix:expr => default map [$kty: ty => $ty:ty]; $($t:tt)*) => {
+		__storage_items_internal!((pub) () ($ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]);
+		storage_items!($($t)*);
+	};
+	($name:ident : $prefix:expr => required map [$kty: ty => $ty:ty]; $($t:tt)*) => {
+		__storage_items_internal!(() () ($ty) (require) (take_or_panic) $name: $prefix => map [$kty => $ty]);
+		storage_items!($($t)*);
+	};
+	(pub $name:ident : $prefix:expr => required map [$kty: ty => $ty:ty]; $($t:tt)*) => {
+		__storage_items_internal!((pub) () ($ty) (require) (take_or_panic) $name: $prefix => map [$kty => $ty]);
+		storage_items!($($t)*);
+	};
+
+	($name:ident get($getfn:ident) : $prefix:expr => map [$kty: ty => $ty:ty]; $($t:tt)*) => {
+		__storage_items_internal!(() ($getfn) (Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]);
+		storage_items!($($t)*);
+	};
+	(pub $name:ident get($getfn:ident) : $prefix:expr => map [$kty: ty => $ty:ty]; $($t:tt)*) => {
+		__storage_items_internal!((pub) ($getfn) (Option<$ty>) (get) (take) $name: $prefix => map [$kty => $ty]);
 		storage_items!($($t)*);
 	};
-	(pub $name: ident: $prefix: expr => map [$kty: ty => $ty:ty]; $($t:tt)*) => {
-		__storage_items_internal!((pub) $name: $prefix => map [$kty => $ty]);
+	($name:ident get($getfn:ident) : $prefix:expr => default map [$kty: ty => $ty:ty]; $($t:tt)*) => {
+		__storage_items_internal!(() ($getfn) ($ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]);
 		storage_items!($($t)*);
 	};
+	(pub $name:ident get($getfn:ident) : $prefix:expr => default map [$kty: ty => $ty:ty]; $($t:tt)*) => {
+		__storage_items_internal!((pub) ($getfn) ($ty) (get_or_default) (take_or_default) $name: $prefix => map [$kty => $ty]);
+		storage_items!($($t)*);
+	};
+	($name:ident get($getfn:ident) : $prefix:expr => required map [$kty: ty => $ty:ty]; $($t:tt)*) => {
+		__storage_items_internal!(() ($getfn) ($ty) (require) (take_or_panic) $name: $prefix => map [$kty => $ty]);
+		storage_items!($($t)*);
+	};
+	(pub $name:ident get($getfn:ident) : $prefix:expr => required map [$kty: ty => $ty:ty]; $($t:tt)*) => {
+		__storage_items_internal!((pub) ($getfn) ($ty) (require) (take_or_panic) $name: $prefix => map [$kty => $ty]);
+		storage_items!($($t)*);
+	};
+
+
 	// lists
-	($name: ident: $prefix: expr => list [$ty:ty]; $($t:tt)*) => {
+	($name:ident : $prefix:expr => list [$ty:ty]; $($t:tt)*) => {
 		__storage_items_internal!(() $name: $prefix => list [$ty]);
 		storage_items!($($t)*);
 	};
-	(pub $name: ident: $prefix: expr => list [$ty:ty]; $($t:tt)*) => {
+	(pub $name:ident : $prefix:expr => list [$ty:ty]; $($t:tt)*) => {
 		__storage_items_internal!((pub) $name: $prefix => list [$ty]);
 		storage_items!($($t)*);
 	};
@@ -424,11 +455,15 @@ mod tests {
 	use super::*;
 
 	impl Storage for RefCell<HashMap<Vec<u8>, Vec<u8>>> {
-		fn load<T: Slicable>(&self, key: &[u8]) -> Option<T> {
+		fn exists(&self, key: &[u8]) -> bool {
+			self.borrow_mut().get(key).is_some()
+		}
+
+		fn get<T: Slicable>(&self, key: &[u8]) -> Option<T> {
 			self.borrow_mut().get(key).map(|v| T::decode(&mut &v[..]).unwrap())
 		}
 
-		fn store<T: Slicable>(&self, key: &[u8], val: &T) {
+		fn put<T: Slicable>(&self, key: &[u8], val: &T) {
 			self.borrow_mut().insert(key.to_owned(), val.encode());
 		}
 
@@ -443,14 +478,14 @@ mod tests {
 		Map: b"c:" => map [u32 => [u8; 32]];
 	}
 
-    #[test]
+	#[test]
 	fn value() {
 		let storage = RefCell::new(HashMap::new());
-		assert!(Value::load(&storage).is_none());
-		Value::store(&100_000, &storage);
-		assert_eq!(Value::load(&storage), Some(100_000));
+		assert!(Value::get(&storage).is_none());
+		Value::put(&100_000, &storage);
+		assert_eq!(Value::get(&storage), Some(100_000));
 		Value::kill(&storage);
-		assert!(Value::load(&storage).is_none());
+		assert!(Value::get(&storage).is_none());
 	}
 
 	#[test]
diff --git a/substrate/substrate/runtime-support/src/storage/mod.rs b/substrate/substrate/runtime-support/src/storage/mod.rs
index fb4aa17487360e52efc10d79b86fdf83d5af3c2f..635a30848f5a24f9c303f3ed90234a81ab68c78d 100644
--- a/substrate/substrate/runtime-support/src/storage/mod.rs
+++ b/substrate/substrate/runtime-support/src/storage/mod.rs
@@ -47,7 +47,7 @@ pub fn get<T: Slicable + Sized>(key: &[u8]) -> Option<T> {
 			key: &key[..],
 			pos: 0,
 		};
-		Slicable::decode(&mut input).expect("stroage is not null, therefore must be a valid type")
+		Slicable::decode(&mut input).expect("storage is not null, therefore must be a valid type")
 	})
 }
 
@@ -122,58 +122,78 @@ pub fn put_raw(key: &[u8], value: &[u8]) {
 	runtime_io::set_storage(&twox_128(key)[..], value)
 }
 
-struct RuntimeStorage;
+/// The underlying runtime storage.
+pub struct RuntimeStorage;
 
 impl ::GenericStorage for RuntimeStorage {
+	fn exists(&self, key: &[u8]) -> bool {
+		super::storage::exists(key)
+	}
+
 	/// Load the bytes of a key from storage. Can panic if the type is incorrect.
-	fn load<T: Slicable>(&self, key: &[u8]) -> Option<T> {
-		get(key)
+	fn get<T: Slicable>(&self, key: &[u8]) -> Option<T> {
+		super::storage::get(key)
 	}
 
 	/// Put a value in under a key.
-	fn store<T: Slicable>(&self, key: &[u8], val: &T) {
-		put(key, val)
+	fn put<T: Slicable>(&self, key: &[u8], val: &T) {
+		super::storage::put(key, val)
 	}
 
 	/// Remove the bytes of a key from storage.
 	fn kill(&self, key: &[u8]) {
-		kill(key)
+		super::storage::kill(key)
 	}
 
 	/// Take a value from storage, deleting it after reading.
 	fn take<T: Slicable>(&self, key: &[u8]) -> Option<T> {
-		take(key)
+		super::storage::take(key)
 	}
 }
 
 /// A trait for working with macro-generated storage values under the substrate storage API.
 pub trait StorageValue<T: Slicable> {
+	/// The type that get/take return.
+	type Query;
+
 	/// Get the storage key.
 	fn key() -> &'static [u8];
+
+	/// Does the value (explicitly) exist in storage?
+	fn exists() -> bool;
+
 	/// Load the value from the provided storage instance.
-	fn load() -> Option<T>;
+	fn get() -> Self::Query;
+
 	/// Store a value under this key into the provded storage instance.
-	fn store(val: &T);
+	fn put<Arg: Borrow<T>>(val: Arg);
+
 	/// Clear the storage value.
 	fn kill();
+
 	/// Take a value from storage, removing it afterwards.
-	fn take() -> Option<T>;
+	fn take() -> Self::Query;
 }
 
 impl<T: Slicable, U> StorageValue<T> for U where U: generator::StorageValue<T> {
+	type Query = U::Query;
+
 	fn key() -> &'static [u8] {
 		<U as generator::StorageValue<T>>::key()
 	}
-	fn load() -> Option<T> {
-		U::load(&RuntimeStorage)
+	fn exists() -> bool {
+		U::exists(&RuntimeStorage)
+	}
+	fn get() -> Self::Query {
+		U::get(&RuntimeStorage)
 	}
-	fn store(val: &T) {
-		U::store(val, &RuntimeStorage)
+	fn put<Arg: Borrow<T>>(val: Arg) {
+		U::put(val.borrow(), &RuntimeStorage)
 	}
 	fn kill() {
 		U::kill(&RuntimeStorage)
 	}
-	fn take() -> Option<T> {
+	fn take() -> Self::Query {
 		U::take(&RuntimeStorage)
 	}
 }
@@ -196,7 +216,7 @@ pub trait StorageList<T: Slicable> {
 	fn set_items(items: &[T]);
 
 	/// Set the item at the given index.
-	fn set_item(index: u32, item: &T);
+	fn set_item<Arg: Borrow<T>>(index: u32, val: Arg);
 
 	/// Load the value at given index. Returns `None` if the index is out-of-bounds.
 	fn get(index: u32) -> Option<T>;
@@ -229,8 +249,8 @@ impl<T: Slicable, U> StorageList<T> for U where U: generator::StorageList<T> {
 		U::set_items(items, &RuntimeStorage)
 	}
 
-	fn set_item(index: u32, item: &T) {
-		U::set_item(index, item, &RuntimeStorage)
+	fn set_item<Arg: Borrow<T>>(index: u32, val: Arg) {
+		U::set_item(index, val.borrow(), &RuntimeStorage)
 	}
 
 	fn get(index: u32) -> Option<T> {
@@ -248,48 +268,60 @@ impl<T: Slicable, U> StorageList<T> for U where U: generator::StorageList<T> {
 
 /// A strongly-typed map in storage.
 pub trait StorageMap<K: Slicable, V: Slicable> {
+	/// The type that get/take return.
+	type Query;
+
 	/// Get the prefix key in storage.
 	fn prefix() -> &'static [u8];
 
 	/// Get the storage key used to fetch a value corresponding to a specific key.
-	fn key_for(x: &K) -> Vec<u8>;
+	fn key_for<KeyArg: Borrow<K>>(key: KeyArg) -> Vec<u8>;
+
+	/// Does the value (explicitly) exist in storage?
+	fn exists<KeyArg: Borrow<K>>(key: KeyArg) -> bool;
 
 	/// Load the value associated with the given key from the map.
-	fn get(key: &K) -> Option<V>;
+	fn get<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query;
 
 	/// Store a value to be associated with the given key from the map.
-	fn insert(key: &K, val: &V);
+	fn insert<KeyArg: Borrow<K>, ValArg: Borrow<V>>(key: KeyArg, val: ValArg);
 
 	/// Remove the value under a key.
-	fn remove(key: &K);
+	fn remove<KeyArg: Borrow<K>>(key: KeyArg);
 
 	/// Take the value under a key.
-	fn take(key: &K) -> Option<V>;
+	fn take<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query;
 }
 
 impl<K: Slicable, V: Slicable, U> StorageMap<K, V> for U where U: generator::StorageMap<K, V> {
+	type Query = U::Query;
+
 	fn prefix() -> &'static [u8] {
 		<U as generator::StorageMap<K, V>>::prefix()
 	}
 
-	fn key_for(item: &K) -> Vec<u8> {
-		<U as generator::StorageMap<K, V>>::key_for(item)
+	fn key_for<KeyArg: Borrow<K>>(key: KeyArg) -> Vec<u8> {
+		<U as generator::StorageMap<K, V>>::key_for(key.borrow())
+	}
+
+	fn exists<KeyArg: Borrow<K>>(key: KeyArg) -> bool {
+		U::exists(key.borrow(), &RuntimeStorage)
 	}
 
-	fn get(key: &K) -> Option<V> {
-		U::get(key, &RuntimeStorage)
+	fn get<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query {
+		U::get(key.borrow(), &RuntimeStorage)
 	}
 
-	fn insert(key: &K, val: &V) {
-		U::insert(key, val, &RuntimeStorage)
+	fn insert<KeyArg: Borrow<K>, ValArg: Borrow<V>>(key: KeyArg, val: ValArg) {
+		U::insert(key.borrow(), val.borrow(), &RuntimeStorage)
 	}
 
-	fn remove(key: &K) {
-		U::remove(key, &RuntimeStorage)
+	fn remove<KeyArg: Borrow<K>>(key: KeyArg) {
+		U::remove(key.borrow(), &RuntimeStorage)
 	}
 
-	fn take(key: &K) -> Option<V> {
-		U::take(key, &RuntimeStorage)
+	fn take<KeyArg: Borrow<K>>(key: KeyArg) -> Self::Query {
+		U::take(key.borrow(), &RuntimeStorage)
 	}
 }
 
diff --git a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm
index b7150f9c4c350640c84ef908d233c9c9618f2dc4..63c43ca592414e834452fb3a16a0a360a8869acd 100644
Binary files a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ
diff --git a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm
index e7533bbd880e220b5de92621dde2562f93cf6e01..b43b00f68772fcf6a1054abe5dc4bc26451cf00c 100644
Binary files a/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm and b/substrate/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm differ