diff --git a/Cargo.lock b/Cargo.lock
index 2d4485c92211b7bdac97e383e71ff82748471812..0d41be5c9bd10624050913ab40f387afb572106e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -11472,6 +11472,7 @@ dependencies = [
  "paste",
  "polkavm 0.10.0",
  "pretty_assertions",
+ "rlp",
  "scale-info",
  "serde",
  "sp-api",
@@ -11494,6 +11495,8 @@ dependencies = [
  "frame-system",
  "parity-wasm",
  "polkavm-linker 0.10.0",
+ "sp-core",
+ "sp-io",
  "sp-runtime",
  "tempfile",
  "toml 0.8.12",
@@ -16924,9 +16927,9 @@ dependencies = [
 
 [[package]]
 name = "ruint"
-version = "1.11.1"
+version = "1.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825"
+checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286"
 dependencies = [
  "alloy-rlp",
  "ark-ff 0.3.0",
@@ -16948,9 +16951,9 @@ dependencies = [
 
 [[package]]
 name = "ruint-macro"
-version = "1.1.0"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09"
+checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18"
 
 [[package]]
 name = "rustc-demangle"
diff --git a/prdoc/pr_5548.prdoc b/prdoc/pr_5548.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..69e79213fa294864068af09692e729a89c5df281
--- /dev/null
+++ b/prdoc/pr_5548.prdoc
@@ -0,0 +1,16 @@
+title: Use H160 when interfacing with contracts
+
+doc:
+  - audience: Runtime Dev
+    description: |
+     When interfacing with a contract we now use the native ethereum address
+     type and map it to AccountId32 when interfacing with the rest
+     of substrate.
+
+crates:
+  - name: pallet-revive
+    bump: major
+  - name: pallet-revive-fixtures
+    bump: major
+  - name: pallet-revive-mock-network
+    bump: major
diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index ef5c52bf6e6ec88fa7db507e8900e988871ba209..7ef0779dd9b842de7b2b39a508f3d76f7dcdaa82 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -91,7 +91,7 @@ use sp_consensus_beefy::{
 	mmr::MmrLeafVersion,
 };
 use sp_consensus_grandpa::AuthorityId as GrandpaId;
-use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
+use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H160};
 use sp_inherents::{CheckInherentsResult, InherentData};
 use sp_runtime::{
 	create_runtime_str,
@@ -1392,7 +1392,7 @@ impl pallet_revive::Config for Runtime {
 	type WeightPrice = pallet_transaction_payment::Pallet<Self>;
 	type WeightInfo = pallet_revive::weights::SubstrateWeight<Self>;
 	type ChainExtension = ();
-	type AddressGenerator = pallet_revive::DefaultAddressGenerator;
+	type AddressMapper = pallet_revive::DefaultAddressMapper;
 	type MaxCodeLen = ConstU32<{ 123 * 1024 }>;
 	type RuntimeMemory = ConstU32<{ 128 * 1024 * 1024 }>;
 	type PVFMemory = ConstU32<{ 512 * 1024 * 1024 }>;
@@ -2988,11 +2988,11 @@ impl_runtime_apis! {
 		}
 	}
 
-	impl pallet_revive::ReviveApi<Block, AccountId, Balance, BlockNumber, Hash, EventRecord> for Runtime
+	impl pallet_revive::ReviveApi<Block, AccountId, Balance, BlockNumber, EventRecord> for Runtime
 	{
 		fn call(
 			origin: AccountId,
-			dest: AccountId,
+			dest: H160,
 			value: Balance,
 			gas_limit: Option<Weight>,
 			storage_deposit_limit: Option<Balance>,
@@ -3015,10 +3015,10 @@ impl_runtime_apis! {
 			value: Balance,
 			gas_limit: Option<Weight>,
 			storage_deposit_limit: Option<Balance>,
-			code: pallet_revive::Code<Hash>,
+			code: pallet_revive::Code,
 			data: Vec<u8>,
-			salt: Vec<u8>,
-		) -> pallet_revive::ContractInstantiateResult<AccountId, Balance, EventRecord>
+			salt: [u8; 32],
+		) -> pallet_revive::ContractInstantiateResult<Balance, EventRecord>
 		{
 			Revive::bare_instantiate(
 				RuntimeOrigin::signed(origin),
@@ -3037,7 +3037,7 @@ impl_runtime_apis! {
 			origin: AccountId,
 			code: Vec<u8>,
 			storage_deposit_limit: Option<Balance>,
-		) -> pallet_revive::CodeUploadResult<Hash, Balance>
+		) -> pallet_revive::CodeUploadResult<Balance>
 		{
 			Revive::bare_upload_code(
 				RuntimeOrigin::signed(origin),
@@ -3047,8 +3047,8 @@ impl_runtime_apis! {
 		}
 
 		fn get_storage(
-			address: AccountId,
-			key: Vec<u8>,
+			address: H160,
+			key: [u8; 32],
 		) -> pallet_revive::GetStorageResult {
 			Revive::get_storage(
 				address,
diff --git a/substrate/frame/revive/Cargo.toml b/substrate/frame/revive/Cargo.toml
index 747c2283e21747845d3ab363bca09b73cebf6623..6b7542e8920284cbd2906b938be66e6889b84b97 100644
--- a/substrate/frame/revive/Cargo.toml
+++ b/substrate/frame/revive/Cargo.toml
@@ -18,6 +18,7 @@ workspace = true
 targets = ["x86_64-unknown-linux-gnu"]
 
 [dependencies]
+environmental = { workspace = true }
 paste = { workspace = true }
 polkavm = { version = "0.10.0", default-features = false }
 bitflags = { workspace = true }
@@ -29,9 +30,9 @@ scale-info = { features = ["derive"], workspace = true }
 log = { workspace = true }
 serde = { optional = true, features = ["derive"], workspace = true, default-features = true }
 impl-trait-for-tuples = { workspace = true }
+rlp = { workspace = true }
 
-# Substrate Dependencies
-environmental = { workspace = true }
+# Polkadot SDK Dependencies
 frame-benchmarking = { optional = true, workspace = true }
 frame-support = { workspace = true }
 frame-system = { workspace = true }
@@ -54,10 +55,7 @@ pretty_assertions = { workspace = true }
 wat = { workspace = true }
 pallet-revive-fixtures = { workspace = true, default-features = true }
 
-# Polkadot Dependencies
-xcm-builder = { workspace = true, default-features = true }
-
-# Substrate Dependencies
+# Polkadot SDK Dependencies
 pallet-balances = { workspace = true, default-features = true }
 pallet-timestamp = { workspace = true, default-features = true }
 pallet-message-queue = { workspace = true, default-features = true }
@@ -66,6 +64,7 @@ pallet-assets = { workspace = true, default-features = true }
 pallet-proxy = { workspace = true, default-features = true }
 sp-keystore = { workspace = true, default-features = true }
 sp-tracing = { workspace = true, default-features = true }
+xcm-builder = { workspace = true, default-features = true }
 
 [features]
 default = ["std"]
@@ -86,6 +85,7 @@ std = [
 	"pallet-timestamp/std",
 	"pallet-utility/std",
 	"polkavm/std",
+	"rlp/std",
 	"scale-info/std",
 	"serde",
 	"sp-api/std",
diff --git a/substrate/frame/revive/fixtures/Cargo.toml b/substrate/frame/revive/fixtures/Cargo.toml
index 9e54acdace709103be12905e39283e5e776e9b29..db284c7cc062fc98d5b61d6b432932b339c71044 100644
--- a/substrate/frame/revive/fixtures/Cargo.toml
+++ b/substrate/frame/revive/fixtures/Cargo.toml
@@ -12,15 +12,17 @@ workspace = true
 
 [dependencies]
 frame-system = { workspace = true, default-features = true, optional = true }
+sp-core = { workspace = true, default-features = true, optional = true }
+sp-io = { workspace = true, default-features = true, optional = true }
 sp-runtime = { workspace = true, default-features = true, optional = true }
-anyhow = { workspace = true }
+anyhow = { workspace = true, default-features = true, optional = true }
 
 [build-dependencies]
 parity-wasm = { workspace = true }
 tempfile = { workspace = true }
 toml = { workspace = true }
 polkavm-linker = { version = "0.10.0" }
-anyhow = { workspace = true }
+anyhow = { workspace = true, default-features = true }
 
 [features]
 default = ["std"]
@@ -30,7 +32,9 @@ default = ["std"]
 riscv = []
 # only when std is enabled all fixtures are available
 std = [
-	"anyhow/std",
+	"anyhow",
 	"frame-system",
+	"sp-core",
+	"sp-io",
 	"sp-runtime",
 ]
diff --git a/substrate/frame/revive/fixtures/contracts/call.rs b/substrate/frame/revive/fixtures/contracts/call.rs
index a75aee65c20525f19ed386d67c7dee020de2a66b..73f427650c2021dd0ddd894639aedf9b125aaf2e 100644
--- a/substrate/frame/revive/fixtures/contracts/call.rs
+++ b/substrate/frame/revive/fixtures/contracts/call.rs
@@ -31,7 +31,7 @@ pub extern "C" fn deploy() {}
 pub extern "C" fn call() {
 	input!(
 		callee_input: [u8; 4],
-		callee_addr: [u8; 32],
+		callee_addr: [u8; 20],
 	);
 
 	// Call the callee
diff --git a/substrate/frame/revive/fixtures/contracts/call_return_code.rs b/substrate/frame/revive/fixtures/contracts/call_return_code.rs
index 32654d59ef1f5e6e4aeb5ac7370288d0edff3397..e8f995cffc7f5985a82e890e406d8203280467b3 100644
--- a/substrate/frame/revive/fixtures/contracts/call_return_code.rs
+++ b/substrate/frame/revive/fixtures/contracts/call_return_code.rs
@@ -33,7 +33,7 @@ pub extern "C" fn deploy() {}
 pub extern "C" fn call() {
 	input!(
 		100,
-		callee_addr: [u8; 32],
+		callee_addr: [u8; 20],
 		input: [u8],
 	);
 
diff --git a/substrate/frame/revive/fixtures/contracts/call_runtime_and_call.rs b/substrate/frame/revive/fixtures/contracts/call_runtime_and_call.rs
index 1323c8c5d55db4e71978e1bb7e2586f7cb739c96..f3d2ece213279ed7c7a07e7cf13fa1149cc669be 100644
--- a/substrate/frame/revive/fixtures/contracts/call_runtime_and_call.rs
+++ b/substrate/frame/revive/fixtures/contracts/call_runtime_and_call.rs
@@ -31,7 +31,7 @@ pub extern "C" fn call() {
 	input!(
 		512,
 		callee_input: [u8; 4],
-		callee_addr: [u8; 32],
+		callee_addr: [u8; 20],
 		call: [u8],
 	);
 
diff --git a/substrate/frame/revive/fixtures/contracts/call_with_flags_and_value.rs b/substrate/frame/revive/fixtures/contracts/call_with_flags_and_value.rs
index a078162d7995547e914a2964b827f7eaee574552..15c1124eeaee83458e7c3edc5dc8d6489da15207 100644
--- a/substrate/frame/revive/fixtures/contracts/call_with_flags_and_value.rs
+++ b/substrate/frame/revive/fixtures/contracts/call_with_flags_and_value.rs
@@ -31,7 +31,7 @@ pub extern "C" fn deploy() {}
 pub extern "C" fn call() {
 	input!(
 		256,
-		callee_addr: [u8; 32],
+		callee_addr: [u8; 20],
 		flags: u32,
 		value: u64,
 		forwarded_input: [u8],
diff --git a/substrate/frame/revive/fixtures/contracts/call_with_limit.rs b/substrate/frame/revive/fixtures/contracts/call_with_limit.rs
index a5356924f24f14926112de5562b1f3a96c7be638..985df6724110aa3e400d50d7f1764e0e8cfbaedd 100644
--- a/substrate/frame/revive/fixtures/contracts/call_with_limit.rs
+++ b/substrate/frame/revive/fixtures/contracts/call_with_limit.rs
@@ -32,7 +32,7 @@ pub extern "C" fn deploy() {}
 pub extern "C" fn call() {
 	input!(
 		256,
-		callee_addr: [u8; 32],
+		callee_addr: [u8; 20],
 		ref_time: u64,
 		proof_size: u64,
 		forwarded_input: [u8],
diff --git a/substrate/frame/revive/fixtures/contracts/caller_contract.rs b/substrate/frame/revive/fixtures/contracts/caller_contract.rs
index 2fa11df82d04a605e7020deda31e8ad6ba4045f9..dceab813f88fa785f69843bcf8b5943129cb0d42 100644
--- a/substrate/frame/revive/fixtures/contracts/caller_contract.rs
+++ b/substrate/frame/revive/fixtures/contracts/caller_contract.rs
@@ -33,7 +33,7 @@ pub extern "C" fn call() {
 	// The value to transfer on instantiation and calls. Chosen to be greater than existential
 	// deposit.
 	let value = 32768u64.to_le_bytes();
-	let salt = [0u8; 0];
+	let salt = [0u8; 32];
 
 	// Callee will use the first 4 bytes of the input to return an exit status.
 	let input = [0u8, 1, 34, 51, 68, 85, 102, 119];
@@ -72,7 +72,7 @@ pub extern "C" fn call() {
 	assert!(matches!(res, Err(ReturnErrorCode::CalleeTrapped)));
 
 	// Deploy the contract successfully.
-	let mut callee = [0u8; 32];
+	let mut callee = [0u8; 20];
 	let callee = &mut &mut callee[..];
 
 	api::instantiate(
@@ -87,7 +87,7 @@ pub extern "C" fn call() {
 		&salt,
 	)
 	.unwrap();
-	assert_eq!(callee.len(), 32);
+	assert_eq!(callee.len(), 20);
 
 	// Call the new contract and expect it to return failing exit code.
 	let res = api::call(
diff --git a/substrate/frame/revive/fixtures/contracts/create_storage_and_call.rs b/substrate/frame/revive/fixtures/contracts/create_storage_and_call.rs
index d0d3651dfe4d70f899334bf86dc422b55d8e35f1..7a0b497079cd69df7ece5c9b691a93169bf2696d 100644
--- a/substrate/frame/revive/fixtures/contracts/create_storage_and_call.rs
+++ b/substrate/frame/revive/fixtures/contracts/create_storage_and_call.rs
@@ -32,7 +32,7 @@ pub extern "C" fn call() {
 	input!(
 		buffer,
 		input: [u8; 4],
-		callee: [u8; 32],
+		callee: [u8; 20],
 		deposit_limit: [u8; 8],
 	);
 
diff --git a/substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs b/substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs
index 918a4abe6b21c6c243913ca9825b99e9b69765e6..53b9afba77830893b4de5095182d90861c4f7152 100644
--- a/substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs
+++ b/substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs
@@ -36,8 +36,8 @@ pub extern "C" fn call() {
 	);
 
 	let value = 10_000u64.to_le_bytes();
-	let salt = [0u8; 0];
-	let mut address = [0u8; 32];
+	let salt = [0u8; 32];
+	let mut address = [0u8; 20];
 	let address = &mut &mut address[..];
 
 	api::instantiate(
diff --git a/substrate/frame/revive/fixtures/contracts/create_transient_storage_and_call.rs b/substrate/frame/revive/fixtures/contracts/create_transient_storage_and_call.rs
index a2a0e85bcf64f5409b509d32d4813b31659c4a55..8788542a0c5a16539e3318181c2b057078aaa181 100644
--- a/substrate/frame/revive/fixtures/contracts/create_transient_storage_and_call.rs
+++ b/substrate/frame/revive/fixtures/contracts/create_transient_storage_and_call.rs
@@ -35,7 +35,7 @@ pub extern "C" fn call() {
 		buffer,
 		len: u32,
 		input: [u8; 4],
-		callee: [u8; 32],
+		callee: [u8; 20],
 	);
 
 	let rounds = len as usize / BUFFER.len();
diff --git a/substrate/frame/revive/fixtures/contracts/delegate_call_lib.rs b/substrate/frame/revive/fixtures/contracts/delegate_call_lib.rs
index 055760729bd250982ac682e16c550171c0381c0d..921543dced067936e96a7bc56121965c171371f4 100644
--- a/substrate/frame/revive/fixtures/contracts/delegate_call_lib.rs
+++ b/substrate/frame/revive/fixtures/contracts/delegate_call_lib.rs
@@ -44,6 +44,6 @@ pub extern "C" fn call() {
 	assert_eq!(value_transferred, 1337);
 
 	// Assert that ALICE is the caller of the contract.
-	output!(caller, [0u8; 32], api::caller,);
-	assert_eq!(&caller[..], &[1u8; 32]);
+	output!(caller, [0u8; 20], api::caller,);
+	assert_eq!(&caller[..], &[1u8; 20]);
 }
diff --git a/substrate/frame/revive/fixtures/contracts/destroy_and_transfer.rs b/substrate/frame/revive/fixtures/contracts/destroy_and_transfer.rs
index 8b74493a1e38c9c843775c071c573fcf0a961892..b86e761d53e762c36a0adb205c702e949f1e96f7 100644
--- a/substrate/frame/revive/fixtures/contracts/destroy_and_transfer.rs
+++ b/substrate/frame/revive/fixtures/contracts/destroy_and_transfer.rs
@@ -30,9 +30,9 @@ pub extern "C" fn deploy() {
 	input!(code_hash: [u8; 32],);
 
 	let input = [0u8; 0];
-	let mut address = [0u8; 32];
+	let mut address = [0u8; 20];
 	let address = &mut &mut address[..];
-	let salt = [71u8, 17u8];
+	let salt = [47u8; 32];
 
 	api::instantiate(
 		code_hash,
@@ -54,7 +54,7 @@ pub extern "C" fn deploy() {
 #[no_mangle]
 #[polkavm_derive::polkavm_export]
 pub extern "C" fn call() {
-	let mut callee_addr = [0u8; 32];
+	let mut callee_addr = [0u8; 20];
 	let callee_addr = &mut &mut callee_addr[..];
 	api::get_storage(StorageFlags::empty(), &ADDRESS_KEY, callee_addr).unwrap();
 
diff --git a/substrate/frame/revive/fixtures/contracts/locking_delegate_dependency.rs b/substrate/frame/revive/fixtures/contracts/locking_delegate_dependency.rs
index 3ed886b494891f24bc8310cd4f6ecb41439fcff7..2f3e5ae148cb4074d75f2e556fc8b94d119517ee 100644
--- a/substrate/frame/revive/fixtures/contracts/locking_delegate_dependency.rs
+++ b/substrate/frame/revive/fixtures/contracts/locking_delegate_dependency.rs
@@ -23,7 +23,7 @@
 use common::input;
 use uapi::{HostFn, HostFnImpl as api};
 
-const ALICE: [u8; 32] = [1u8; 32];
+const ETH_ALICE: [u8; 20] = [1u8; 20];
 
 /// Load input data and perform the action specified by the input.
 /// If `delegate_call` is true, then delegate call into the contract.
@@ -44,7 +44,7 @@ fn load_input(delegate_call: bool) {
 		},
 		// 3 = Terminate
 		3 => {
-			api::terminate(&ALICE);
+			api::terminate(&ETH_ALICE);
 		},
 		// Everything else is a noop
 		_ => {},
diff --git a/substrate/frame/revive/fixtures/contracts/read_only_call.rs b/substrate/frame/revive/fixtures/contracts/read_only_call.rs
index a62bb205039f859db74eeb8fe1d2fcf331ccff33..ef8bc95f00980ba86f04904da748568ae73f913d 100644
--- a/substrate/frame/revive/fixtures/contracts/read_only_call.rs
+++ b/substrate/frame/revive/fixtures/contracts/read_only_call.rs
@@ -31,7 +31,7 @@ pub extern "C" fn deploy() {}
 pub extern "C" fn call() {
 	input!(
 		256,
-		callee_addr: [u8; 32],
+		callee_addr: [u8; 20],
 		callee_input: [u8],
 	);
 
diff --git a/substrate/frame/revive/fixtures/contracts/self_destruct.rs b/substrate/frame/revive/fixtures/contracts/self_destruct.rs
index 10f33226acf224bacbd718015f8f06f1862d95d9..b0e004018f1003e064a73d28e67919cb138bbafd 100644
--- a/substrate/frame/revive/fixtures/contracts/self_destruct.rs
+++ b/substrate/frame/revive/fixtures/contracts/self_destruct.rs
@@ -21,7 +21,7 @@
 use common::{input, output};
 use uapi::{HostFn, HostFnImpl as api};
 
-const DJANGO: [u8; 32] = [4u8; 32];
+const ETH_DJANGO: [u8; 20] = [4u8; 20];
 
 #[no_mangle]
 #[polkavm_derive::polkavm_export]
@@ -36,7 +36,7 @@ pub extern "C" fn call() {
 	input!(input, 4,);
 
 	if !input.is_empty() {
-		output!(addr, [0u8; 32], api::address,);
+		output!(addr, [0u8; 20], api::address,);
 		api::call(
 			uapi::CallFlags::ALLOW_REENTRY,
 			addr,
@@ -50,6 +50,6 @@ pub extern "C" fn call() {
 		.unwrap();
 	} else {
 		// Try to terminate and give balance to django.
-		api::terminate(&DJANGO);
+		api::terminate(&ETH_DJANGO);
 	}
 }
diff --git a/substrate/frame/revive/fixtures/src/lib.rs b/substrate/frame/revive/fixtures/src/lib.rs
index 1b6103f57aee2c9469a8687b709f1d87ddadd978..54e32130635a4b1fd468a8490138cd4d2a2ac43b 100644
--- a/substrate/frame/revive/fixtures/src/lib.rs
+++ b/substrate/frame/revive/fixtures/src/lib.rs
@@ -21,18 +21,12 @@ extern crate alloc;
 
 /// Load a given wasm module and returns a wasm binary contents along with it's hash.
 #[cfg(feature = "std")]
-pub fn compile_module<T>(
-	fixture_name: &str,
-) -> anyhow::Result<(Vec<u8>, <T::Hashing as sp_runtime::traits::Hash>::Output)>
-where
-	T: frame_system::Config,
-{
-	use sp_runtime::traits::Hash;
+pub fn compile_module(fixture_name: &str) -> anyhow::Result<(Vec<u8>, sp_core::H256)> {
 	let out_dir: std::path::PathBuf = env!("OUT_DIR").into();
 	let fixture_path = out_dir.join(format!("{fixture_name}.polkavm"));
 	let binary = std::fs::read(fixture_path)?;
-	let code_hash = T::Hashing::hash(&binary);
-	Ok((binary, code_hash))
+	let code_hash = sp_io::hashing::keccak_256(&binary);
+	Ok((binary, sp_core::H256(code_hash)))
 }
 
 /// Fixtures used in runtime benchmarks.
diff --git a/substrate/frame/revive/mock-network/src/parachain/contracts_config.rs b/substrate/frame/revive/mock-network/src/parachain/contracts_config.rs
index 49f53ae5bc3d5f581b650335a1fdb155cb696b3e..678e7a44490045f827adc1cfb014be0d80684108 100644
--- a/substrate/frame/revive/mock-network/src/parachain/contracts_config.rs
+++ b/substrate/frame/revive/mock-network/src/parachain/contracts_config.rs
@@ -20,7 +20,7 @@ use frame_support::derive_impl;
 
 #[derive_impl(pallet_revive::config_preludes::TestDefaultConfig)]
 impl pallet_revive::Config for Runtime {
-	type AddressGenerator = pallet_revive::DefaultAddressGenerator;
+	type AddressMapper = pallet_revive::DefaultAddressMapper;
 	type Currency = Balances;
 	type Time = super::Timestamp;
 	type Xcm = pallet_xcm::Pallet<Self>;
diff --git a/substrate/frame/revive/src/address.rs b/substrate/frame/revive/src/address.rs
index 5758daf7b1ff8117d1de5e48e8c1e40490ed7a69..f1bd36dcbba862055e6df616a8982dc980b26732 100644
--- a/substrate/frame/revive/src/address.rs
+++ b/substrate/frame/revive/src/address.rs
@@ -15,54 +15,115 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//! Functions that deal with address derivation.
+//! Functions that deal contract addresses.
 
-use crate::{CodeHash, Config};
-use codec::{Decode, Encode};
-use sp_runtime::traits::{Hash, TrailingZeroInput};
+use alloc::vec::Vec;
+use sp_core::H160;
+use sp_io::hashing::keccak_256;
+use sp_runtime::AccountId32;
 
-/// Provides the contract address generation method.
+/// Map between the native chain account id `T` and an Ethereum [`H160`].
 ///
-/// See [`DefaultAddressGenerator`] for the default implementation.
+/// This trait exists only to emulate specialization for different concrete
+/// native account ids. **Not** to make the mapping user configurable. Hence
+/// the trait is `Sealed` and only one mandatory implementor [`DefaultAddressMapper`]
+/// exists.
 ///
-/// # Note for implementors
-///
-/// 1. Make sure that there are no collisions, different inputs never lead to the same output.
-/// 2. Make sure that the same inputs lead to the same output.
-pub trait AddressGenerator<T: Config> {
-	/// The address of a contract based on the given instantiate parameters.
+/// Please note that we assume that the native account is at least 20 bytes and
+/// only implement this type for a `T` where this is the case. Luckily, this is the
+/// case for all existing runtimes as of right now. Reasing is that this will allow
+/// us to reverse an address -> account_id mapping by just stripping the prefix.
+pub trait AddressMapper<T>: private::Sealed {
+	/// Convert an account id to an ethereum adress.
+	///
+	/// This mapping is **not** required to be reversible.
+	fn to_address(account_id: &T) -> H160;
+
+	/// Convert an ethereum address to a native account id.
 	///
-	/// Changing the formular for an already deployed chain is fine as long as no collisions
-	/// with the old formular. Changes only affect existing contracts.
-	fn contract_address(
-		deploying_address: &T::AccountId,
-		code_hash: &CodeHash<T>,
-		input_data: &[u8],
-		salt: &[u8],
-	) -> T::AccountId;
+	/// This mapping is **required** to be reversible.
+	fn to_account_id(address: &H160) -> T;
+
+	/// Same as [`Self::to_account_id`] but when we know the address is a contract.
+	///
+	/// This is only the case when we just generated the new address.
+	fn to_account_id_contract(address: &H160) -> T;
 }
 
-/// Default address generator.
-///
-/// This is the default address generator used by contract instantiation. Its result
-/// is only dependent on its inputs. It can therefore be used to reliably predict the
-/// address of a contract. This is akin to the formula of eth's CREATE2 opcode. There
-/// is no CREATE equivalent because CREATE2 is strictly more powerful.
-/// Formula:
-/// `hash("contract_addr_v1" ++ deploying_address ++ code_hash ++ input_data ++ salt)`
-pub struct DefaultAddressGenerator;
-
-impl<T: Config> AddressGenerator<T> for DefaultAddressGenerator {
-	/// Formula: `hash("contract_addr_v1" ++ deploying_address ++ code_hash ++ input_data ++ salt)`
-	fn contract_address(
-		deploying_address: &T::AccountId,
-		code_hash: &CodeHash<T>,
-		input_data: &[u8],
-		salt: &[u8],
-	) -> T::AccountId {
-		let entropy = (b"contract_addr_v1", deploying_address, code_hash, input_data, salt)
-			.using_encoded(T::Hashing::hash);
-		Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref()))
-			.expect("infinite length input; no invalid inputs for type; qed")
+mod private {
+	pub trait Sealed {}
+	impl Sealed for super::DefaultAddressMapper {}
+}
+
+/// The only implementor for `AddressMapper`.
+pub enum DefaultAddressMapper {}
+
+impl AddressMapper<AccountId32> for DefaultAddressMapper {
+	fn to_address(account_id: &AccountId32) -> H160 {
+		H160::from_slice(&<AccountId32 as AsRef<[u8; 32]>>::as_ref(&account_id)[..20])
+	}
+
+	fn to_account_id(address: &H160) -> AccountId32 {
+		let mut account_id = AccountId32::new([0xEE; 32]);
+		<AccountId32 as AsMut<[u8; 32]>>::as_mut(&mut account_id)[..20]
+			.copy_from_slice(address.as_bytes());
+		account_id
+	}
+
+	fn to_account_id_contract(address: &H160) -> AccountId32 {
+		Self::to_account_id(address)
+	}
+}
+
+/// Determine the address of a contract using CREATE semantics.
+#[allow(dead_code)]
+pub fn create1(deployer: &H160, nonce: u64) -> H160 {
+	let mut list = rlp::RlpStream::new_list(2);
+	list.append(&deployer.as_bytes());
+	list.append(&nonce);
+	let hash = keccak_256(&list.out());
+	H160::from_slice(&hash[12..])
+}
+
+/// Determine the address of a contract using the CREATE2 semantics.
+pub fn create2(deployer: &H160, code: &[u8], input_data: &[u8], salt: &[u8; 32]) -> H160 {
+	let init_code_hash = {
+		let init_code: Vec<u8> = code.into_iter().chain(input_data).cloned().collect();
+		keccak_256(init_code.as_ref())
+	};
+	let mut bytes = [0; 85];
+	bytes[0] = 0xff;
+	bytes[1..21].copy_from_slice(deployer.as_bytes());
+	bytes[21..53].copy_from_slice(salt);
+	bytes[53..85].copy_from_slice(&init_code_hash);
+	let hash = keccak_256(&bytes);
+	H160::from_slice(&hash[12..])
+}
+
+#[cfg(test)]
+mod test {
+	use super::*;
+	use crate::test_utils::ALICE_ADDR;
+	use sp_core::{hex2array, H160};
+
+	#[test]
+	fn create1_works() {
+		assert_eq!(
+			create1(&ALICE_ADDR, 1u64),
+			H160(hex2array!("c851da37e4e8d3a20d8d56be2963934b4ad71c3b")),
+		)
+	}
+
+	#[test]
+	fn create2_works() {
+		assert_eq!(
+			create2(
+				&ALICE_ADDR,
+				&hex2array!("600060005560016000"),
+				&hex2array!("55"),
+				&hex2array!("1234567890123456789012345678901234567890123456789012345678901234")
+			),
+			H160(hex2array!("7f31e795e5836a19a8f919ab5a9de9a197ecd2b6")),
+		)
 	}
 }
diff --git a/substrate/frame/revive/src/benchmarking/call_builder.rs b/substrate/frame/revive/src/benchmarking/call_builder.rs
index 654ba3de4f729756844415010b3b127732f5b918..c000817a8a395530786e1825c8c28f247183140c 100644
--- a/substrate/frame/revive/src/benchmarking/call_builder.rs
+++ b/substrate/frame/revive/src/benchmarking/call_builder.rs
@@ -16,6 +16,7 @@
 // limitations under the License.
 
 use crate::{
+	address::AddressMapper,
 	benchmarking::{default_deposit_limit, Contract, WasmModule},
 	exec::{ExportedFunction, Ext, Key, Stack},
 	storage::meter::Meter,
@@ -59,7 +60,7 @@ where
 	<BalanceOf<T> as HasCompact>::Type: Clone + Eq + PartialEq + Debug + TypeInfo + Encode,
 {
 	/// Setup a new call for the given module.
-	pub fn new(module: WasmModule<T>) -> Self {
+	pub fn new(module: WasmModule) -> Self {
 		let contract = Contract::<T>::new(module.clone(), vec![]).unwrap();
 		let dest = contract.account_id.clone();
 		let origin = Origin::from_account_id(contract.caller.clone());
@@ -74,7 +75,10 @@ where
 		// Whitelist the contract's contractInfo as it is already accounted for in the call
 		// benchmark
 		benchmarking::add_to_whitelist(
-			crate::ContractInfoOf::<T>::hashed_key_for(&contract.account_id).into(),
+			crate::ContractInfoOf::<T>::hashed_key_for(&T::AddressMapper::to_address(
+				&contract.account_id,
+			))
+			.into(),
 		);
 
 		Self {
@@ -138,7 +142,7 @@ where
 	/// Build the call stack.
 	pub fn ext(&mut self) -> (StackExt<'_, T>, WasmBlob<T>) {
 		let mut ext = StackExt::bench_new_call(
-			self.dest.clone(),
+			T::AddressMapper::to_address(&self.dest),
 			self.origin.clone(),
 			&mut self.gas_meter,
 			&mut self.storage_meter,
diff --git a/substrate/frame/revive/src/benchmarking/code.rs b/substrate/frame/revive/src/benchmarking/code.rs
index eba4710d8a2c50a8bc6b894c80cd933a556c22c5..ede3bb69b11bbcf1e631384fdaec6e02a3e5561f 100644
--- a/substrate/frame/revive/src/benchmarking/code.rs
+++ b/substrate/frame/revive/src/benchmarking/code.rs
@@ -24,19 +24,19 @@
 //! we define this simple definition of a contract that can be passed to `create_code` that
 //! compiles it down into a `WasmModule` that can be used as a contract's code.
 
-use crate::Config;
 use alloc::vec::Vec;
 use pallet_revive_fixtures::bench as bench_fixtures;
-use sp_runtime::traits::Hash;
+use sp_core::H256;
+use sp_io::hashing::keccak_256;
 
 /// A wasm module ready to be put on chain.
 #[derive(Clone)]
-pub struct WasmModule<T: Config> {
+pub struct WasmModule {
 	pub code: Vec<u8>,
-	pub hash: <T::Hashing as Hash>::Output,
+	pub hash: H256,
 }
 
-impl<T: Config> WasmModule<T> {
+impl WasmModule {
 	/// Return a contract code that does nothing.
 	pub fn dummy() -> Self {
 		Self::new(bench_fixtures::DUMMY.to_vec())
@@ -63,7 +63,7 @@ impl<T: Config> WasmModule<T> {
 	}
 
 	fn new(code: Vec<u8>) -> Self {
-		let hash = T::Hashing::hash(&code);
-		Self { code, hash }
+		let hash = keccak_256(&code);
+		Self { code, hash: H256(hash) }
 	}
 }
diff --git a/substrate/frame/revive/src/benchmarking/mod.rs b/substrate/frame/revive/src/benchmarking/mod.rs
index b4bd028d6f032500fc6a4d33be34b5536595d17f..409d53b8a0627d79ce0422e99da1c79314103e3e 100644
--- a/substrate/frame/revive/src/benchmarking/mod.rs
+++ b/substrate/frame/revive/src/benchmarking/mod.rs
@@ -65,7 +65,7 @@ const UNBALANCED_TRIE_LAYERS: u32 = 20;
 struct Contract<T: Config> {
 	caller: T::AccountId,
 	account_id: T::AccountId,
-	addr: AccountIdLookupOf<T>,
+	addr: T::AccountId,
 }
 
 impl<T> Contract<T>
@@ -74,14 +74,14 @@ where
 	<BalanceOf<T> as HasCompact>::Type: Clone + Eq + PartialEq + Debug + TypeInfo + Encode,
 {
 	/// Create new contract and use a default account id as instantiator.
-	fn new(module: WasmModule<T>, data: Vec<u8>) -> Result<Contract<T>, &'static str> {
+	fn new(module: WasmModule, data: Vec<u8>) -> Result<Contract<T>, &'static str> {
 		Self::with_index(0, module, data)
 	}
 
 	/// Create new contract and use an account id derived from the supplied index as instantiator.
 	fn with_index(
 		index: u32,
-		module: WasmModule<T>,
+		module: WasmModule,
 		data: Vec<u8>,
 	) -> Result<Contract<T>, &'static str> {
 		Self::with_caller(account("instantiator", index, 0), module, data)
@@ -90,11 +90,11 @@ where
 	/// Create new contract and use the supplied `caller` as instantiator.
 	fn with_caller(
 		caller: T::AccountId,
-		module: WasmModule<T>,
+		module: WasmModule,
 		data: Vec<u8>,
 	) -> Result<Contract<T>, &'static str> {
 		T::Currency::set_balance(&caller, caller_funding::<T>());
-		let salt = vec![0xff];
+		let salt = [0xffu8; 32];
 
 		let outcome = Contracts::<T>::bare_instantiate(
 			RawOrigin::Signed(caller.clone()).into(),
@@ -108,20 +108,17 @@ where
 			CollectEvents::Skip,
 		);
 
-		let addr = outcome.result?.account_id;
-		let result = Contract { caller, account_id: addr.clone(), addr: T::Lookup::unlookup(addr) };
+		let address = outcome.result?.addr;
+		let account_id = T::AddressMapper::to_account_id_contract(&address);
+		let result = Contract { caller, account_id: account_id.clone(), addr: account_id };
 
-		ContractInfoOf::<T>::insert(&result.account_id, result.info()?);
+		ContractInfoOf::<T>::insert(&address, result.info()?);
 
 		Ok(result)
 	}
 
 	/// Create a new contract with the supplied storage item count and size each.
-	fn with_storage(
-		code: WasmModule<T>,
-		stor_num: u32,
-		stor_size: u32,
-	) -> Result<Self, &'static str> {
+	fn with_storage(code: WasmModule, stor_num: u32, stor_size: u32) -> Result<Self, &'static str> {
 		let contract = Contract::<T>::new(code, vec![])?;
 		let storage_items = (0..stor_num)
 			.map(|i| {
@@ -143,12 +140,12 @@ where
 			info.write(&Key::Fix(item.0), Some(item.1.clone()), None, false)
 				.map_err(|_| "Failed to write storage to restoration dest")?;
 		}
-		<ContractInfoOf<T>>::insert(&self.account_id, info);
+		<ContractInfoOf<T>>::insert(T::AddressMapper::to_address(&self.account_id), info);
 		Ok(())
 	}
 
 	/// Create a new contract with the specified unbalanced storage trie.
-	fn with_unbalanced_storage_trie(code: WasmModule<T>, key: &[u8]) -> Result<Self, &'static str> {
+	fn with_unbalanced_storage_trie(code: WasmModule, key: &[u8]) -> Result<Self, &'static str> {
 		if (key.len() as u32) < (UNBALANCED_TRIE_LAYERS + 1) / 2 {
 			return Err("Key size too small to create the specified trie");
 		}
@@ -179,7 +176,8 @@ where
 
 	/// Get the `ContractInfo` of the `addr` or an error if it no longer exists.
 	fn address_info(addr: &T::AccountId) -> Result<ContractInfo<T>, &'static str> {
-		ContractInfoOf::<T>::get(addr).ok_or("Expected contract to exist at this point.")
+		ContractInfoOf::<T>::get(T::AddressMapper::to_address(addr))
+			.ok_or("Expected contract to exist at this point.")
 	}
 
 	/// Get the `ContractInfo` of this contract or an error if it no longer exists.
@@ -193,12 +191,12 @@ where
 	}
 
 	/// Returns `true` iff all storage entries related to code storage exist.
-	fn code_exists(hash: &CodeHash<T>) -> bool {
+	fn code_exists(hash: &sp_core::H256) -> bool {
 		<PristineCode<T>>::contains_key(hash) && <CodeInfoOf<T>>::contains_key(&hash)
 	}
 
 	/// Returns `true` iff no storage entry related to code storage exist.
-	fn code_removed(hash: &CodeHash<T>) -> bool {
+	fn code_removed(hash: &sp_core::H256) -> bool {
 		!<PristineCode<T>>::contains_key(hash) && !<CodeInfoOf<T>>::contains_key(&hash)
 	}
 }
@@ -328,7 +326,7 @@ mod benchmarks {
 		let instance =
 			Contract::<T>::with_caller(whitelisted_caller(), WasmModule::sized(c), vec![])?;
 		let value = Pallet::<T>::min_balance();
-		let callee = instance.addr;
+		let callee = T::AddressMapper::to_address(&instance.addr);
 		let storage_deposit = default_deposit_limit::<T>();
 
 		#[extrinsic_call]
@@ -351,22 +349,23 @@ mod benchmarks {
 	fn instantiate_with_code(
 		c: Linear<0, { T::MaxCodeLen::get() }>,
 		i: Linear<0, { limits::MEMORY_BYTES }>,
-		s: Linear<0, { limits::MEMORY_BYTES }>,
 	) {
 		let input = vec![42u8; i as usize];
-		let salt = vec![42u8; s as usize];
+		let salt = [42u8; 32];
 		let value = Pallet::<T>::min_balance();
 		let caller = whitelisted_caller();
 		T::Currency::set_balance(&caller, caller_funding::<T>());
-		let WasmModule { code, hash, .. } = WasmModule::<T>::sized(c);
+		let WasmModule { code, .. } = WasmModule::sized(c);
 		let origin = RawOrigin::Signed(caller.clone());
-		let addr = Contracts::<T>::contract_address(&caller, &hash, &input, &salt);
+		let deployer = T::AddressMapper::to_address(&caller);
+		let addr = crate::address::create2(&deployer, &code, &input, &salt);
+		let account_id = T::AddressMapper::to_account_id_contract(&addr);
 		let storage_deposit = default_deposit_limit::<T>();
 		#[extrinsic_call]
 		_(origin, value, Weight::MAX, storage_deposit, code, input, salt);
 
 		let deposit =
-			T::Currency::balance_on_hold(&HoldReason::StorageDepositReserve.into(), &addr);
+			T::Currency::balance_on_hold(&HoldReason::StorageDepositReserve.into(), &account_id);
 		// uploading the code reserves some balance in the callers account
 		let code_deposit =
 			T::Currency::balance_on_hold(&HoldReason::CodeUploadDepositReserve.into(), &caller);
@@ -375,27 +374,26 @@ mod benchmarks {
 			caller_funding::<T>() - value - deposit - code_deposit - Pallet::<T>::min_balance(),
 		);
 		// contract has the full value
-		assert_eq!(T::Currency::balance(&addr), value + Pallet::<T>::min_balance());
+		assert_eq!(T::Currency::balance(&account_id), value + Pallet::<T>::min_balance());
 	}
 
 	// `i`: Size of the input in bytes.
 	// `s`: Size of the salt in bytes.
 	#[benchmark(pov_mode = Measured)]
-	fn instantiate(
-		i: Linear<0, { limits::MEMORY_BYTES }>,
-		s: Linear<0, { limits::MEMORY_BYTES }>,
-	) -> Result<(), BenchmarkError> {
+	fn instantiate(i: Linear<0, { limits::MEMORY_BYTES }>) -> Result<(), BenchmarkError> {
 		let input = vec![42u8; i as usize];
-		let salt = vec![42u8; s as usize];
+		let salt = [42u8; 32];
 		let value = Pallet::<T>::min_balance();
 		let caller = whitelisted_caller();
 		T::Currency::set_balance(&caller, caller_funding::<T>());
 		let origin = RawOrigin::Signed(caller.clone());
-		let WasmModule { code, .. } = WasmModule::<T>::dummy();
+		let WasmModule { code, .. } = WasmModule::dummy();
 		let storage_deposit = default_deposit_limit::<T>();
+		let deployer = T::AddressMapper::to_address(&caller);
+		let addr = crate::address::create2(&deployer, &code, &input, &salt);
 		let hash =
 			Contracts::<T>::bare_upload_code(origin.into(), code, storage_deposit)?.code_hash;
-		let addr = Contracts::<T>::contract_address(&caller, &hash, &input, &salt);
+		let account_id = T::AddressMapper::to_account_id_contract(&addr);
 
 		#[extrinsic_call]
 		_(
@@ -409,16 +407,16 @@ mod benchmarks {
 		);
 
 		let deposit =
-			T::Currency::balance_on_hold(&HoldReason::StorageDepositReserve.into(), &addr);
+			T::Currency::balance_on_hold(&HoldReason::StorageDepositReserve.into(), &account_id);
 		let code_deposit =
-			T::Currency::balance_on_hold(&HoldReason::CodeUploadDepositReserve.into(), &caller);
+			T::Currency::balance_on_hold(&HoldReason::CodeUploadDepositReserve.into(), &account_id);
 		// value was removed from the caller
 		assert_eq!(
-			T::Currency::balance(&caller),
+			T::Currency::total_balance(&caller),
 			caller_funding::<T>() - value - deposit - code_deposit - Pallet::<T>::min_balance(),
 		);
 		// contract has the full value
-		assert_eq!(T::Currency::balance(&addr), value + Pallet::<T>::min_balance());
+		assert_eq!(T::Currency::balance(&account_id), value + Pallet::<T>::min_balance());
 
 		Ok(())
 	}
@@ -437,7 +435,7 @@ mod benchmarks {
 			Contract::<T>::with_caller(whitelisted_caller(), WasmModule::dummy(), vec![])?;
 		let value = Pallet::<T>::min_balance();
 		let origin = RawOrigin::Signed(instance.caller.clone());
-		let callee = instance.addr.clone();
+		let callee = T::AddressMapper::to_address(&instance.addr);
 		let before = T::Currency::balance(&instance.account_id);
 		let storage_deposit = default_deposit_limit::<T>();
 		#[extrinsic_call]
@@ -470,7 +468,7 @@ mod benchmarks {
 	fn upload_code(c: Linear<0, { T::MaxCodeLen::get() }>) {
 		let caller = whitelisted_caller();
 		T::Currency::set_balance(&caller, caller_funding::<T>());
-		let WasmModule { code, hash, .. } = WasmModule::<T>::sized(c);
+		let WasmModule { code, hash, .. } = WasmModule::sized(c);
 		let origin = RawOrigin::Signed(caller.clone());
 		let storage_deposit = default_deposit_limit::<T>();
 		#[extrinsic_call]
@@ -487,7 +485,7 @@ mod benchmarks {
 	fn remove_code() -> Result<(), BenchmarkError> {
 		let caller = whitelisted_caller();
 		T::Currency::set_balance(&caller, caller_funding::<T>());
-		let WasmModule { code, hash, .. } = WasmModule::<T>::dummy();
+		let WasmModule { code, hash, .. } = WasmModule::dummy();
 		let origin = RawOrigin::Signed(caller.clone());
 		let storage_deposit = default_deposit_limit::<T>();
 		let uploaded =
@@ -508,12 +506,12 @@ mod benchmarks {
 		let instance =
 			<Contract<T>>::with_caller(whitelisted_caller(), WasmModule::dummy(), vec![])?;
 		// we just add some bytes so that the code hash is different
-		let WasmModule { code, .. } = <WasmModule<T>>::dummy_unique(128);
+		let WasmModule { code, .. } = WasmModule::dummy_unique(128);
 		let origin = RawOrigin::Signed(instance.caller.clone());
 		let storage_deposit = default_deposit_limit::<T>();
 		let hash =
 			<Contracts<T>>::bare_upload_code(origin.into(), code, storage_deposit)?.code_hash;
-		let callee = instance.addr.clone();
+		let callee = T::AddressMapper::to_address(&instance.addr);
 		assert_ne!(instance.info()?.code_hash, hash);
 		#[extrinsic_call]
 		_(RawOrigin::Root, callee, hash);
@@ -534,7 +532,7 @@ mod benchmarks {
 
 	#[benchmark(pov_mode = Measured)]
 	fn seal_caller() {
-		let len = <T::AccountId as MaxEncodedLen>::max_encoded_len() as u32;
+		let len = H160::len_bytes();
 		build_runtime!(runtime, memory: [len.to_le_bytes(), vec![0u8; len as _], ]);
 
 		let result;
@@ -545,8 +543,8 @@ mod benchmarks {
 
 		assert_ok!(result);
 		assert_eq!(
-			&<T::AccountId as Decode>::decode(&mut &memory[4..]).unwrap(),
-			runtime.ext().caller().account_id().unwrap()
+			<H160 as Decode>::decode(&mut &memory[4..]).unwrap(),
+			T::AddressMapper::to_address(&runtime.ext().caller().account_id().unwrap())
 		);
 	}
 
@@ -569,7 +567,7 @@ mod benchmarks {
 	#[benchmark(pov_mode = Measured)]
 	fn seal_code_hash() {
 		let contract = Contract::<T>::with_index(1, WasmModule::dummy(), vec![]).unwrap();
-		let len = <CodeHash<T> as MaxEncodedLen>::max_encoded_len() as u32;
+		let len = <sp_core::H256 as MaxEncodedLen>::max_encoded_len() as u32;
 		build_runtime!(runtime, memory: [len.to_le_bytes(), vec![0u8; len as _], contract.account_id.encode(), ]);
 
 		let result;
@@ -580,14 +578,14 @@ mod benchmarks {
 
 		assert_ok!(result);
 		assert_eq!(
-			<CodeHash<T> as Decode>::decode(&mut &memory[4..]).unwrap(),
+			<sp_core::H256 as Decode>::decode(&mut &memory[4..]).unwrap(),
 			contract.info().unwrap().code_hash
 		);
 	}
 
 	#[benchmark(pov_mode = Measured)]
 	fn seal_own_code_hash() {
-		let len = <CodeHash<T> as MaxEncodedLen>::max_encoded_len() as u32;
+		let len = <sp_core::H256 as MaxEncodedLen>::max_encoded_len() as u32;
 		build_runtime!(runtime, contract, memory: [len.to_le_bytes(), vec![0u8; len as _], ]);
 		let result;
 		#[block]
@@ -597,7 +595,7 @@ mod benchmarks {
 
 		assert_ok!(result);
 		assert_eq!(
-			<CodeHash<T> as Decode>::decode(&mut &memory[4..]).unwrap(),
+			<sp_core::H256 as Decode>::decode(&mut &memory[4..]).unwrap(),
 			contract.info().unwrap().code_hash
 		);
 	}
@@ -631,7 +629,7 @@ mod benchmarks {
 
 	#[benchmark(pov_mode = Measured)]
 	fn seal_address() {
-		let len = <AccountIdOf<T> as MaxEncodedLen>::max_encoded_len() as u32;
+		let len = H160::len_bytes();
 		build_runtime!(runtime, memory: [len.to_le_bytes(), vec![0u8; len as _], ]);
 
 		let result;
@@ -640,10 +638,7 @@ mod benchmarks {
 			result = runtime.bench_address(memory.as_mut_slice(), 4, 0);
 		}
 		assert_ok!(result);
-		assert_eq!(
-			&<T::AccountId as Decode>::decode(&mut &memory[4..]).unwrap(),
-			runtime.ext().address()
-		);
+		assert_eq!(<H160 as Decode>::decode(&mut &memory[4..]).unwrap(), runtime.ext().address());
 	}
 
 	#[benchmark(pov_mode = Measured)]
@@ -809,7 +804,7 @@ mod benchmarks {
 		build_runtime!(runtime, memory: [beneficiary.encode(),]);
 
 		(0..n).for_each(|i| {
-			let new_code = WasmModule::<T>::dummy_unique(65 + i);
+			let new_code = WasmModule::dummy_unique(65 + i);
 			Contracts::<T>::bare_upload_code(origin.clone().into(), new_code.code, storage_deposit)
 				.unwrap();
 			runtime.ext().lock_delegate_dependency(new_code.hash).unwrap();
@@ -1536,10 +1531,8 @@ mod benchmarks {
 	// i: size of input in bytes
 	// s: size of salt in bytes
 	#[benchmark(pov_mode = Measured)]
-	fn seal_instantiate(
-		i: Linear<0, { limits::MEMORY_BYTES }>,
-		s: Linear<0, { limits::MEMORY_BYTES }>,
-	) -> Result<(), BenchmarkError> {
+	fn seal_instantiate(i: Linear<0, { limits::MEMORY_BYTES }>) -> Result<(), BenchmarkError> {
+		let code = WasmModule::dummy();
 		let hash = Contract::<T>::with_index(1, WasmModule::dummy(), vec![])?.info()?.code_hash;
 		let hash_bytes = hash.encode();
 		let hash_len = hash_bytes.len() as u32;
@@ -1561,8 +1554,10 @@ mod benchmarks {
 		let mut runtime = crate::wasm::Runtime::<_, [u8]>::new(&mut ext, vec![]);
 
 		let input = vec![42u8; i as _];
-		let salt = vec![42u8; s as _];
-		let addr = Contracts::<T>::contract_address(&account_id, &hash, &input, &salt);
+		let salt = [42u8; 32];
+		let deployer = T::AddressMapper::to_address(&account_id);
+		let addr = crate::address::create2(&deployer, &code.code, &input, &salt);
+		let account_id = T::AddressMapper::to_account_id_contract(&addr);
 		let mut memory = memory!(hash_bytes, deposit_bytes, value_bytes, input, salt,);
 
 		let mut offset = {
@@ -1592,13 +1587,13 @@ mod benchmarks {
 				SENTINEL,            // output_ptr
 				0,                   // output_len_ptr
 				offset(i),           // salt_ptr
-				s,                   // salt_len
+				32,                  // salt_len
 			);
 		}
 
 		assert_ok!(result);
 		assert!(ContractInfoOf::<T>::get(&addr).is_some());
-		assert_eq!(T::Currency::balance(&addr), Pallet::<T>::min_balance() + value);
+		assert_eq!(T::Currency::balance(&account_id), Pallet::<T>::min_balance() + value);
 		Ok(())
 	}
 
diff --git a/substrate/frame/revive/src/debug.rs b/substrate/frame/revive/src/debug.rs
index 467f4e1ad4910127667ba17eaea3be75266bfbc3..00e893b94f86d66781dec83e08be23e78ef4cfce 100644
--- a/substrate/frame/revive/src/debug.rs
+++ b/substrate/frame/revive/src/debug.rs
@@ -20,6 +20,7 @@ pub use crate::{
 	primitives::ExecReturnValue,
 };
 use crate::{Config, LOG_TARGET};
+use sp_core::H160;
 
 /// Umbrella trait for all interfaces that serves for debugging.
 pub trait Debugger<T: Config>: Tracing<T> + CallInterceptor<T> {}
@@ -43,7 +44,7 @@ pub trait Tracing<T: Config> {
 	/// * `entry_point` - Describes whether the call is the constructor or a regular call.
 	/// * `input_data` - The raw input data of the call.
 	fn new_call_span(
-		contract_address: &T::AccountId,
+		contract_address: &H160,
 		entry_point: ExportedFunction,
 		input_data: &[u8],
 	) -> Self::CallSpan;
@@ -62,11 +63,7 @@ pub trait CallSpan {
 impl<T: Config> Tracing<T> for () {
 	type CallSpan = ();
 
-	fn new_call_span(
-		contract_address: &T::AccountId,
-		entry_point: ExportedFunction,
-		input_data: &[u8],
-	) {
+	fn new_call_span(contract_address: &H160, entry_point: ExportedFunction, input_data: &[u8]) {
 		log::trace!(target: LOG_TARGET, "call {entry_point:?} account: {contract_address:?}, input_data: {input_data:?}")
 	}
 }
@@ -95,7 +92,7 @@ pub trait CallInterceptor<T: Config> {
 	/// is returned.
 	/// * `None` - otherwise, i.e. the call should be executed normally.
 	fn intercept_call(
-		contract_address: &T::AccountId,
+		contract_address: &H160,
 		entry_point: ExportedFunction,
 		input_data: &[u8],
 	) -> Option<ExecResult>;
@@ -103,7 +100,7 @@ pub trait CallInterceptor<T: Config> {
 
 impl<T: Config> CallInterceptor<T> for () {
 	fn intercept_call(
-		_contract_address: &T::AccountId,
+		_contract_address: &H160,
 		_entry_point: ExportedFunction,
 		_input_data: &[u8],
 	) -> Option<ExecResult> {
diff --git a/substrate/frame/revive/src/exec.rs b/substrate/frame/revive/src/exec.rs
index 9740707ae706596ddeb96dc034d8862cd275b0a3..54019a6ba9928a23784c5d4c3b9b9a783c3e6240 100644
--- a/substrate/frame/revive/src/exec.rs
+++ b/substrate/frame/revive/src/exec.rs
@@ -16,6 +16,7 @@
 // limitations under the License.
 
 use crate::{
+	address::{self, AddressMapper},
 	debug::{CallInterceptor, CallSpan, Tracing},
 	gas::GasMeter,
 	limits,
@@ -23,8 +24,8 @@ use crate::{
 	runtime_decl_for_revive_api::{Decode, Encode, RuntimeDebugNoBound, TypeInfo},
 	storage::{self, meter::Diff, WriteOutcome},
 	transient_storage::TransientStorage,
-	BalanceOf, CodeHash, CodeInfo, CodeInfoOf, Config, ContractInfo, ContractInfoOf, DebugBuffer,
-	Error, Event, Pallet as Contracts, LOG_TARGET,
+	BalanceOf, CodeInfo, CodeInfoOf, Config, ContractInfo, ContractInfoOf, DebugBuffer, Error,
+	Event, Pallet as Contracts, LOG_TARGET,
 };
 use alloc::vec::Vec;
 use core::{fmt::Debug, marker::PhantomData, mem};
@@ -48,7 +49,7 @@ use frame_system::{
 use sp_core::{
 	ecdsa::Public as ECDSAPublic,
 	sr25519::{Public as SR25519Public, Signature as SR25519Signature},
-	ConstU32, Get,
+	ConstU32, Get, H160, H256,
 };
 use sp_io::{crypto::secp256k1_ecdsa_recover_compressed, hashing::blake2_256};
 use sp_runtime::{
@@ -184,7 +185,7 @@ pub trait Ext: sealing::Sealed {
 		&mut self,
 		gas_limit: Weight,
 		deposit_limit: BalanceOf<Self::T>,
-		to: AccountIdOf<Self::T>,
+		to: &H160,
 		value: BalanceOf<Self::T>,
 		input_data: Vec<u8>,
 		allows_reentry: bool,
@@ -196,7 +197,7 @@ pub trait Ext: sealing::Sealed {
 	/// Returns the code size of the called contract.
 	fn delegate_call(
 		&mut self,
-		code: CodeHash<Self::T>,
+		code: H256,
 		input_data: Vec<u8>,
 	) -> Result<ExecReturnValue, ExecError>;
 
@@ -209,11 +210,11 @@ pub trait Ext: sealing::Sealed {
 		&mut self,
 		gas_limit: Weight,
 		deposit_limit: BalanceOf<Self::T>,
-		code: CodeHash<Self::T>,
+		code: H256,
 		value: BalanceOf<Self::T>,
 		input_data: Vec<u8>,
-		salt: &[u8],
-	) -> Result<(AccountIdOf<Self::T>, ExecReturnValue), ExecError>;
+		salt: &[u8; 32],
+	) -> Result<(H160, ExecReturnValue), ExecError>;
 
 	/// Transfer all funds to `beneficiary` and delete the contract.
 	///
@@ -222,10 +223,10 @@ pub trait Ext: sealing::Sealed {
 	///
 	/// This function will fail if the same contract is present on the contract
 	/// call stack.
-	fn terminate(&mut self, beneficiary: &AccountIdOf<Self::T>) -> DispatchResult;
+	fn terminate(&mut self, beneficiary: &H160) -> DispatchResult;
 
 	/// Transfer some amount of funds into the specified account.
-	fn transfer(&mut self, to: &AccountIdOf<Self::T>, value: BalanceOf<Self::T>) -> DispatchResult;
+	fn transfer(&mut self, to: &H160, value: BalanceOf<Self::T>) -> DispatchResult;
 
 	/// Returns the storage entry of the executing account by the given `key`.
 	///
@@ -273,15 +274,15 @@ pub trait Ext: sealing::Sealed {
 	fn caller(&self) -> Origin<Self::T>;
 
 	/// Check if a contract lives at the specified `address`.
-	fn is_contract(&self, address: &AccountIdOf<Self::T>) -> bool;
+	fn is_contract(&self, address: &H160) -> bool;
 
 	/// Returns the code hash of the contract for the given `address`.
 	///
 	/// Returns `None` if the `address` does not belong to a contract.
-	fn code_hash(&self, address: &AccountIdOf<Self::T>) -> Option<CodeHash<Self::T>>;
+	fn code_hash(&self, address: &H160) -> Option<H256>;
 
 	/// Returns the code hash of the contract being executed.
-	fn own_code_hash(&mut self) -> &CodeHash<Self::T>;
+	fn own_code_hash(&mut self) -> &H256;
 
 	/// Check if the caller of the current contract is the origin of the whole call stack.
 	///
@@ -293,7 +294,12 @@ pub trait Ext: sealing::Sealed {
 	fn caller_is_root(&self) -> bool;
 
 	/// Returns a reference to the account id of the current contract.
-	fn address(&self) -> &AccountIdOf<Self::T>;
+	fn account_id(&self) -> &AccountIdOf<Self::T>;
+
+	/// Returns a reference to the [`H160`] address of the current contract.
+	fn address(&self) -> H160 {
+		<Self::T as Config>::AddressMapper::to_address(self.account_id())
+	}
 
 	/// Returns the balance of the current contract.
 	///
@@ -368,7 +374,7 @@ pub trait Ext: sealing::Sealed {
 	fn transient_storage(&mut self) -> &mut TransientStorage<Self::T>;
 
 	/// Sets new code hash for existing contract.
-	fn set_code_hash(&mut self, hash: CodeHash<Self::T>) -> DispatchResult;
+	fn set_code_hash(&mut self, hash: H256) -> DispatchResult;
 
 	/// Returns the number of times the specified contract exists on the call stack. Delegated calls
 	/// Increment the reference count of a of a stored code by one.
@@ -377,7 +383,7 @@ pub trait Ext: sealing::Sealed {
 	///
 	/// [`Error::CodeNotFound`] is returned if no stored code found having the specified
 	/// `code_hash`.
-	fn increment_refcount(code_hash: CodeHash<Self::T>) -> DispatchResult;
+	fn increment_refcount(code_hash: H256) -> DispatchResult;
 
 	/// Decrement the reference count of a stored code by one.
 	///
@@ -385,7 +391,7 @@ pub trait Ext: sealing::Sealed {
 	///
 	/// A contract whose reference count dropped to zero isn't automatically removed. A
 	/// `remove_code` transaction must be submitted by the original uploader to do so.
-	fn decrement_refcount(code_hash: CodeHash<Self::T>);
+	fn decrement_refcount(code_hash: H256);
 
 	/// Adds a delegate dependency to [`ContractInfo`]'s `delegate_dependencies` field.
 	///
@@ -398,7 +404,7 @@ pub trait Ext: sealing::Sealed {
 	/// - [`Error::MaxDelegateDependenciesReached`]
 	/// - [`Error::CannotAddSelfAsDelegateDependency`]
 	/// - [`Error::DelegateDependencyAlreadyExists`]
-	fn lock_delegate_dependency(&mut self, code_hash: CodeHash<Self::T>) -> DispatchResult;
+	fn lock_delegate_dependency(&mut self, code_hash: H256) -> DispatchResult;
 
 	/// Removes a delegate dependency from [`ContractInfo`]'s `delegate_dependencies` field.
 	///
@@ -408,7 +414,7 @@ pub trait Ext: sealing::Sealed {
 	/// # Errors
 	///
 	/// - [`Error::DelegateDependencyNotFound`]
-	fn unlock_delegate_dependency(&mut self, code_hash: &CodeHash<Self::T>) -> DispatchResult;
+	fn unlock_delegate_dependency(&mut self, code_hash: &H256) -> DispatchResult;
 
 	/// Returns the number of locked delegate dependencies.
 	///
@@ -447,10 +453,7 @@ pub trait Executable<T: Config>: Sized {
 	///
 	/// # Note
 	/// Charges size base load weight from the gas meter.
-	fn from_storage(
-		code_hash: CodeHash<T>,
-		gas_meter: &mut GasMeter<T>,
-	) -> Result<Self, DispatchError>;
+	fn from_storage(code_hash: H256, gas_meter: &mut GasMeter<T>) -> Result<Self, DispatchError>;
 
 	/// Execute the specified exported function and return the result.
 	///
@@ -471,8 +474,11 @@ pub trait Executable<T: Config>: Sized {
 	/// The code info of the executable.
 	fn code_info(&self) -> &CodeInfo<T>;
 
+	/// The raw code of the executable.
+	fn code(&self) -> &[u8];
+
 	/// The code hash of the executable.
-	fn code_hash(&self) -> &CodeHash<T>;
+	fn code_hash(&self) -> &H256;
 }
 
 /// The complete call stack of a contract execution.
@@ -519,7 +525,7 @@ pub struct Stack<'a, T: Config, E> {
 /// For each nested contract call or instantiate one frame is created. It holds specific
 /// information for the said call and caches the in-storage `ContractInfo` data structure.
 struct Frame<T: Config> {
-	/// The account id of the executing contract.
+	/// The address of the executing contract.
 	account_id: T::AccountId,
 	/// The cached in-storage data of the contract.
 	contract_info: CachedContract<T>,
@@ -567,7 +573,7 @@ enum FrameArgs<'a, T: Config, E> {
 		/// The executable whose `deploy` function is run.
 		executable: E,
 		/// A salt used in the contract address derivation of the new contract.
-		salt: &'a [u8],
+		salt: &'a [u8; 32],
 		/// The input data is used in the contract address derivation of the new contract.
 		input_data: &'a [u8],
 	},
@@ -668,7 +674,7 @@ impl<T: Config> CachedContract<T> {
 	/// Load the `contract_info` from storage if necessary.
 	fn load(&mut self, account_id: &T::AccountId) {
 		if let CachedContract::Invalidated = self {
-			let contract = <ContractInfoOf<T>>::get(&account_id);
+			let contract = <ContractInfoOf<T>>::get(T::AddressMapper::to_address(account_id));
 			if let Some(contract) = contract {
 				*self = CachedContract::Cached(contract);
 			}
@@ -705,7 +711,7 @@ where
 	/// Result<(ExecReturnValue, CodeSize), (ExecError, CodeSize)>
 	pub fn run_call(
 		origin: Origin<T>,
-		dest: T::AccountId,
+		dest: H160,
 		gas_meter: &'a mut GasMeter<T>,
 		storage_meter: &'a mut storage::meter::Meter<T>,
 		value: BalanceOf<T>,
@@ -713,7 +719,11 @@ where
 		debug_message: Option<&'a mut DebugBuffer>,
 	) -> Result<ExecReturnValue, ExecError> {
 		let (mut stack, executable) = Self::new(
-			FrameArgs::Call { dest, cached_info: None, delegated_call: None },
+			FrameArgs::Call {
+				dest: T::AddressMapper::to_account_id(&dest),
+				cached_info: None,
+				delegated_call: None,
+			},
 			origin,
 			gas_meter,
 			storage_meter,
@@ -740,9 +750,9 @@ where
 		storage_meter: &'a mut storage::meter::Meter<T>,
 		value: BalanceOf<T>,
 		input_data: Vec<u8>,
-		salt: &[u8],
+		salt: &[u8; 32],
 		debug_message: Option<&'a mut DebugBuffer>,
-	) -> Result<(T::AccountId, ExecReturnValue), ExecError> {
+	) -> Result<(H160, ExecReturnValue), ExecError> {
 		let (mut stack, executable) = Self::new(
 			FrameArgs::Instantiate {
 				sender: origin.clone(),
@@ -756,13 +766,13 @@ where
 			value,
 			debug_message,
 		)?;
-		let account_id = stack.top_frame().account_id.clone();
-		stack.run(executable, input_data).map(|ret| (account_id, ret))
+		let address = T::AddressMapper::to_address(&stack.top_frame().account_id);
+		stack.run(executable, input_data).map(|ret| (address, ret))
 	}
 
 	#[cfg(all(feature = "runtime-benchmarks", feature = "riscv"))]
 	pub fn bench_new_call(
-		dest: T::AccountId,
+		dest: H160,
 		origin: Origin<T>,
 		gas_meter: &'a mut GasMeter<T>,
 		storage_meter: &'a mut storage::meter::Meter<T>,
@@ -770,7 +780,11 @@ where
 		debug_message: Option<&'a mut DebugBuffer>,
 	) -> (Self, E) {
 		Self::new(
-			FrameArgs::Call { dest, cached_info: None, delegated_call: None },
+			FrameArgs::Call {
+				dest: T::AddressMapper::to_account_id(&dest),
+				cached_info: None,
+				delegated_call: None,
+			},
 			origin,
 			gas_meter,
 			storage_meter,
@@ -834,7 +848,8 @@ where
 				let contract = if let Some(contract) = cached_info {
 					contract
 				} else {
-					<ContractInfoOf<T>>::get(&dest).ok_or(<Error<T>>::ContractNotFound)?
+					<ContractInfoOf<T>>::get(T::AddressMapper::to_address(&dest))
+						.ok_or(<Error<T>>::ContractNotFound)?
 				};
 
 				let (executable, delegate_caller) =
@@ -847,18 +862,20 @@ where
 				(dest, contract, executable, delegate_caller, ExportedFunction::Call)
 			},
 			FrameArgs::Instantiate { sender, executable, salt, input_data } => {
-				let account_id = Contracts::<T>::contract_address(
-					&sender,
-					&executable.code_hash(),
-					input_data,
-					salt,
-				);
+				let deployer = T::AddressMapper::to_address(&sender);
+				let address = address::create2(&deployer, executable.code(), input_data, salt);
 				let contract = ContractInfo::new(
-					&account_id,
+					&address,
 					<System<T>>::account_nonce(&sender),
 					*executable.code_hash(),
 				)?;
-				(account_id, contract, executable, None, ExportedFunction::Constructor)
+				(
+					T::AddressMapper::to_account_id_contract(&address),
+					contract,
+					executable,
+					None,
+					ExportedFunction::Constructor,
+				)
 			},
 		};
 
@@ -887,7 +904,7 @@ where
 		read_only: bool,
 	) -> Result<E, ExecError> {
 		if self.frames.len() as u32 == limits::CALL_STACK_DEPTH {
-			return Err(Error::<T>::MaxCallDepthReached.into())
+			return Err(Error::<T>::MaxCallDepthReached.into());
 		}
 
 		// We need to make sure that changes made to the contract info are not discarded.
@@ -898,7 +915,10 @@ where
 		if let (CachedContract::Cached(contract), ExportedFunction::Call) =
 			(&frame.contract_info, frame.entry_point)
 		{
-			<ContractInfoOf<T>>::insert(frame.account_id.clone(), contract.clone());
+			<ContractInfoOf<T>>::insert(
+				T::AddressMapper::to_address(&frame.account_id),
+				contract.clone(),
+			);
 		}
 
 		let frame = top_frame_mut!(self);
@@ -950,11 +970,11 @@ where
 			// Every non delegate call or instantiate also optionally transfers the balance.
 			self.initial_transfer()?;
 
-			let contract_address = &top_frame!(self).account_id;
+			let contract_address = T::AddressMapper::to_address(&top_frame!(self).account_id);
 
-			let call_span = T::Debug::new_call_span(contract_address, entry_point, &input_data);
+			let call_span = T::Debug::new_call_span(&contract_address, entry_point, &input_data);
 
-			let output = T::Debug::intercept_call(contract_address, entry_point, &input_data)
+			let output = T::Debug::intercept_call(&contract_address, entry_point, &input_data)
 				.unwrap_or_else(|| {
 					executable
 						.execute(self, entry_point, input_data)
@@ -965,7 +985,7 @@ where
 
 			// Avoid useless work that would be reverted anyways.
 			if output.did_revert() {
-				return Ok(output)
+				return Ok(output);
 			}
 
 			// Storage limit is normally enforced as late as possible (when the last frame returns)
@@ -980,12 +1000,12 @@ where
 			}
 
 			let frame = self.top_frame();
-			let account_id = &frame.account_id.clone();
+			let account_id = T::AddressMapper::to_address(&frame.account_id);
 			match (entry_point, delegated_code_hash) {
 				(ExportedFunction::Constructor, _) => {
 					// It is not allowed to terminate a contract inside its constructor.
 					if matches!(frame.contract_info, CachedContract::Terminated) {
-						return Err(Error::<T>::TerminatedInConstructor.into())
+						return Err(Error::<T>::TerminatedInConstructor.into());
 					}
 
 					// If a special limit was set for the sub-call, we enforce it here.
@@ -995,17 +1015,17 @@ where
 					let contract = frame.contract_info.as_contract();
 					frame.nested_storage.enforce_subcall_limit(contract)?;
 
-					let caller = self.caller().account_id()?.clone();
+					let caller = T::AddressMapper::to_address(self.caller().account_id()?);
 
 					// Deposit an instantiation event.
 					Contracts::<T>::deposit_event(Event::Instantiated {
 						deployer: caller,
-						contract: account_id.clone(),
+						contract: account_id,
 					});
 				},
 				(ExportedFunction::Call, Some(code_hash)) => {
 					Contracts::<T>::deposit_event(Event::DelegateCalled {
-						contract: account_id.clone(),
+						contract: account_id,
 						code_hash,
 					});
 				},
@@ -1019,7 +1039,7 @@ where
 					let caller = self.caller();
 					Contracts::<T>::deposit_event(Event::Called {
 						caller: caller.clone(),
-						contract: account_id.clone(),
+						contract: account_id,
 					});
 				},
 			}
@@ -1081,7 +1101,7 @@ where
 
 			// Only gas counter changes are persisted in case of a failure.
 			if !persist {
-				return
+				return;
 			}
 
 			// Record the storage meter changes of the nested call into the parent meter.
@@ -1100,7 +1120,7 @@ where
 				// trigger a rollback.
 				if prev.account_id == *account_id {
 					prev.contract_info = CachedContract::Cached(contract);
-					return
+					return;
 				}
 
 				// Predecessor is a different contract: We persist the info and invalidate the first
@@ -1108,7 +1128,7 @@ where
 				// because that case is already handled by the optimization above. Only the first
 				// cache needs to be invalidated because that one will invalidate the next cache
 				// when it is popped from the stack.
-				<ContractInfoOf<T>>::insert(account_id, contract);
+				<ContractInfoOf<T>>::insert(T::AddressMapper::to_address(account_id), contract);
 				if let Some(c) = self.frames_mut().skip(1).find(|f| f.account_id == *account_id) {
 					c.contract_info = CachedContract::Invalidated;
 				}
@@ -1123,7 +1143,7 @@ where
 			}
 			self.gas_meter.absorb_nested(mem::take(&mut self.first_frame.nested_gas));
 			if !persist {
-				return
+				return;
 			}
 			let mut contract = self.first_frame.contract_info.as_contract();
 			self.storage_meter.absorb(
@@ -1132,7 +1152,10 @@ where
 				contract.as_deref_mut(),
 			);
 			if let Some(contract) = contract {
-				<ContractInfoOf<T>>::insert(&self.first_frame.account_id, contract);
+				<ContractInfoOf<T>>::insert(
+					T::AddressMapper::to_address(&self.first_frame.account_id),
+					contract,
+				);
 			}
 		}
 	}
@@ -1158,7 +1181,7 @@ where
 		// If it is a delegate call, then we've already transferred tokens in the
 		// last non-delegate frame.
 		if frame.delegate_caller.is_some() {
-			return Ok(())
+			return Ok(());
 		}
 
 		let value = frame.value_transferred;
@@ -1203,7 +1226,7 @@ where
 	}
 
 	/// Returns whether the specified contract allows to be reentered right now.
-	fn allows_reentry(&self, id: &AccountIdOf<T>) -> bool {
+	fn allows_reentry(&self, id: &T::AccountId) -> bool {
 		!self.frames().any(|f| &f.account_id == id && !f.allows_reentry)
 	}
 }
@@ -1219,7 +1242,7 @@ where
 		&mut self,
 		gas_limit: Weight,
 		deposit_limit: BalanceOf<T>,
-		to: T::AccountId,
+		dest: &H160,
 		value: BalanceOf<T>,
 		input_data: Vec<u8>,
 		allows_reentry: bool,
@@ -1230,9 +1253,11 @@ where
 		// is caught by it.
 		self.top_frame_mut().allows_reentry = allows_reentry;
 
+		let dest = T::AddressMapper::to_account_id(dest);
+
 		let try_call = || {
-			if !self.allows_reentry(&to) {
-				return Err(<Error<T>>::ReentranceDenied.into())
+			if !self.allows_reentry(&dest) {
+				return Err(<Error<T>>::ReentranceDenied.into());
 			}
 
 			// We ignore instantiate frames in our search for a cached contract.
@@ -1240,13 +1265,13 @@ where
 			// constructor: We disallow calling not fully constructed contracts.
 			let cached_info = self
 				.frames()
-				.find(|f| f.entry_point == ExportedFunction::Call && f.account_id == to)
+				.find(|f| f.entry_point == ExportedFunction::Call && f.account_id == dest)
 				.and_then(|f| match &f.contract_info {
 					CachedContract::Cached(contract) => Some(contract.clone()),
 					_ => None,
 				});
 			let executable = self.push_frame(
-				FrameArgs::Call { dest: to, cached_info, delegated_call: None },
+				FrameArgs::Call { dest, cached_info, delegated_call: None },
 				value,
 				gas_limit,
 				deposit_limit,
@@ -1267,7 +1292,7 @@ where
 
 	fn delegate_call(
 		&mut self,
-		code_hash: CodeHash<Self::T>,
+		code_hash: H256,
 		input_data: Vec<u8>,
 	) -> Result<ExecReturnValue, ExecError> {
 		let executable = E::from_storage(code_hash, self.gas_meter_mut())?;
@@ -1293,11 +1318,11 @@ where
 		&mut self,
 		gas_limit: Weight,
 		deposit_limit: BalanceOf<Self::T>,
-		code_hash: CodeHash<T>,
+		code_hash: H256,
 		value: BalanceOf<T>,
 		input_data: Vec<u8>,
-		salt: &[u8],
-	) -> Result<(AccountIdOf<T>, ExecReturnValue), ExecError> {
+		salt: &[u8; 32],
+	) -> Result<(H160, ExecReturnValue), ExecError> {
 		let executable = E::from_storage(code_hash, self.gas_meter_mut())?;
 		let sender = &self.top_frame().account_id;
 		let executable = self.push_frame(
@@ -1312,20 +1337,22 @@ where
 			deposit_limit,
 			self.is_read_only(),
 		)?;
-		let account_id = self.top_frame().account_id.clone();
-		self.run(executable, input_data).map(|ret| (account_id, ret))
+		let address = T::AddressMapper::to_address(&self.top_frame().account_id);
+		self.run(executable, input_data).map(|ret| (address, ret))
 	}
 
-	fn terminate(&mut self, beneficiary: &AccountIdOf<Self::T>) -> DispatchResult {
+	fn terminate(&mut self, beneficiary: &H160) -> DispatchResult {
 		if self.is_recursive() {
-			return Err(Error::<T>::TerminatedWhileReentrant.into())
+			return Err(Error::<T>::TerminatedWhileReentrant.into());
 		}
 		let frame = self.top_frame_mut();
 		let info = frame.terminate();
-		frame.nested_storage.terminate(&info, beneficiary.clone());
+		let beneficiary_account = T::AddressMapper::to_account_id(beneficiary);
+		frame.nested_storage.terminate(&info, beneficiary_account);
 
 		info.queue_trie_for_deletion();
-		ContractInfoOf::<T>::remove(&frame.account_id);
+		let account_address = T::AddressMapper::to_address(&frame.account_id);
+		ContractInfoOf::<T>::remove(&account_address);
 		Self::decrement_refcount(info.code_hash);
 
 		for (code_hash, deposit) in info.delegate_dependencies() {
@@ -1336,14 +1363,19 @@ where
 		}
 
 		Contracts::<T>::deposit_event(Event::Terminated {
-			contract: frame.account_id.clone(),
-			beneficiary: beneficiary.clone(),
+			contract: account_address,
+			beneficiary: *beneficiary,
 		});
 		Ok(())
 	}
 
-	fn transfer(&mut self, to: &T::AccountId, value: BalanceOf<T>) -> DispatchResult {
-		Self::transfer(Preservation::Preserve, &self.top_frame().account_id, to, value)
+	fn transfer(&mut self, to: &H160, value: BalanceOf<T>) -> DispatchResult {
+		Self::transfer(
+			Preservation::Preserve,
+			&self.top_frame().account_id,
+			&T::AddressMapper::to_account_id(to),
+			value,
+		)
 	}
 
 	fn get_storage(&mut self, key: &Key) -> Option<Vec<u8>> {
@@ -1370,11 +1402,13 @@ where
 	}
 
 	fn get_transient_storage(&self, key: &Key) -> Option<Vec<u8>> {
-		self.transient_storage.read(self.address(), key)
+		self.transient_storage.read(self.account_id(), key)
 	}
 
 	fn get_transient_storage_size(&self, key: &Key) -> Option<u32> {
-		self.transient_storage.read(self.address(), key).map(|value| value.len() as _)
+		self.transient_storage
+			.read(self.account_id(), key)
+			.map(|value| value.len() as _)
 	}
 
 	fn set_transient_storage(
@@ -1383,11 +1417,11 @@ where
 		value: Option<Vec<u8>>,
 		take_old: bool,
 	) -> Result<WriteOutcome, DispatchError> {
-		let account_id = self.address().clone();
+		let account_id = self.account_id().clone();
 		self.transient_storage.write(&account_id, key, value, take_old)
 	}
 
-	fn address(&self) -> &T::AccountId {
+	fn account_id(&self) -> &T::AccountId {
 		&self.top_frame().account_id
 	}
 
@@ -1402,15 +1436,15 @@ where
 		}
 	}
 
-	fn is_contract(&self, address: &T::AccountId) -> bool {
+	fn is_contract(&self, address: &H160) -> bool {
 		ContractInfoOf::<T>::contains_key(&address)
 	}
 
-	fn code_hash(&self, address: &T::AccountId) -> Option<CodeHash<Self::T>> {
+	fn code_hash(&self, address: &H160) -> Option<H256> {
 		<ContractInfoOf<T>>::get(&address).map(|contract| contract.code_hash)
 	}
 
-	fn own_code_hash(&mut self) -> &CodeHash<Self::T> {
+	fn own_code_hash(&mut self) -> &H256 {
 		&self.top_frame_mut().contract_info().code_hash
 	}
 
@@ -1446,7 +1480,10 @@ where
 	fn deposit_event(&mut self, topics: Vec<T::Hash>, data: Vec<u8>) {
 		Contracts::<Self::T>::deposit_indexed_event(
 			topics,
-			Event::ContractEmitted { contract: self.top_frame().account_id.clone(), data },
+			Event::ContractEmitted {
+				contract: T::AddressMapper::to_address(self.account_id()),
+				data,
+			},
 		);
 	}
 
@@ -1497,7 +1534,7 @@ where
 	}
 
 	fn call_runtime(&self, call: <Self::T as Config>::RuntimeCall) -> DispatchResultWithPostInfo {
-		let mut origin: T::RuntimeOrigin = RawOrigin::Signed(self.address().clone()).into();
+		let mut origin: T::RuntimeOrigin = RawOrigin::Signed(self.account_id().clone()).into();
 		origin.add_filter(T::CallFilter::contains);
 		call.dispatch(origin)
 	}
@@ -1528,7 +1565,7 @@ where
 		&mut self.transient_storage
 	}
 
-	fn set_code_hash(&mut self, hash: CodeHash<Self::T>) -> DispatchResult {
+	fn set_code_hash(&mut self, hash: H256) -> DispatchResult {
 		let frame = top_frame_mut!(self);
 
 		let info = frame.contract_info();
@@ -1548,14 +1585,14 @@ where
 		Self::increment_refcount(hash)?;
 		Self::decrement_refcount(prev_hash);
 		Contracts::<Self::T>::deposit_event(Event::ContractCodeUpdated {
-			contract: frame.account_id.clone(),
+			contract: T::AddressMapper::to_address(&frame.account_id),
 			new_code_hash: hash,
 			old_code_hash: prev_hash,
 		});
 		Ok(())
 	}
 
-	fn increment_refcount(code_hash: CodeHash<Self::T>) -> DispatchResult {
+	fn increment_refcount(code_hash: H256) -> DispatchResult {
 		<CodeInfoOf<Self::T>>::mutate(code_hash, |existing| -> Result<(), DispatchError> {
 			if let Some(info) = existing {
 				*info.refcount_mut() = info.refcount().saturating_add(1);
@@ -1566,7 +1603,7 @@ where
 		})
 	}
 
-	fn decrement_refcount(code_hash: CodeHash<T>) {
+	fn decrement_refcount(code_hash: H256) {
 		<CodeInfoOf<T>>::mutate(code_hash, |existing| {
 			if let Some(info) = existing {
 				*info.refcount_mut() = info.refcount().saturating_sub(1);
@@ -1574,7 +1611,7 @@ where
 		});
 	}
 
-	fn lock_delegate_dependency(&mut self, code_hash: CodeHash<Self::T>) -> DispatchResult {
+	fn lock_delegate_dependency(&mut self, code_hash: H256) -> DispatchResult {
 		let frame = self.top_frame_mut();
 		let info = frame.contract_info.get(&frame.account_id);
 		ensure!(code_hash != info.code_hash, Error::<T>::CannotAddSelfAsDelegateDependency);
@@ -1590,7 +1627,7 @@ where
 		Ok(())
 	}
 
-	fn unlock_delegate_dependency(&mut self, code_hash: &CodeHash<Self::T>) -> DispatchResult {
+	fn unlock_delegate_dependency(&mut self, code_hash: &H256) -> DispatchResult {
 		let frame = self.top_frame_mut();
 		let info = frame.contract_info.get(&frame.account_id);
 
@@ -1635,10 +1672,9 @@ mod tests {
 			test_utils::{get_balance, place_contract, set_balance},
 			ExtBuilder, RuntimeCall, RuntimeEvent as MetaEvent, Test, TestFilter,
 		},
-		Error,
+		AddressMapper, Error,
 	};
 	use assert_matches::assert_matches;
-	use codec::{Decode, Encode};
 	use frame_support::{assert_err, assert_ok, parameter_types};
 	use frame_system::{EventRecord, Phase};
 	use pallet_revive_uapi::ReturnFlags;
@@ -1673,25 +1709,25 @@ mod tests {
 	struct MockExecutable {
 		func: Rc<dyn for<'a> Fn(MockCtx<'a>, &Self) -> ExecResult + 'static>,
 		func_type: ExportedFunction,
-		code_hash: CodeHash<Test>,
+		code_hash: H256,
 		code_info: CodeInfo<Test>,
 	}
 
 	#[derive(Default, Clone)]
 	pub struct MockLoader {
-		map: HashMap<CodeHash<Test>, MockExecutable>,
+		map: HashMap<H256, MockExecutable>,
 		counter: u64,
 	}
 
 	impl MockLoader {
-		fn code_hashes() -> Vec<CodeHash<Test>> {
+		fn code_hashes() -> Vec<H256> {
 			Loader::get().map.keys().copied().collect()
 		}
 
 		fn insert(
 			func_type: ExportedFunction,
 			f: impl Fn(MockCtx, &MockExecutable) -> ExecResult + 'static,
-		) -> CodeHash<Test> {
+		) -> H256 {
 			Loader::mutate(|loader| {
 				// Generate code hashes as monotonically increasing values.
 				let hash = <Test as frame_system::Config>::Hash::from_low_u64_be(loader.counter);
@@ -1712,7 +1748,7 @@ mod tests {
 
 	impl Executable<Test> for MockExecutable {
 		fn from_storage(
-			code_hash: CodeHash<Test>,
+			code_hash: H256,
 			_gas_meter: &mut GasMeter<Test>,
 		) -> Result<Self, DispatchError> {
 			Loader::mutate(|loader| {
@@ -1746,7 +1782,12 @@ mod tests {
 			}
 		}
 
-		fn code_hash(&self) -> &CodeHash<Test> {
+		fn code(&self) -> &[u8] {
+			// The mock executable doesn't have code", so we return the code hash.
+			self.code_hash.as_ref()
+		}
+
+		fn code_hash(&self) -> &H256 {
 			&self.code_hash
 		}
 
@@ -1784,7 +1825,7 @@ mod tests {
 			assert_matches!(
 				MockStack::run_call(
 					Origin::from_account_id(ALICE),
-					BOB,
+					BOB_ADDR,
 					&mut gas_meter,
 					&mut storage_meter,
 					value,
@@ -1802,24 +1843,19 @@ mod tests {
 	fn transfer_works() {
 		// This test verifies that a contract is able to transfer
 		// some funds to another account.
-		let origin = ALICE;
-		let dest = BOB;
-
 		ExtBuilder::default().build().execute_with(|| {
-			set_balance(&origin, 100);
-			set_balance(&dest, 0);
+			set_balance(&ALICE, 100);
+			set_balance(&BOB, 0);
 
-			MockStack::transfer(Preservation::Preserve, &origin, &dest, 55).unwrap();
+			MockStack::transfer(Preservation::Preserve, &ALICE, &BOB, 55).unwrap();
 
-			assert_eq!(get_balance(&origin), 45);
-			assert_eq!(get_balance(&dest), 55);
+			assert_eq!(get_balance(&ALICE), 45);
+			assert_eq!(get_balance(&BOB), 55);
 		});
 	}
 
 	#[test]
 	fn correct_transfer_on_call() {
-		let origin = ALICE;
-		let dest = BOB;
 		let value = 55;
 
 		let success_ch = MockLoader::insert(Call, move |ctx, _| {
@@ -1828,15 +1864,15 @@ mod tests {
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
-			place_contract(&dest, success_ch);
-			set_balance(&origin, 100);
-			let balance = get_balance(&dest);
-			let contract_origin = Origin::from_account_id(origin.clone());
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, value).unwrap();
+			place_contract(&BOB, success_ch);
+			set_balance(&ALICE, 100);
+			let balance = get_balance(&BOB_CONTRACT_ID);
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, value).unwrap();
 
 			let _ = MockStack::run_call(
-				contract_origin.clone(),
-				dest.clone(),
+				origin.clone(),
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				value,
@@ -1845,15 +1881,13 @@ mod tests {
 			)
 			.unwrap();
 
-			assert_eq!(get_balance(&origin), 100 - value);
-			assert_eq!(get_balance(&dest), balance + value);
+			assert_eq!(get_balance(&ALICE), 100 - value);
+			assert_eq!(get_balance(&BOB_CONTRACT_ID), balance + value);
 		});
 	}
 
 	#[test]
 	fn correct_transfer_on_delegate_call() {
-		let origin = ALICE;
-		let dest = BOB;
 		let value = 35;
 
 		let success_ch = MockLoader::insert(Call, move |ctx, _| {
@@ -1868,15 +1902,15 @@ mod tests {
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
-			place_contract(&dest, delegate_ch);
-			set_balance(&origin, 100);
-			let balance = get_balance(&dest);
-			let contract_origin = Origin::from_account_id(origin.clone());
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 55).unwrap();
+			place_contract(&BOB, delegate_ch);
+			set_balance(&ALICE, 100);
+			let balance = get_balance(&BOB_CONTRACT_ID);
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 55).unwrap();
 
 			let _ = MockStack::run_call(
-				contract_origin.clone(),
-				dest.clone(),
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				value,
@@ -1885,8 +1919,8 @@ mod tests {
 			)
 			.unwrap();
 
-			assert_eq!(get_balance(&origin), 100 - value);
-			assert_eq!(get_balance(&dest), balance + value);
+			assert_eq!(get_balance(&ALICE), 100 - value);
+			assert_eq!(get_balance(&BOB_CONTRACT_ID), balance + value);
 		});
 	}
 
@@ -1894,23 +1928,21 @@ mod tests {
 	fn changes_are_reverted_on_failing_call() {
 		// This test verifies that changes are reverted on a call which fails (or equally, returns
 		// a non-zero status code).
-		let origin = ALICE;
-		let dest = BOB;
 
 		let return_ch = MockLoader::insert(Call, |_, _| {
 			Ok(ExecReturnValue { flags: ReturnFlags::REVERT, data: Vec::new() })
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
-			place_contract(&dest, return_ch);
-			set_balance(&origin, 100);
-			let balance = get_balance(&dest);
-			let contract_origin = Origin::from_account_id(origin.clone());
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 55).unwrap();
+			place_contract(&BOB, return_ch);
+			set_balance(&ALICE, 100);
+			let balance = get_balance(&BOB);
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 55).unwrap();
 
 			let output = MockStack::run_call(
-				contract_origin.clone(),
-				dest.clone(),
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				55,
@@ -1920,8 +1952,8 @@ mod tests {
 			.unwrap();
 
 			assert!(output.did_revert());
-			assert_eq!(get_balance(&origin), 100);
-			assert_eq!(get_balance(&dest), balance);
+			assert_eq!(get_balance(&ALICE), 100);
+			assert_eq!(get_balance(&BOB), balance);
 		});
 	}
 
@@ -1947,20 +1979,18 @@ mod tests {
 	fn output_is_returned_on_success() {
 		// Verifies that if a contract returns data with a successful exit status, this data
 		// is returned from the execution context.
-		let origin = ALICE;
-		let dest = BOB;
 		let return_ch = MockLoader::insert(Call, |_, _| {
 			Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: vec![1, 2, 3, 4] })
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
-			let contract_origin = Origin::from_account_id(origin);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			place_contract(&BOB, return_ch);
 
 			let result = MockStack::run_call(
-				contract_origin,
-				dest,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -1978,20 +2008,18 @@ mod tests {
 	fn output_is_returned_on_failure() {
 		// Verifies that if a contract returns data with a failing exit status, this data
 		// is returned from the execution context.
-		let origin = ALICE;
-		let dest = BOB;
 		let return_ch = MockLoader::insert(Call, |_, _| {
 			Ok(ExecReturnValue { flags: ReturnFlags::REVERT, data: vec![1, 2, 3, 4] })
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, return_ch);
-			let contract_origin = Origin::from_account_id(origin);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 
 			let result = MockStack::run_call(
-				contract_origin,
-				dest,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -2015,12 +2043,12 @@ mod tests {
 		// This one tests passing the input data into a contract via call.
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, input_data_ch);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -2048,13 +2076,10 @@ mod tests {
 				let executable =
 					MockExecutable::from_storage(input_data_ch, &mut gas_meter).unwrap();
 				set_balance(&ALICE, min_balance * 10_000);
-				let contract_origin = Origin::from_account_id(ALICE);
-				let mut storage_meter = storage::meter::Meter::new(
-					&contract_origin,
-					deposit_limit::<Test>(),
-					min_balance,
-				)
-				.unwrap();
+				let origin = Origin::from_account_id(ALICE);
+				let mut storage_meter =
+					storage::meter::Meter::new(&origin, deposit_limit::<Test>(), min_balance)
+						.unwrap();
 
 				let result = MockStack::run_instantiate(
 					ALICE,
@@ -2063,7 +2088,7 @@ mod tests {
 					&mut storage_meter,
 					min_balance,
 					vec![1, 2, 3, 4],
-					&[],
+					&[0; 32],
 					None,
 				);
 				assert_matches!(result, Ok(_));
@@ -2083,7 +2108,7 @@ mod tests {
 			let r = ctx.ext.call(
 				Weight::zero(),
 				BalanceOf::<Test>::zero(),
-				BOB,
+				&BOB_ADDR,
 				0,
 				vec![],
 				true,
@@ -2108,12 +2133,12 @@ mod tests {
 		ExtBuilder::default().build().execute_with(|| {
 			set_balance(&BOB, 1);
 			place_contract(&BOB, recurse_ch);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, value).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, value).unwrap();
 
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				value,
@@ -2127,18 +2152,18 @@ mod tests {
 
 	#[test]
 	fn caller_returns_proper_values() {
-		let origin = ALICE;
-		let dest = BOB;
-
 		parameter_types! {
-			static WitnessedCallerBob: Option<AccountIdOf<Test>> = None;
-			static WitnessedCallerCharlie: Option<AccountIdOf<Test>> = None;
+			static WitnessedCallerBob: Option<H160> = None;
+			static WitnessedCallerCharlie: Option<H160> = None;
 		}
 
 		let bob_ch = MockLoader::insert(Call, |ctx, _| {
 			// Record the caller for bob.
 			WitnessedCallerBob::mutate(|caller| {
-				*caller = Some(ctx.ext.caller().account_id().unwrap().clone())
+				let origin = ctx.ext.caller();
+				*caller = Some(<Test as Config>::AddressMapper::to_address(
+					&origin.account_id().unwrap(),
+				));
 			});
 
 			// Call into CHARLIE contract.
@@ -2146,7 +2171,7 @@ mod tests {
 				ctx.ext.call(
 					Weight::zero(),
 					BalanceOf::<Test>::zero(),
-					CHARLIE,
+					&CHARLIE_ADDR,
 					0,
 					vec![],
 					true,
@@ -2159,20 +2184,23 @@ mod tests {
 		let charlie_ch = MockLoader::insert(Call, |ctx, _| {
 			// Record the caller for charlie.
 			WitnessedCallerCharlie::mutate(|caller| {
-				*caller = Some(ctx.ext.caller().account_id().unwrap().clone())
+				let origin = ctx.ext.caller();
+				*caller = Some(<Test as Config>::AddressMapper::to_address(
+					&origin.account_id().unwrap(),
+				));
 			});
 			exec_success()
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
-			place_contract(&dest, bob_ch);
+			place_contract(&BOB, bob_ch);
 			place_contract(&CHARLIE, charlie_ch);
-			let contract_origin = Origin::from_account_id(origin.clone());
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 
 			let result = MockStack::run_call(
-				contract_origin.clone(),
-				dest.clone(),
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -2183,28 +2211,28 @@ mod tests {
 			assert_matches!(result, Ok(_));
 		});
 
-		assert_eq!(WitnessedCallerBob::get(), Some(origin));
-		assert_eq!(WitnessedCallerCharlie::get(), Some(dest));
+		assert_eq!(WitnessedCallerBob::get(), Some(ALICE_ADDR));
+		assert_eq!(WitnessedCallerCharlie::get(), Some(BOB_ADDR));
 	}
 
 	#[test]
 	fn is_contract_returns_proper_values() {
 		let bob_ch = MockLoader::insert(Call, |ctx, _| {
 			// Verify that BOB is a contract
-			assert!(ctx.ext.is_contract(&BOB));
+			assert!(ctx.ext.is_contract(&BOB_ADDR));
 			// Verify that ALICE is not a contract
-			assert!(!ctx.ext.is_contract(&ALICE));
+			assert!(!ctx.ext.is_contract(&ALICE_ADDR));
 			exec_success()
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, bob_ch);
 
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -2219,20 +2247,20 @@ mod tests {
 	fn code_hash_returns_proper_values() {
 		let code_bob = MockLoader::insert(Call, |ctx, _| {
 			// ALICE is not a contract and hence they do not have a code_hash
-			assert!(ctx.ext.code_hash(&ALICE).is_none());
+			assert!(ctx.ext.code_hash(&ALICE_ADDR).is_none());
 			// BOB is a contract and hence it has a code_hash
-			assert!(ctx.ext.code_hash(&BOB).is_some());
+			assert!(ctx.ext.code_hash(&BOB_ADDR).is_some());
 			exec_success()
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, code_bob);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			// ALICE (not contract) -> BOB (contract)
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -2246,19 +2274,19 @@ mod tests {
 	#[test]
 	fn own_code_hash_returns_proper_values() {
 		let bob_ch = MockLoader::insert(Call, |ctx, _| {
-			let code_hash = ctx.ext.code_hash(&BOB).unwrap();
+			let code_hash = ctx.ext.code_hash(&BOB_ADDR).unwrap();
 			assert_eq!(*ctx.ext.own_code_hash(), code_hash);
 			exec_success()
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, bob_ch);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			// ALICE (not contract) -> BOB (contract)
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -2281,19 +2309,26 @@ mod tests {
 			// ALICE is the origin of the call stack
 			assert!(ctx.ext.caller_is_origin());
 			// BOB calls CHARLIE
-			ctx.ext
-				.call(Weight::zero(), BalanceOf::<Test>::zero(), CHARLIE, 0, vec![], true, false)
+			ctx.ext.call(
+				Weight::zero(),
+				BalanceOf::<Test>::zero(),
+				&CHARLIE_ADDR,
+				0,
+				vec![],
+				true,
+				false,
+			)
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, code_bob);
 			place_contract(&CHARLIE, code_charlie);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			// ALICE -> BOB (caller is origin) -> CHARLIE (caller is not origin)
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -2314,12 +2349,12 @@ mod tests {
 
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, code_bob);
-			let contract_origin = Origin::Root;
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::Root;
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			// root -> BOB (caller is root)
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -2340,12 +2375,12 @@ mod tests {
 
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, code_bob);
-			let contract_origin = Origin::Root;
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::Root;
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			// root -> BOB (caller is root)
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				1,
@@ -2368,19 +2403,26 @@ mod tests {
 			// root is the origin of the call stack.
 			assert!(ctx.ext.caller_is_root());
 			// BOB calls CHARLIE.
-			ctx.ext
-				.call(Weight::zero(), BalanceOf::<Test>::zero(), CHARLIE, 0, vec![], true, false)
+			ctx.ext.call(
+				Weight::zero(),
+				BalanceOf::<Test>::zero(),
+				&CHARLIE_ADDR,
+				0,
+				vec![],
+				true,
+				false,
+			)
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, code_bob);
 			place_contract(&CHARLIE, code_charlie);
-			let contract_origin = Origin::Root;
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::Root;
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			// root -> BOB (caller is root) -> CHARLIE (caller is not root)
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -2395,14 +2437,14 @@ mod tests {
 	fn address_returns_proper_values() {
 		let bob_ch = MockLoader::insert(Call, |ctx, _| {
 			// Verify that address matches BOB.
-			assert_eq!(*ctx.ext.address(), BOB);
+			assert_eq!(ctx.ext.address(), BOB_ADDR);
 
 			// Call into charlie contract.
 			assert_matches!(
 				ctx.ext.call(
 					Weight::zero(),
 					BalanceOf::<Test>::zero(),
-					CHARLIE,
+					&CHARLIE_ADDR,
 					0,
 					vec![],
 					true,
@@ -2413,19 +2455,19 @@ mod tests {
 			exec_success()
 		});
 		let charlie_ch = MockLoader::insert(Call, |ctx, _| {
-			assert_eq!(*ctx.ext.address(), CHARLIE);
+			assert_eq!(ctx.ext.address(), CHARLIE_ADDR);
 			exec_success()
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, bob_ch);
 			place_contract(&CHARLIE, charlie_ch);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -2444,8 +2486,8 @@ mod tests {
 		ExtBuilder::default().existential_deposit(15).build().execute_with(|| {
 			let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 			let executable = MockExecutable::from_storage(dummy_ch, &mut gas_meter).unwrap();
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 
 			assert_matches!(
 				MockStack::run_instantiate(
@@ -2455,7 +2497,7 @@ mod tests {
 					&mut storage_meter,
 					0, // <- zero value
 					vec![],
-					&[],
+					&[0; 32],
 					None,
 				),
 				Err(_)
@@ -2478,10 +2520,9 @@ mod tests {
 				let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 				let executable = MockExecutable::from_storage(dummy_ch, &mut gas_meter).unwrap();
 				set_balance(&ALICE, min_balance * 1000);
-				let contract_origin = Origin::from_account_id(ALICE);
+				let origin = Origin::from_account_id(ALICE);
 				let mut storage_meter =
-					storage::meter::Meter::new(&contract_origin, min_balance * 100, min_balance)
-						.unwrap();
+					storage::meter::Meter::new(&origin, min_balance * 100, min_balance).unwrap();
 
 				let instantiated_contract_address = assert_matches!(
 					MockStack::run_instantiate(
@@ -2492,22 +2533,26 @@ mod tests {
 
 						min_balance,
 						vec![],
-						&[],
+						&[0;32],
 						None,
 					),
 					Ok((address, ref output)) if output.data == vec![80, 65, 83, 83] => address
 				);
+				let instantiated_contract_id =
+					<Test as Config>::AddressMapper::to_account_id_contract(
+						&instantiated_contract_address,
+					);
 
 				// Check that the newly created account has the expected code hash and
 				// there are instantiation event.
 				assert_eq!(
-					ContractInfo::<Test>::load_code_hash(&instantiated_contract_address).unwrap(),
+					ContractInfo::<Test>::load_code_hash(&instantiated_contract_id).unwrap(),
 					dummy_ch
 				);
 				assert_eq!(
 					&events(),
 					&[Event::Instantiated {
-						deployer: ALICE,
+						deployer: ALICE_ADDR,
 						contract: instantiated_contract_address
 					}]
 				);
@@ -2529,10 +2574,9 @@ mod tests {
 				let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 				let executable = MockExecutable::from_storage(dummy_ch, &mut gas_meter).unwrap();
 				set_balance(&ALICE, min_balance * 1000);
-				let contract_origin = Origin::from_account_id(ALICE);
+				let origin = Origin::from_account_id(ALICE);
 				let mut storage_meter =
-					storage::meter::Meter::new(&contract_origin, min_balance * 100, min_balance)
-						.unwrap();
+					storage::meter::Meter::new(&origin, min_balance * 100, min_balance).unwrap();
 
 				let instantiated_contract_address = assert_matches!(
 					MockStack::run_instantiate(
@@ -2543,16 +2587,19 @@ mod tests {
 
 						min_balance,
 						vec![],
-						&[],
+						&[0;32],
 						None,
 					),
 					Ok((address, ref output)) if output.data == vec![70, 65, 73, 76] => address
 				);
 
+				let instantiated_contract_id =
+					<Test as Config>::AddressMapper::to_account_id_contract(
+						&instantiated_contract_address,
+					);
+
 				// Check that the account has not been created.
-				assert!(
-					ContractInfo::<Test>::load_code_hash(&instantiated_contract_address).is_none()
-				);
+				assert!(ContractInfo::<Test>::load_code_hash(&instantiated_contract_id).is_none());
 				assert!(events().is_empty());
 			});
 	}
@@ -2560,7 +2607,7 @@ mod tests {
 	#[test]
 	fn instantiation_from_contract() {
 		let dummy_ch = MockLoader::insert(Call, |_, _| exec_success());
-		let instantiated_contract_address = Rc::new(RefCell::new(None::<AccountIdOf<Test>>));
+		let instantiated_contract_address = Rc::new(RefCell::new(None::<H160>));
 		let instantiator_ch = MockLoader::insert(Call, {
 			let instantiated_contract_address = Rc::clone(&instantiated_contract_address);
 			move |ctx, _| {
@@ -2573,11 +2620,11 @@ mod tests {
 						dummy_ch,
 						<Test as Config>::Currency::minimum_balance(),
 						vec![],
-						&[48, 49, 50],
+						&[48; 32],
 					)
 					.unwrap();
 
-				*instantiated_contract_address.borrow_mut() = address.into();
+				*instantiated_contract_address.borrow_mut() = Some(address);
 				Ok(output)
 			}
 		});
@@ -2590,18 +2637,15 @@ mod tests {
 				let min_balance = <Test as Config>::Currency::minimum_balance();
 				set_balance(&ALICE, min_balance * 100);
 				place_contract(&BOB, instantiator_ch);
-				let contract_origin = Origin::from_account_id(ALICE);
-				let mut storage_meter = storage::meter::Meter::new(
-					&contract_origin,
-					min_balance * 10,
-					min_balance * 10,
-				)
-				.unwrap();
+				let origin = Origin::from_account_id(ALICE);
+				let mut storage_meter =
+					storage::meter::Meter::new(&origin, min_balance * 10, min_balance * 10)
+						.unwrap();
 
 				assert_matches!(
 					MockStack::run_call(
-						contract_origin,
-						BOB,
+						origin,
+						BOB_ADDR,
 						&mut GasMeter::<Test>::new(GAS_LIMIT),
 						&mut storage_meter,
 						min_balance * 10,
@@ -2612,22 +2656,30 @@ mod tests {
 				);
 
 				let instantiated_contract_address =
-					instantiated_contract_address.borrow().as_ref().unwrap().clone();
+					*instantiated_contract_address.borrow().as_ref().unwrap();
+
+				let instantiated_contract_id =
+					<Test as Config>::AddressMapper::to_account_id_contract(
+						&instantiated_contract_address,
+					);
 
 				// Check that the newly created account has the expected code hash and
 				// there are instantiation event.
 				assert_eq!(
-					ContractInfo::<Test>::load_code_hash(&instantiated_contract_address).unwrap(),
+					ContractInfo::<Test>::load_code_hash(&instantiated_contract_id).unwrap(),
 					dummy_ch
 				);
 				assert_eq!(
 					&events(),
 					&[
 						Event::Instantiated {
-							deployer: BOB,
+							deployer: BOB_ADDR,
 							contract: instantiated_contract_address
 						},
-						Event::Called { caller: Origin::from_account_id(ALICE), contract: BOB },
+						Event::Called {
+							caller: Origin::from_account_id(ALICE),
+							contract: BOB_ADDR
+						},
 					]
 				);
 			});
@@ -2646,7 +2698,7 @@ mod tests {
 						dummy_ch,
 						<Test as Config>::Currency::minimum_balance(),
 						vec![],
-						&[],
+						&[0; 32],
 					),
 					Err(ExecError {
 						error: DispatchError::Other("It's a trap!"),
@@ -2664,16 +2716,15 @@ mod tests {
 			.build()
 			.execute_with(|| {
 				set_balance(&ALICE, 1000);
-				set_balance(&BOB, 100);
+				set_balance(&BOB_CONTRACT_ID, 100);
 				place_contract(&BOB, instantiator_ch);
-				let contract_origin = Origin::from_account_id(ALICE);
-				let mut storage_meter =
-					storage::meter::Meter::new(&contract_origin, 200, 0).unwrap();
+				let origin = Origin::from_account_id(ALICE);
+				let mut storage_meter = storage::meter::Meter::new(&origin, 200, 0).unwrap();
 
 				assert_matches!(
 					MockStack::run_call(
-						contract_origin,
-						BOB,
+						origin,
+						BOB_ADDR,
 						&mut GasMeter::<Test>::new(GAS_LIMIT),
 						&mut storage_meter,
 						0,
@@ -2687,7 +2738,7 @@ mod tests {
 				// event here.
 				assert_eq!(
 					&events(),
-					&[Event::Called { caller: Origin::from_account_id(ALICE), contract: BOB },]
+					&[Event::Called { caller: Origin::from_account_id(ALICE), contract: BOB_ADDR },]
 				);
 			});
 	}
@@ -2695,7 +2746,7 @@ mod tests {
 	#[test]
 	fn termination_from_instantiate_fails() {
 		let terminate_ch = MockLoader::insert(Constructor, |ctx, _| {
-			ctx.ext.terminate(&ALICE).unwrap();
+			ctx.ext.terminate(&ALICE_ADDR).unwrap();
 			exec_success()
 		});
 
@@ -2708,10 +2759,9 @@ mod tests {
 				let executable =
 					MockExecutable::from_storage(terminate_ch, &mut gas_meter).unwrap();
 				set_balance(&ALICE, 10_000);
-				let contract_origin = Origin::from_account_id(ALICE);
+				let origin = Origin::from_account_id(ALICE);
 				let mut storage_meter =
-					storage::meter::Meter::new(&contract_origin, deposit_limit::<Test>(), 100)
-						.unwrap();
+					storage::meter::Meter::new(&origin, deposit_limit::<Test>(), 100).unwrap();
 
 				assert_eq!(
 					MockStack::run_instantiate(
@@ -2721,7 +2771,7 @@ mod tests {
 						&mut storage_meter,
 						100,
 						vec![],
-						&[],
+						&[0; 32],
 						None,
 					),
 					Err(Error::<Test>::TerminatedInConstructor.into())
@@ -2750,7 +2800,7 @@ mod tests {
 					ctx.ext.call(
 						Weight::zero(),
 						BalanceOf::<Test>::zero(),
-						CHARLIE,
+						&CHARLIE_ADDR,
 						0,
 						vec![],
 						true,
@@ -2765,7 +2815,15 @@ mod tests {
 		let code_charlie = MockLoader::insert(Call, |ctx, _| {
 			assert!(ctx
 				.ext
-				.call(Weight::zero(), BalanceOf::<Test>::zero(), BOB, 0, vec![99], true, false)
+				.call(
+					Weight::zero(),
+					BalanceOf::<Test>::zero(),
+					&BOB_ADDR,
+					0,
+					vec![99],
+					true,
+					false
+				)
 				.is_ok());
 			exec_trapped()
 		});
@@ -2774,12 +2832,12 @@ mod tests {
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, code_bob);
 			place_contract(&CHARLIE, code_charlie);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -2793,10 +2851,13 @@ mod tests {
 	#[test]
 	fn recursive_call_during_constructor_fails() {
 		let code = MockLoader::insert(Constructor, |ctx, _| {
+			let account_id = ctx.ext.account_id().clone();
+			let addr = <Test as Config>::AddressMapper::to_address(&account_id);
+
 			assert_matches!(
-				ctx.ext.call(Weight::zero(), BalanceOf::<Test>::zero(), ctx.ext.address().clone(), 0, vec![], true, false),
-				Err(ExecError{error, ..}) if error == <Error<Test>>::ContractNotFound.into()
-			);
+						   ctx.ext.call(Weight::zero(), BalanceOf::<Test>::zero(), &addr, 0, vec![],
+			true, false), 				Err(ExecError{error, ..}) if error == <Error<Test>>::ContractNotFound.into()
+					   );
 			exec_success()
 		});
 
@@ -2809,13 +2870,10 @@ mod tests {
 				let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 				let executable = MockExecutable::from_storage(code, &mut gas_meter).unwrap();
 				set_balance(&ALICE, min_balance * 10_000);
-				let contract_origin = Origin::from_account_id(ALICE);
-				let mut storage_meter = storage::meter::Meter::new(
-					&contract_origin,
-					deposit_limit::<Test>(),
-					min_balance,
-				)
-				.unwrap();
+				let origin = Origin::from_account_id(ALICE);
+				let mut storage_meter =
+					storage::meter::Meter::new(&origin, deposit_limit::<Test>(), min_balance)
+						.unwrap();
 
 				let result = MockStack::run_instantiate(
 					ALICE,
@@ -2824,7 +2882,7 @@ mod tests {
 					&mut storage_meter,
 					min_balance,
 					vec![],
-					&[],
+					&[0; 32],
 					None,
 				);
 				assert_matches!(result, Ok(_));
@@ -2847,11 +2905,11 @@ mod tests {
 			let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 			set_balance(&ALICE, min_balance * 10);
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
 				0,
@@ -2880,11 +2938,11 @@ mod tests {
 			let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 			set_balance(&ALICE, min_balance * 10);
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
 				0,
@@ -2913,11 +2971,11 @@ mod tests {
 			let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 			set_balance(&ALICE, min_balance * 10);
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
 				0,
@@ -2933,9 +2991,9 @@ mod tests {
 	fn call_reentry_direct_recursion() {
 		// call the contract passed as input with disabled reentry
 		let code_bob = MockLoader::insert(Call, |ctx, _| {
-			let dest = Decode::decode(&mut ctx.input_data.as_ref()).unwrap();
+			let dest = H160::from_slice(ctx.input_data.as_ref());
 			ctx.ext
-				.call(Weight::zero(), BalanceOf::<Test>::zero(), dest, 0, vec![], false, false)
+				.call(Weight::zero(), BalanceOf::<Test>::zero(), &dest, 0, vec![], false, false)
 		});
 
 		let code_charlie = MockLoader::insert(Call, |_, _| exec_success());
@@ -2943,29 +3001,29 @@ mod tests {
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, code_bob);
 			place_contract(&CHARLIE, code_charlie);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 
 			// Calling another contract should succeed
 			assert_ok!(MockStack::run_call(
-				contract_origin.clone(),
-				BOB,
+				origin.clone(),
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
-				CHARLIE.encode(),
+				CHARLIE_ADDR.as_bytes().to_vec(),
 				None,
 			));
 
 			// Calling into oneself fails
 			assert_err!(
 				MockStack::run_call(
-					contract_origin,
-					BOB,
+					origin,
+					BOB_ADDR,
 					&mut GasMeter::<Test>::new(GAS_LIMIT),
 					&mut storage_meter,
 					0,
-					BOB.encode(),
+					BOB_ADDR.as_bytes().to_vec(),
 					None,
 				)
 				.map_err(|e| e.error),
@@ -2981,7 +3039,7 @@ mod tests {
 				ctx.ext.call(
 					Weight::zero(),
 					BalanceOf::<Test>::zero(),
-					CHARLIE,
+					&CHARLIE_ADDR,
 					0,
 					vec![],
 					false,
@@ -2994,21 +3052,28 @@ mod tests {
 
 		// call BOB with input set to '1'
 		let code_charlie = MockLoader::insert(Call, |ctx, _| {
-			ctx.ext
-				.call(Weight::zero(), BalanceOf::<Test>::zero(), BOB, 0, vec![1], true, false)
+			ctx.ext.call(
+				Weight::zero(),
+				BalanceOf::<Test>::zero(),
+				&BOB_ADDR,
+				0,
+				vec![1],
+				true,
+				false,
+			)
 		});
 
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, code_bob);
 			place_contract(&CHARLIE, code_charlie);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 
 			// BOB -> CHARLIE -> BOB fails as BOB denies reentry.
 			assert_err!(
 				MockStack::run_call(
-					contract_origin,
-					BOB,
+					origin,
+					BOB_ADDR,
 					&mut GasMeter::<Test>::new(GAS_LIMIT),
 					&mut storage_meter,
 					0,
@@ -3037,12 +3102,12 @@ mod tests {
 			let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 			set_balance(&ALICE, min_balance * 10);
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			System::reset_events();
 			MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
 				0,
@@ -3058,7 +3123,7 @@ mod tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: MetaEvent::System(frame_system::Event::Remarked {
-							sender: BOB,
+							sender: BOB_CONTRACT_ID,
 							hash: remark_hash
 						}),
 						topics: vec![],
@@ -3067,7 +3132,7 @@ mod tests {
 						phase: Phase::Initialization,
 						event: MetaEvent::Contracts(crate::Event::Called {
 							caller: Origin::from_account_id(ALICE),
-							contract: BOB,
+							contract: BOB_ADDR,
 						}),
 						topics: vec![],
 					},
@@ -3121,12 +3186,12 @@ mod tests {
 			let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 			set_balance(&ALICE, min_balance * 10);
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			System::reset_events();
 			MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
 				0,
@@ -3142,7 +3207,7 @@ mod tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: MetaEvent::System(frame_system::Event::Remarked {
-							sender: BOB,
+							sender: BOB_CONTRACT_ID,
 							hash: remark_hash
 						}),
 						topics: vec![],
@@ -3164,7 +3229,7 @@ mod tests {
 						phase: Phase::Initialization,
 						event: MetaEvent::Contracts(crate::Event::Called {
 							caller: Origin::from_account_id(ALICE),
-							contract: BOB,
+							contract: BOB_ADDR,
 						}),
 						topics: vec![],
 					},
@@ -3185,16 +3250,16 @@ mod tests {
 					fail_code,
 					ctx.ext.minimum_balance() * 100,
 					vec![],
-					&[],
+					&[0; 32],
 				)
 				.ok();
 			exec_success()
 		});
 		let succ_succ_code = MockLoader::insert(Constructor, move |ctx, _| {
 			let alice_nonce = System::account_nonce(&ALICE);
-			assert_eq!(System::account_nonce(ctx.ext.address()), 0);
+			assert_eq!(System::account_nonce(ctx.ext.account_id()), 0);
 			assert_eq!(ctx.ext.caller().account_id().unwrap(), &ALICE);
-			let (account_id, _) = ctx
+			let (addr, _) = ctx
 				.ext
 				.instantiate(
 					Weight::zero(),
@@ -3202,29 +3267,23 @@ mod tests {
 					success_code,
 					ctx.ext.minimum_balance() * 100,
 					vec![],
-					&[],
+					&[0; 32],
 				)
 				.unwrap();
 
+			let account_id = <Test as Config>::AddressMapper::to_account_id_contract(&addr);
+
 			assert_eq!(System::account_nonce(&ALICE), alice_nonce);
-			assert_eq!(System::account_nonce(ctx.ext.address()), 1);
+			assert_eq!(System::account_nonce(ctx.ext.account_id()), 1);
 			assert_eq!(System::account_nonce(&account_id), 0);
 
 			// a plain call should not influence the account counter
 			ctx.ext
-				.call(
-					Weight::zero(),
-					BalanceOf::<Test>::zero(),
-					account_id.clone(),
-					0,
-					vec![],
-					false,
-					false,
-				)
+				.call(Weight::zero(), BalanceOf::<Test>::zero(), &addr, 0, vec![], false, false)
 				.unwrap();
 
 			assert_eq!(System::account_nonce(ALICE), alice_nonce);
-			assert_eq!(System::account_nonce(ctx.ext.address()), 1);
+			assert_eq!(System::account_nonce(ctx.ext.account_id()), 1);
 			assert_eq!(System::account_nonce(&account_id), 0);
 
 			exec_success()
@@ -3246,13 +3305,10 @@ mod tests {
 					MockExecutable::from_storage(succ_succ_code, &mut gas_meter).unwrap();
 				set_balance(&ALICE, min_balance * 10_000);
 				set_balance(&BOB, min_balance * 10_000);
-				let contract_origin = Origin::from_account_id(BOB);
-				let mut storage_meter = storage::meter::Meter::new(
-					&contract_origin,
-					deposit_limit::<Test>(),
-					min_balance * 100,
-				)
-				.unwrap();
+				let origin = Origin::from_account_id(BOB);
+				let mut storage_meter =
+					storage::meter::Meter::new(&origin, deposit_limit::<Test>(), min_balance * 100)
+						.unwrap();
 
 				// fail should not increment
 				MockStack::run_instantiate(
@@ -3262,7 +3318,7 @@ mod tests {
 					&mut storage_meter,
 					min_balance * 100,
 					vec![],
-					&[],
+					&[0; 32],
 					None,
 				)
 				.ok();
@@ -3275,7 +3331,7 @@ mod tests {
 					&mut storage_meter,
 					min_balance * 100,
 					vec![],
-					&[],
+					&[0; 32],
 					None,
 				));
 				assert_eq!(System::account_nonce(&ALICE), 1);
@@ -3287,7 +3343,7 @@ mod tests {
 					&mut storage_meter,
 					min_balance * 200,
 					vec![],
-					&[],
+					&[0; 32],
 					None,
 				));
 				assert_eq!(System::account_nonce(&ALICE), 2);
@@ -3299,7 +3355,7 @@ mod tests {
 					&mut storage_meter,
 					min_balance * 200,
 					vec![],
-					&[],
+					&[0; 32],
 					None,
 				));
 				assert_eq!(System::account_nonce(&ALICE), 3);
@@ -3358,12 +3414,12 @@ mod tests {
 			let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 			set_balance(&ALICE, min_balance * 1000);
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
+			let origin = Origin::from_account_id(ALICE);
 			let mut storage_meter =
-				storage::meter::Meter::new(&contract_origin, deposit_limit::<Test>(), 0).unwrap();
+				storage::meter::Meter::new(&origin, deposit_limit::<Test>(), 0).unwrap();
 			assert_ok!(MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
 				0,
@@ -3469,12 +3525,12 @@ mod tests {
 			let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 			set_balance(&ALICE, min_balance * 1000);
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
+			let origin = Origin::from_account_id(ALICE);
 			let mut storage_meter =
-				storage::meter::Meter::new(&contract_origin, deposit_limit::<Test>(), 0).unwrap();
+				storage::meter::Meter::new(&origin, deposit_limit::<Test>(), 0).unwrap();
 			assert_ok!(MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
 				0,
@@ -3508,12 +3564,12 @@ mod tests {
 			let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 			set_balance(&ALICE, min_balance * 1000);
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
+			let origin = Origin::from_account_id(ALICE);
 			let mut storage_meter =
-				storage::meter::Meter::new(&contract_origin, deposit_limit::<Test>(), 0).unwrap();
+				storage::meter::Meter::new(&origin, deposit_limit::<Test>(), 0).unwrap();
 			assert_ok!(MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
 				0,
@@ -3547,12 +3603,12 @@ mod tests {
 			let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 			set_balance(&ALICE, min_balance * 1000);
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
+			let origin = Origin::from_account_id(ALICE);
 			let mut storage_meter =
-				storage::meter::Meter::new(&contract_origin, deposit_limit::<Test>(), 0).unwrap();
+				storage::meter::Meter::new(&origin, deposit_limit::<Test>(), 0).unwrap();
 			assert_ok!(MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
 				0,
@@ -3600,12 +3656,12 @@ mod tests {
 			let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 			set_balance(&ALICE, min_balance * 1000);
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
+			let origin = Origin::from_account_id(ALICE);
 			let mut storage_meter =
-				storage::meter::Meter::new(&contract_origin, deposit_limit::<Test>(), 0).unwrap();
+				storage::meter::Meter::new(&origin, deposit_limit::<Test>(), 0).unwrap();
 			assert_ok!(MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
 				0,
@@ -3656,12 +3712,12 @@ mod tests {
 			let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
 			set_balance(&ALICE, min_balance * 1000);
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
+			let origin = Origin::from_account_id(ALICE);
 			let mut storage_meter =
-				storage::meter::Meter::new(&contract_origin, deposit_limit::<Test>(), 0).unwrap();
+				storage::meter::Meter::new(&origin, deposit_limit::<Test>(), 0).unwrap();
 			assert_ok!(MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut gas_meter,
 				&mut storage_meter,
 				0,
@@ -3731,12 +3787,12 @@ mod tests {
 
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
+			let origin = Origin::from_account_id(ALICE);
 			let mut storage_meter =
-				storage::meter::Meter::new(&contract_origin, deposit_limit::<Test>(), 0).unwrap();
+				storage::meter::Meter::new(&origin, deposit_limit::<Test>(), 0).unwrap();
 			assert_ok!(MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -3762,7 +3818,7 @@ mod tests {
 					ctx.ext.call(
 						Weight::zero(),
 						BalanceOf::<Test>::zero(),
-						CHARLIE,
+						&CHARLIE_ADDR,
 						0,
 						vec![],
 						true,
@@ -3788,7 +3844,15 @@ mod tests {
 		let code_charlie = MockLoader::insert(Call, |ctx, _| {
 			assert!(ctx
 				.ext
-				.call(Weight::zero(), BalanceOf::<Test>::zero(), BOB, 0, vec![99], true, false)
+				.call(
+					Weight::zero(),
+					BalanceOf::<Test>::zero(),
+					&BOB_ADDR,
+					0,
+					vec![99],
+					true,
+					false
+				)
 				.is_ok());
 			// CHARLIE can not read BOB`s storage.
 			assert_eq!(ctx.ext.get_transient_storage(storage_key_1), None);
@@ -3799,12 +3863,12 @@ mod tests {
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, code_bob);
 			place_contract(&CHARLIE, code_charlie);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -3838,11 +3902,11 @@ mod tests {
 
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, code_hash);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			assert_ok!(MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -3866,7 +3930,7 @@ mod tests {
 					ctx.ext.call(
 						Weight::zero(),
 						BalanceOf::<Test>::zero(),
-						CHARLIE,
+						&CHARLIE_ADDR,
 						0,
 						vec![],
 						true,
@@ -3888,7 +3952,15 @@ mod tests {
 		let code_charlie = MockLoader::insert(Call, |ctx, _| {
 			assert!(ctx
 				.ext
-				.call(Weight::zero(), BalanceOf::<Test>::zero(), BOB, 0, vec![99], true, false)
+				.call(
+					Weight::zero(),
+					BalanceOf::<Test>::zero(),
+					&BOB_ADDR,
+					0,
+					vec![99],
+					true,
+					false
+				)
 				.is_ok());
 			exec_trapped()
 		});
@@ -3897,12 +3969,12 @@ mod tests {
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, code_bob);
 			place_contract(&CHARLIE, code_charlie);
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
@@ -3931,11 +4003,11 @@ mod tests {
 		ExtBuilder::default().build().execute_with(|| {
 			place_contract(&BOB, bob_ch);
 
-			let contract_origin = Origin::from_account_id(ALICE);
-			let mut storage_meter = storage::meter::Meter::new(&contract_origin, 0, 0).unwrap();
+			let origin = Origin::from_account_id(ALICE);
+			let mut storage_meter = storage::meter::Meter::new(&origin, 0, 0).unwrap();
 			let result = MockStack::run_call(
-				contract_origin,
-				BOB,
+				origin,
+				BOB_ADDR,
 				&mut GasMeter::<Test>::new(GAS_LIMIT),
 				&mut storage_meter,
 				0,
diff --git a/substrate/frame/revive/src/lib.rs b/substrate/frame/revive/src/lib.rs
index 303c649bc8cf1b0dfbf2eb5247d04655db88eddc..359434b9abd61b03681c5554231d0789e500c21c 100644
--- a/substrate/frame/revive/src/lib.rs
+++ b/substrate/frame/revive/src/lib.rs
@@ -70,13 +70,14 @@ use frame_system::{
 	EventRecord, Pallet as System,
 };
 use scale_info::TypeInfo;
+use sp_core::{H160, H256};
 use sp_runtime::{
-	traits::{BadOrigin, Convert, Dispatchable, Saturating, StaticLookup},
+	traits::{BadOrigin, Convert, Dispatchable, Saturating},
 	DispatchError,
 };
 
 pub use crate::{
-	address::{AddressGenerator, DefaultAddressGenerator},
+	address::{AddressMapper, DefaultAddressMapper},
 	debug::Tracing,
 	migration::{MigrateSequence, Migration, NoopMigration},
 	pallet::*,
@@ -86,12 +87,10 @@ pub use weights::WeightInfo;
 #[cfg(doc)]
 pub use crate::wasm::SyscallDoc;
 
-type CodeHash<T> = <T as frame_system::Config>::Hash;
 type TrieId = BoundedVec<u8, ConstU32<128>>;
 type BalanceOf<T> =
 	<<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
 type CodeVec<T> = BoundedVec<u8, <T as Config>::MaxCodeLen>;
-type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;
 type EventRecordOf<T> =
 	EventRecord<<T as frame_system::Config>::RuntimeEvent, <T as frame_system::Config>::Hash>;
 type DebugBuffer = BoundedVec<u8, ConstU32<{ limits::DEBUG_BUFFER_BYTES }>>;
@@ -228,9 +227,9 @@ pub mod pallet {
 		#[pallet::constant]
 		type CodeHashLockupDepositPercent: Get<Perbill>;
 
-		/// The address generator used to generate the addresses of contracts.
+		/// Only valid type is [`DefaultAddressMapper`].
 		#[pallet::no_default_bounds]
-		type AddressGenerator: AddressGenerator<Self>;
+		type AddressMapper: AddressMapper<AccountIdOf<Self>>;
 
 		/// The maximum length of a contract code in bytes.
 		///
@@ -376,8 +375,7 @@ pub mod pallet {
 
 			#[inject_runtime_type]
 			type RuntimeCall = ();
-
-			type AddressGenerator = DefaultAddressGenerator;
+			type AddressMapper = DefaultAddressMapper;
 			type CallFilter = ();
 			type ChainExtension = ();
 			type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
@@ -401,7 +399,7 @@ pub mod pallet {
 	#[pallet::event]
 	pub enum Event<T: Config> {
 		/// Contract deployed by address at the specified address.
-		Instantiated { deployer: T::AccountId, contract: T::AccountId },
+		Instantiated { deployer: H160, contract: H160 },
 
 		/// Contract has been removed.
 		///
@@ -411,34 +409,34 @@ pub mod pallet {
 		/// `seal_terminate`.
 		Terminated {
 			/// The contract that was terminated.
-			contract: T::AccountId,
+			contract: H160,
 			/// The account that received the contracts remaining balance
-			beneficiary: T::AccountId,
+			beneficiary: H160,
 		},
 
 		/// Code with the specified hash has been stored.
-		CodeStored { code_hash: T::Hash, deposit_held: BalanceOf<T>, uploader: T::AccountId },
+		CodeStored { code_hash: H256, deposit_held: BalanceOf<T>, uploader: H160 },
 
 		/// A custom event emitted by the contract.
 		ContractEmitted {
 			/// The contract that emitted the event.
-			contract: T::AccountId,
+			contract: H160,
 			/// Data supplied by the contract. Metadata generated during contract compilation
 			/// is needed to decode it.
 			data: Vec<u8>,
 		},
 
 		/// A code with the specified hash was removed.
-		CodeRemoved { code_hash: T::Hash, deposit_released: BalanceOf<T>, remover: T::AccountId },
+		CodeRemoved { code_hash: H256, deposit_released: BalanceOf<T>, remover: H160 },
 
 		/// A contract's code was updated.
 		ContractCodeUpdated {
 			/// The contract that has been updated.
-			contract: T::AccountId,
+			contract: H160,
 			/// New code hash that was set for the contract.
-			new_code_hash: T::Hash,
+			new_code_hash: H256,
 			/// Previous code hash of the contract.
-			old_code_hash: T::Hash,
+			old_code_hash: H256,
 		},
 
 		/// A contract was called either by a plain account or another contract.
@@ -452,7 +450,7 @@ pub mod pallet {
 			/// The caller of the `contract`.
 			caller: Origin<T>,
 			/// The contract that was called.
-			contract: T::AccountId,
+			contract: H160,
 		},
 
 		/// A contract delegate called a code hash.
@@ -465,24 +463,16 @@ pub mod pallet {
 		DelegateCalled {
 			/// The contract that performed the delegate call and hence in whose context
 			/// the `code_hash` is executed.
-			contract: T::AccountId,
+			contract: H160,
 			/// The code hash that was delegate called.
-			code_hash: CodeHash<T>,
+			code_hash: H256,
 		},
 
 		/// Some funds have been transferred and held as storage deposit.
-		StorageDepositTransferredAndHeld {
-			from: T::AccountId,
-			to: T::AccountId,
-			amount: BalanceOf<T>,
-		},
+		StorageDepositTransferredAndHeld { from: H160, to: H160, amount: BalanceOf<T> },
 
 		/// Some storage deposit funds have been transferred and released.
-		StorageDepositTransferredAndReleased {
-			from: T::AccountId,
-			to: T::AccountId,
-			amount: BalanceOf<T>,
-		},
+		StorageDepositTransferredAndReleased { from: H160, to: H160, amount: BalanceOf<T> },
 	}
 
 	#[pallet::error]
@@ -592,16 +582,15 @@ pub mod pallet {
 
 	/// A mapping from a contract's code hash to its code.
 	#[pallet::storage]
-	pub(crate) type PristineCode<T: Config> = StorageMap<_, Identity, CodeHash<T>, CodeVec<T>>;
+	pub(crate) type PristineCode<T: Config> = StorageMap<_, Identity, H256, CodeVec<T>>;
 
 	/// A mapping from a contract's code hash to its code info.
 	#[pallet::storage]
-	pub(crate) type CodeInfoOf<T: Config> = StorageMap<_, Identity, CodeHash<T>, CodeInfo<T>>;
+	pub(crate) type CodeInfoOf<T: Config> = StorageMap<_, Identity, H256, CodeInfo<T>>;
 
 	/// The code associated with a given account.
 	#[pallet::storage]
-	pub(crate) type ContractInfoOf<T: Config> =
-		StorageMap<_, Identity, T::AccountId, ContractInfo<T>>;
+	pub(crate) type ContractInfoOf<T: Config> = StorageMap<_, Identity, H160, ContractInfo<T>>;
 
 	/// Evicted contracts that await child trie deletion.
 	///
@@ -804,13 +793,12 @@ pub mod pallet {
 		#[pallet::weight(T::WeightInfo::call().saturating_add(*gas_limit))]
 		pub fn call(
 			origin: OriginFor<T>,
-			dest: AccountIdLookupOf<T>,
+			dest: H160,
 			#[pallet::compact] value: BalanceOf<T>,
 			gas_limit: Weight,
 			#[pallet::compact] storage_deposit_limit: BalanceOf<T>,
 			data: Vec<u8>,
 		) -> DispatchResultWithPostInfo {
-			let dest = T::Lookup::lookup(dest)?;
 			let mut output = Self::bare_call(
 				origin,
 				dest,
@@ -843,9 +831,9 @@ pub mod pallet {
 			#[pallet::compact] value: BalanceOf<T>,
 			gas_limit: Weight,
 			#[pallet::compact] storage_deposit_limit: BalanceOf<T>,
-			code_hash: CodeHash<T>,
+			code_hash: sp_core::H256,
 			data: Vec<u8>,
-			salt: Vec<u8>,
+			salt: [u8; 32],
 		) -> DispatchResultWithPostInfo {
 			let data_len = data.len() as u32;
 			let salt_len = salt.len() as u32;
@@ -887,7 +875,7 @@ pub mod pallet {
 		///   from the caller to pay for the storage consumed.
 		/// * `code`: The contract code to deploy in raw bytes.
 		/// * `data`: The input data to pass to the contract constructor.
-		/// * `salt`: Used for the address derivation. See [`Pallet::contract_address`].
+		/// * `salt`: Used for the address derivation. See [`crate::address::create2`].
 		///
 		/// Instantiation is executed as follows:
 		///
@@ -909,7 +897,7 @@ pub mod pallet {
 			#[pallet::compact] storage_deposit_limit: BalanceOf<T>,
 			code: Vec<u8>,
 			data: Vec<u8>,
-			salt: Vec<u8>,
+			salt: [u8; 32],
 		) -> DispatchResultWithPostInfo {
 			let code_len = code.len() as u32;
 			let data_len = data.len() as u32;
@@ -967,7 +955,7 @@ pub mod pallet {
 		#[pallet::weight(T::WeightInfo::remove_code())]
 		pub fn remove_code(
 			origin: OriginFor<T>,
-			code_hash: CodeHash<T>,
+			code_hash: sp_core::H256,
 		) -> DispatchResultWithPostInfo {
 			Migration::<T>::ensure_migrated()?;
 			let origin = ensure_signed(origin)?;
@@ -990,12 +978,11 @@ pub mod pallet {
 		#[pallet::weight(T::WeightInfo::set_code())]
 		pub fn set_code(
 			origin: OriginFor<T>,
-			dest: AccountIdLookupOf<T>,
-			code_hash: CodeHash<T>,
+			dest: H160,
+			code_hash: sp_core::H256,
 		) -> DispatchResult {
 			Migration::<T>::ensure_migrated()?;
 			ensure_root(origin)?;
-			let dest = T::Lookup::lookup(dest)?;
 			<ContractInfoOf<T>>::try_mutate(&dest, |contract| {
 				let contract = if let Some(contract) = contract {
 					contract
@@ -1005,7 +992,7 @@ pub mod pallet {
 				<ExecStack<T, WasmBlob<T>>>::increment_refcount(code_hash)?;
 				<ExecStack<T, WasmBlob<T>>>::decrement_refcount(contract.code_hash);
 				Self::deposit_event(Event::ContractCodeUpdated {
-					contract: dest.clone(),
+					contract: dest,
 					new_code_hash: code_hash,
 					old_code_hash: contract.code_hash,
 				});
@@ -1075,7 +1062,7 @@ impl<T: Config> Pallet<T> {
 	/// collection).
 	pub fn bare_call(
 		origin: OriginFor<T>,
-		dest: T::AccountId,
+		dest: H160,
 		value: BalanceOf<T>,
 		gas_limit: Weight,
 		storage_deposit_limit: BalanceOf<T>,
@@ -1133,12 +1120,12 @@ impl<T: Config> Pallet<T> {
 		value: BalanceOf<T>,
 		gas_limit: Weight,
 		mut storage_deposit_limit: BalanceOf<T>,
-		code: Code<CodeHash<T>>,
+		code: Code,
 		data: Vec<u8>,
-		salt: Vec<u8>,
+		salt: [u8; 32],
 		debug: DebugInfo,
 		collect_events: CollectEvents,
-	) -> ContractInstantiateResult<T::AccountId, BalanceOf<T>, EventRecordOf<T>> {
+	) -> ContractInstantiateResult<BalanceOf<T>, EventRecordOf<T>> {
 		let mut gas_meter = GasMeter::new(gas_limit);
 		let mut storage_deposit = Default::default();
 		let mut debug_message =
@@ -1187,7 +1174,7 @@ impl<T: Config> Pallet<T> {
 		};
 		ContractInstantiateResult {
 			result: output
-				.map(|(account_id, result)| InstantiateReturnValue { result, account_id })
+				.map(|(addr, result)| InstantiateReturnValue { result, addr })
 				.map_err(|e| e.error),
 			gas_consumed: gas_meter.gas_consumed(),
 			gas_required: gas_meter.gas_required(),
@@ -1204,7 +1191,7 @@ impl<T: Config> Pallet<T> {
 		origin: OriginFor<T>,
 		code: Vec<u8>,
 		storage_deposit_limit: BalanceOf<T>,
-	) -> CodeUploadResult<CodeHash<T>, BalanceOf<T>> {
+	) -> CodeUploadResult<BalanceOf<T>> {
 		Migration::<T>::ensure_migrated()?;
 		let origin = T::UploadOrigin::ensure_origin(origin)?;
 		let (module, deposit) = Self::try_upload_code(origin, code, storage_deposit_limit, None)?;
@@ -1212,34 +1199,17 @@ impl<T: Config> Pallet<T> {
 	}
 
 	/// Query storage of a specified contract under a specified key.
-	pub fn get_storage(address: T::AccountId, key: Vec<u8>) -> GetStorageResult {
+	pub fn get_storage(address: H160, key: [u8; 32]) -> GetStorageResult {
 		if Migration::<T>::in_progress() {
 			return Err(ContractAccessError::MigrationInProgress)
 		}
 		let contract_info =
 			ContractInfoOf::<T>::get(&address).ok_or(ContractAccessError::DoesntExist)?;
 
-		let maybe_value = contract_info.read(
-			&Key::try_from_var(key)
-				.map_err(|_| ContractAccessError::KeyDecodingFailed)?
-				.into(),
-		);
+		let maybe_value = contract_info.read(&Key::from_fixed(key));
 		Ok(maybe_value)
 	}
 
-	/// Determine the address of a contract.
-	///
-	/// This is the address generation function used by contract instantiation. See
-	/// [`DefaultAddressGenerator`] for the default implementation.
-	pub fn contract_address(
-		deploying_address: &T::AccountId,
-		code_hash: &CodeHash<T>,
-		input_data: &[u8],
-		salt: &[u8],
-	) -> T::AccountId {
-		T::AddressGenerator::contract_address(deploying_address, code_hash, input_data, salt)
-	}
-
 	/// Uploads new code and returns the Wasm blob and deposit amount collected.
 	fn try_upload_code(
 		origin: T::AccountId,
@@ -1300,11 +1270,10 @@ environmental!(executing_contract: bool);
 sp_api::decl_runtime_apis! {
 	/// The API used to dry-run contract interactions.
 	#[api_version(1)]
-	pub trait ReviveApi<AccountId, Balance, BlockNumber, Hash, EventRecord> where
+	pub trait ReviveApi<AccountId, Balance, BlockNumber, EventRecord> where
 		AccountId: Codec,
 		Balance: Codec,
 		BlockNumber: Codec,
-		Hash: Codec,
 		EventRecord: Codec,
 	{
 		/// Perform a call from a specified account to a given contract.
@@ -1312,7 +1281,7 @@ sp_api::decl_runtime_apis! {
 		/// See [`crate::Pallet::bare_call`].
 		fn call(
 			origin: AccountId,
-			dest: AccountId,
+			dest: H160,
 			value: Balance,
 			gas_limit: Option<Weight>,
 			storage_deposit_limit: Option<Balance>,
@@ -1327,10 +1296,10 @@ sp_api::decl_runtime_apis! {
 			value: Balance,
 			gas_limit: Option<Weight>,
 			storage_deposit_limit: Option<Balance>,
-			code: Code<Hash>,
+			code: Code,
 			data: Vec<u8>,
-			salt: Vec<u8>,
-		) -> ContractInstantiateResult<AccountId, Balance, EventRecord>;
+			salt: [u8; 32],
+		) -> ContractInstantiateResult<Balance, EventRecord>;
 
 		/// Upload new code without instantiating a contract from it.
 		///
@@ -1339,7 +1308,7 @@ sp_api::decl_runtime_apis! {
 			origin: AccountId,
 			code: Vec<u8>,
 			storage_deposit_limit: Option<Balance>,
-		) -> CodeUploadResult<Hash, Balance>;
+		) -> CodeUploadResult<Balance>;
 
 		/// Query a given storage key in a given contract.
 		///
@@ -1347,8 +1316,8 @@ sp_api::decl_runtime_apis! {
 		/// specified account and `Ok(None)` if it doesn't. If the account specified by the address
 		/// doesn't exist, or doesn't have a contract then `Err` is returned.
 		fn get_storage(
-			address: AccountId,
-			key: Vec<u8>,
+			address: H160,
+			key: [u8; 32],
 		) -> GetStorageResult;
 	}
 }
diff --git a/substrate/frame/revive/src/primitives.rs b/substrate/frame/revive/src/primitives.rs
index a4a1133b71041969fecafbd2496879c249ba9f5b..98e8879457bf140acd62b644591ac2fd0d0d7a68 100644
--- a/substrate/frame/revive/src/primitives.rs
+++ b/substrate/frame/revive/src/primitives.rs
@@ -17,6 +17,7 @@
 
 //! A crate that hosts a common definitions that are relevant for the pallet-revive.
 
+use crate::H160;
 use alloc::vec::Vec;
 use codec::{Decode, Encode, MaxEncodedLen};
 use frame_support::weights::Weight;
@@ -86,12 +87,11 @@ pub type ContractExecResult<Balance, EventRecord> =
 	ContractResult<Result<ExecReturnValue, DispatchError>, Balance, EventRecord>;
 
 /// Result type of a `bare_instantiate` call as well as `ContractsApi::instantiate`.
-pub type ContractInstantiateResult<AccountId, Balance, EventRecord> =
-	ContractResult<Result<InstantiateReturnValue<AccountId>, DispatchError>, Balance, EventRecord>;
+pub type ContractInstantiateResult<Balance, EventRecord> =
+	ContractResult<Result<InstantiateReturnValue, DispatchError>, Balance, EventRecord>;
 
 /// Result type of a `bare_code_upload` call.
-pub type CodeUploadResult<CodeHash, Balance> =
-	Result<CodeUploadReturnValue<CodeHash, Balance>, DispatchError>;
+pub type CodeUploadResult<Balance> = Result<CodeUploadReturnValue<Balance>, DispatchError>;
 
 /// Result type of a `get_storage` call.
 pub type GetStorageResult = Result<Option<Vec<u8>>, ContractAccessError>;
@@ -125,29 +125,29 @@ impl ExecReturnValue {
 
 /// The result of a successful contract instantiation.
 #[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)]
-pub struct InstantiateReturnValue<AccountId> {
+pub struct InstantiateReturnValue {
 	/// The output of the called constructor.
 	pub result: ExecReturnValue,
-	/// The account id of the new contract.
-	pub account_id: AccountId,
+	/// The address of the new contract.
+	pub addr: H160,
 }
 
 /// The result of successfully uploading a contract.
 #[derive(Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, RuntimeDebug, TypeInfo)]
-pub struct CodeUploadReturnValue<CodeHash, Balance> {
+pub struct CodeUploadReturnValue<Balance> {
 	/// The key under which the new code is stored.
-	pub code_hash: CodeHash,
+	pub code_hash: sp_core::H256,
 	/// The deposit that was reserved at the caller. Is zero when the code already existed.
 	pub deposit: Balance,
 }
 
 /// Reference to an existing code hash or a new wasm module.
 #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
-pub enum Code<Hash> {
+pub enum Code {
 	/// A wasm module as raw bytes.
 	Upload(Vec<u8>),
 	/// The code hash of an on-chain wasm blob.
-	Existing(Hash),
+	Existing(sp_core::H256),
 }
 
 /// The amount of balance that was either charged or refunded in order to pay for storage.
diff --git a/substrate/frame/revive/src/storage.rs b/substrate/frame/revive/src/storage.rs
index 87274ce407fa4508f0f205463fe60cafc5789750..91b7b904d2bbecd4e19446a9769ceeb950da176a 100644
--- a/substrate/frame/revive/src/storage.rs
+++ b/substrate/frame/revive/src/storage.rs
@@ -20,12 +20,13 @@
 pub mod meter;
 
 use crate::{
+	address::AddressMapper,
 	exec::{AccountIdOf, Key},
 	limits,
 	storage::meter::Diff,
 	weights::WeightInfo,
-	BalanceOf, CodeHash, CodeInfo, Config, ContractInfoOf, DeletionQueue, DeletionQueueCounter,
-	Error, TrieId, SENTINEL,
+	BalanceOf, CodeInfo, Config, ContractInfoOf, DeletionQueue, DeletionQueueCounter, Error,
+	TrieId, SENTINEL,
 };
 use alloc::vec::Vec;
 use codec::{Decode, Encode, MaxEncodedLen};
@@ -36,7 +37,7 @@ use frame_support::{
 	CloneNoBound, DefaultNoBound,
 };
 use scale_info::TypeInfo;
-use sp_core::{ConstU32, Get};
+use sp_core::{ConstU32, Get, H160};
 use sp_io::KillStorageResult;
 use sp_runtime::{
 	traits::{Hash, Saturating, Zero},
@@ -44,7 +45,7 @@ use sp_runtime::{
 };
 
 type DelegateDependencyMap<T> =
-	BoundedBTreeMap<CodeHash<T>, BalanceOf<T>, ConstU32<{ limits::DELEGATE_DEPENDENCIES }>>;
+	BoundedBTreeMap<sp_core::H256, BalanceOf<T>, ConstU32<{ limits::DELEGATE_DEPENDENCIES }>>;
 
 /// Information for managing an account and its sub trie abstraction.
 /// This is the required info to cache for an account.
@@ -54,7 +55,7 @@ pub struct ContractInfo<T: Config> {
 	/// Unique ID for the subtree encoded as a bytes vector.
 	pub trie_id: TrieId,
 	/// The code associated with a given account.
-	pub code_hash: CodeHash<T>,
+	pub code_hash: sp_core::H256,
 	/// How many bytes of storage are accumulated in this contract's child trie.
 	storage_bytes: u32,
 	/// How many items of storage are accumulated in this contract's child trie.
@@ -82,9 +83,9 @@ impl<T: Config> ContractInfo<T> {
 	/// This returns an `Err` if an contract with the supplied `account` already exists
 	/// in storage.
 	pub fn new(
-		account: &AccountIdOf<T>,
+		account: &H160,
 		nonce: T::Nonce,
-		code_hash: CodeHash<T>,
+		code_hash: sp_core::H256,
 	) -> Result<Self, DispatchError> {
 		if <ContractInfoOf<T>>::contains_key(account) {
 			return Err(Error::<T>::DuplicateContract.into())
@@ -259,7 +260,7 @@ impl<T: Config> ContractInfo<T> {
 	/// the delegate dependency already exists.
 	pub fn lock_delegate_dependency(
 		&mut self,
-		code_hash: CodeHash<T>,
+		code_hash: sp_core::H256,
 		amount: BalanceOf<T>,
 	) -> DispatchResult {
 		self.delegate_dependencies
@@ -275,7 +276,7 @@ impl<T: Config> ContractInfo<T> {
 	/// Returns an error if the entry doesn't exist.
 	pub fn unlock_delegate_dependency(
 		&mut self,
-		code_hash: &CodeHash<T>,
+		code_hash: &sp_core::H256,
 	) -> Result<BalanceOf<T>, DispatchError> {
 		self.delegate_dependencies
 			.remove(code_hash)
@@ -352,8 +353,8 @@ impl<T: Config> ContractInfo<T> {
 	}
 
 	/// Returns the code hash of the contract specified by `account` ID.
-	pub fn load_code_hash(account: &AccountIdOf<T>) -> Option<CodeHash<T>> {
-		<ContractInfoOf<T>>::get(account).map(|i| i.code_hash)
+	pub fn load_code_hash(account: &AccountIdOf<T>) -> Option<sp_core::H256> {
+		<ContractInfoOf<T>>::get(&T::AddressMapper::to_address(account)).map(|i| i.code_hash)
 	}
 }
 
diff --git a/substrate/frame/revive/src/storage/meter.rs b/substrate/frame/revive/src/storage/meter.rs
index 8735aa8234213b49e8b6f93a9996ea06593d9728..f6ad4c5fc346471a0cb2e50b367f186dce6375e9 100644
--- a/substrate/frame/revive/src/storage/meter.rs
+++ b/substrate/frame/revive/src/storage/meter.rs
@@ -18,8 +18,8 @@
 //! This module contains functions to meter the storage deposit.
 
 use crate::{
-	storage::ContractInfo, AccountIdOf, BalanceOf, CodeInfo, Config, Error, Event, HoldReason,
-	Inspect, Origin, Pallet, StorageDeposit as Deposit, System, LOG_TARGET,
+	address::AddressMapper, storage::ContractInfo, AccountIdOf, BalanceOf, CodeInfo, Config, Error,
+	Event, HoldReason, Inspect, Origin, Pallet, StorageDeposit as Deposit, System, LOG_TARGET,
 };
 
 use alloc::vec::Vec;
@@ -537,8 +537,8 @@ impl<T: Config> Ext<T> for ReservingExt {
 				)?;
 
 				Pallet::<T>::deposit_event(Event::StorageDepositTransferredAndHeld {
-					from: origin.clone(),
-					to: contract.clone(),
+					from: T::AddressMapper::to_address(origin),
+					to: T::AddressMapper::to_address(contract),
 					amount: *amount,
 				});
 			},
@@ -554,8 +554,8 @@ impl<T: Config> Ext<T> for ReservingExt {
 				)?;
 
 				Pallet::<T>::deposit_event(Event::StorageDepositTransferredAndReleased {
-					from: contract.clone(),
-					to: origin.clone(),
+					from: T::AddressMapper::to_address(contract),
+					to: T::AddressMapper::to_address(origin),
 					amount: transferred,
 				});
 
diff --git a/substrate/frame/revive/src/test_utils.rs b/substrate/frame/revive/src/test_utils.rs
index 2bfe754f86cdeab81d30516e9877d567f149deb7..671efebdf4bd502de91fb6efe1765096576433d7 100644
--- a/substrate/frame/revive/src/test_utils.rs
+++ b/substrate/frame/revive/src/test_utils.rs
@@ -24,12 +24,40 @@ pub mod builder;
 
 use crate::{BalanceOf, Config};
 use frame_support::weights::Weight;
+use sp_core::H160;
 pub use sp_runtime::AccountId32;
 
+const fn ee_suffix(addr: H160) -> AccountId32 {
+	let mut id = [0u8; 32];
+	let mut i = 0;
+	while i < 20 {
+		id[i] = addr.0[i];
+		i += 1;
+	}
+
+	let mut j = 20;
+	while j < 32 {
+		id[j] = 0xee;
+		j += 1;
+	}
+
+	AccountId32::new(id)
+}
+
 pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]);
+pub const ALICE_ADDR: H160 = H160([1u8; 20]);
+pub const ETH_ALICE: AccountId32 = ee_suffix(ALICE_ADDR);
+
 pub const BOB: AccountId32 = AccountId32::new([2u8; 32]);
+pub const BOB_ADDR: H160 = H160([2u8; 20]);
+pub const BOB_CONTRACT_ID: AccountId32 = ee_suffix(BOB_ADDR);
+
 pub const CHARLIE: AccountId32 = AccountId32::new([3u8; 32]);
+pub const CHARLIE_ADDR: H160 = H160([3u8; 20]);
+
 pub const DJANGO: AccountId32 = AccountId32::new([4u8; 32]);
+pub const DJANGO_ADDR: H160 = H160([4u8; 20]);
+pub const ETH_DJANGO: AccountId32 = ee_suffix(DJANGO_ADDR);
 
 pub const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024);
 
diff --git a/substrate/frame/revive/src/test_utils/builder.rs b/substrate/frame/revive/src/test_utils/builder.rs
index bf8cbcd5a01f3b4206d8a66429ad875ce419b7ac..76b4c98d4cb063a2044510d0e005bf5fabb08b51 100644
--- a/substrate/frame/revive/src/test_utils/builder.rs
+++ b/substrate/frame/revive/src/test_utils/builder.rs
@@ -17,7 +17,7 @@
 
 use super::{deposit_limit, GAS_LIMIT};
 use crate::{
-	AccountIdLookupOf, AccountIdOf, BalanceOf, Code, CodeHash, CollectEvents, Config,
+	address::AddressMapper, AccountIdOf, BalanceOf, Code, CollectEvents, Config,
 	ContractExecResult, ContractInstantiateResult, DebugInfo, EventRecordOf, ExecReturnValue,
 	InstantiateReturnValue, OriginFor, Pallet, Weight,
 };
@@ -26,6 +26,7 @@ use core::fmt::Debug;
 use frame_support::pallet_prelude::DispatchResultWithPostInfo;
 use paste::paste;
 use scale_info::TypeInfo;
+use sp_core::H160;
 
 /// Helper macro to generate a builder for contract API calls.
 macro_rules! builder {
@@ -74,6 +75,11 @@ macro_rules! builder {
 	}
 }
 
+pub struct Contract<T: Config> {
+	pub account_id: AccountIdOf<T>,
+	pub addr: H160,
+}
+
 builder!(
 	instantiate_with_code(
 		origin: OriginFor<T>,
@@ -82,7 +88,7 @@ builder!(
 		storage_deposit_limit: BalanceOf<T>,
 		code: Vec<u8>,
 		data: Vec<u8>,
-		salt: Vec<u8>,
+		salt: [u8; 32],
 	) -> DispatchResultWithPostInfo;
 
 	/// Create an [`InstantiateWithCodeBuilder`] with default values.
@@ -94,7 +100,7 @@ builder!(
 			storage_deposit_limit: deposit_limit::<T>(),
 			code,
 			data: vec![],
-			salt: vec![],
+			salt: [0; 32],
 		}
 	}
 );
@@ -105,13 +111,13 @@ builder!(
 		value: BalanceOf<T>,
 		gas_limit: Weight,
 		storage_deposit_limit: BalanceOf<T>,
-		code_hash: CodeHash<T>,
+		code_hash: sp_core::H256,
 		data: Vec<u8>,
-		salt: Vec<u8>,
+		salt: [u8; 32],
 	) -> DispatchResultWithPostInfo;
 
 	/// Create an [`InstantiateBuilder`] with default values.
-	pub fn instantiate(origin: OriginFor<T>, code_hash: CodeHash<T>) -> Self {
+	pub fn instantiate(origin: OriginFor<T>, code_hash: sp_core::H256) -> Self {
 		Self {
 			origin,
 			value: 0u32.into(),
@@ -119,7 +125,7 @@ builder!(
 			storage_deposit_limit: deposit_limit::<T>(),
 			code_hash,
 			data: vec![],
-			salt: vec![],
+			salt: [0; 32],
 		}
 	}
 );
@@ -130,24 +136,27 @@ builder!(
 		value: BalanceOf<T>,
 		gas_limit: Weight,
 		storage_deposit_limit: BalanceOf<T>,
-		code: Code<CodeHash<T>>,
+		code: Code,
 		data: Vec<u8>,
-		salt: Vec<u8>,
+		salt: [u8; 32],
 		debug: DebugInfo,
 		collect_events: CollectEvents,
-	) -> ContractInstantiateResult<AccountIdOf<T>, BalanceOf<T>, EventRecordOf<T>>;
+	) -> ContractInstantiateResult<BalanceOf<T>, EventRecordOf<T>>;
 
 	/// Build the instantiate call and unwrap the result.
-	pub fn build_and_unwrap_result(self) -> InstantiateReturnValue<AccountIdOf<T>> {
+	pub fn build_and_unwrap_result(self) -> InstantiateReturnValue {
 		self.build().result.unwrap()
 	}
 
 	/// Build the instantiate call and unwrap the account id.
-	pub fn build_and_unwrap_account_id(self) -> AccountIdOf<T> {
-		self.build().result.unwrap().account_id
+	pub fn build_and_unwrap_contract(self) -> Contract<T> {
+		let addr = self.build().result.unwrap().addr;
+		let account_id = T::AddressMapper::to_account_id(&addr);
+		Contract{ account_id,  addr }
 	}
 
-	pub fn bare_instantiate(origin: OriginFor<T>, code: Code<CodeHash<T>>) -> Self {
+	/// Create a [`BareInstantiateBuilder`] with default values.
+	pub fn bare_instantiate(origin: OriginFor<T>, code: Code) -> Self {
 		Self {
 			origin,
 			value: 0u32.into(),
@@ -155,7 +164,7 @@ builder!(
 			storage_deposit_limit: deposit_limit::<T>(),
 			code,
 			data: vec![],
-			salt: vec![],
+			salt: [0; 32],
 			debug: DebugInfo::UnsafeDebug,
 			collect_events: CollectEvents::Skip,
 		}
@@ -165,7 +174,7 @@ builder!(
 builder!(
 	call(
 		origin: OriginFor<T>,
-		dest: AccountIdLookupOf<T>,
+		dest: H160,
 		value: BalanceOf<T>,
 		gas_limit: Weight,
 		storage_deposit_limit: BalanceOf<T>,
@@ -173,7 +182,7 @@ builder!(
 	) -> DispatchResultWithPostInfo;
 
 	/// Create a [`CallBuilder`] with default values.
-	pub fn call(origin: OriginFor<T>, dest: AccountIdLookupOf<T>) -> Self {
+	pub fn call(origin: OriginFor<T>, dest: H160) -> Self {
 		CallBuilder {
 			origin,
 			dest,
@@ -188,7 +197,7 @@ builder!(
 builder!(
 	bare_call(
 		origin: OriginFor<T>,
-		dest: AccountIdOf<T>,
+		dest: H160,
 		value: BalanceOf<T>,
 		gas_limit: Weight,
 		storage_deposit_limit: BalanceOf<T>,
@@ -203,7 +212,7 @@ builder!(
 	}
 
 	/// Create a [`BareCallBuilder`] with default values.
-	pub fn bare_call(origin: OriginFor<T>, dest: AccountIdOf<T>) -> Self {
+	pub fn bare_call(origin: OriginFor<T>, dest: H160) -> Self {
 		Self {
 			origin,
 			dest,
diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs
index 52ee7b310542f245aea786b5a5a3314e7aad21ed..a37e9842a2cb6394208837b19a0cb033d43e1baa 100644
--- a/substrate/frame/revive/src/tests.rs
+++ b/substrate/frame/revive/src/tests.rs
@@ -26,6 +26,7 @@ use self::{
 };
 use crate::{
 	self as pallet_revive,
+	address::AddressMapper,
 	chain_extension::{
 		ChainExtension, Environment, Ext, RegisteredChainExtension, Result as ExtensionResult,
 		RetVal, ReturnFlags,
@@ -39,10 +40,12 @@ use crate::{
 	tests::test_utils::{get_contract, get_contract_checked},
 	wasm::Memory,
 	weights::WeightInfo,
-	BalanceOf, Code, CodeHash, CodeInfoOf, CollectEvents, Config, ContractInfo, ContractInfoOf,
-	DebugInfo, DefaultAddressGenerator, DeletionQueueCounter, Error, HoldReason,
-	MigrationInProgress, Origin, Pallet, PristineCode,
+	BalanceOf, Code, CodeInfoOf, CollectEvents, Config, ContractInfo, ContractInfoOf, DebugInfo,
+	DefaultAddressMapper, DeletionQueueCounter, Error, HoldReason, MigrationInProgress, Origin,
+	Pallet, PristineCode, H160,
 };
+
+use crate::test_utils::builder::Contract;
 use assert_matches::assert_matches;
 use codec::{Decode, Encode};
 use frame_support::{
@@ -62,12 +65,11 @@ use frame_support::{
 use frame_system::{EventRecord, Phase};
 use pallet_revive_fixtures::{bench::dummy_unique, compile_module};
 use pallet_revive_uapi::ReturnErrorCode as RuntimeReturnCode;
-use sp_core::ByteArray;
 use sp_io::hashing::blake2_256;
 use sp_keystore::{testing::MemoryKeystore, KeystoreExt};
 use sp_runtime::{
 	testing::H256,
-	traits::{BlakeTwo256, Convert, Hash, IdentityLookup},
+	traits::{BlakeTwo256, Convert, IdentityLookup},
 	AccountId32, BuildStorage, DispatchError, Perbill, TokenError,
 };
 
@@ -102,15 +104,17 @@ macro_rules! assert_refcount {
 pub mod test_utils {
 	use super::{Contracts, DepositPerByte, DepositPerItem, Test};
 	use crate::{
-		exec::AccountIdOf, BalanceOf, CodeHash, CodeInfo, CodeInfoOf, Config, ContractInfo,
-		ContractInfoOf, PristineCode,
+		address::AddressMapper, exec::AccountIdOf, BalanceOf, CodeInfo, CodeInfoOf, Config,
+		ContractInfo, ContractInfoOf, PristineCode,
 	};
 	use codec::{Encode, MaxEncodedLen};
 	use frame_support::traits::fungible::{InspectHold, Mutate};
+	use sp_core::H160;
 
-	pub fn place_contract(address: &AccountIdOf<Test>, code_hash: CodeHash<Test>) {
+	pub fn place_contract(address: &AccountIdOf<Test>, code_hash: sp_core::H256) {
 		set_balance(address, Contracts::min_balance() * 10);
 		<CodeInfoOf<Test>>::insert(code_hash, CodeInfo::new(address.clone()));
+		let address = <Test as Config>::AddressMapper::to_address(&address);
 		let contract = <ContractInfo<Test>>::new(&address, 0, code_hash).unwrap();
 		<ContractInfoOf<Test>>::insert(address, contract);
 	}
@@ -126,18 +130,16 @@ pub mod test_utils {
 	) -> u64 {
 		<Test as Config>::Currency::balance_on_hold(reason.into(), who)
 	}
-	pub fn get_contract(addr: &AccountIdOf<Test>) -> ContractInfo<Test> {
+	pub fn get_contract(addr: &H160) -> ContractInfo<Test> {
 		get_contract_checked(addr).unwrap()
 	}
-	pub fn get_contract_checked(addr: &AccountIdOf<Test>) -> Option<ContractInfo<Test>> {
+	pub fn get_contract_checked(addr: &H160) -> Option<ContractInfo<Test>> {
 		ContractInfoOf::<Test>::get(addr)
 	}
-	pub fn get_code_deposit(code_hash: &CodeHash<Test>) -> BalanceOf<Test> {
+	pub fn get_code_deposit(code_hash: &sp_core::H256) -> BalanceOf<Test> {
 		crate::CodeInfoOf::<Test>::get(code_hash).unwrap().deposit()
 	}
-	pub fn contract_info_storage_deposit(
-		addr: &<Test as frame_system::Config>::AccountId,
-	) -> BalanceOf<Test> {
+	pub fn contract_info_storage_deposit(addr: &H160) -> BalanceOf<Test> {
 		let contract_info = self::get_contract(&addr);
 		let info_size = contract_info.encoded_size() as u64;
 		DepositPerByte::get()
@@ -152,7 +154,7 @@ pub mod test_utils {
 		DepositPerByte::get().saturating_mul(code_len as u64 + code_info_len) +
 			DepositPerItem::get().saturating_mul(2)
 	}
-	pub fn ensure_stored(code_hash: CodeHash<Test>) -> usize {
+	pub fn ensure_stored(code_hash: sp_core::H256) -> usize {
 		// Assert that code_info is stored
 		assert!(CodeInfoOf::<Test>::contains_key(&code_hash));
 		// Assert that contract code is stored, and get its size.
@@ -163,16 +165,17 @@ pub mod test_utils {
 mod builder {
 	use super::Test;
 	use crate::{
-		test_utils::{builder::*, AccountId32, ALICE},
+		test_utils::{builder::*, ALICE},
 		tests::RuntimeOrigin,
-		AccountIdLookupOf, Code, CodeHash,
+		Code,
 	};
+	use sp_core::{H160, H256};
 
-	pub fn bare_instantiate(code: Code<CodeHash<Test>>) -> BareInstantiateBuilder<Test> {
+	pub fn bare_instantiate(code: Code) -> BareInstantiateBuilder<Test> {
 		BareInstantiateBuilder::<Test>::bare_instantiate(RuntimeOrigin::signed(ALICE), code)
 	}
 
-	pub fn bare_call(dest: AccountId32) -> BareCallBuilder<Test> {
+	pub fn bare_call(dest: H160) -> BareCallBuilder<Test> {
 		BareCallBuilder::<Test>::bare_call(RuntimeOrigin::signed(ALICE), dest)
 	}
 
@@ -183,11 +186,11 @@ mod builder {
 		)
 	}
 
-	pub fn instantiate(code_hash: CodeHash<Test>) -> InstantiateBuilder<Test> {
+	pub fn instantiate(code_hash: H256) -> InstantiateBuilder<Test> {
 		InstantiateBuilder::<Test>::instantiate(RuntimeOrigin::signed(ALICE), code_hash)
 	}
 
-	pub fn call(dest: AccountIdLookupOf<Test>) -> CallBuilder<Test> {
+	pub fn call(dest: H160) -> CallBuilder<Test> {
 		CallBuilder::<Test>::call(RuntimeOrigin::signed(ALICE), dest)
 	}
 }
@@ -483,7 +486,7 @@ impl Config for Test {
 		(TestExtension, DisabledExtension, RevertingExtension, TempStorageExtension);
 	type DepositPerByte = DepositPerByte;
 	type DepositPerItem = DepositPerItem;
-	type AddressGenerator = DefaultAddressGenerator;
+	type AddressMapper = DefaultAddressMapper;
 	type UnsafeUnstableInterface = UnstableInterface;
 	type UploadOrigin = EnsureAccount<Self, UploadAccount>;
 	type InstantiateOrigin = EnsureAccount<Self, InstantiateAccount>;
@@ -495,7 +498,7 @@ impl Config for Test {
 pub struct ExtBuilder {
 	existential_deposit: u64,
 	storage_version: Option<StorageVersion>,
-	code_hashes: Vec<CodeHash<Test>>,
+	code_hashes: Vec<sp_core::H256>,
 }
 
 impl Default for ExtBuilder {
@@ -513,7 +516,7 @@ impl ExtBuilder {
 		self.existential_deposit = existential_deposit;
 		self
 	}
-	pub fn with_code_hashes(mut self, code_hashes: Vec<CodeHash<Test>>) -> Self {
+	pub fn with_code_hashes(mut self, code_hashes: Vec<sp_core::H256>) -> Self {
 		self.code_hashes = code_hashes;
 		self
 	}
@@ -601,7 +604,7 @@ mod run_tests {
 			let base_cost = <<Test as Config>::WeightInfo as WeightInfo>::call();
 
 			assert_eq!(
-				builder::call(BOB).build(),
+				builder::call(BOB_ADDR).build(),
 				Err(DispatchErrorWithPostInfo {
 					error: Error::<Test>::ContractNotFound.into(),
 					post_info: PostDispatchInfo {
@@ -636,7 +639,7 @@ mod run_tests {
 
 	#[test]
 	fn migration_in_progress_works() {
-		let (wasm, code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, code_hash) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().existential_deposit(1).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
@@ -655,11 +658,11 @@ mod run_tests {
 				Error::<Test>::MigrationInProgress,
 			);
 			assert_err!(
-				Contracts::set_code(RuntimeOrigin::signed(ALICE), BOB.clone(), code_hash),
+				Contracts::set_code(RuntimeOrigin::signed(ALICE), BOB_ADDR, code_hash),
 				Error::<Test>::MigrationInProgress,
 			);
 			assert_err_ignore_postinfo!(
-				builder::call(BOB).build(),
+				builder::call(BOB_ADDR).build(),
 				Error::<Test>::MigrationInProgress
 			);
 			assert_err_ignore_postinfo!(
@@ -675,7 +678,7 @@ mod run_tests {
 
 	#[test]
 	fn instantiate_and_call_and_deposit_event() {
-		let (wasm, code_hash) = compile_module::<Test>("event_and_return_on_deploy").unwrap();
+		let (wasm, code_hash) = compile_module("event_and_return_on_deploy").unwrap();
 
 		ExtBuilder::default().existential_deposit(1).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
@@ -694,9 +697,10 @@ mod run_tests {
 			initialize_block(2);
 
 			// Check at the end to get hash on error easily
-			let addr = builder::bare_instantiate(Code::Existing(code_hash))
-				.value(value)
-				.build_and_unwrap_account_id();
+			let Contract { addr, account_id } =
+				builder::bare_instantiate(Code::Existing(code_hash))
+					.value(value)
+					.build_and_unwrap_contract();
 			assert!(ContractInfoOf::<Test>::contains_key(&addr));
 
 			assert_eq!(
@@ -705,14 +709,14 @@ mod run_tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::System(frame_system::Event::NewAccount {
-							account: addr.clone()
+							account: account_id.clone()
 						}),
 						topics: vec![],
 					},
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Endowed {
-							account: addr.clone(),
+							account: account_id.clone(),
 							free_balance: min_balance,
 						}),
 						topics: vec![],
@@ -721,7 +725,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Transfer {
 							from: ALICE,
-							to: addr.clone(),
+							to: account_id.clone(),
 							amount: min_balance,
 						}),
 						topics: vec![],
@@ -730,7 +734,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Transfer {
 							from: ALICE,
-							to: addr.clone(),
+							to: account_id.clone(),
 							amount: value,
 						}),
 						topics: vec![],
@@ -738,7 +742,7 @@ mod run_tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::ContractEmitted {
-							contract: addr.clone(),
+							contract: addr,
 							data: vec![1, 2, 3, 4]
 						}),
 						topics: vec![],
@@ -746,8 +750,8 @@ mod run_tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Instantiated {
-							deployer: ALICE,
-							contract: addr.clone()
+							deployer: ALICE_ADDR,
+							contract: addr
 						}),
 						topics: vec![],
 					},
@@ -755,8 +759,8 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(
 							pallet_revive::Event::StorageDepositTransferredAndHeld {
-								from: ALICE,
-								to: addr.clone(),
+								from: ALICE_ADDR,
+								to: addr,
 								amount: test_utils::contract_info_storage_deposit(&addr),
 							}
 						),
@@ -769,17 +773,17 @@ mod run_tests {
 
 	#[test]
 	fn deposit_event_max_value_limit() {
-		let (wasm, _code_hash) = compile_module::<Test>("event_size").unwrap();
+		let (wasm, _code_hash) = compile_module("event_size").unwrap();
 
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			// Create
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(30_000)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			// Call contract with allowed storage value.
-			assert_ok!(builder::call(addr.clone())
+			assert_ok!(builder::call(addr)
 				.gas_limit(GAS_LIMIT.set_ref_time(GAS_LIMIT.ref_time() * 2)) // we are copying a huge buffer,
 				.data(limits::PAYLOAD_BYTES.encode())
 				.build());
@@ -795,14 +799,14 @@ mod run_tests {
 	// Fail out of fuel (ref_time weight) in the engine.
 	#[test]
 	fn run_out_of_fuel_engine() {
-		let (wasm, _code_hash) = compile_module::<Test>("run_out_of_gas").unwrap();
+		let (wasm, _code_hash) = compile_module("run_out_of_gas").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(100 * min_balance)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			// Call the contract with a fixed gas limit. It must run out of gas because it just
 			// loops forever.
@@ -818,19 +822,19 @@ mod run_tests {
 	// Fail out of fuel (ref_time weight) in the host.
 	#[test]
 	fn run_out_of_fuel_host() {
-		let (code, _hash) = compile_module::<Test>("chain_extension").unwrap();
+		let (code, _hash) = compile_module("chain_extension").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
 
-			let addr = builder::bare_instantiate(Code::Upload(code))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(code))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			let gas_limit = Weight::from_parts(u32::MAX as u64, GAS_LIMIT.proof_size());
 
 			// Use chain extension to charge more ref_time than it is available.
-			let result = builder::bare_call(addr.clone())
+			let result = builder::bare_call(addr)
 				.gas_limit(gas_limit)
 				.data(
 					ExtensionInput { extension_id: 0, func_id: 2, extra: &u32::MAX.encode() }
@@ -844,16 +848,17 @@ mod run_tests {
 
 	#[test]
 	fn gas_syncs_work() {
-		let (code, _code_hash) = compile_module::<Test>("caller_is_origin_n").unwrap();
+		let (code, _code_hash) = compile_module("caller_is_origin_n").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
-			let addr = builder::bare_instantiate(Code::Upload(code)).build_and_unwrap_account_id();
+			let contract =
+				builder::bare_instantiate(Code::Upload(code)).build_and_unwrap_contract();
 
-			let result = builder::bare_call(addr.clone()).data(0u32.encode()).build();
+			let result = builder::bare_call(contract.addr).data(0u32.encode()).build();
 			assert_ok!(result.result);
 			let engine_consumed_noop = result.gas_consumed.ref_time();
 
-			let result = builder::bare_call(addr.clone()).data(1u32.encode()).build();
+			let result = builder::bare_call(contract.addr).data(1u32.encode()).build();
 			assert_ok!(result.result);
 			let gas_consumed_once = result.gas_consumed.ref_time();
 			let host_consumed_once =
@@ -861,7 +866,7 @@ mod run_tests {
 			let engine_consumed_once =
 				gas_consumed_once - host_consumed_once - engine_consumed_noop;
 
-			let result = builder::bare_call(addr).data(2u32.encode()).build();
+			let result = builder::bare_call(contract.addr).data(2u32.encode()).build();
 			assert_ok!(result.result);
 			let gas_consumed_twice = result.gas_consumed.ref_time();
 			let host_consumed_twice = host_consumed_once * 2;
@@ -878,7 +883,7 @@ mod run_tests {
 	/// Check the `Nonce` storage item for more information.
 	#[test]
 	fn instantiate_unique_trie_id() {
-		let (wasm, code_hash) = compile_module::<Test>("self_destruct").unwrap();
+		let (wasm, code_hash) = compile_module("self_destruct").unwrap();
 
 		ExtBuilder::default().existential_deposit(500).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
@@ -886,8 +891,8 @@ mod run_tests {
 				.unwrap();
 
 			// Instantiate the contract and store its trie id for later comparison.
-			let addr =
-				builder::bare_instantiate(Code::Existing(code_hash)).build_and_unwrap_account_id();
+			let Contract { addr, .. } =
+				builder::bare_instantiate(Code::Existing(code_hash)).build_and_unwrap_contract();
 			let trie_id = get_contract(&addr).trie_id;
 
 			// Try to instantiate it again without termination should yield an error.
@@ -897,7 +902,7 @@ mod run_tests {
 			);
 
 			// Terminate the contract.
-			assert_ok!(builder::call(addr.clone()).build());
+			assert_ok!(builder::call(addr).build());
 
 			// Re-Instantiate after termination.
 			assert_ok!(builder::instantiate(code_hash).build());
@@ -909,14 +914,14 @@ mod run_tests {
 
 	#[test]
 	fn storage_work() {
-		let (code, _code_hash) = compile_module::<Test>("storage").unwrap();
+		let (code, _code_hash) = compile_module("storage").unwrap();
 
 		ExtBuilder::default().build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let min_balance = Contracts::min_balance();
-			let addr = builder::bare_instantiate(Code::Upload(code))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(code))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			builder::bare_call(addr).build_and_unwrap_result();
 		});
@@ -924,18 +929,18 @@ mod run_tests {
 
 	#[test]
 	fn storage_max_value_limit() {
-		let (wasm, _code_hash) = compile_module::<Test>("storage_size").unwrap();
+		let (wasm, _code_hash) = compile_module("storage_size").unwrap();
 
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			// Create
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(30_000)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 			get_contract(&addr);
 
 			// Call contract with allowed storage value.
-			assert_ok!(builder::call(addr.clone())
+			assert_ok!(builder::call(addr)
 				.gas_limit(GAS_LIMIT.set_ref_time(GAS_LIMIT.ref_time() * 2)) // we are copying a huge buffer
 				.data(limits::PAYLOAD_BYTES.encode())
 				.build());
@@ -950,14 +955,14 @@ mod run_tests {
 
 	#[test]
 	fn transient_storage_work() {
-		let (code, _code_hash) = compile_module::<Test>("transient_storage").unwrap();
+		let (code, _code_hash) = compile_module("transient_storage").unwrap();
 
 		ExtBuilder::default().build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let min_balance = Contracts::min_balance();
-			let addr = builder::bare_instantiate(Code::Upload(code))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(code))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			builder::bare_call(addr).build_and_unwrap_result();
 		});
@@ -966,28 +971,27 @@ mod run_tests {
 	#[test]
 	fn transient_storage_limit_in_call() {
 		let (wasm_caller, _code_hash_caller) =
-			compile_module::<Test>("create_transient_storage_and_call").unwrap();
-		let (wasm_callee, _code_hash_callee) =
-			compile_module::<Test>("set_transient_storage").unwrap();
+			compile_module("create_transient_storage_and_call").unwrap();
+		let (wasm_callee, _code_hash_callee) = compile_module("set_transient_storage").unwrap();
 		ExtBuilder::default().build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Create both contracts: Constructors do nothing.
-			let addr_caller =
-				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_account_id();
-			let addr_callee =
-				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_account_id();
+			let Contract { addr: addr_caller, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_contract();
+			let Contract { addr: addr_callee, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_contract();
 
 			// Call contracts with storage values within the limit.
 			// Caller and Callee contracts each set a transient storage value of size 100.
-			assert_ok!(builder::call(addr_caller.clone())
+			assert_ok!(builder::call(addr_caller)
 				.data((100u32, 100u32, &addr_callee).encode())
 				.build(),);
 
 			// Call a contract with a storage value that is too large.
 			// Limit exceeded in the caller contract.
 			assert_err_ignore_postinfo!(
-				builder::call(addr_caller.clone())
+				builder::call(addr_caller)
 					.data((4u32 * 1024u32, 200u32, &addr_callee).encode())
 					.build(),
 				<Error<Test>>::OutOfTransientStorage,
@@ -1006,17 +1010,27 @@ mod run_tests {
 
 	#[test]
 	fn deploy_and_call_other_contract() {
-		let (caller_wasm, _caller_code_hash) = compile_module::<Test>("caller_contract").unwrap();
-		let (callee_wasm, callee_code_hash) = compile_module::<Test>("return_with_data").unwrap();
+		let (caller_wasm, _caller_code_hash) = compile_module("caller_contract").unwrap();
+		let (callee_wasm, callee_code_hash) = compile_module("return_with_data").unwrap();
 
 		ExtBuilder::default().existential_deposit(1).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 
 			// Create
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
-			let caller_addr = builder::bare_instantiate(Code::Upload(caller_wasm))
-				.value(100_000)
-				.build_and_unwrap_account_id();
+			let Contract { addr: caller_addr, account_id: caller_account } =
+				builder::bare_instantiate(Code::Upload(caller_wasm))
+					.value(100_000)
+					.build_and_unwrap_contract();
+
+			let callee_addr = crate::address::create2(
+				&caller_addr,
+				&callee_wasm,
+				&[0, 1, 34, 51, 68, 85, 102, 119], // hard coded in wasm
+				&[0u8; 32],
+			);
+			let callee_account = <Test as Config>::AddressMapper::to_account_id(&callee_addr);
+
 			Contracts::upload_code(
 				RuntimeOrigin::signed(ALICE),
 				callee_wasm,
@@ -1024,21 +1038,12 @@ mod run_tests {
 			)
 			.unwrap();
 
-			let callee_addr = Contracts::contract_address(
-				&caller_addr,
-				&callee_code_hash,
-				&[0, 1, 34, 51, 68, 85, 102, 119], // hard coded in wasm
-				&[],
-			);
-
 			// Drop previous events
 			initialize_block(2);
 
 			// Call BOB contract, which attempts to instantiate and call the callee contract and
 			// makes various assertions on the results from those calls.
-			assert_ok!(builder::call(caller_addr.clone())
-				.data(callee_code_hash.as_ref().to_vec())
-				.build());
+			assert_ok!(builder::call(caller_addr).data(callee_code_hash.as_ref().to_vec()).build());
 
 			assert_eq!(
 				System::events(),
@@ -1046,14 +1051,14 @@ mod run_tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::System(frame_system::Event::NewAccount {
-							account: callee_addr.clone()
+							account: callee_account.clone()
 						}),
 						topics: vec![],
 					},
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Endowed {
-							account: callee_addr.clone(),
+							account: callee_account.clone(),
 							free_balance: min_balance,
 						}),
 						topics: vec![],
@@ -1062,7 +1067,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Transfer {
 							from: ALICE,
-							to: callee_addr.clone(),
+							to: callee_account.clone(),
 							amount: min_balance,
 						}),
 						topics: vec![],
@@ -1070,8 +1075,8 @@ mod run_tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Transfer {
-							from: caller_addr.clone(),
-							to: callee_addr.clone(),
+							from: caller_account.clone(),
+							to: callee_account.clone(),
 							amount: 32768 // hardcoded in wasm
 						}),
 						topics: vec![],
@@ -1079,16 +1084,16 @@ mod run_tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Instantiated {
-							deployer: caller_addr.clone(),
-							contract: callee_addr.clone(),
+							deployer: caller_addr,
+							contract: callee_addr,
 						}),
 						topics: vec![],
 					},
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Transfer {
-							from: caller_addr.clone(),
-							to: callee_addr.clone(),
+							from: caller_account.clone(),
+							to: callee_account.clone(),
 							amount: 32768,
 						}),
 						topics: vec![],
@@ -1096,8 +1101,8 @@ mod run_tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Called {
-							caller: Origin::from_account_id(caller_addr.clone()),
-							contract: callee_addr.clone(),
+							caller: Origin::from_account_id(caller_account.clone()),
+							contract: callee_addr,
 						}),
 						topics: vec![],
 					},
@@ -1105,7 +1110,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Called {
 							caller: Origin::from_account_id(ALICE),
-							contract: caller_addr.clone(),
+							contract: caller_addr,
 						}),
 						topics: vec![],
 					},
@@ -1113,8 +1118,8 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(
 							pallet_revive::Event::StorageDepositTransferredAndHeld {
-								from: ALICE,
-								to: callee_addr.clone(),
+								from: ALICE_ADDR,
+								to: callee_addr,
 								amount: test_utils::contract_info_storage_deposit(&callee_addr),
 							}
 						),
@@ -1127,20 +1132,21 @@ mod run_tests {
 
 	#[test]
 	fn delegate_call() {
-		let (caller_wasm, _caller_code_hash) = compile_module::<Test>("delegate_call").unwrap();
-		let (callee_wasm, callee_code_hash) = compile_module::<Test>("delegate_call_lib").unwrap();
+		let (caller_wasm, _caller_code_hash) = compile_module("delegate_call").unwrap();
+		let (callee_wasm, callee_code_hash) = compile_module("delegate_call_lib").unwrap();
 
 		ExtBuilder::default().existential_deposit(500).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Instantiate the 'caller'
-			let caller_addr = builder::bare_instantiate(Code::Upload(caller_wasm))
-				.value(300_000)
-				.build_and_unwrap_account_id();
+			let Contract { addr: caller_addr, .. } =
+				builder::bare_instantiate(Code::Upload(caller_wasm))
+					.value(300_000)
+					.build_and_unwrap_contract();
 			// Only upload 'callee' code
 			assert_ok!(Contracts::upload_code(RuntimeOrigin::signed(ALICE), callee_wasm, 100_000,));
 
-			assert_ok!(builder::call(caller_addr.clone())
+			assert_ok!(builder::call(caller_addr)
 				.value(1337)
 				.data(callee_code_hash.as_ref().to_vec())
 				.build());
@@ -1149,29 +1155,33 @@ mod run_tests {
 
 	#[test]
 	fn transfer_expendable_cannot_kill_account() {
-		let (wasm, _code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, _code_hash) = compile_module("dummy").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Instantiate the BOB contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(1_000)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			// Check that the BOB contract has been instantiated.
 			get_contract(&addr);
 
-			let total_balance = <Test as Config>::Currency::total_balance(&addr);
+			let account = <Test as Config>::AddressMapper::to_account_id(&addr);
+			let total_balance = <Test as Config>::Currency::total_balance(&account);
 
 			assert_eq!(
-				test_utils::get_balance_on_hold(&HoldReason::StorageDepositReserve.into(), &addr),
+				test_utils::get_balance_on_hold(
+					&HoldReason::StorageDepositReserve.into(),
+					&account
+				),
 				test_utils::contract_info_storage_deposit(&addr)
 			);
 
 			// Some ot the total balance is held, so it can't be transferred.
 			assert_err!(
 				<<Test as Config>::Currency as Mutate<AccountId32>>::transfer(
-					&addr,
+					&account,
 					&ALICE,
 					total_balance,
 					Preservation::Expendable,
@@ -1179,33 +1189,34 @@ mod run_tests {
 				TokenError::FundsUnavailable,
 			);
 
-			assert_eq!(<Test as Config>::Currency::total_balance(&addr), total_balance);
+			assert_eq!(<Test as Config>::Currency::total_balance(&account), total_balance);
 		});
 	}
 
 	#[test]
 	fn cannot_self_destruct_through_draining() {
-		let (wasm, _code_hash) = compile_module::<Test>("drain").unwrap();
+		let (wasm, _code_hash) = compile_module("drain").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let value = 1_000;
 			let min_balance = Contracts::min_balance();
 
 			// Instantiate the BOB contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(value)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
+			let account = <Test as Config>::AddressMapper::to_account_id(&addr);
 
 			// Check that the BOB contract has been instantiated.
 			get_contract(&addr);
 
 			// Call BOB which makes it send all funds to the zero address
 			// The contract code asserts that the transfer fails with the correct error code
-			assert_ok!(builder::call(addr.clone()).build());
+			assert_ok!(builder::call(addr).build());
 
 			// Make sure the account wasn't remove by sending all free balance away.
 			assert_eq!(
-				<Test as Config>::Currency::total_balance(&addr),
+				<Test as Config>::Currency::total_balance(&account),
 				value + test_utils::contract_info_storage_deposit(&addr) + min_balance,
 			);
 		});
@@ -1213,54 +1224,54 @@ mod run_tests {
 
 	#[test]
 	fn cannot_self_destruct_through_storage_refund_after_price_change() {
-		let (wasm, _code_hash) = compile_module::<Test>("store_call").unwrap();
+		let (wasm, _code_hash) = compile_module("store_call").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let min_balance = Contracts::min_balance();
 
 			// Instantiate the BOB contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_account_id();
-
-			let info_deposit = test_utils::contract_info_storage_deposit(&addr);
+			let contract =
+				builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_contract();
+			let info_deposit = test_utils::contract_info_storage_deposit(&contract.addr);
 
 			// Check that the contract has been instantiated and has the minimum balance
-			assert_eq!(get_contract(&addr).total_deposit(), info_deposit);
-			assert_eq!(get_contract(&addr).extra_deposit(), 0);
+			assert_eq!(get_contract(&contract.addr).total_deposit(), info_deposit);
+			assert_eq!(get_contract(&contract.addr).extra_deposit(), 0);
 			assert_eq!(
-				<Test as Config>::Currency::total_balance(&addr),
+				<Test as Config>::Currency::total_balance(&contract.account_id),
 				info_deposit + min_balance
 			);
 
 			// Create 100 bytes of storage with a price of per byte and a single storage item of
 			// price 2
-			assert_ok!(builder::call(addr.clone()).data(100u32.to_le_bytes().to_vec()).build());
-			assert_eq!(get_contract(&addr).total_deposit(), info_deposit + 102);
+			assert_ok!(builder::call(contract.addr).data(100u32.to_le_bytes().to_vec()).build());
+			assert_eq!(get_contract(&contract.addr).total_deposit(), info_deposit + 102);
 
 			// Increase the byte price and trigger a refund. This should not have any influence
 			// because the removal is pro rata and exactly those 100 bytes should have been
 			// removed.
 			DEPOSIT_PER_BYTE.with(|c| *c.borrow_mut() = 500);
-			assert_ok!(builder::call(addr.clone()).data(0u32.to_le_bytes().to_vec()).build());
+			assert_ok!(builder::call(contract.addr).data(0u32.to_le_bytes().to_vec()).build());
 
 			// Make sure the account wasn't removed by the refund
 			assert_eq!(
-				<Test as Config>::Currency::total_balance(&addr),
-				get_contract(&addr).total_deposit() + min_balance,
+				<Test as Config>::Currency::total_balance(&contract.account_id),
+				get_contract(&contract.addr).total_deposit() + min_balance,
 			);
-			assert_eq!(get_contract(&addr).extra_deposit(), 2);
+			assert_eq!(get_contract(&contract.addr).extra_deposit(), 2);
 		});
 	}
 
 	#[test]
 	fn cannot_self_destruct_while_live() {
-		let (wasm, _code_hash) = compile_module::<Test>("self_destruct").unwrap();
+		let (wasm, _code_hash) = compile_module("self_destruct").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Instantiate the BOB contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(100_000)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			// Check that the BOB contract has been instantiated.
 			get_contract(&addr);
@@ -1268,7 +1279,7 @@ mod run_tests {
 			// Call BOB with input data, forcing it make a recursive call to itself to
 			// self-destruct, resulting in a trap.
 			assert_err_ignore_postinfo!(
-				builder::call(addr.clone()).data(vec![0]).build(),
+				builder::call(addr).data(vec![0]).build(),
 				Error::<Test>::ContractTrapped,
 			);
 
@@ -1279,38 +1290,38 @@ mod run_tests {
 
 	#[test]
 	fn self_destruct_works() {
-		let (wasm, code_hash) = compile_module::<Test>("self_destruct").unwrap();
+		let (wasm, code_hash) = compile_module("self_destruct").unwrap();
 		ExtBuilder::default().existential_deposit(1_000).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
-			let _ = <Test as Config>::Currency::set_balance(&DJANGO, 1_000_000);
+			let _ = <Test as Config>::Currency::set_balance(&ETH_DJANGO, 1_000_000);
 			let min_balance = Contracts::min_balance();
 
 			// Instantiate the BOB contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let contract = builder::bare_instantiate(Code::Upload(wasm))
 				.value(100_000)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			// Check that the BOB contract has been instantiated.
-			let _ = get_contract(&addr);
+			let _ = get_contract(&contract.addr);
 
-			let info_deposit = test_utils::contract_info_storage_deposit(&addr);
+			let info_deposit = test_utils::contract_info_storage_deposit(&contract.addr);
 
 			// Drop all previous events
 			initialize_block(2);
 
 			// Call BOB without input data which triggers termination.
-			assert_matches!(builder::call(addr.clone()).build(), Ok(_));
+			assert_matches!(builder::call(contract.addr).build(), Ok(_));
 
 			// Check that code is still there but refcount dropped to zero.
 			assert_refcount!(&code_hash, 0);
 
 			// Check that account is gone
-			assert!(get_contract_checked(&addr).is_none());
-			assert_eq!(<Test as Config>::Currency::total_balance(&addr), 0);
+			assert!(get_contract_checked(&contract.addr).is_none());
+			assert_eq!(<Test as Config>::Currency::total_balance(&contract.account_id), 0);
 
 			// Check that the beneficiary (django) got remaining balance.
 			assert_eq!(
-				<Test as Config>::Currency::free_balance(DJANGO),
+				<Test as Config>::Currency::free_balance(ETH_DJANGO),
 				1_000_000 + 100_000 + min_balance
 			);
 
@@ -1327,8 +1338,8 @@ mod run_tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Terminated {
-							contract: addr.clone(),
-							beneficiary: DJANGO
+							contract: contract.addr,
+							beneficiary: DJANGO_ADDR,
 						}),
 						topics: vec![],
 					},
@@ -1336,7 +1347,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Called {
 							caller: Origin::from_account_id(ALICE),
-							contract: addr.clone(),
+							contract: contract.addr,
 						}),
 						topics: vec![],
 					},
@@ -1344,8 +1355,8 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(
 							pallet_revive::Event::StorageDepositTransferredAndReleased {
-								from: addr.clone(),
-								to: ALICE,
+								from: contract.addr,
+								to: ALICE_ADDR,
 								amount: info_deposit,
 							}
 						),
@@ -1354,15 +1365,15 @@ mod run_tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::System(frame_system::Event::KilledAccount {
-							account: addr.clone()
+							account: contract.account_id.clone()
 						}),
 						topics: vec![],
 					},
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Transfer {
-							from: addr.clone(),
-							to: DJANGO,
+							from: contract.account_id.clone(),
+							to: ETH_DJANGO,
 							amount: 100_000 + min_balance,
 						}),
 						topics: vec![],
@@ -1376,30 +1387,30 @@ mod run_tests {
 	// additional funds after it has been drained.
 	#[test]
 	fn destroy_contract_and_transfer_funds() {
-		let (callee_wasm, callee_code_hash) = compile_module::<Test>("self_destruct").unwrap();
-		let (caller_wasm, _caller_code_hash) =
-			compile_module::<Test>("destroy_and_transfer").unwrap();
+		let (callee_wasm, callee_code_hash) = compile_module("self_destruct").unwrap();
+		let (caller_wasm, _caller_code_hash) = compile_module("destroy_and_transfer").unwrap();
 
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			// Create code hash for bob to instantiate
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			Contracts::upload_code(
 				RuntimeOrigin::signed(ALICE),
-				callee_wasm,
+				callee_wasm.clone(),
 				deposit_limit::<Test>(),
 			)
 			.unwrap();
 
 			// This deploys the BOB contract, which in turn deploys the CHARLIE contract during
 			// construction.
-			let addr_bob = builder::bare_instantiate(Code::Upload(caller_wasm))
-				.value(200_000)
-				.data(callee_code_hash.as_ref().to_vec())
-				.build_and_unwrap_account_id();
+			let Contract { addr: addr_bob, .. } =
+				builder::bare_instantiate(Code::Upload(caller_wasm))
+					.value(200_000)
+					.data(callee_code_hash.as_ref().to_vec())
+					.build_and_unwrap_contract();
 
 			// Check that the CHARLIE contract has been instantiated.
-			let addr_charlie =
-				Contracts::contract_address(&addr_bob, &callee_code_hash, &[], &[0x47, 0x11]);
+			let salt = [47; 32]; // hard coded in fixture.
+			let addr_charlie = crate::address::create2(&addr_bob, &callee_wasm, &[], &salt);
 			get_contract(&addr_charlie);
 
 			// Call BOB, which calls CHARLIE, forcing CHARLIE to self-destruct.
@@ -1412,7 +1423,7 @@ mod run_tests {
 
 	#[test]
 	fn cannot_self_destruct_in_constructor() {
-		let (wasm, _) = compile_module::<Test>("self_destructing_constructor").unwrap();
+		let (wasm, _) = compile_module("self_destructing_constructor").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
@@ -1426,15 +1437,15 @@ mod run_tests {
 
 	#[test]
 	fn crypto_hashes() {
-		let (wasm, _code_hash) = compile_module::<Test>("crypto_hashes").unwrap();
+		let (wasm, _code_hash) = compile_module("crypto_hashes").unwrap();
 
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Instantiate the CRYPTO_HASHES contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(100_000)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 			// Perform the call.
 			let input = b"_DEAD_BEEF";
 			use sp_io::hashing::*;
@@ -1456,8 +1467,7 @@ mod run_tests {
 				// We offset data in the contract tables by 1.
 				let mut params = vec![(n + 1) as u8];
 				params.extend_from_slice(input);
-				let result =
-					builder::bare_call(addr.clone()).data(params).build_and_unwrap_result();
+				let result = builder::bare_call(addr).data(params).build_and_unwrap_result();
 				assert!(!result.did_revert());
 				let expected = hash_fn(input.as_ref());
 				assert_eq!(&result.data[..*expected_size], &*expected);
@@ -1467,54 +1477,54 @@ mod run_tests {
 
 	#[test]
 	fn transfer_return_code() {
-		let (wasm, _code_hash) = compile_module::<Test>("transfer_return_code").unwrap();
+		let (wasm, _code_hash) = compile_module("transfer_return_code").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
 
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let contract = builder::bare_instantiate(Code::Upload(wasm))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			// Contract has only the minimal balance so any transfer will fail.
-			<Test as Config>::Currency::set_balance(&addr, min_balance);
-			let result = builder::bare_call(addr.clone()).build_and_unwrap_result();
+			<Test as Config>::Currency::set_balance(&contract.account_id, min_balance);
+			let result = builder::bare_call(contract.addr).build_and_unwrap_result();
 			assert_return_code!(result, RuntimeReturnCode::TransferFailed);
 		});
 	}
 
 	#[test]
 	fn call_return_code() {
-		let (caller_code, _caller_hash) = compile_module::<Test>("call_return_code").unwrap();
-		let (callee_code, _callee_hash) = compile_module::<Test>("ok_trap_revert").unwrap();
+		let (caller_code, _caller_hash) = compile_module("call_return_code").unwrap();
+		let (callee_code, _callee_hash) = compile_module("ok_trap_revert").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
 			let _ = <Test as Config>::Currency::set_balance(&CHARLIE, 1000 * min_balance);
 
-			let addr_bob = builder::bare_instantiate(Code::Upload(caller_code))
+			let bob = builder::bare_instantiate(Code::Upload(caller_code))
 				.value(min_balance * 100)
 				.data(vec![0])
-				.build_and_unwrap_account_id();
-			<Test as Config>::Currency::set_balance(&addr_bob, min_balance);
+				.build_and_unwrap_contract();
+			<Test as Config>::Currency::set_balance(&bob.account_id, min_balance);
 
 			// Contract calls into Django which is no valid contract
-			let result = builder::bare_call(addr_bob.clone())
+			let result = builder::bare_call(bob.addr)
 				.data(AsRef::<[u8]>::as_ref(&DJANGO).to_vec())
 				.build_and_unwrap_result();
 			assert_return_code!(result, RuntimeReturnCode::NotCallable);
 
-			let addr_django = builder::bare_instantiate(Code::Upload(callee_code))
+			let django = builder::bare_instantiate(Code::Upload(callee_code))
 				.origin(RuntimeOrigin::signed(CHARLIE))
 				.value(min_balance * 100)
 				.data(vec![0])
-				.build_and_unwrap_account_id();
-			<Test as Config>::Currency::set_balance(&addr_django, min_balance);
+				.build_and_unwrap_contract();
+			<Test as Config>::Currency::set_balance(&django.account_id, min_balance);
 
 			// Contract has only the minimal balance so any transfer will fail.
-			let result = builder::bare_call(addr_bob.clone())
+			let result = builder::bare_call(bob.addr)
 				.data(
-					AsRef::<[u8]>::as_ref(&addr_django)
+					AsRef::<[u8]>::as_ref(&django.addr)
 						.iter()
 						.chain(&0u32.to_le_bytes())
 						.cloned()
@@ -1524,10 +1534,10 @@ mod run_tests {
 			assert_return_code!(result, RuntimeReturnCode::TransferFailed);
 
 			// Contract has enough balance but callee reverts because "1" is passed.
-			<Test as Config>::Currency::set_balance(&addr_bob, min_balance + 1000);
-			let result = builder::bare_call(addr_bob.clone())
+			<Test as Config>::Currency::set_balance(&bob.account_id, min_balance + 1000);
+			let result = builder::bare_call(bob.addr)
 				.data(
-					AsRef::<[u8]>::as_ref(&addr_django)
+					AsRef::<[u8]>::as_ref(&django.addr)
 						.iter()
 						.chain(&1u32.to_le_bytes())
 						.cloned()
@@ -1537,9 +1547,9 @@ mod run_tests {
 			assert_return_code!(result, RuntimeReturnCode::CalleeReverted);
 
 			// Contract has enough balance but callee traps because "2" is passed.
-			let result = builder::bare_call(addr_bob)
+			let result = builder::bare_call(bob.addr)
 				.data(
-					AsRef::<[u8]>::as_ref(&addr_django)
+					AsRef::<[u8]>::as_ref(&django.addr)
 						.iter()
 						.chain(&2u32.to_le_bytes())
 						.cloned()
@@ -1552,9 +1562,8 @@ mod run_tests {
 
 	#[test]
 	fn instantiate_return_code() {
-		let (caller_code, _caller_hash) =
-			compile_module::<Test>("instantiate_return_code").unwrap();
-		let (callee_code, callee_hash) = compile_module::<Test>("ok_trap_revert").unwrap();
+		let (caller_code, _caller_hash) = compile_module("instantiate_return_code").unwrap();
+		let (callee_code, callee_hash) = compile_module("ok_trap_revert").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
@@ -1565,31 +1574,31 @@ mod run_tests {
 				.value(min_balance * 100)
 				.build());
 
-			let addr = builder::bare_instantiate(Code::Upload(caller_code))
+			let contract = builder::bare_instantiate(Code::Upload(caller_code))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			// Contract has only the minimal balance so any transfer will fail.
-			<Test as Config>::Currency::set_balance(&addr, min_balance);
-			let result = builder::bare_call(addr.clone())
+			<Test as Config>::Currency::set_balance(&contract.account_id, min_balance);
+			let result = builder::bare_call(contract.addr)
 				.data(callee_hash.clone())
 				.build_and_unwrap_result();
 			assert_return_code!(result, RuntimeReturnCode::TransferFailed);
 
 			// Contract has enough balance but the passed code hash is invalid
-			<Test as Config>::Currency::set_balance(&addr, min_balance + 10_000);
+			<Test as Config>::Currency::set_balance(&contract.account_id, min_balance + 10_000);
 			let result =
-				builder::bare_call(addr.clone()).data(vec![0; 33]).build_and_unwrap_result();
+				builder::bare_call(contract.addr).data(vec![0; 33]).build_and_unwrap_result();
 			assert_return_code!(result, RuntimeReturnCode::CodeNotFound);
 
 			// Contract has enough balance but callee reverts because "1" is passed.
-			let result = builder::bare_call(addr.clone())
+			let result = builder::bare_call(contract.addr)
 				.data(callee_hash.iter().chain(&1u32.to_le_bytes()).cloned().collect())
 				.build_and_unwrap_result();
 			assert_return_code!(result, RuntimeReturnCode::CalleeReverted);
 
 			// Contract has enough balance but callee traps because "2" is passed.
-			let result = builder::bare_call(addr)
+			let result = builder::bare_call(contract.addr)
 				.data(callee_hash.iter().chain(&2u32.to_le_bytes()).cloned().collect())
 				.build_and_unwrap_result();
 			assert_return_code!(result, RuntimeReturnCode::CalleeTrapped);
@@ -1598,16 +1607,16 @@ mod run_tests {
 
 	#[test]
 	fn disabled_chain_extension_errors_on_call() {
-		let (code, _hash) = compile_module::<Test>("chain_extension").unwrap();
+		let (code, _hash) = compile_module("chain_extension").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
-			let addr = builder::bare_instantiate(Code::Upload(code))
+			let contract = builder::bare_instantiate(Code::Upload(code))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 			TestExtension::disable();
 			assert_err_ignore_postinfo!(
-				builder::call(addr.clone()).data(vec![7u8; 8]).build(),
+				builder::call(contract.addr).data(vec![7u8; 8]).build(),
 				Error::<Test>::NoChainExtension,
 			);
 		});
@@ -1615,46 +1624,46 @@ mod run_tests {
 
 	#[test]
 	fn chain_extension_works() {
-		let (code, _hash) = compile_module::<Test>("chain_extension").unwrap();
+		let (code, _hash) = compile_module("chain_extension").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
-			let addr = builder::bare_instantiate(Code::Upload(code))
+			let contract = builder::bare_instantiate(Code::Upload(code))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			// 0 = read input buffer and pass it through as output
 			let input: Vec<u8> =
 				ExtensionInput { extension_id: 0, func_id: 0, extra: &[99] }.into();
-			let result = builder::bare_call(addr.clone()).data(input.clone()).build();
+			let result = builder::bare_call(contract.addr).data(input.clone()).build();
 			assert_eq!(TestExtension::last_seen_buffer(), input);
 			assert_eq!(result.result.unwrap().data, input);
 
 			// 1 = treat inputs as integer primitives and store the supplied integers
-			builder::bare_call(addr.clone())
+			builder::bare_call(contract.addr)
 				.data(ExtensionInput { extension_id: 0, func_id: 1, extra: &[] }.into())
 				.build_and_unwrap_result();
 			assert_eq!(TestExtension::last_seen_input_len(), 4);
 
 			// 2 = charge some extra weight (amount supplied in the fifth byte)
-			let result = builder::bare_call(addr.clone())
+			let result = builder::bare_call(contract.addr)
 				.data(ExtensionInput { extension_id: 0, func_id: 2, extra: &0u32.encode() }.into())
 				.build();
 			assert_ok!(result.result);
 			let gas_consumed = result.gas_consumed;
-			let result = builder::bare_call(addr.clone())
+			let result = builder::bare_call(contract.addr)
 				.data(ExtensionInput { extension_id: 0, func_id: 2, extra: &42u32.encode() }.into())
 				.build();
 			assert_ok!(result.result);
 			assert_eq!(result.gas_consumed.ref_time(), gas_consumed.ref_time() + 42);
-			let result = builder::bare_call(addr.clone())
+			let result = builder::bare_call(contract.addr)
 				.data(ExtensionInput { extension_id: 0, func_id: 2, extra: &95u32.encode() }.into())
 				.build();
 			assert_ok!(result.result);
 			assert_eq!(result.gas_consumed.ref_time(), gas_consumed.ref_time() + 95);
 
 			// 3 = diverging chain extension call that sets flags to 0x1 and returns a fixed buffer
-			let result = builder::bare_call(addr.clone())
+			let result = builder::bare_call(contract.addr)
 				.data(ExtensionInput { extension_id: 0, func_id: 3, extra: &[] }.into())
 				.build_and_unwrap_result();
 			assert_eq!(result.flags, ReturnFlags::REVERT);
@@ -1663,7 +1672,7 @@ mod run_tests {
 			// diverging to second chain extension that sets flags to 0x1 and returns a fixed buffer
 			// We set the MSB part to 1 (instead of 0) which routes the request into the second
 			// extension
-			let result = builder::bare_call(addr.clone())
+			let result = builder::bare_call(contract.addr)
 				.data(ExtensionInput { extension_id: 1, func_id: 0, extra: &[] }.into())
 				.build_and_unwrap_result();
 			assert_eq!(result.flags, ReturnFlags::REVERT);
@@ -1673,7 +1682,7 @@ mod run_tests {
 			// We set the MSB part to 2 (instead of 0) which routes the request into the third
 			// extension
 			assert_err_ignore_postinfo!(
-				builder::call(addr.clone())
+				builder::call(contract.addr)
 					.data(ExtensionInput { extension_id: 2, func_id: 0, extra: &[] }.into())
 					.build(),
 				Error::<Test>::NoChainExtension,
@@ -1683,13 +1692,13 @@ mod run_tests {
 
 	#[test]
 	fn chain_extension_temp_storage_works() {
-		let (code, _hash) = compile_module::<Test>("chain_extension_temp_storage").unwrap();
+		let (code, _hash) = compile_module("chain_extension_temp_storage").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
-			let addr = builder::bare_instantiate(Code::Upload(code))
+			let contract = builder::bare_instantiate(Code::Upload(code))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			// Call func 0 and func 1 back to back.
 			let stop_recursion = 0u8;
@@ -1701,32 +1710,32 @@ mod run_tests {
 					.as_ref(),
 			);
 
-			assert_ok!(builder::bare_call(addr.clone()).data(input.clone()).build().result);
+			assert_ok!(builder::bare_call(contract.addr).data(input.clone()).build().result);
 		})
 	}
 
 	#[test]
 	fn lazy_removal_works() {
-		let (code, _hash) = compile_module::<Test>("self_destruct").unwrap();
+		let (code, _hash) = compile_module("self_destruct").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
 
-			let addr = builder::bare_instantiate(Code::Upload(code))
+			let contract = builder::bare_instantiate(Code::Upload(code))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
-			let info = get_contract(&addr);
+			let info = get_contract(&contract.addr);
 			let trie = &info.child_trie_info();
 
 			// Put value into the contracts child trie
 			child::put(trie, &[99], &42);
 
 			// Terminate the contract
-			assert_ok!(builder::call(addr.clone()).build());
+			assert_ok!(builder::call(contract.addr).build());
 
 			// Contract info should be gone
-			assert!(!<ContractInfoOf::<Test>>::contains_key(&addr));
+			assert!(!<ContractInfoOf::<Test>>::contains_key(&contract.addr));
 
 			// But value should be still there as the lazy removal did not run, yet.
 			assert_matches!(child::get(trie, &[99]), Some(42));
@@ -1741,19 +1750,19 @@ mod run_tests {
 
 	#[test]
 	fn lazy_batch_removal_works() {
-		let (code, _hash) = compile_module::<Test>("self_destruct").unwrap();
+		let (code, _hash) = compile_module("self_destruct").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
 			let mut tries: Vec<child::ChildInfo> = vec![];
 
 			for i in 0..3u8 {
-				let addr = builder::bare_instantiate(Code::Upload(code.clone()))
+				let contract = builder::bare_instantiate(Code::Upload(code.clone()))
 					.value(min_balance * 100)
-					.salt(vec![i])
-					.build_and_unwrap_account_id();
+					.salt([i; 32])
+					.build_and_unwrap_contract();
 
-				let info = get_contract(&addr);
+				let info = get_contract(&contract.addr);
 				let trie = &info.child_trie_info();
 
 				// Put value into the contracts child trie
@@ -1761,9 +1770,9 @@ mod run_tests {
 
 				// Terminate the contract. Contract info should be gone, but value should be still
 				// there as the lazy removal did not run, yet.
-				assert_ok!(builder::call(addr.clone()).build());
+				assert_ok!(builder::call(contract.addr).build());
 
-				assert!(!<ContractInfoOf::<Test>>::contains_key(&addr));
+				assert!(!<ContractInfoOf::<Test>>::contains_key(&contract.addr));
 				assert_matches!(child::get(trie, &[99]), Some(42));
 
 				tries.push(trie.clone())
@@ -1781,7 +1790,7 @@ mod run_tests {
 
 	#[test]
 	fn lazy_removal_partial_remove_works() {
-		let (code, _hash) = compile_module::<Test>("self_destruct").unwrap();
+		let (code, _hash) = compile_module("self_destruct").unwrap();
 
 		// We create a contract with some extra keys above the weight limit
 		let extra_keys = 7u32;
@@ -1797,9 +1806,9 @@ mod run_tests {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
 
-			let addr = builder::bare_instantiate(Code::Upload(code))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(code))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			let info = get_contract(&addr);
 
@@ -1810,7 +1819,7 @@ mod run_tests {
 			<ContractInfoOf<Test>>::insert(&addr, info.clone());
 
 			// Terminate the contract
-			assert_ok!(builder::call(addr.clone()).build());
+			assert_ok!(builder::call(addr).build());
 
 			// Contract info should be gone
 			assert!(!<ContractInfoOf::<Test>>::contains_key(&addr));
@@ -1856,14 +1865,14 @@ mod run_tests {
 
 	#[test]
 	fn lazy_removal_does_no_run_on_low_remaining_weight() {
-		let (code, _hash) = compile_module::<Test>("self_destruct").unwrap();
+		let (code, _hash) = compile_module("self_destruct").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
 
-			let addr = builder::bare_instantiate(Code::Upload(code))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(code))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			let info = get_contract(&addr);
 			let trie = &info.child_trie_info();
@@ -1872,7 +1881,7 @@ mod run_tests {
 			child::put(trie, &[99], &42);
 
 			// Terminate the contract
-			assert_ok!(builder::call(addr.clone()).build());
+			assert_ok!(builder::call(addr).build());
 
 			// Contract info should be gone
 			assert!(!<ContractInfoOf::<Test>>::contains_key(&addr));
@@ -1906,7 +1915,7 @@ mod run_tests {
 
 	#[test]
 	fn lazy_removal_does_not_use_all_weight() {
-		let (code, _hash) = compile_module::<Test>("self_destruct").unwrap();
+		let (code, _hash) = compile_module("self_destruct").unwrap();
 
 		let mut meter = WeightMeter::with_limit(Weight::from_parts(5_000_000_000, 100 * 1024));
 		let mut ext = ExtBuilder::default().existential_deposit(50).build();
@@ -1915,9 +1924,9 @@ mod run_tests {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
 
-			let addr = builder::bare_instantiate(Code::Upload(code))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(code))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			let info = get_contract(&addr);
 			let (weight_per_key, max_keys) = ContractInfo::<Test>::deletion_budget(&meter);
@@ -1935,7 +1944,7 @@ mod run_tests {
 			<ContractInfoOf<Test>>::insert(&addr, info.clone());
 
 			// Terminate the contract
-			assert_ok!(builder::call(addr.clone()).build());
+			assert_ok!(builder::call(addr).build());
 
 			// Contract info should be gone
 			assert!(!<ContractInfoOf::<Test>>::contains_key(&addr));
@@ -1970,7 +1979,7 @@ mod run_tests {
 
 	#[test]
 	fn deletion_queue_ring_buffer_overflow() {
-		let (code, _hash) = compile_module::<Test>("self_destruct").unwrap();
+		let (code, _hash) = compile_module("self_destruct").unwrap();
 		let mut ext = ExtBuilder::default().existential_deposit(50).build();
 
 		// setup the deletion queue with custom counters
@@ -1989,10 +1998,10 @@ mod run_tests {
 
 			// add 3 contracts to the deletion queue
 			for i in 0..3u8 {
-				let addr = builder::bare_instantiate(Code::Upload(code.clone()))
+				let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(code.clone()))
 					.value(min_balance * 100)
-					.salt(vec![i])
-					.build_and_unwrap_account_id();
+					.salt([i; 32])
+					.build_and_unwrap_contract();
 
 				let info = get_contract(&addr);
 				let trie = &info.child_trie_info();
@@ -2002,7 +2011,7 @@ mod run_tests {
 
 				// Terminate the contract. Contract info should be gone, but value should be still
 				// there as the lazy removal did not run, yet.
-				assert_ok!(builder::call(addr.clone()).build());
+				assert_ok!(builder::call(addr).build());
 
 				assert!(!<ContractInfoOf::<Test>>::contains_key(&addr));
 				assert_matches!(child::get(trie, &[99]), Some(42));
@@ -2024,27 +2033,29 @@ mod run_tests {
 	}
 	#[test]
 	fn refcounter() {
-		let (wasm, code_hash) = compile_module::<Test>("self_destruct").unwrap();
+		let (wasm, code_hash) = compile_module("self_destruct").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let min_balance = Contracts::min_balance();
 
 			// Create two contracts with the same code and check that they do in fact share it.
-			let addr0 = builder::bare_instantiate(Code::Upload(wasm.clone()))
-				.value(min_balance * 100)
-				.salt(vec![0])
-				.build_and_unwrap_account_id();
-			let addr1 = builder::bare_instantiate(Code::Upload(wasm.clone()))
-				.value(min_balance * 100)
-				.salt(vec![1])
-				.build_and_unwrap_account_id();
+			let Contract { addr: addr0, .. } =
+				builder::bare_instantiate(Code::Upload(wasm.clone()))
+					.value(min_balance * 100)
+					.salt([0; 32])
+					.build_and_unwrap_contract();
+			let Contract { addr: addr1, .. } =
+				builder::bare_instantiate(Code::Upload(wasm.clone()))
+					.value(min_balance * 100)
+					.salt([1; 32])
+					.build_and_unwrap_contract();
 			assert_refcount!(code_hash, 2);
 
 			// Sharing should also work with the usual instantiate call
-			let addr2 = builder::bare_instantiate(Code::Existing(code_hash))
+			let Contract { addr: addr2, .. } = builder::bare_instantiate(Code::Existing(code_hash))
 				.value(min_balance * 100)
-				.salt(vec![2])
-				.build_and_unwrap_account_id();
+				.salt([2; 32])
+				.build_and_unwrap_contract();
 			assert_refcount!(code_hash, 3);
 
 			// Terminating one contract should decrement the refcount
@@ -2069,13 +2080,13 @@ mod run_tests {
 
 	#[test]
 	fn debug_message_works() {
-		let (wasm, _code_hash) = compile_module::<Test>("debug_message_works").unwrap();
+		let (wasm, _code_hash) = compile_module("debug_message_works").unwrap();
 
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(30_000)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 			let result = builder::bare_call(addr).debug(DebugInfo::UnsafeDebug).build();
 
 			assert_matches!(result.result, Ok(_));
@@ -2085,13 +2096,13 @@ mod run_tests {
 
 	#[test]
 	fn debug_message_logging_disabled() {
-		let (wasm, _code_hash) = compile_module::<Test>("debug_message_logging_disabled").unwrap();
+		let (wasm, _code_hash) = compile_module("debug_message_logging_disabled").unwrap();
 
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(30_000)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 			// the dispatchables always run without debugging
 			assert_ok!(Contracts::call(
 				RuntimeOrigin::signed(ALICE),
@@ -2106,13 +2117,13 @@ mod run_tests {
 
 	#[test]
 	fn debug_message_invalid_utf8() {
-		let (wasm, _code_hash) = compile_module::<Test>("debug_message_invalid_utf8").unwrap();
+		let (wasm, _code_hash) = compile_module("debug_message_invalid_utf8").unwrap();
 
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(30_000)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 			let result = builder::bare_call(addr).debug(DebugInfo::UnsafeDebug).build();
 			assert_ok!(result.result);
 			assert!(result.debug_message.is_empty());
@@ -2121,24 +2132,27 @@ mod run_tests {
 
 	#[test]
 	fn gas_estimation_for_subcalls() {
-		let (caller_code, _caller_hash) = compile_module::<Test>("call_with_limit").unwrap();
-		let (call_runtime_code, _caller_hash) = compile_module::<Test>("call_runtime").unwrap();
-		let (dummy_code, _callee_hash) = compile_module::<Test>("dummy").unwrap();
+		let (caller_code, _caller_hash) = compile_module("call_with_limit").unwrap();
+		let (call_runtime_code, _caller_hash) = compile_module("call_runtime").unwrap();
+		let (dummy_code, _callee_hash) = compile_module("dummy").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 2_000 * min_balance);
 
-			let addr_caller = builder::bare_instantiate(Code::Upload(caller_code))
-				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+			let Contract { addr: addr_caller, .. } =
+				builder::bare_instantiate(Code::Upload(caller_code))
+					.value(min_balance * 100)
+					.build_and_unwrap_contract();
 
-			let addr_dummy = builder::bare_instantiate(Code::Upload(dummy_code))
-				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+			let Contract { addr: addr_dummy, .. } =
+				builder::bare_instantiate(Code::Upload(dummy_code))
+					.value(min_balance * 100)
+					.build_and_unwrap_contract();
 
-			let addr_call_runtime = builder::bare_instantiate(Code::Upload(call_runtime_code))
-				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+			let Contract { addr: addr_call_runtime, .. } =
+				builder::bare_instantiate(Code::Upload(call_runtime_code))
+					.value(min_balance * 100)
+					.build_and_unwrap_contract();
 
 			// Run the test for all of those weight limits for the subcall
 			let weights = [
@@ -2174,8 +2188,7 @@ mod run_tests {
 						.collect();
 
 					// Call in order to determine the gas that is required for this call
-					let result_orig =
-						builder::bare_call(addr_caller.clone()).data(input.clone()).build();
+					let result_orig = builder::bare_call(addr_caller).data(input.clone()).build();
 					assert_ok!(&result_orig.result);
 
 					// If the out of gas happens in the subcall the caller contract
@@ -2190,7 +2203,7 @@ mod run_tests {
 					};
 
 					// Make the same call using the estimated gas. Should succeed.
-					let result = builder::bare_call(addr_caller.clone())
+					let result = builder::bare_call(addr_caller)
 						.gas_limit(result_orig.gas_required)
 						.storage_deposit_limit(result_orig.storage_deposit.charge_or_zero())
 						.data(input.clone())
@@ -2198,7 +2211,7 @@ mod run_tests {
 					assert_ok!(&result.result);
 
 					// Check that it fails with too little ref_time
-					let result = builder::bare_call(addr_caller.clone())
+					let result = builder::bare_call(addr_caller)
 						.gas_limit(result_orig.gas_required.sub_ref_time(1))
 						.storage_deposit_limit(result_orig.storage_deposit.charge_or_zero())
 						.data(input.clone())
@@ -2206,7 +2219,7 @@ mod run_tests {
 					assert_err!(result.result, error);
 
 					// Check that it fails with too little proof_size
-					let result = builder::bare_call(addr_caller.clone())
+					let result = builder::bare_call(addr_caller)
 						.gas_limit(result_orig.gas_required.sub_proof_size(1))
 						.storage_deposit_limit(result_orig.storage_deposit.charge_or_zero())
 						.data(input.clone())
@@ -2219,16 +2232,17 @@ mod run_tests {
 
 	#[test]
 	fn gas_estimation_call_runtime() {
-		let (caller_code, _caller_hash) = compile_module::<Test>("call_runtime").unwrap();
+		let (caller_code, _caller_hash) = compile_module("call_runtime").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
 			let _ = <Test as Config>::Currency::set_balance(&CHARLIE, 1000 * min_balance);
 
-			let addr_caller = builder::bare_instantiate(Code::Upload(caller_code))
-				.value(min_balance * 100)
-				.salt(vec![0])
-				.build_and_unwrap_account_id();
+			let Contract { addr: addr_caller, .. } =
+				builder::bare_instantiate(Code::Upload(caller_code))
+					.value(min_balance * 100)
+					.salt([0; 32])
+					.build_and_unwrap_contract();
 
 			// Call something trivial with a huge gas limit so that we can observe the effects
 			// of pre-charging. This should create a difference between consumed and required.
@@ -2236,7 +2250,7 @@ mod run_tests {
 				pre_charge: Weight::from_parts(10_000_000, 1_000),
 				actual_weight: Weight::from_parts(100, 100),
 			});
-			let result = builder::bare_call(addr_caller.clone()).data(call.encode()).build();
+			let result = builder::bare_call(addr_caller).data(call.encode()).build();
 			// contract encodes the result of the dispatch runtime
 			let outcome = u32::decode(&mut result.result.unwrap().data.as_ref()).unwrap();
 			assert_eq!(outcome, 0);
@@ -2255,22 +2269,24 @@ mod run_tests {
 
 	#[test]
 	fn call_runtime_reentrancy_guarded() {
-		let (caller_code, _caller_hash) = compile_module::<Test>("call_runtime").unwrap();
-		let (callee_code, _callee_hash) = compile_module::<Test>("dummy").unwrap();
+		let (caller_code, _caller_hash) = compile_module("call_runtime").unwrap();
+		let (callee_code, _callee_hash) = compile_module("dummy").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
 			let _ = <Test as Config>::Currency::set_balance(&CHARLIE, 1000 * min_balance);
 
-			let addr_caller = builder::bare_instantiate(Code::Upload(caller_code))
-				.value(min_balance * 100)
-				.salt(vec![0])
-				.build_and_unwrap_account_id();
+			let Contract { addr: addr_caller, .. } =
+				builder::bare_instantiate(Code::Upload(caller_code))
+					.value(min_balance * 100)
+					.salt([0; 32])
+					.build_and_unwrap_contract();
 
-			let addr_callee = builder::bare_instantiate(Code::Upload(callee_code))
-				.value(min_balance * 100)
-				.salt(vec![1])
-				.build_and_unwrap_account_id();
+			let Contract { addr: addr_callee, .. } =
+				builder::bare_instantiate(Code::Upload(callee_code))
+					.value(min_balance * 100)
+					.salt([1; 32])
+					.build_and_unwrap_contract();
 
 			// Call pallet_revive call() dispatchable
 			let call = RuntimeCall::Contracts(crate::Call::call {
@@ -2283,9 +2299,8 @@ mod run_tests {
 
 			// Call runtime to re-enter back to contracts engine by
 			// calling dummy contract
-			let result = builder::bare_call(addr_caller.clone())
-				.data(call.encode())
-				.build_and_unwrap_result();
+			let result =
+				builder::bare_call(addr_caller).data(call.encode()).build_and_unwrap_result();
 			// Call to runtime should fail because of the re-entrancy guard
 			assert_return_code!(result, RuntimeReturnCode::CallRuntimeFailed);
 		});
@@ -2293,15 +2308,15 @@ mod run_tests {
 
 	#[test]
 	fn ecdsa_recover() {
-		let (wasm, _code_hash) = compile_module::<Test>("ecdsa_recover").unwrap();
+		let (wasm, _code_hash) = compile_module("ecdsa_recover").unwrap();
 
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Instantiate the ecdsa_recover contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(100_000)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			#[rustfmt::skip]
 		let signature: [u8; 65] = [
@@ -2326,7 +2341,7 @@ mod run_tests {
 			params.extend_from_slice(&signature);
 			params.extend_from_slice(&message_hash);
 			assert!(params.len() == 65 + 32);
-			let result = builder::bare_call(addr.clone()).data(params).build_and_unwrap_result();
+			let result = builder::bare_call(addr).data(params).build_and_unwrap_result();
 			assert!(!result.did_revert());
 			assert_eq!(result.data, EXPECTED_COMPRESSED_PUBLIC_KEY);
 		})
@@ -2334,7 +2349,7 @@ mod run_tests {
 
 	#[test]
 	fn bare_instantiate_returns_events() {
-		let (wasm, _code_hash) = compile_module::<Test>("transfer_return_code").unwrap();
+		let (wasm, _code_hash) = compile_module("transfer_return_code").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
@@ -2352,7 +2367,7 @@ mod run_tests {
 
 	#[test]
 	fn bare_instantiate_does_not_return_events() {
-		let (wasm, _code_hash) = compile_module::<Test>("transfer_return_code").unwrap();
+		let (wasm, _code_hash) = compile_module("transfer_return_code").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
@@ -2368,18 +2383,17 @@ mod run_tests {
 
 	#[test]
 	fn bare_call_returns_events() {
-		let (wasm, _code_hash) = compile_module::<Test>("transfer_return_code").unwrap();
+		let (wasm, _code_hash) = compile_module("transfer_return_code").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
 
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
-			let result = builder::bare_call(addr.clone())
-				.collect_events(CollectEvents::UnsafeCollect)
-				.build();
+			let result =
+				builder::bare_call(addr).collect_events(CollectEvents::UnsafeCollect).build();
 
 			let events = result.events.unwrap();
 			assert_return_code!(&result.result.unwrap(), RuntimeReturnCode::Success);
@@ -2390,16 +2404,16 @@ mod run_tests {
 
 	#[test]
 	fn bare_call_does_not_return_events() {
-		let (wasm, _code_hash) = compile_module::<Test>("transfer_return_code").unwrap();
+		let (wasm, _code_hash) = compile_module("transfer_return_code").unwrap();
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let min_balance = Contracts::min_balance();
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1000 * min_balance);
 
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(min_balance * 100)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
-			let result = builder::bare_call(addr.clone()).build();
+			let result = builder::bare_call(addr).build();
 
 			let events = result.events;
 			assert_return_code!(&result.result.unwrap(), RuntimeReturnCode::Success);
@@ -2410,15 +2424,15 @@ mod run_tests {
 
 	#[test]
 	fn sr25519_verify() {
-		let (wasm, _code_hash) = compile_module::<Test>("sr25519_verify").unwrap();
+		let (wasm, _code_hash) = compile_module("sr25519_verify").unwrap();
 
 		ExtBuilder::default().existential_deposit(50).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Instantiate the sr25519_verify contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(100_000)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			let call_with = |message: &[u8; 11]| {
 				// Alice's signature for "hello world"
@@ -2442,7 +2456,7 @@ mod run_tests {
 				params.extend_from_slice(&public_key);
 				params.extend_from_slice(message);
 
-				builder::bare_call(addr.clone()).data(params).build_and_unwrap_result()
+				builder::bare_call(addr).data(params).build_and_unwrap_result()
 			};
 
 			// verification should succeed for "hello world"
@@ -2455,8 +2469,8 @@ mod run_tests {
 
 	#[test]
 	fn failed_deposit_charge_should_roll_back_call() {
-		let (wasm_caller, _) = compile_module::<Test>("call_runtime_and_call").unwrap();
-		let (wasm_callee, _) = compile_module::<Test>("store_call").unwrap();
+		let (wasm_caller, _) = compile_module("call_runtime_and_call").unwrap();
+		let (wasm_callee, _) = compile_module("store_call").unwrap();
 		const ED: u64 = 200;
 
 		let execute = || {
@@ -2464,15 +2478,16 @@ mod run_tests {
 				let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 				// Instantiate both contracts.
-				let addr_caller = builder::bare_instantiate(Code::Upload(wasm_caller.clone()))
-					.build_and_unwrap_account_id();
-				let addr_callee = builder::bare_instantiate(Code::Upload(wasm_callee.clone()))
-					.build_and_unwrap_account_id();
+				let caller = builder::bare_instantiate(Code::Upload(wasm_caller.clone()))
+					.build_and_unwrap_contract();
+				let Contract { addr: addr_callee, .. } =
+					builder::bare_instantiate(Code::Upload(wasm_callee.clone()))
+						.build_and_unwrap_contract();
 
 				// Give caller proxy access to Alice.
 				assert_ok!(Proxy::add_proxy(
 					RuntimeOrigin::signed(ALICE),
-					addr_caller.clone(),
+					caller.account_id.clone(),
 					(),
 					0
 				));
@@ -2497,7 +2512,7 @@ mod run_tests {
 					transfer_proxy_call,
 				);
 
-				builder::call(addr_caller).data(data.encode()).build()
+				builder::call(caller.addr).data(data.encode()).build()
 			})
 		};
 
@@ -2511,7 +2526,7 @@ mod run_tests {
 
 	#[test]
 	fn upload_code_works() {
-		let (wasm, code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, code_hash) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
@@ -2532,7 +2547,7 @@ mod run_tests {
 					event: RuntimeEvent::Contracts(crate::Event::CodeStored {
 						code_hash,
 						deposit_held: deposit_expected,
-						uploader: ALICE
+						uploader: ALICE_ADDR
 					}),
 					topics: vec![],
 				},]
@@ -2542,7 +2557,7 @@ mod run_tests {
 
 	#[test]
 	fn upload_code_limit_too_low() {
-		let (wasm, _code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, _code_hash) = compile_module("dummy").unwrap();
 		let deposit_expected = expected_deposit(wasm.len());
 		let deposit_insufficient = deposit_expected.saturating_sub(1);
 
@@ -2563,7 +2578,7 @@ mod run_tests {
 
 	#[test]
 	fn upload_code_not_enough_balance() {
-		let (wasm, _code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, _code_hash) = compile_module("dummy").unwrap();
 		let deposit_expected = expected_deposit(wasm.len());
 		let deposit_insufficient = deposit_expected.saturating_sub(1);
 
@@ -2584,7 +2599,7 @@ mod run_tests {
 
 	#[test]
 	fn remove_code_works() {
-		let (wasm, code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, code_hash) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
@@ -2605,7 +2620,7 @@ mod run_tests {
 						event: RuntimeEvent::Contracts(crate::Event::CodeStored {
 							code_hash,
 							deposit_held: deposit_expected,
-							uploader: ALICE
+							uploader: ALICE_ADDR
 						}),
 						topics: vec![],
 					},
@@ -2614,7 +2629,7 @@ mod run_tests {
 						event: RuntimeEvent::Contracts(crate::Event::CodeRemoved {
 							code_hash,
 							deposit_released: deposit_expected,
-							remover: ALICE
+							remover: ALICE_ADDR
 						}),
 						topics: vec![],
 					},
@@ -2625,7 +2640,7 @@ mod run_tests {
 
 	#[test]
 	fn remove_code_wrong_origin() {
-		let (wasm, code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, code_hash) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
@@ -2649,7 +2664,7 @@ mod run_tests {
 					event: RuntimeEvent::Contracts(crate::Event::CodeStored {
 						code_hash,
 						deposit_held: deposit_expected,
-						uploader: ALICE
+						uploader: ALICE_ADDR
 					}),
 					topics: vec![],
 				},]
@@ -2659,7 +2674,7 @@ mod run_tests {
 
 	#[test]
 	fn remove_code_in_use() {
-		let (wasm, code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, code_hash) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
@@ -2680,7 +2695,7 @@ mod run_tests {
 
 	#[test]
 	fn remove_code_not_found() {
-		let (_wasm, code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (_wasm, code_hash) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
@@ -2699,7 +2714,7 @@ mod run_tests {
 
 	#[test]
 	fn instantiate_with_zero_balance_works() {
-		let (wasm, code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, code_hash) = compile_module("dummy").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let min_balance = Contracts::min_balance();
@@ -2708,15 +2723,16 @@ mod run_tests {
 			initialize_block(2);
 
 			// Instantiate the BOB contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_account_id();
+			let Contract { addr, account_id } =
+				builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_contract();
 
 			// Ensure the contract was stored and get expected deposit amount to be reserved.
 			let deposit_expected = expected_deposit(ensure_stored(code_hash));
 
 			// Make sure the account exists even though no free balance was send
-			assert_eq!(<Test as Config>::Currency::free_balance(&addr), min_balance);
+			assert_eq!(<Test as Config>::Currency::free_balance(&account_id), min_balance);
 			assert_eq!(
-				<Test as Config>::Currency::total_balance(&addr),
+				<Test as Config>::Currency::total_balance(&account_id),
 				min_balance + test_utils::contract_info_storage_deposit(&addr)
 			);
 
@@ -2728,21 +2744,21 @@ mod run_tests {
 						event: RuntimeEvent::Contracts(crate::Event::CodeStored {
 							code_hash,
 							deposit_held: deposit_expected,
-							uploader: ALICE
+							uploader: ALICE_ADDR
 						}),
 						topics: vec![],
 					},
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::System(frame_system::Event::NewAccount {
-							account: addr.clone(),
+							account: account_id.clone(),
 						}),
 						topics: vec![],
 					},
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Endowed {
-							account: addr.clone(),
+							account: account_id.clone(),
 							free_balance: min_balance,
 						}),
 						topics: vec![],
@@ -2751,7 +2767,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Transfer {
 							from: ALICE,
-							to: addr.clone(),
+							to: account_id,
 							amount: min_balance,
 						}),
 						topics: vec![],
@@ -2759,8 +2775,8 @@ mod run_tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Instantiated {
-							deployer: ALICE,
-							contract: addr.clone(),
+							deployer: ALICE_ADDR,
+							contract: addr,
 						}),
 						topics: vec![],
 					},
@@ -2768,8 +2784,8 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(
 							pallet_revive::Event::StorageDepositTransferredAndHeld {
-								from: ALICE,
-								to: addr.clone(),
+								from: ALICE_ADDR,
+								to: addr,
 								amount: test_utils::contract_info_storage_deposit(&addr),
 							}
 						),
@@ -2782,7 +2798,7 @@ mod run_tests {
 
 	#[test]
 	fn instantiate_with_below_existential_deposit_works() {
-		let (wasm, code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, code_hash) = compile_module("dummy").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let min_balance = Contracts::min_balance();
@@ -2792,16 +2808,16 @@ mod run_tests {
 			initialize_block(2);
 
 			// Instantiate the BOB contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, account_id } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(value)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			// Ensure the contract was stored and get expected deposit amount to be reserved.
 			let deposit_expected = expected_deposit(ensure_stored(code_hash));
 			// Make sure the account exists even though not enough free balance was send
-			assert_eq!(<Test as Config>::Currency::free_balance(&addr), min_balance + value);
+			assert_eq!(<Test as Config>::Currency::free_balance(&account_id), min_balance + value);
 			assert_eq!(
-				<Test as Config>::Currency::total_balance(&addr),
+				<Test as Config>::Currency::total_balance(&account_id),
 				min_balance + value + test_utils::contract_info_storage_deposit(&addr)
 			);
 
@@ -2813,21 +2829,21 @@ mod run_tests {
 						event: RuntimeEvent::Contracts(crate::Event::CodeStored {
 							code_hash,
 							deposit_held: deposit_expected,
-							uploader: ALICE
+							uploader: ALICE_ADDR
 						}),
 						topics: vec![],
 					},
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::System(frame_system::Event::NewAccount {
-							account: addr.clone()
+							account: account_id.clone()
 						}),
 						topics: vec![],
 					},
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Endowed {
-							account: addr.clone(),
+							account: account_id.clone(),
 							free_balance: min_balance,
 						}),
 						topics: vec![],
@@ -2836,7 +2852,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Transfer {
 							from: ALICE,
-							to: addr.clone(),
+							to: account_id.clone(),
 							amount: min_balance,
 						}),
 						topics: vec![],
@@ -2845,7 +2861,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Transfer {
 							from: ALICE,
-							to: addr.clone(),
+							to: account_id.clone(),
 							amount: 50,
 						}),
 						topics: vec![],
@@ -2853,8 +2869,8 @@ mod run_tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Instantiated {
-							deployer: ALICE,
-							contract: addr.clone(),
+							deployer: ALICE_ADDR,
+							contract: addr,
 						}),
 						topics: vec![],
 					},
@@ -2862,8 +2878,8 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(
 							pallet_revive::Event::StorageDepositTransferredAndHeld {
-								from: ALICE,
-								to: addr.clone(),
+								from: ALICE_ADDR,
+								to: addr,
 								amount: test_utils::contract_info_storage_deposit(&addr),
 							}
 						),
@@ -2876,11 +2892,12 @@ mod run_tests {
 
 	#[test]
 	fn storage_deposit_works() {
-		let (wasm, _code_hash) = compile_module::<Test>("multi_store").unwrap();
+		let (wasm, _code_hash) = compile_module("multi_store").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
-			let addr = builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_account_id();
+			let Contract { addr, account_id } =
+				builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_contract();
 
 			let mut deposit = test_utils::contract_info_storage_deposit(&addr);
 
@@ -2888,20 +2905,20 @@ mod run_tests {
 			initialize_block(2);
 
 			// Create storage
-			assert_ok!(builder::call(addr.clone()).value(42).data((50u32, 20u32).encode()).build());
+			assert_ok!(builder::call(addr).value(42).data((50u32, 20u32).encode()).build());
 			// 4 is for creating 2 storage items
 			let charged0 = 4 + 50 + 20;
 			deposit += charged0;
 			assert_eq!(get_contract(&addr).total_deposit(), deposit);
 
 			// Add more storage (but also remove some)
-			assert_ok!(builder::call(addr.clone()).data((100u32, 10u32).encode()).build());
+			assert_ok!(builder::call(addr).data((100u32, 10u32).encode()).build());
 			let charged1 = 50 - 10;
 			deposit += charged1;
 			assert_eq!(get_contract(&addr).total_deposit(), deposit);
 
 			// Remove more storage (but also add some)
-			assert_ok!(builder::call(addr.clone()).data((10u32, 20u32).encode()).build());
+			assert_ok!(builder::call(addr).data((10u32, 20u32).encode()).build());
 			// -1 for numeric instability
 			let refunded0 = 90 - 10 - 1;
 			deposit -= refunded0;
@@ -2914,7 +2931,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Balances(pallet_balances::Event::Transfer {
 							from: ALICE,
-							to: addr.clone(),
+							to: account_id.clone(),
 							amount: 42,
 						}),
 						topics: vec![],
@@ -2923,7 +2940,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Called {
 							caller: Origin::from_account_id(ALICE),
-							contract: addr.clone(),
+							contract: addr,
 						}),
 						topics: vec![],
 					},
@@ -2931,8 +2948,8 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(
 							pallet_revive::Event::StorageDepositTransferredAndHeld {
-								from: ALICE,
-								to: addr.clone(),
+								from: ALICE_ADDR,
+								to: addr,
 								amount: charged0,
 							}
 						),
@@ -2942,7 +2959,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Called {
 							caller: Origin::from_account_id(ALICE),
-							contract: addr.clone(),
+							contract: addr,
 						}),
 						topics: vec![],
 					},
@@ -2950,8 +2967,8 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(
 							pallet_revive::Event::StorageDepositTransferredAndHeld {
-								from: ALICE,
-								to: addr.clone(),
+								from: ALICE_ADDR,
+								to: addr,
 								amount: charged1,
 							}
 						),
@@ -2961,7 +2978,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Called {
 							caller: Origin::from_account_id(ALICE),
-							contract: addr.clone(),
+							contract: addr,
 						}),
 						topics: vec![],
 					},
@@ -2969,8 +2986,8 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(
 							pallet_revive::Event::StorageDepositTransferredAndReleased {
-								from: addr.clone(),
-								to: ALICE,
+								from: addr,
+								to: ALICE_ADDR,
 								amount: refunded0,
 							}
 						),
@@ -2983,24 +3000,24 @@ mod run_tests {
 
 	#[test]
 	fn storage_deposit_callee_works() {
-		let (wasm_caller, _code_hash_caller) = compile_module::<Test>("call").unwrap();
-		let (wasm_callee, _code_hash_callee) = compile_module::<Test>("store_call").unwrap();
+		let (wasm_caller, _code_hash_caller) = compile_module("call").unwrap();
+		let (wasm_callee, _code_hash_callee) = compile_module("store_call").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let min_balance = Contracts::min_balance();
 
 			// Create both contracts: Constructors do nothing.
-			let addr_caller =
-				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_account_id();
-			let addr_callee =
-				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_account_id();
+			let Contract { addr: addr_caller, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_contract();
+			let Contract { addr: addr_callee, account_id } =
+				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_contract();
 
 			assert_ok!(builder::call(addr_caller).data((100u32, &addr_callee).encode()).build());
 
 			let callee = get_contract(&addr_callee);
 			let deposit = DepositPerByte::get() * 100 + DepositPerItem::get() * 1;
 
-			assert_eq!(test_utils::get_balance(&addr_callee), min_balance);
+			assert_eq!(test_utils::get_balance(&account_id), min_balance);
 			assert_eq!(
 				callee.total_deposit(),
 				deposit + test_utils::contract_info_storage_deposit(&addr_callee)
@@ -3010,15 +3027,16 @@ mod run_tests {
 
 	#[test]
 	fn set_code_extrinsic() {
-		let (wasm, code_hash) = compile_module::<Test>("dummy").unwrap();
-		let (new_wasm, new_code_hash) = compile_module::<Test>("crypto_hashes").unwrap();
+		let (wasm, code_hash) = compile_module("dummy").unwrap();
+		let (new_wasm, new_code_hash) = compile_module("crypto_hashes").unwrap();
 
 		assert_ne!(code_hash, new_code_hash);
 
 		ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
-			let addr = builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_account_id();
+			let Contract { addr, .. } =
+				builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_contract();
 
 			assert_ok!(Contracts::upload_code(
 				RuntimeOrigin::signed(ALICE),
@@ -3035,7 +3053,7 @@ mod run_tests {
 
 			// only root can execute this extrinsic
 			assert_noop!(
-				Contracts::set_code(RuntimeOrigin::signed(ALICE), addr.clone(), new_code_hash),
+				Contracts::set_code(RuntimeOrigin::signed(ALICE), addr, new_code_hash),
 				sp_runtime::traits::BadOrigin,
 			);
 			assert_eq!(get_contract(&addr).code_hash, code_hash);
@@ -3045,7 +3063,7 @@ mod run_tests {
 
 			// contract must exist
 			assert_noop!(
-				Contracts::set_code(RuntimeOrigin::root(), BOB, new_code_hash),
+				Contracts::set_code(RuntimeOrigin::root(), BOB_ADDR, new_code_hash),
 				<Error<Test>>::ContractNotFound,
 			);
 			assert_eq!(get_contract(&addr).code_hash, code_hash);
@@ -3055,7 +3073,7 @@ mod run_tests {
 
 			// new code hash must exist
 			assert_noop!(
-				Contracts::set_code(RuntimeOrigin::root(), addr.clone(), Default::default()),
+				Contracts::set_code(RuntimeOrigin::root(), addr, Default::default()),
 				<Error<Test>>::CodeNotFound,
 			);
 			assert_eq!(get_contract(&addr).code_hash, code_hash);
@@ -3064,7 +3082,7 @@ mod run_tests {
 			assert_eq!(System::events(), vec![]);
 
 			// successful call
-			assert_ok!(Contracts::set_code(RuntimeOrigin::root(), addr.clone(), new_code_hash));
+			assert_ok!(Contracts::set_code(RuntimeOrigin::root(), addr, new_code_hash));
 			assert_eq!(get_contract(&addr).code_hash, new_code_hash);
 			assert_refcount!(&code_hash, 0);
 			assert_refcount!(&new_code_hash, 1);
@@ -3073,7 +3091,7 @@ mod run_tests {
 				vec![EventRecord {
 					phase: Phase::Initialization,
 					event: RuntimeEvent::Contracts(pallet_revive::Event::ContractCodeUpdated {
-						contract: addr.clone(),
+						contract: addr,
 						new_code_hash,
 						old_code_hash: code_hash,
 					}),
@@ -3085,15 +3103,15 @@ mod run_tests {
 
 	#[test]
 	fn slash_cannot_kill_account() {
-		let (wasm, _code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, _code_hash) = compile_module("dummy").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let value = 700;
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let min_balance = Contracts::min_balance();
 
-			let addr = builder::bare_instantiate(Code::Upload(wasm))
+			let Contract { addr, account_id } = builder::bare_instantiate(Code::Upload(wasm))
 				.value(value)
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			// Drop previous events
 			initialize_block(2);
@@ -3101,12 +3119,15 @@ mod run_tests {
 			let info_deposit = test_utils::contract_info_storage_deposit(&addr);
 
 			assert_eq!(
-				test_utils::get_balance_on_hold(&HoldReason::StorageDepositReserve.into(), &addr),
+				test_utils::get_balance_on_hold(
+					&HoldReason::StorageDepositReserve.into(),
+					&account_id
+				),
 				info_deposit
 			);
 
 			assert_eq!(
-				<Test as Config>::Currency::total_balance(&addr),
+				<Test as Config>::Currency::total_balance(&account_id),
 				info_deposit + value + min_balance
 			);
 
@@ -3116,18 +3137,18 @@ mod run_tests {
 			// in staking.
 			let _ = <Test as Config>::Currency::slash(
 				&HoldReason::StorageDepositReserve.into(),
-				&addr,
-				<Test as Config>::Currency::total_balance(&addr),
+				&account_id,
+				<Test as Config>::Currency::total_balance(&account_id),
 			);
 
 			// Slashing only removed the balance held.
-			assert_eq!(<Test as Config>::Currency::total_balance(&addr), value + min_balance);
+			assert_eq!(<Test as Config>::Currency::total_balance(&account_id), value + min_balance);
 		});
 	}
 
 	#[test]
 	fn contract_reverted() {
-		let (wasm, code_hash) = compile_module::<Test>("return_with_data").unwrap();
+		let (wasm, code_hash) = compile_module("return_with_data").unwrap();
 
 		ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
@@ -3163,21 +3184,21 @@ mod run_tests {
 				.build_and_unwrap_result();
 			assert_eq!(result.result.flags, flags);
 			assert_eq!(result.result.data, buffer);
-			assert!(!<ContractInfoOf<Test>>::contains_key(result.account_id));
+			assert!(!<ContractInfoOf<Test>>::contains_key(result.addr));
 
 			// Pass empty flags and therefore successfully instantiate the contract for later use.
-			let addr = builder::bare_instantiate(Code::Existing(code_hash))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Existing(code_hash))
 				.data(ReturnFlags::empty().bits().encode())
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			// Calling extrinsic: revert leads to an error
 			assert_err_ignore_postinfo!(
-				builder::call(addr.clone()).data(input.clone()).build(),
+				builder::call(addr).data(input.clone()).build(),
 				<Error<Test>>::ContractReverted,
 			);
 
 			// Calling directly: revert leads to success but the flags indicate the error
-			let result = builder::bare_call(addr.clone()).data(input).build_and_unwrap_result();
+			let result = builder::bare_call(addr).data(input).build_and_unwrap_result();
 			assert_eq!(result.flags, flags);
 			assert_eq!(result.data, buffer);
 		});
@@ -3185,17 +3206,17 @@ mod run_tests {
 
 	#[test]
 	fn set_code_hash() {
-		let (wasm, code_hash) = compile_module::<Test>("set_code_hash").unwrap();
-		let (new_wasm, new_code_hash) =
-			compile_module::<Test>("new_set_code_hash_contract").unwrap();
+		let (wasm, code_hash) = compile_module("set_code_hash").unwrap();
+		let (new_wasm, new_code_hash) = compile_module("new_set_code_hash_contract").unwrap();
 
 		ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Instantiate the 'caller'
-			let contract_addr = builder::bare_instantiate(Code::Upload(wasm))
-				.value(300_000)
-				.build_and_unwrap_account_id();
+			let Contract { addr: contract_addr, .. } =
+				builder::bare_instantiate(Code::Upload(wasm))
+					.value(300_000)
+					.build_and_unwrap_contract();
 			// upload new code
 			assert_ok!(Contracts::upload_code(
 				RuntimeOrigin::signed(ALICE),
@@ -3206,14 +3227,14 @@ mod run_tests {
 			System::reset_events();
 
 			// First call sets new code_hash and returns 1
-			let result = builder::bare_call(contract_addr.clone())
+			let result = builder::bare_call(contract_addr)
 				.data(new_code_hash.as_ref().to_vec())
 				.debug(DebugInfo::UnsafeDebug)
 				.build_and_unwrap_result();
 			assert_return_code!(result, 1);
 
 			// Second calls new contract code that returns 2
-			let result = builder::bare_call(contract_addr.clone())
+			let result = builder::bare_call(contract_addr)
 				.debug(DebugInfo::UnsafeDebug)
 				.build_and_unwrap_result();
 			assert_return_code!(result, 2);
@@ -3225,7 +3246,7 @@ mod run_tests {
 					EventRecord {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::ContractCodeUpdated {
-							contract: contract_addr.clone(),
+							contract: contract_addr,
 							new_code_hash,
 							old_code_hash: code_hash,
 						}),
@@ -3235,7 +3256,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Called {
 							caller: Origin::from_account_id(ALICE),
-							contract: contract_addr.clone(),
+							contract: contract_addr,
 						}),
 						topics: vec![],
 					},
@@ -3243,7 +3264,7 @@ mod run_tests {
 						phase: Phase::Initialization,
 						event: RuntimeEvent::Contracts(crate::Event::Called {
 							caller: Origin::from_account_id(ALICE),
-							contract: contract_addr.clone(),
+							contract: contract_addr,
 						}),
 						topics: vec![],
 					},
@@ -3254,7 +3275,7 @@ mod run_tests {
 
 	#[test]
 	fn storage_deposit_limit_is_enforced() {
-		let (wasm, _code_hash) = compile_module::<Test>("store_call").unwrap();
+		let (wasm, _code_hash) = compile_module("store_call").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let min_balance = Contracts::min_balance();
@@ -3270,13 +3291,14 @@ mod run_tests {
 			);
 
 			// Instantiate the BOB contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_account_id();
+			let Contract { addr, account_id } =
+				builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_contract();
 
 			let info_deposit = test_utils::contract_info_storage_deposit(&addr);
 			// Check that the BOB contract has been instantiated and has the minimum balance
 			assert_eq!(get_contract(&addr).total_deposit(), info_deposit);
 			assert_eq!(
-				<Test as Config>::Currency::total_balance(&addr),
+				<Test as Config>::Currency::total_balance(&account_id),
 				info_deposit + min_balance
 			);
 
@@ -3284,7 +3306,7 @@ mod run_tests {
 			// setting insufficient deposit limit, as it requires 3 Balance:
 			// 2 for the item added + 1 for the new storage item.
 			assert_err_ignore_postinfo!(
-				builder::call(addr.clone())
+				builder::call(addr)
 					.storage_deposit_limit(2)
 					.data(1u32.to_le_bytes().to_vec())
 					.build(),
@@ -3294,7 +3316,7 @@ mod run_tests {
 			// Create 1 byte of storage, should cost 3 Balance:
 			// 2 for the item added + 1 for the new storage item.
 			// Should pass as it fallbacks to DefaultDepositLimit.
-			assert_ok!(builder::call(addr.clone())
+			assert_ok!(builder::call(addr)
 				.storage_deposit_limit(3)
 				.data(1u32.to_le_bytes().to_vec())
 				.build());
@@ -3302,7 +3324,7 @@ mod run_tests {
 			// Use 4 more bytes of the storage for the same item, which requires 4 Balance.
 			// Should fail as DefaultDepositLimit is 3 and hence isn't enough.
 			assert_err_ignore_postinfo!(
-				builder::call(addr.clone())
+				builder::call(addr)
 					.storage_deposit_limit(3)
 					.data(5u32.to_le_bytes().to_vec())
 					.build(),
@@ -3313,21 +3335,20 @@ mod run_tests {
 
 	#[test]
 	fn deposit_limit_in_nested_calls() {
-		let (wasm_caller, _code_hash_caller) =
-			compile_module::<Test>("create_storage_and_call").unwrap();
-		let (wasm_callee, _code_hash_callee) = compile_module::<Test>("store_call").unwrap();
+		let (wasm_caller, _code_hash_caller) = compile_module("create_storage_and_call").unwrap();
+		let (wasm_callee, _code_hash_callee) = compile_module("store_call").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Create both contracts: Constructors do nothing.
-			let addr_caller =
-				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_account_id();
-			let addr_callee =
-				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_account_id();
+			let Contract { addr: addr_caller, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_contract();
+			let Contract { addr: addr_callee, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_contract();
 
 			// Create 100 bytes of storage with a price of per byte
 			// This is 100 Balance + 2 Balance for the item
-			assert_ok!(builder::call(addr_callee.clone())
+			assert_ok!(builder::call(addr_callee)
 				.storage_deposit_limit(102)
 				.data(100u32.to_le_bytes().to_vec())
 				.build());
@@ -3338,7 +3359,7 @@ mod run_tests {
 			// This should fail as the specified parent's limit is less than the cost: 13 <
 			// 14.
 			assert_err_ignore_postinfo!(
-				builder::call(addr_caller.clone())
+				builder::call(addr_caller)
 					.storage_deposit_limit(13)
 					.data((100u32, &addr_callee, 0u64).encode())
 					.build(),
@@ -3352,7 +3373,7 @@ mod run_tests {
 			// This should fail as the specified parent's limit is less than the cost: 14
 			// < 15.
 			assert_err_ignore_postinfo!(
-				builder::call(addr_caller.clone())
+				builder::call(addr_caller)
 					.storage_deposit_limit(14)
 					.data((101u32, &addr_callee, 0u64).encode())
 					.build(),
@@ -3365,7 +3386,7 @@ mod run_tests {
 			// that the nested call should have a deposit limit of at least 2 Balance. The
 			// sub-call should be rolled back, which is covered by the next test case.
 			assert_err_ignore_postinfo!(
-				builder::call(addr_caller.clone())
+				builder::call(addr_caller)
 					.storage_deposit_limit(16)
 					.data((102u32, &addr_callee, 1u64).encode())
 					.build(),
@@ -3376,7 +3397,7 @@ mod run_tests {
 			// caller. Note that if previous sub-call wouldn't roll back, this call would pass
 			// making the test case fail. We don't set a special limit for the nested call here.
 			assert_err_ignore_postinfo!(
-				builder::call(addr_caller.clone())
+				builder::call(addr_caller)
 					.storage_deposit_limit(0)
 					.data((87u32, &addr_callee, 0u64).encode())
 					.build(),
@@ -3388,16 +3409,14 @@ mod run_tests {
 			// Require more than the sender's balance.
 			// We don't set a special limit for the nested call.
 			assert_err_ignore_postinfo!(
-				builder::call(addr_caller.clone())
-					.data((512u32, &addr_callee, 1u64).encode())
-					.build(),
+				builder::call(addr_caller).data((512u32, &addr_callee, 1u64).encode()).build(),
 				<Error<Test>>::StorageDepositLimitExhausted,
 			);
 
 			// Same as above but allow for the additional deposit of 1 Balance in parent.
 			// We set the special deposit limit of 1 Balance for the nested call, which isn't
 			// enforced as callee frees up storage. This should pass.
-			assert_ok!(builder::call(addr_caller.clone())
+			assert_ok!(builder::call(addr_caller)
 				.storage_deposit_limit(1)
 				.data((87u32, &addr_callee, 1u64).encode())
 				.build());
@@ -3407,20 +3426,21 @@ mod run_tests {
 	#[test]
 	fn deposit_limit_in_nested_instantiate() {
 		let (wasm_caller, _code_hash_caller) =
-			compile_module::<Test>("create_storage_and_instantiate").unwrap();
-		let (wasm_callee, code_hash_callee) = compile_module::<Test>("store_deploy").unwrap();
+			compile_module("create_storage_and_instantiate").unwrap();
+		let (wasm_callee, code_hash_callee) = compile_module("store_deploy").unwrap();
 		const ED: u64 = 5;
 		ExtBuilder::default().existential_deposit(ED).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let _ = <Test as Config>::Currency::set_balance(&BOB, 1_000_000);
 			// Create caller contract
-			let addr_caller = builder::bare_instantiate(Code::Upload(wasm_caller))
-				.value(10_000u64) // this balance is later passed to the deployed contract
-				.build_and_unwrap_account_id();
+			let Contract { addr: addr_caller, account_id: caller_id } =
+				builder::bare_instantiate(Code::Upload(wasm_caller))
+					.value(10_000u64) // this balance is later passed to the deployed contract
+					.build_and_unwrap_contract();
 			// Deploy a contract to get its occupied storage size
-			let addr = builder::bare_instantiate(Code::Upload(wasm_callee))
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(wasm_callee))
 				.data(vec![0, 0, 0, 0])
-				.build_and_unwrap_account_id();
+				.build_and_unwrap_contract();
 
 			let callee_info_len = ContractInfoOf::<Test>::get(&addr).unwrap().encoded_size() as u64;
 
@@ -3436,7 +3456,7 @@ mod run_tests {
 			// Provided the limit is set to be 1 Balance less,
 			// this call should fail on the return from the caller contract.
 			assert_err_ignore_postinfo!(
-				builder::call(addr_caller.clone())
+				builder::call(addr_caller)
 					.origin(RuntimeOrigin::signed(BOB))
 					.storage_deposit_limit(callee_info_len + 2 + ED + 1)
 					.data((0u32, &code_hash_callee, 0u64).encode())
@@ -3450,7 +3470,7 @@ mod run_tests {
 			// byte in the constructor. Hence +1 Balance to the limit is needed. This should fail on
 			// the return from constructor.
 			assert_err_ignore_postinfo!(
-				builder::call(addr_caller.clone())
+				builder::call(addr_caller)
 					.origin(RuntimeOrigin::signed(BOB))
 					.storage_deposit_limit(callee_info_len + 2 + ED + 2)
 					.data((1u32, &code_hash_callee, 0u64).encode())
@@ -3464,7 +3484,7 @@ mod run_tests {
 			// instantiate. This should fail during the charging for the instantiation in
 			// `RawMeter::charge_instantiate()`
 			assert_err_ignore_postinfo!(
-				builder::call(addr_caller.clone())
+				builder::call(addr_caller)
 					.origin(RuntimeOrigin::signed(BOB))
 					.storage_deposit_limit(callee_info_len + 2 + ED + 2)
 					.data((0u32, &code_hash_callee, callee_info_len + 2 + ED + 1).encode())
@@ -3479,7 +3499,7 @@ mod run_tests {
 			// Now we set enough limit for the parent call, but insufficient limit for child
 			// instantiate. This should fail right after the constructor execution.
 			assert_err_ignore_postinfo!(
-				builder::call(addr_caller.clone())
+				builder::call(addr_caller)
 					.origin(RuntimeOrigin::signed(BOB))
 					.storage_deposit_limit(callee_info_len + 2 + ED + 3) // enough parent limit
 					.data((1u32, &code_hash_callee, callee_info_len + 2 + ED + 2).encode())
@@ -3490,7 +3510,7 @@ mod run_tests {
 			assert_eq!(<Test as Config>::Currency::free_balance(&BOB), 1_000_000);
 
 			// Set enough deposit limit for the child instantiate. This should succeed.
-			let result = builder::bare_call(addr_caller.clone())
+			let result = builder::bare_call(addr_caller)
 				.origin(RuntimeOrigin::signed(BOB))
 				.storage_deposit_limit(callee_info_len + 2 + ED + 4)
 				.data((1u32, &code_hash_callee, callee_info_len + 2 + ED + 3).encode())
@@ -3499,12 +3519,13 @@ mod run_tests {
 			let returned = result.result.unwrap();
 			// All balance of the caller except ED has been transferred to the callee.
 			// No deposit has been taken from it.
-			assert_eq!(<Test as Config>::Currency::free_balance(&addr_caller), ED);
+			assert_eq!(<Test as Config>::Currency::free_balance(&caller_id), ED);
 			// Get address of the deployed contract.
-			let addr_callee = AccountId32::from_slice(&returned.data[0..32]).unwrap();
+			let addr_callee = H160::from_slice(&returned.data[0..20]);
+			let callee_account_id = <Test as Config>::AddressMapper::to_account_id(&addr_callee);
 			// 10_000 should be sent to callee from the caller contract, plus ED to be sent from the
 			// origin.
-			assert_eq!(<Test as Config>::Currency::free_balance(&addr_callee), 10_000 + ED);
+			assert_eq!(<Test as Config>::Currency::free_balance(&callee_account_id), 10_000 + ED);
 			// The origin should be charged with:
 			//  - callee instantiation deposit = (callee_info_len + 2)
 			//  - callee account ED
@@ -3520,7 +3541,7 @@ mod run_tests {
 
 	#[test]
 	fn deposit_limit_honors_liquidity_restrictions() {
-		let (wasm, _code_hash) = compile_module::<Test>("store_call").unwrap();
+		let (wasm, _code_hash) = compile_module("store_call").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let bobs_balance = 1_000;
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
@@ -3528,13 +3549,14 @@ mod run_tests {
 			let min_balance = Contracts::min_balance();
 
 			// Instantiate the BOB contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_account_id();
+			let Contract { addr, account_id } =
+				builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_contract();
 
 			let info_deposit = test_utils::contract_info_storage_deposit(&addr);
 			// Check that the contract has been instantiated and has the minimum balance
 			assert_eq!(get_contract(&addr).total_deposit(), info_deposit);
 			assert_eq!(
-				<Test as Config>::Currency::total_balance(&addr),
+				<Test as Config>::Currency::total_balance(&account_id),
 				info_deposit + min_balance
 			);
 
@@ -3546,7 +3568,7 @@ mod run_tests {
 			)
 			.unwrap();
 			assert_err_ignore_postinfo!(
-				builder::call(addr.clone())
+				builder::call(addr)
 					.origin(RuntimeOrigin::signed(BOB))
 					.storage_deposit_limit(10_000)
 					.data(100u32.to_le_bytes().to_vec())
@@ -3559,27 +3581,28 @@ mod run_tests {
 
 	#[test]
 	fn deposit_limit_honors_existential_deposit() {
-		let (wasm, _code_hash) = compile_module::<Test>("store_call").unwrap();
+		let (wasm, _code_hash) = compile_module("store_call").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let _ = <Test as Config>::Currency::set_balance(&BOB, 300);
 			let min_balance = Contracts::min_balance();
 
 			// Instantiate the BOB contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_account_id();
+			let Contract { addr, account_id } =
+				builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_contract();
 
 			let info_deposit = test_utils::contract_info_storage_deposit(&addr);
 
 			// Check that the contract has been instantiated and has the minimum balance
 			assert_eq!(get_contract(&addr).total_deposit(), info_deposit);
 			assert_eq!(
-				<Test as Config>::Currency::total_balance(&addr),
+				<Test as Config>::Currency::total_balance(&account_id),
 				min_balance + info_deposit
 			);
 
 			// check that the deposit can't bring the account below the existential deposit
 			assert_err_ignore_postinfo!(
-				builder::call(addr.clone())
+				builder::call(addr)
 					.origin(RuntimeOrigin::signed(BOB))
 					.storage_deposit_limit(10_000)
 					.data(100u32.to_le_bytes().to_vec())
@@ -3592,14 +3615,15 @@ mod run_tests {
 
 	#[test]
 	fn deposit_limit_honors_min_leftover() {
-		let (wasm, _code_hash) = compile_module::<Test>("store_call").unwrap();
+		let (wasm, _code_hash) = compile_module("store_call").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 			let _ = <Test as Config>::Currency::set_balance(&BOB, 1_000);
 			let min_balance = Contracts::min_balance();
 
 			// Instantiate the BOB contract.
-			let addr = builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_account_id();
+			let Contract { addr, account_id } =
+				builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_contract();
 
 			let info_deposit = test_utils::contract_info_storage_deposit(&addr);
 
@@ -3607,7 +3631,7 @@ mod run_tests {
 			// storage deposit
 			assert_eq!(get_contract(&addr).total_deposit(), info_deposit);
 			assert_eq!(
-				<Test as Config>::Currency::total_balance(&addr),
+				<Test as Config>::Currency::total_balance(&account_id),
 				info_deposit + min_balance
 			);
 
@@ -3616,7 +3640,7 @@ mod run_tests {
 			// 50 for the storage deposit. Which is not enough to store the 50 bytes
 			// as we also need 2 bytes for the item
 			assert_err_ignore_postinfo!(
-				builder::call(addr.clone())
+				builder::call(addr)
 					.origin(RuntimeOrigin::signed(BOB))
 					.value(750)
 					.storage_deposit_limit(10_000)
@@ -3633,13 +3657,12 @@ mod run_tests {
 		// set hash lock up deposit to 30%, to test deposit calculation.
 		CODE_HASH_LOCKUP_DEPOSIT_PERCENT.with(|c| *c.borrow_mut() = Perbill::from_percent(30));
 
-		let (wasm_caller, self_code_hash) =
-			compile_module::<Test>("locking_delegate_dependency").unwrap();
+		let (wasm_caller, self_code_hash) = compile_module("locking_delegate_dependency").unwrap();
 		let callee_codes: Vec<_> =
 			(0..limits::DELEGATE_DEPENDENCIES + 1).map(|idx| dummy_unique(idx)).collect();
 		let callee_hashes: Vec<_> = callee_codes
 			.iter()
-			.map(|c| <Test as frame_system::Config>::Hashing::hash(c))
+			.map(|c| sp_core::H256(sp_io::hashing::keccak_256(c)))
 			.collect();
 
 		// Define inputs with various actions to test locking / unlocking delegate_dependencies.
@@ -3652,17 +3675,21 @@ mod run_tests {
 		// Instantiate the caller contract with the given input.
 		let instantiate = |input: &(u32, H256)| {
 			builder::bare_instantiate(Code::Upload(wasm_caller.clone()))
+				.origin(RuntimeOrigin::signed(ETH_ALICE))
 				.data(input.encode())
 				.build()
 		};
 
 		// Call contract with the given input.
-		let call = |addr_caller: &AccountId32, input: &(u32, H256)| {
-			builder::bare_call(addr_caller.clone()).data(input.encode()).build()
+		let call = |addr_caller: &H160, input: &(u32, H256)| {
+			builder::bare_call(*addr_caller)
+				.origin(RuntimeOrigin::signed(ETH_ALICE))
+				.data(input.encode())
+				.build()
 		};
 		const ED: u64 = 2000;
 		ExtBuilder::default().existential_deposit(ED).build().execute_with(|| {
-			let _ = Balances::set_balance(&ALICE, 1_000_000);
+			let _ = Balances::set_balance(&ETH_ALICE, 1_000_000);
 
 			// Instantiate with lock_delegate_dependency should fail since the code is not yet on
 			// chain.
@@ -3676,7 +3703,7 @@ mod run_tests {
 			for code in callee_codes.iter() {
 				let CodeUploadReturnValue { deposit: deposit_per_code, .. } =
 					Contracts::bare_upload_code(
-						RuntimeOrigin::signed(ALICE),
+						RuntimeOrigin::signed(ETH_ALICE),
 						code.clone(),
 						deposit_limit::<Test>(),
 					)
@@ -3685,8 +3712,8 @@ mod run_tests {
 			}
 
 			// Instantiate should now work.
-			let addr_caller =
-				instantiate(&lock_delegate_dependency_input).result.unwrap().account_id;
+			let addr_caller = instantiate(&lock_delegate_dependency_input).result.unwrap().addr;
+			let caller_account_id = <Test as Config>::AddressMapper::to_account_id(&addr_caller);
 
 			// There should be a dependency and a deposit.
 			let contract = test_utils::get_contract(&addr_caller);
@@ -3699,14 +3726,14 @@ mod run_tests {
 			assert_eq!(
 				test_utils::get_balance_on_hold(
 					&HoldReason::StorageDepositReserve.into(),
-					&addr_caller
+					&caller_account_id
 				),
 				dependency_deposit + contract.storage_base_deposit()
 			);
 
 			// Removing the code should fail, since we have added a dependency.
 			assert_err!(
-				Contracts::remove_code(RuntimeOrigin::signed(ALICE), callee_hashes[0]),
+				Contracts::remove_code(RuntimeOrigin::signed(ETH_ALICE), callee_hashes[0]),
 				<Error<Test>>::CodeInUse
 			);
 
@@ -3742,7 +3769,7 @@ mod run_tests {
 			assert_eq!(
 				test_utils::get_balance_on_hold(
 					&HoldReason::StorageDepositReserve.into(),
-					&addr_caller
+					&caller_account_id
 				),
 				contract.storage_base_deposit()
 			);
@@ -3755,7 +3782,7 @@ mod run_tests {
 
 			// Locking a dependency with a storage limit too low should fail.
 			assert_err!(
-				builder::bare_call(addr_caller.clone())
+				builder::bare_call(addr_caller)
 					.storage_deposit_limit(dependency_deposit - 1)
 					.data(lock_delegate_dependency_input.encode())
 					.build()
@@ -3764,14 +3791,14 @@ mod run_tests {
 			);
 
 			// Since we unlocked the dependency we should now be able to remove the code.
-			assert_ok!(Contracts::remove_code(RuntimeOrigin::signed(ALICE), callee_hashes[0]));
+			assert_ok!(Contracts::remove_code(RuntimeOrigin::signed(ETH_ALICE), callee_hashes[0]));
 
 			// Calling should fail since the delegated contract is not on chain anymore.
 			assert_err!(call(&addr_caller, &noop_input).result, Error::<Test>::ContractTrapped);
 
 			// Add the dependency back.
 			Contracts::upload_code(
-				RuntimeOrigin::signed(ALICE),
+				RuntimeOrigin::signed(ETH_ALICE),
 				callee_codes[0].clone(),
 				deposit_limit::<Test>(),
 			)
@@ -3779,22 +3806,22 @@ mod run_tests {
 			call(&addr_caller, &lock_delegate_dependency_input).result.unwrap();
 
 			// Call terminate should work, and return the deposit.
-			let balance_before = test_utils::get_balance(&ALICE);
+			let balance_before = test_utils::get_balance(&ETH_ALICE);
 			assert_ok!(call(&addr_caller, &terminate_input).result);
 			assert_eq!(
-				test_utils::get_balance(&ALICE),
+				test_utils::get_balance(&ETH_ALICE),
 				ED + balance_before + contract.storage_base_deposit() + dependency_deposit
 			);
 
 			// Terminate should also remove the dependency, so we can remove the code.
-			assert_ok!(Contracts::remove_code(RuntimeOrigin::signed(ALICE), callee_hashes[0]));
+			assert_ok!(Contracts::remove_code(RuntimeOrigin::signed(ETH_ALICE), callee_hashes[0]));
 		});
 	}
 
 	#[test]
 	fn native_dependency_deposit_works() {
-		let (wasm, code_hash) = compile_module::<Test>("set_code_hash").unwrap();
-		let (dummy_wasm, dummy_code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, code_hash) = compile_module("set_code_hash").unwrap();
+		let (dummy_wasm, dummy_code_hash) = compile_module("dummy").unwrap();
 
 		// Set hash lock up deposit to 30%, to test deposit calculation.
 		CODE_HASH_LOCKUP_DEPOSIT_PERCENT.with(|c| *c.borrow_mut() = Perbill::from_percent(30));
@@ -3830,7 +3857,8 @@ mod run_tests {
 				// Instantiate the set_code_hash contract.
 				let res = builder::bare_instantiate(code).build();
 
-				let addr = res.result.unwrap().account_id;
+				let addr = res.result.unwrap().addr;
+				let account_id = <Test as Config>::AddressMapper::to_account_id(&addr);
 				let base_deposit = test_utils::contract_info_storage_deposit(&addr);
 				let upload_deposit = test_utils::get_code_deposit(&code_hash);
 				let extra_deposit = add_upload_deposit.then(|| upload_deposit).unwrap_or_default();
@@ -3846,7 +3874,7 @@ mod run_tests {
 				);
 
 				// call set_code_hash
-				builder::bare_call(addr.clone())
+				builder::bare_call(addr)
 					.data(dummy_code_hash.encode())
 					.build_and_unwrap_result();
 
@@ -3858,7 +3886,7 @@ mod run_tests {
 				assert_eq!(
 					test_utils::get_balance_on_hold(
 						&HoldReason::StorageDepositReserve.into(),
-						&addr
+						&account_id
 					),
 					deposit
 				);
@@ -3868,7 +3896,7 @@ mod run_tests {
 
 	#[test]
 	fn root_cannot_upload_code() {
-		let (wasm, _) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, _) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().build().execute_with(|| {
 			assert_noop!(
@@ -3880,7 +3908,7 @@ mod run_tests {
 
 	#[test]
 	fn root_cannot_remove_code() {
-		let (_, code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (_, code_hash) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().build().execute_with(|| {
 			assert_noop!(
@@ -3892,11 +3920,11 @@ mod run_tests {
 
 	#[test]
 	fn signed_cannot_set_code() {
-		let (_, code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (_, code_hash) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().build().execute_with(|| {
 			assert_noop!(
-				Contracts::set_code(RuntimeOrigin::signed(ALICE), BOB, code_hash),
+				Contracts::set_code(RuntimeOrigin::signed(ALICE), BOB_ADDR, code_hash),
 				DispatchError::BadOrigin,
 			);
 		});
@@ -3906,7 +3934,7 @@ mod run_tests {
 	fn none_cannot_call_code() {
 		ExtBuilder::default().build().execute_with(|| {
 			assert_err_ignore_postinfo!(
-				builder::call(BOB).origin(RuntimeOrigin::none()).build(),
+				builder::call(BOB_ADDR).origin(RuntimeOrigin::none()).build(),
 				DispatchError::BadOrigin,
 			);
 		});
@@ -3914,21 +3942,22 @@ mod run_tests {
 
 	#[test]
 	fn root_can_call() {
-		let (wasm, _) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, _) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
-			let addr = builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_account_id();
+			let Contract { addr, .. } =
+				builder::bare_instantiate(Code::Upload(wasm)).build_and_unwrap_contract();
 
 			// Call the contract.
-			assert_ok!(builder::call(addr.clone()).origin(RuntimeOrigin::root()).build());
+			assert_ok!(builder::call(addr).origin(RuntimeOrigin::root()).build());
 		});
 	}
 
 	#[test]
 	fn root_cannot_instantiate_with_code() {
-		let (wasm, _) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, _) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().build().execute_with(|| {
 			assert_err_ignore_postinfo!(
@@ -3940,7 +3969,7 @@ mod run_tests {
 
 	#[test]
 	fn root_cannot_instantiate() {
-		let (_, code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (_, code_hash) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().build().execute_with(|| {
 			assert_err_ignore_postinfo!(
@@ -3952,7 +3981,7 @@ mod run_tests {
 
 	#[test]
 	fn only_upload_origin_can_upload() {
-		let (wasm, _) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, _) = compile_module("dummy").unwrap();
 		UploadAccount::set(Some(ALICE));
 		ExtBuilder::default().build().execute_with(|| {
 			let _ = Balances::set_balance(&ALICE, 1_000_000);
@@ -3987,7 +4016,7 @@ mod run_tests {
 
 	#[test]
 	fn only_instantiation_origin_can_instantiate() {
-		let (code, code_hash) = compile_module::<Test>("dummy").unwrap();
+		let (code, code_hash) = compile_module("dummy").unwrap();
 		InstantiateAccount::set(Some(ALICE));
 		ExtBuilder::default().build().execute_with(|| {
 			let _ = Balances::set_balance(&ALICE, 1_000_000);
@@ -4020,23 +4049,23 @@ mod run_tests {
 
 	#[test]
 	fn balance_api_returns_free_balance() {
-		let (wasm, _code_hash) = compile_module::<Test>("balance").unwrap();
+		let (wasm, _code_hash) = compile_module("balance").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Instantiate the BOB contract without any extra balance.
-			let addr = builder::bare_instantiate(Code::Upload(wasm.to_vec()))
-				.build_and_unwrap_account_id();
+			let Contract { addr, .. } =
+				builder::bare_instantiate(Code::Upload(wasm.to_vec())).build_and_unwrap_contract();
 
 			let value = 0;
 			// Call BOB which makes it call the balance runtime API.
 			// The contract code asserts that the returned balance is 0.
-			assert_ok!(builder::call(addr.clone()).value(value).build());
+			assert_ok!(builder::call(addr).value(value).build());
 
 			let value = 1;
 			// Calling with value will trap the contract.
 			assert_err_ignore_postinfo!(
-				builder::call(addr.clone()).value(value).build(),
+				builder::call(addr).value(value).build(),
 				<Error<Test>>::ContractTrapped
 			);
 		});
@@ -4044,17 +4073,18 @@ mod run_tests {
 
 	#[test]
 	fn gas_consumed_is_linear_for_nested_calls() {
-		let (code, _code_hash) = compile_module::<Test>("recurse").unwrap();
+		let (code, _code_hash) = compile_module("recurse").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
-			let addr = builder::bare_instantiate(Code::Upload(code)).build_and_unwrap_account_id();
+			let Contract { addr, .. } =
+				builder::bare_instantiate(Code::Upload(code)).build_and_unwrap_contract();
 
 			let [gas_0, gas_1, gas_2, gas_max] = {
 				[0u32, 1u32, 2u32, limits::CALL_STACK_DEPTH]
 					.iter()
 					.map(|i| {
-						let result = builder::bare_call(addr.clone()).data(i.encode()).build();
+						let result = builder::bare_call(addr).data(i.encode()).build();
 						assert_ok!(result.result);
 						result.gas_consumed
 					})
@@ -4070,16 +4100,16 @@ mod run_tests {
 
 	#[test]
 	fn read_only_call_cannot_store() {
-		let (wasm_caller, _code_hash_caller) = compile_module::<Test>("read_only_call").unwrap();
-		let (wasm_callee, _code_hash_callee) = compile_module::<Test>("store_call").unwrap();
+		let (wasm_caller, _code_hash_caller) = compile_module("read_only_call").unwrap();
+		let (wasm_callee, _code_hash_callee) = compile_module("store_call").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Create both contracts: Constructors do nothing.
-			let addr_caller =
-				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_account_id();
-			let addr_callee =
-				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_account_id();
+			let Contract { addr: addr_caller, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_contract();
+			let Contract { addr: addr_callee, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_contract();
 
 			// Read-only call fails when modifying storage.
 			assert_err_ignore_postinfo!(
@@ -4091,17 +4121,16 @@ mod run_tests {
 
 	#[test]
 	fn read_only_call_cannot_transfer() {
-		let (wasm_caller, _code_hash_caller) =
-			compile_module::<Test>("call_with_flags_and_value").unwrap();
-		let (wasm_callee, _code_hash_callee) = compile_module::<Test>("dummy").unwrap();
+		let (wasm_caller, _code_hash_caller) = compile_module("call_with_flags_and_value").unwrap();
+		let (wasm_callee, _code_hash_callee) = compile_module("dummy").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Create both contracts: Constructors do nothing.
-			let addr_caller =
-				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_account_id();
-			let addr_callee =
-				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_account_id();
+			let Contract { addr: addr_caller, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_contract();
+			let Contract { addr: addr_callee, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_contract();
 
 			// Read-only call fails when a non-zero value is set.
 			assert_err_ignore_postinfo!(
@@ -4118,21 +4147,20 @@ mod run_tests {
 
 	#[test]
 	fn read_only_subsequent_call_cannot_store() {
-		let (wasm_read_only_caller, _code_hash_caller) =
-			compile_module::<Test>("read_only_call").unwrap();
-		let (wasm_caller, _code_hash_caller) =
-			compile_module::<Test>("call_with_flags_and_value").unwrap();
-		let (wasm_callee, _code_hash_callee) = compile_module::<Test>("store_call").unwrap();
+		let (wasm_read_only_caller, _code_hash_caller) = compile_module("read_only_call").unwrap();
+		let (wasm_caller, _code_hash_caller) = compile_module("call_with_flags_and_value").unwrap();
+		let (wasm_callee, _code_hash_callee) = compile_module("store_call").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Create contracts: Constructors do nothing.
-			let addr_caller = builder::bare_instantiate(Code::Upload(wasm_read_only_caller))
-				.build_and_unwrap_account_id();
-			let addr_subsequent_caller =
-				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_account_id();
-			let addr_callee =
-				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_account_id();
+			let Contract { addr: addr_caller, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_read_only_caller))
+					.build_and_unwrap_contract();
+			let Contract { addr: addr_subsequent_caller, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_contract();
+			let Contract { addr: addr_callee, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_contract();
 
 			// Subsequent call input.
 			let input = (&addr_callee, pallet_revive_uapi::CallFlags::empty().bits(), 0u64, 100u32);
@@ -4149,18 +4177,18 @@ mod run_tests {
 
 	#[test]
 	fn read_only_call_works() {
-		let (wasm_caller, _code_hash_caller) = compile_module::<Test>("read_only_call").unwrap();
-		let (wasm_callee, _code_hash_callee) = compile_module::<Test>("dummy").unwrap();
+		let (wasm_caller, _code_hash_caller) = compile_module("read_only_call").unwrap();
+		let (wasm_callee, _code_hash_callee) = compile_module("dummy").unwrap();
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
 
 			// Create both contracts: Constructors do nothing.
-			let addr_caller =
-				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_account_id();
-			let addr_callee =
-				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_account_id();
+			let Contract { addr: addr_caller, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_caller)).build_and_unwrap_contract();
+			let Contract { addr: addr_callee, .. } =
+				builder::bare_instantiate(Code::Upload(wasm_callee)).build_and_unwrap_contract();
 
-			assert_ok!(builder::call(addr_caller.clone()).data(addr_callee.encode()).build());
+			assert_ok!(builder::call(addr_caller).data(addr_callee.encode()).build());
 		});
 	}
 }
diff --git a/substrate/frame/revive/src/tests/test_debug.rs b/substrate/frame/revive/src/tests/test_debug.rs
index 166a0a8606a69c98fb38ea657d98bbf9e051c217..e3571b7f21eb9dc397b9c44e4ebe0d1179afd1af 100644
--- a/substrate/frame/revive/src/tests/test_debug.rs
+++ b/substrate/frame/revive/src/tests/test_debug.rs
@@ -16,18 +16,19 @@
 // limitations under the License.
 
 use super::*;
+
 use crate::{
 	debug::{CallInterceptor, CallSpan, ExecResult, ExportedFunction, Tracing},
 	primitives::ExecReturnValue,
 	test_utils::*,
-	AccountIdOf,
 };
 use frame_support::traits::Currency;
+use sp_core::H160;
 use std::cell::RefCell;
 
 #[derive(Clone, PartialEq, Eq, Debug)]
 struct DebugFrame {
-	contract_account: AccountId32,
+	contract_account: sp_core::H160,
 	call: ExportedFunction,
 	input: Vec<u8>,
 	result: Option<Vec<u8>>,
@@ -35,12 +36,12 @@ struct DebugFrame {
 
 thread_local! {
 	static DEBUG_EXECUTION_TRACE: RefCell<Vec<DebugFrame>> = RefCell::new(Vec::new());
-	static INTERCEPTED_ADDRESS: RefCell<Option<AccountId32>> = RefCell::new(None);
+	static INTERCEPTED_ADDRESS: RefCell<Option<sp_core::H160>> = RefCell::new(None);
 }
 
 pub struct TestDebug;
 pub struct TestCallSpan {
-	contract_account: AccountId32,
+	contract_account: sp_core::H160,
 	call: ExportedFunction,
 	input: Vec<u8>,
 }
@@ -49,20 +50,20 @@ impl Tracing<Test> for TestDebug {
 	type CallSpan = TestCallSpan;
 
 	fn new_call_span(
-		contract_account: &AccountIdOf<Test>,
+		contract_account: &crate::H160,
 		entry_point: ExportedFunction,
 		input_data: &[u8],
 	) -> TestCallSpan {
 		DEBUG_EXECUTION_TRACE.with(|d| {
 			d.borrow_mut().push(DebugFrame {
-				contract_account: contract_account.clone(),
+				contract_account: *contract_account,
 				call: entry_point,
 				input: input_data.to_vec(),
 				result: None,
 			})
 		});
 		TestCallSpan {
-			contract_account: contract_account.clone(),
+			contract_account: *contract_account,
 			call: entry_point,
 			input: input_data.to_vec(),
 		}
@@ -71,7 +72,7 @@ impl Tracing<Test> for TestDebug {
 
 impl CallInterceptor<Test> for TestDebug {
 	fn intercept_call(
-		contract_address: &<Test as frame_system::Config>::AccountId,
+		contract_address: &sp_core::H160,
 		_entry_point: ExportedFunction,
 		_input_data: &[u8],
 	) -> Option<ExecResult> {
@@ -106,14 +107,14 @@ mod run_tests {
 
 	#[test]
 	fn debugging_works() {
-		let (wasm_caller, _) = compile_module::<Test>("call").unwrap();
-		let (wasm_callee, _) = compile_module::<Test>("store_call").unwrap();
+		let (wasm_caller, _) = compile_module("call").unwrap();
+		let (wasm_callee, _) = compile_module("store_call").unwrap();
 
 		fn current_stack() -> Vec<DebugFrame> {
 			DEBUG_EXECUTION_TRACE.with(|stack| stack.borrow().clone())
 		}
 
-		fn deploy(wasm: Vec<u8>) -> AccountId32 {
+		fn deploy(wasm: Vec<u8>) -> H160 {
 			Contracts::bare_instantiate(
 				RuntimeOrigin::signed(ALICE),
 				0,
@@ -121,27 +122,27 @@ mod run_tests {
 				deposit_limit::<Test>(),
 				Code::Upload(wasm),
 				vec![],
-				vec![],
+				[0u8; 32],
 				DebugInfo::Skip,
 				CollectEvents::Skip,
 			)
 			.result
 			.unwrap()
-			.account_id
+			.addr
 		}
 
-		fn constructor_frame(contract_account: &AccountId32, after: bool) -> DebugFrame {
+		fn constructor_frame(contract_account: &H160, after: bool) -> DebugFrame {
 			DebugFrame {
-				contract_account: contract_account.clone(),
+				contract_account: *contract_account,
 				call: ExportedFunction::Constructor,
 				input: vec![],
 				result: if after { Some(vec![]) } else { None },
 			}
 		}
 
-		fn call_frame(contract_account: &AccountId32, args: Vec<u8>, after: bool) -> DebugFrame {
+		fn call_frame(contract_account: &H160, args: Vec<u8>, after: bool) -> DebugFrame {
 			DebugFrame {
-				contract_account: contract_account.clone(),
+				contract_account: *contract_account,
 				call: ExportedFunction::Call,
 				input: args,
 				result: if after { Some(vec![]) } else { None },
@@ -171,7 +172,7 @@ mod run_tests {
 
 			assert_ok!(Contracts::call(
 				RuntimeOrigin::signed(ALICE),
-				addr_caller.clone(),
+				addr_caller,
 				0,
 				GAS_LIMIT,
 				deposit_limit::<Test>(),
@@ -193,7 +194,7 @@ mod run_tests {
 
 	#[test]
 	fn call_interception_works() {
-		let (wasm, _) = compile_module::<Test>("dummy").unwrap();
+		let (wasm, _) = compile_module("dummy").unwrap();
 
 		ExtBuilder::default().existential_deposit(200).build().execute_with(|| {
 			let _ = Balances::deposit_creating(&ALICE, 1_000_000);
@@ -206,18 +207,18 @@ mod run_tests {
 				Code::Upload(wasm),
 				vec![],
 				// some salt to ensure that the address of this contract is unique among all tests
-				vec![0x41, 0x41, 0x41, 0x41],
+				[0x41; 32],
 				DebugInfo::Skip,
 				CollectEvents::Skip,
 			)
 			.result
 			.unwrap()
-			.account_id;
+			.addr;
 
 			// no interception yet
 			assert_ok!(Contracts::call(
 				RuntimeOrigin::signed(ALICE),
-				account_id.clone(),
+				account_id,
 				0,
 				GAS_LIMIT,
 				deposit_limit::<Test>(),
@@ -225,7 +226,7 @@ mod run_tests {
 			));
 
 			// intercept calls to this contract
-			INTERCEPTED_ADDRESS.with(|i| *i.borrow_mut() = Some(account_id.clone()));
+			INTERCEPTED_ADDRESS.with(|i| *i.borrow_mut() = Some(account_id));
 
 			assert_err_ignore_postinfo!(
 				Contracts::call(
diff --git a/substrate/frame/revive/src/wasm/mod.rs b/substrate/frame/revive/src/wasm/mod.rs
index 784993ca793d969a18b988dc6ea2a2f73ec1e6d3..9024390fd24f41f19f3d9e0f1a3b371cc86ed923 100644
--- a/substrate/frame/revive/src/wasm/mod.rs
+++ b/substrate/frame/revive/src/wasm/mod.rs
@@ -32,12 +32,13 @@ pub use crate::wasm::runtime::{ReturnData, TrapReason};
 pub use crate::wasm::runtime::{ApiVersion, Memory, Runtime, RuntimeCosts};
 
 use crate::{
+	address::AddressMapper,
 	exec::{ExecResult, Executable, ExportedFunction, Ext},
 	gas::{GasMeter, Token},
 	storage::meter::Diff,
 	weights::WeightInfo,
-	AccountIdOf, BadOrigin, BalanceOf, CodeHash, CodeInfoOf, CodeVec, Config, Error, Event,
-	ExecError, HoldReason, Pallet, PristineCode, Weight, API_VERSION, LOG_TARGET,
+	AccountIdOf, BadOrigin, BalanceOf, CodeInfoOf, CodeVec, Config, Error, Event, ExecError,
+	HoldReason, Pallet, PristineCode, Weight, API_VERSION, LOG_TARGET,
 };
 use alloc::vec::Vec;
 use codec::{Decode, Encode, MaxEncodedLen};
@@ -47,7 +48,7 @@ use frame_support::{
 	traits::{fungible::MutateHold, tokens::Precision::BestEffort},
 };
 use sp_core::Get;
-use sp_runtime::{traits::Hash, DispatchError};
+use sp_runtime::DispatchError;
 
 /// Validated Wasm module ready for execution.
 /// This data structure is immutable once created and stored.
@@ -61,7 +62,7 @@ pub struct WasmBlob<T: Config> {
 	code_info: CodeInfo<T>,
 	// This is for not calculating the hash every time we need it.
 	#[codec(skip)]
-	code_hash: CodeHash<T>,
+	code_hash: sp_core::H256,
 }
 
 /// Contract code related data, such as:
@@ -143,14 +144,14 @@ impl<T: Config> WasmBlob<T> {
 			api_version: API_VERSION,
 			behaviour_version: Default::default(),
 		};
-		let code_hash = T::Hashing::hash(&code);
+		let code_hash = sp_core::H256(sp_io::hashing::keccak_256(&code));
 		Ok(WasmBlob { code, code_info, code_hash })
 	}
 
 	/// Remove the code from storage and refund the deposit to its owner.
 	///
 	/// Applies all necessary checks before removing the code.
-	pub fn remove(origin: &T::AccountId, code_hash: CodeHash<T>) -> DispatchResult {
+	pub fn remove(origin: &T::AccountId, code_hash: sp_core::H256) -> DispatchResult {
 		<CodeInfoOf<T>>::try_mutate_exists(&code_hash, |existing| {
 			if let Some(code_info) = existing {
 				ensure!(code_info.refcount == 0, <Error<T>>::CodeInUse);
@@ -162,7 +163,7 @@ impl<T: Config> WasmBlob<T> {
 					BestEffort,
 				);
 				let deposit_released = code_info.deposit;
-				let remover = code_info.owner.clone();
+				let remover = T::AddressMapper::to_address(&code_info.owner);
 
 				*existing = None;
 				<PristineCode<T>>::remove(&code_hash);
@@ -201,10 +202,11 @@ impl<T: Config> WasmBlob<T> {
 					self.code_info.refcount = 0;
 					<PristineCode<T>>::insert(code_hash, &self.code);
 					*stored_code_info = Some(self.code_info.clone());
+					let uploader = T::AddressMapper::to_address(&self.code_info.owner);
 					<Pallet<T>>::deposit_event(Event::CodeStored {
 						code_hash,
 						deposit_held: deposit,
-						uploader: self.code_info.owner.clone(),
+						uploader,
 					});
 					Ok(deposit)
 				},
@@ -315,7 +317,7 @@ impl<T: Config> WasmBlob<T> {
 
 impl<T: Config> Executable<T> for WasmBlob<T> {
 	fn from_storage(
-		code_hash: CodeHash<T>,
+		code_hash: sp_core::H256,
 		gas_meter: &mut GasMeter<T>,
 	) -> Result<Self, DispatchError> {
 		let code_info = <CodeInfoOf<T>>::get(code_hash).ok_or(Error::<T>::CodeNotFound)?;
@@ -340,11 +342,15 @@ impl<T: Config> Executable<T> for WasmBlob<T> {
 		prepared_call.call()
 	}
 
-	fn code_info(&self) -> &CodeInfo<T> {
-		&self.code_info
+	fn code(&self) -> &[u8] {
+		self.code.as_ref()
 	}
 
-	fn code_hash(&self) -> &CodeHash<T> {
+	fn code_hash(&self) -> &sp_core::H256 {
 		&self.code_hash
 	}
+
+	fn code_info(&self) -> &CodeInfo<T> {
+		&self.code_info
+	}
 }
diff --git a/substrate/frame/revive/src/wasm/runtime.rs b/substrate/frame/revive/src/wasm/runtime.rs
index de910e79e73e94a31a235a5d6a1765d6e2c0c9e9..70d405da9897492548d9433e340b73b1e76d1946 100644
--- a/substrate/frame/revive/src/wasm/runtime.rs
+++ b/substrate/frame/revive/src/wasm/runtime.rs
@@ -18,12 +18,13 @@
 //! Environment definition of the wasm smart-contract runtime.
 
 use crate::{
+	address::AddressMapper,
 	exec::{ExecError, ExecResult, Ext, Key, TopicOf},
 	gas::{ChargedAmount, Token},
 	limits,
 	primitives::ExecReturnValue,
 	weights::WeightInfo,
-	BalanceOf, CodeHash, Config, Error, LOG_TARGET, SENTINEL,
+	BalanceOf, Config, Error, LOG_TARGET, SENTINEL,
 };
 use alloc::{boxed::Box, vec, vec::Vec};
 use codec::{Decode, DecodeLimit, Encode, MaxEncodedLen};
@@ -34,6 +35,7 @@ use frame_support::{
 };
 use pallet_revive_proc_macro::define_env;
 use pallet_revive_uapi::{CallFlags, ReturnErrorCode, ReturnFlags, StorageFlags};
+use sp_core::{H160, H256};
 use sp_io::hashing::{blake2_128, blake2_256, keccak_256, sha2_256};
 use sp_runtime::{traits::Zero, DispatchError, RuntimeDebug};
 
@@ -939,8 +941,8 @@ impl<'a, E: Ext, M: ?Sized + Memory<E::T>> Runtime<'a, E, M> {
 
 		let call_outcome = match call_type {
 			CallType::Call { callee_ptr, value_ptr, deposit_ptr, weight } => {
-				let callee: <<E as Ext>::T as frame_system::Config>::AccountId =
-					memory.read_as(callee_ptr)?;
+				let mut callee = H160::zero();
+				memory.read_into_buf(callee_ptr, callee.as_bytes_mut())?;
 				let deposit_limit: BalanceOf<<E as Ext>::T> = if deposit_ptr == SENTINEL {
 					BalanceOf::<<E as Ext>::T>::zero()
 				} else {
@@ -959,7 +961,7 @@ impl<'a, E: Ext, M: ?Sized + Memory<E::T>> Runtime<'a, E, M> {
 				self.ext.call(
 					weight,
 					deposit_limit,
-					callee,
+					&callee,
 					value,
 					input_data,
 					flags.contains(CallFlags::ALLOW_REENTRY),
@@ -1022,9 +1024,10 @@ impl<'a, E: Ext, M: ?Sized + Memory<E::T>> Runtime<'a, E, M> {
 			memory.read_as(deposit_ptr)?
 		};
 		let value: BalanceOf<<E as Ext>::T> = memory.read_as(value_ptr)?;
-		let code_hash: CodeHash<<E as Ext>::T> = memory.read_as(code_hash_ptr)?;
+		let code_hash: H256 = memory.read_as(code_hash_ptr)?;
 		let input_data = memory.read(input_data_ptr, input_data_len)?;
-		let salt = memory.read(salt_ptr, salt_len)?;
+		let mut salt = [0u8; 32];
+		memory.read_into_buf(salt_ptr, salt.as_mut_slice())?;
 		let instantiate_outcome =
 			self.ext.instantiate(weight, deposit_limit, code_hash, value, input_data, &salt);
 		if let Ok((address, output)) = &instantiate_outcome {
@@ -1054,8 +1057,8 @@ impl<'a, E: Ext, M: ?Sized + Memory<E::T>> Runtime<'a, E, M> {
 		let count = self.ext.locked_delegate_dependencies_count() as _;
 		self.charge_gas(RuntimeCosts::Terminate(count))?;
 
-		let beneficiary: <<E as Ext>::T as frame_system::Config>::AccountId =
-			memory.read_as(beneficiary_ptr)?;
+		let mut beneficiary = H160::zero();
+		memory.read_into_buf(beneficiary_ptr, beneficiary.as_bytes_mut())?;
 		self.ext.terminate(&beneficiary)?;
 		Err(TrapReason::Termination)
 	}
@@ -1161,8 +1164,8 @@ pub mod env {
 		value_ptr: u32,
 	) -> Result<ReturnErrorCode, TrapReason> {
 		self.charge_gas(RuntimeCosts::Transfer)?;
-		let callee: <<E as Ext>::T as frame_system::Config>::AccountId =
-			memory.read_as(account_ptr)?;
+		let mut callee = H160::zero();
+		memory.read_into_buf(account_ptr, callee.as_bytes_mut())?;
 		let value: BalanceOf<<E as Ext>::T> = memory.read_as(value_ptr)?;
 		let result = self.ext.transfer(&callee, value);
 		match result {
@@ -1311,12 +1314,12 @@ pub mod env {
 	#[api_version(0)]
 	fn caller(&mut self, memory: &mut M, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
 		self.charge_gas(RuntimeCosts::Caller)?;
-		let caller = self.ext.caller().account_id()?.clone();
+		let caller = <E::T as Config>::AddressMapper::to_address(self.ext.caller().account_id()?);
 		Ok(self.write_sandbox_output(
 			memory,
 			out_ptr,
 			out_len_ptr,
-			&caller.encode(),
+			caller.as_bytes(),
 			false,
 			already_charged,
 		)?)
@@ -1327,9 +1330,8 @@ pub mod env {
 	#[api_version(0)]
 	fn is_contract(&mut self, memory: &mut M, account_ptr: u32) -> Result<u32, TrapReason> {
 		self.charge_gas(RuntimeCosts::IsContract)?;
-		let address: <<E as Ext>::T as frame_system::Config>::AccountId =
-			memory.read_as(account_ptr)?;
-
+		let mut address = H160::zero();
+		memory.read_into_buf(account_ptr, address.as_bytes_mut())?;
 		Ok(self.ext.is_contract(&address) as u32)
 	}
 
@@ -1344,8 +1346,8 @@ pub mod env {
 		out_len_ptr: u32,
 	) -> Result<ReturnErrorCode, TrapReason> {
 		self.charge_gas(RuntimeCosts::CodeHash)?;
-		let address: <<E as Ext>::T as frame_system::Config>::AccountId =
-			memory.read_as(account_ptr)?;
+		let mut address = H160::zero();
+		memory.read_into_buf(account_ptr, address.as_bytes_mut())?;
 		if let Some(value) = self.ext.code_hash(&address) {
 			self.write_sandbox_output(
 				memory,
@@ -1408,11 +1410,12 @@ pub mod env {
 		out_len_ptr: u32,
 	) -> Result<(), TrapReason> {
 		self.charge_gas(RuntimeCosts::Address)?;
+		let address = self.ext.address();
 		Ok(self.write_sandbox_output(
 			memory,
 			out_ptr,
 			out_len_ptr,
-			&self.ext.address().encode(),
+			address.as_bytes(),
 			false,
 			already_charged,
 		)?)
@@ -1754,7 +1757,7 @@ pub mod env {
 			dispatch_info,
 			RuntimeCosts::CallXcmExecute,
 			|runtime| {
-				let origin = crate::RawOrigin::Signed(runtime.ext.address().clone()).into();
+				let origin = crate::RawOrigin::Signed(runtime.ext.account_id().clone()).into();
 				let weight_used = <<E::T as Config>::Xcm>::execute(
 					origin,
 					Box::new(message),
@@ -1786,7 +1789,7 @@ pub mod env {
 		let message: VersionedXcm<()> = memory.read_as_unbounded(msg_ptr, msg_len)?;
 		let weight = <<E::T as Config>::Xcm as SendController<_>>::WeightInfo::send();
 		self.charge_gas(RuntimeCosts::CallRuntime(weight))?;
-		let origin = crate::RawOrigin::Signed(self.ext.address().clone()).into();
+		let origin = crate::RawOrigin::Signed(self.ext.account_id().clone()).into();
 
 		match <<E::T as Config>::Xcm>::send(origin, dest.into(), message.into()) {
 			Ok(message_id) => {
@@ -1872,7 +1875,7 @@ pub mod env {
 		code_hash_ptr: u32,
 	) -> Result<ReturnErrorCode, TrapReason> {
 		self.charge_gas(RuntimeCosts::SetCodeHash)?;
-		let code_hash: CodeHash<<E as Ext>::T> = memory.read_as(code_hash_ptr)?;
+		let code_hash: H256 = memory.read_as(code_hash_ptr)?;
 		match self.ext.set_code_hash(code_hash) {
 			Err(err) => {
 				let code = Self::err_into_return_code(err)?;