diff --git a/prdoc/pr_5861.prdoc b/prdoc/pr_5861.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..e2187dc1bddecd56c84250405ba676a576e7baa5
--- /dev/null
+++ b/prdoc/pr_5861.prdoc
@@ -0,0 +1,37 @@
+title: "[pallet-revive] immutable data storage"
+
+doc:
+  - audience: Runtime Dev
+    description: |
+      This PR introduces the concept of immutable storage data, used for
+      [Solidity immutable variables](https://docs.soliditylang.org/en/latest/contracts.html#immutable).
+      
+      This is a minimal implementation. Immutable data is attached to a contract; to 
+      `ContractInfo` fixed in size, we only store the length there, and store the immutable
+      data in a dedicated storage map instead. Which comes at the cost of requiring an
+      storage read (costly) for contracts using this feature.
+      
+      We discussed more optimal solutions not requiring any additional storage accesses
+      internally, but they turned out to be non-trivial to implement. Another optimization
+      benefiting multiple calls to the same contract in a single call stack would be to cache
+      the immutable data in `Stack`. However, this potential creates a DOS vulnerability (the
+      attack vector is to call into as many contracts in a single stack as possible, where
+      they all have maximum immutable data to fill the cache as efficiently as possible). So
+      this either has to be guaranteed to be a non-issue by limits, or, more likely, to have
+      some logic to bound the cache. Eventually, we should think about introducing the concept
+      of warm and cold storage reads (akin to EVM). Since immutable variables are commonly
+      used in contracts, this change is blocking our initial launch and we should only
+      optimize it properly in follow-ups.
+      
+      This PR also disables the `set_code_hash` API (which isn't usable for Solidity contracts
+      without pre-compiles anyways). With immutable storage attached to contracts, we now want
+      to run the constructor of the new code hash to collect the immutable data during
+      `set_code_hash`. This will be implemented in a follow up PR.
+
+crates:
+  - name: pallet-revive
+    bump: major
+  - name: pallet-revive-fixtures
+    bump: patch
+  - name: pallet-revive-uapi
+    bump: minor
diff --git a/substrate/frame/revive/fixtures/contracts/immutable_data.rs b/substrate/frame/revive/fixtures/contracts/immutable_data.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ac50e61a400b98262ceb3dcbadd5349b09fe102b
--- /dev/null
+++ b/substrate/frame/revive/fixtures/contracts/immutable_data.rs
@@ -0,0 +1,43 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Tests that the `get_immutable_data` and `set_immutable_data` APIs work.
+
+#![no_std]
+#![no_main]
+
+use common::input;
+use uapi::{HostFn, HostFnImpl as api};
+
+#[no_mangle]
+#[polkavm_derive::polkavm_export]
+pub extern "C" fn deploy() {
+	input!(data: &[u8; 8],);
+
+	api::set_immutable_data(data);
+}
+
+#[no_mangle]
+#[polkavm_derive::polkavm_export]
+pub extern "C" fn call() {
+	input!(data: &[u8; 8],);
+
+	let mut buf = [0; 8];
+	api::get_immutable_data(&mut &mut buf[..]);
+
+	assert_eq!(data, &buf);
+}
diff --git a/substrate/frame/revive/src/benchmarking/mod.rs b/substrate/frame/revive/src/benchmarking/mod.rs
index acca876f376a3dee667099afddedf2c39994c3e4..ebafb6c7054ae7c1208c819f9533eca328d06134 100644
--- a/substrate/frame/revive/src/benchmarking/mod.rs
+++ b/substrate/frame/revive/src/benchmarking/mod.rs
@@ -628,6 +628,53 @@ mod benchmarks {
 		assert_eq!(U256::from_little_endian(&memory[..len]), runtime.ext().balance_of(&address));
 	}
 
+	#[benchmark(pov_mode = Measured)]
+	fn seal_get_immutable_data(n: Linear<1, { limits::IMMUTABLE_BYTES }>) {
+		let len = n as usize;
+		let immutable_data = vec![1u8; len];
+
+		build_runtime!(runtime, contract, memory: [(len as u32).encode(), vec![0u8; len],]);
+
+		<ImmutableDataOf<T>>::insert::<_, BoundedVec<_, _>>(
+			contract.address(),
+			immutable_data.clone().try_into().unwrap(),
+		);
+
+		let result;
+		#[block]
+		{
+			result = runtime.bench_get_immutable_data(memory.as_mut_slice(), 4, 0 as u32);
+		}
+
+		assert_ok!(result);
+		assert_eq!(&memory[0..4], (len as u32).encode());
+		assert_eq!(&memory[4..len + 4], &immutable_data);
+	}
+
+	#[benchmark(pov_mode = Measured)]
+	fn seal_set_immutable_data(n: Linear<1, { limits::IMMUTABLE_BYTES }>) {
+		let len = n as usize;
+		let mut memory = vec![1u8; len];
+		let mut setup = CallSetup::<T>::default();
+		let input = setup.data();
+		let (mut ext, _) = setup.ext();
+		ext.override_export(crate::debug::ExportedFunction::Constructor);
+
+		let mut runtime = crate::wasm::Runtime::<_, [u8]>::new(&mut ext, input);
+
+		let result;
+		#[block]
+		{
+			result = runtime.bench_set_immutable_data(memory.as_mut_slice(), 0, n);
+		}
+
+		assert_ok!(result);
+		assert_eq!(
+			&memory[..],
+			&<ImmutableDataOf<T>>::get(setup.contract().address()).unwrap()[..]
+		);
+	}
+
 	#[benchmark(pov_mode = Measured)]
 	fn seal_value_transferred() {
 		build_runtime!(runtime, memory: [[0u8;32], ]);
diff --git a/substrate/frame/revive/src/exec.rs b/substrate/frame/revive/src/exec.rs
index 2e48bab292555ef04a38640121a7ee48c20b9c95..c6d2f205ae226fa4cf92570734b3041782cdaed1 100644
--- a/substrate/frame/revive/src/exec.rs
+++ b/substrate/frame/revive/src/exec.rs
@@ -25,7 +25,7 @@ use crate::{
 	storage::{self, meter::Diff, WriteOutcome},
 	transient_storage::TransientStorage,
 	BalanceOf, CodeInfo, CodeInfoOf, Config, ContractInfo, ContractInfoOf, DebugBuffer, Error,
-	Event, Pallet as Contracts, LOG_TARGET,
+	Event, ImmutableData, ImmutableDataOf, Pallet as Contracts, LOG_TARGET,
 };
 use alloc::vec::Vec;
 use core::{fmt::Debug, marker::PhantomData, mem};
@@ -296,6 +296,18 @@ pub trait Ext: sealing::Sealed {
 		<Self::T as Config>::AddressMapper::to_address(self.account_id())
 	}
 
+	/// Returns the immutable data of the current contract.
+	///
+	/// Returns `Err(InvalidImmutableAccess)` if called from a constructor.
+	fn get_immutable_data(&mut self) -> Result<ImmutableData, DispatchError>;
+
+	/// Set the the immutable data of the current contract.
+	///
+	/// Returns `Err(InvalidImmutableAccess)` if not called from a constructor.
+	///
+	/// Note: Requires &mut self to access the contract info.
+	fn set_immutable_data(&mut self, data: ImmutableData) -> Result<(), DispatchError>;
+
 	/// Returns the balance of the current contract.
 	///
 	/// The `value_transferred` is already added.
@@ -373,7 +385,7 @@ pub trait Ext: sealing::Sealed {
 	#[cfg(feature = "runtime-benchmarks")]
 	fn transient_storage(&mut self) -> &mut TransientStorage<Self::T>;
 
-	/// Sets new code hash for existing contract.
+	/// Sets new code hash and immutable data for an existing contract.
 	fn set_code_hash(&mut self, hash: H256) -> DispatchResult;
 
 	/// Returns the number of times the specified contract exists on the call stack. Delegated calls
@@ -1286,6 +1298,13 @@ where
 	fn account_balance(&self, who: &T::AccountId) -> U256 {
 		T::Currency::reducible_balance(who, Preservation::Preserve, Fortitude::Polite).into()
 	}
+
+	/// Certain APIs, e.g. `{set,get}_immutable_data` behave differently depending
+	/// on the configured entry point. Thus, we allow setting the export manually.
+	#[cfg(all(feature = "runtime-benchmarks", feature = "riscv"))]
+	pub(crate) fn override_export(&mut self, export: ExportedFunction) {
+		self.top_frame_mut().entry_point = export;
+	}
 }
 
 impl<'a, T, E> Ext for Stack<'a, T, E>
@@ -1418,6 +1437,7 @@ where
 		info.queue_trie_for_deletion();
 		let account_address = T::AddressMapper::to_address(&frame.account_id);
 		ContractInfoOf::<T>::remove(&account_address);
+		ImmutableDataOf::<T>::remove(&account_address);
 		Self::decrement_refcount(info.code_hash);
 
 		for (code_hash, deposit) in info.delegate_dependencies() {
@@ -1521,6 +1541,30 @@ where
 		self.caller_is_origin() && self.origin == Origin::Root
 	}
 
+	fn get_immutable_data(&mut self) -> Result<ImmutableData, DispatchError> {
+		if self.top_frame().entry_point == ExportedFunction::Constructor {
+			return Err(Error::<T>::InvalidImmutableAccess.into());
+		}
+
+		let address = T::AddressMapper::to_address(self.account_id());
+		Ok(<ImmutableDataOf<T>>::get(address).ok_or_else(|| Error::<T>::InvalidImmutableAccess)?)
+	}
+
+	fn set_immutable_data(&mut self, data: ImmutableData) -> Result<(), DispatchError> {
+		if self.top_frame().entry_point == ExportedFunction::Call {
+			return Err(Error::<T>::InvalidImmutableAccess.into());
+		}
+
+		let account_id = self.account_id().clone();
+		let len = data.len() as u32;
+		let amount = self.top_frame_mut().contract_info().set_immutable_data_len(len)?;
+		self.top_frame_mut().nested_storage.charge_deposit(account_id.clone(), amount);
+
+		<ImmutableDataOf<T>>::insert(T::AddressMapper::to_address(&account_id), &data);
+
+		Ok(())
+	}
+
 	fn balance(&self) -> U256 {
 		self.account_balance(&self.top_frame().account_id)
 	}
@@ -1627,6 +1671,21 @@ where
 		&mut self.transient_storage
 	}
 
+	/// TODO: This should be changed to run the constructor of the supplied `hash`.
+	///
+	/// Because the immutable data is attached to a contract and not a code,
+	/// we need to update the immutable data too.
+	///
+	/// Otherwise we open a massive footgun:
+	/// If the immutables changed in the new code, the contract will brick.
+	///
+	/// A possible implementation strategy is to add a flag to `FrameArgs::Instantiate`,
+	/// so that `fn run()` will roll back any changes if this flag is set.
+	///
+	/// After running the constructor, the new immutable data is already stored in
+	/// `self.immutable_data` at the address of the (reverted) contract instantiation.
+	///
+	/// The `set_code_hash` contract API stays disabled until this change is implemented.
 	fn set_code_hash(&mut self, hash: H256) -> DispatchResult {
 		let frame = top_frame_mut!(self);
 
@@ -4280,4 +4339,216 @@ mod tests {
 			assert_matches!(result, Ok(_));
 		});
 	}
+
+	#[test]
+	fn immutable_data_access_checks_work() {
+		let dummy_ch = MockLoader::insert(Constructor, move |ctx, _| {
+			// Calls can not store immutable data
+			assert_eq!(
+				ctx.ext.get_immutable_data(),
+				Err(Error::<Test>::InvalidImmutableAccess.into())
+			);
+			exec_success()
+		});
+		let instantiator_ch = MockLoader::insert(Call, {
+			move |ctx, _| {
+				let value = <Test as Config>::Currency::minimum_balance().into();
+
+				assert_eq!(
+					ctx.ext.set_immutable_data(vec![0, 1, 2, 3].try_into().unwrap()),
+					Err(Error::<Test>::InvalidImmutableAccess.into())
+				);
+
+				// Constructors can not access the immutable data
+				ctx.ext
+					.instantiate(Weight::zero(), U256::zero(), dummy_ch, value, vec![], None)
+					.unwrap();
+
+				exec_success()
+			}
+		});
+		ExtBuilder::default()
+			.with_code_hashes(MockLoader::code_hashes())
+			.existential_deposit(15)
+			.build()
+			.execute_with(|| {
+				set_balance(&ALICE, 1000);
+				set_balance(&BOB_CONTRACT_ID, 100);
+				place_contract(&BOB, instantiator_ch);
+				let origin = Origin::from_account_id(ALICE);
+				let mut storage_meter = storage::meter::Meter::new(&origin, 200, 0).unwrap();
+
+				MockStack::run_call(
+					origin,
+					BOB_ADDR,
+					&mut GasMeter::<Test>::new(GAS_LIMIT),
+					&mut storage_meter,
+					0,
+					vec![],
+					None,
+				)
+				.unwrap()
+			});
+	}
+
+	#[test]
+	fn correct_immutable_data_in_delegate_call() {
+		let charlie_ch = MockLoader::insert(Call, |ctx, _| {
+			Ok(ExecReturnValue {
+				flags: ReturnFlags::empty(),
+				data: ctx.ext.get_immutable_data()?.to_vec(),
+			})
+		});
+		let bob_ch = MockLoader::insert(Call, move |ctx, _| {
+			// In a regular call, we should witness the callee immutable data
+			assert_eq!(
+				ctx.ext
+					.call(
+						Weight::zero(),
+						U256::zero(),
+						&CHARLIE_ADDR,
+						U256::zero(),
+						vec![],
+						true,
+						false,
+					)
+					.map(|_| ctx.ext.last_frame_output().data.clone()),
+				Ok(vec![2]),
+			);
+
+			// In a delegate call, we should witness the caller immutable data
+			assert_eq!(
+				ctx.ext.delegate_call(charlie_ch, Vec::new()).map(|_| ctx
+					.ext
+					.last_frame_output()
+					.data
+					.clone()),
+				Ok(vec![1])
+			);
+
+			exec_success()
+		});
+		ExtBuilder::default()
+			.with_code_hashes(MockLoader::code_hashes())
+			.existential_deposit(15)
+			.build()
+			.execute_with(|| {
+				place_contract(&BOB, bob_ch);
+				place_contract(&CHARLIE, charlie_ch);
+
+				let origin = Origin::from_account_id(ALICE);
+				let mut storage_meter = storage::meter::Meter::new(&origin, 200, 0).unwrap();
+
+				// Place unique immutable data for each contract
+				<ImmutableDataOf<Test>>::insert::<_, ImmutableData>(
+					BOB_ADDR,
+					vec![1].try_into().unwrap(),
+				);
+				<ImmutableDataOf<Test>>::insert::<_, ImmutableData>(
+					CHARLIE_ADDR,
+					vec![2].try_into().unwrap(),
+				);
+
+				MockStack::run_call(
+					origin,
+					BOB_ADDR,
+					&mut GasMeter::<Test>::new(GAS_LIMIT),
+					&mut storage_meter,
+					0,
+					vec![],
+					None,
+				)
+				.unwrap()
+			});
+	}
+
+	#[test]
+	fn immutable_data_set_works_only_once() {
+		let dummy_ch = MockLoader::insert(Constructor, move |ctx, _| {
+			// Calling `set_immutable_data` the first time should work
+			assert_ok!(ctx.ext.set_immutable_data(vec![0, 1, 2, 3].try_into().unwrap()));
+			// Calling `set_immutable_data` the second time should error out
+			assert_eq!(
+				ctx.ext.set_immutable_data(vec![0, 1, 2, 3].try_into().unwrap()),
+				Err(Error::<Test>::InvalidImmutableAccess.into())
+			);
+			exec_success()
+		});
+		let instantiator_ch = MockLoader::insert(Call, {
+			move |ctx, _| {
+				let value = <Test as Config>::Currency::minimum_balance().into();
+				ctx.ext
+					.instantiate(Weight::zero(), U256::zero(), dummy_ch, value, vec![], None)
+					.unwrap();
+
+				exec_success()
+			}
+		});
+		ExtBuilder::default()
+			.with_code_hashes(MockLoader::code_hashes())
+			.existential_deposit(15)
+			.build()
+			.execute_with(|| {
+				set_balance(&ALICE, 1000);
+				set_balance(&BOB_CONTRACT_ID, 100);
+				place_contract(&BOB, instantiator_ch);
+				let origin = Origin::from_account_id(ALICE);
+				let mut storage_meter = storage::meter::Meter::new(&origin, 200, 0).unwrap();
+
+				MockStack::run_call(
+					origin,
+					BOB_ADDR,
+					&mut GasMeter::<Test>::new(GAS_LIMIT),
+					&mut storage_meter,
+					0,
+					vec![],
+					None,
+				)
+				.unwrap()
+			});
+	}
+
+	#[test]
+	fn immutable_data_set_errors_with_empty_data() {
+		let dummy_ch = MockLoader::insert(Constructor, move |ctx, _| {
+			// Calling `set_immutable_data` with empty data should error out
+			assert_eq!(
+				ctx.ext.set_immutable_data(Default::default()),
+				Err(Error::<Test>::InvalidImmutableAccess.into())
+			);
+			exec_success()
+		});
+		let instantiator_ch = MockLoader::insert(Call, {
+			move |ctx, _| {
+				let value = <Test as Config>::Currency::minimum_balance().into();
+				ctx.ext
+					.instantiate(Weight::zero(), U256::zero(), dummy_ch, value, vec![], None)
+					.unwrap();
+
+				exec_success()
+			}
+		});
+		ExtBuilder::default()
+			.with_code_hashes(MockLoader::code_hashes())
+			.existential_deposit(15)
+			.build()
+			.execute_with(|| {
+				set_balance(&ALICE, 1000);
+				set_balance(&BOB_CONTRACT_ID, 100);
+				place_contract(&BOB, instantiator_ch);
+				let origin = Origin::from_account_id(ALICE);
+				let mut storage_meter = storage::meter::Meter::new(&origin, 200, 0).unwrap();
+
+				MockStack::run_call(
+					origin,
+					BOB_ADDR,
+					&mut GasMeter::<Test>::new(GAS_LIMIT),
+					&mut storage_meter,
+					0,
+					vec![],
+					None,
+				)
+				.unwrap()
+			});
+	}
 }
diff --git a/substrate/frame/revive/src/lib.rs b/substrate/frame/revive/src/lib.rs
index 91c5fa5563a514f56a0062923b02a9f431313119..6d87fd904c3f8d2c6fbd1bf73b1fd4e2f8fe5756 100644
--- a/substrate/frame/revive/src/lib.rs
+++ b/substrate/frame/revive/src/lib.rs
@@ -94,6 +94,7 @@ type CodeVec = BoundedVec<u8, ConstU32<{ limits::code::BLOB_BYTES }>>;
 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 }>>;
+type ImmutableData = BoundedVec<u8, ConstU32<{ limits::IMMUTABLE_BYTES }>>;
 
 /// Used as a sentinel value when reading and writing contract memory.
 ///
@@ -550,6 +551,9 @@ pub mod pallet {
 		ExecutionFailed,
 		/// Failed to convert a U256 to a Balance.
 		BalanceConversionFailed,
+		/// Immutable data can only be set during deploys and only be read during calls.
+		/// Additionally, it is only valid to set the data once and it must not be empty.
+		InvalidImmutableAccess,
 	}
 
 	/// A reason for the pallet contracts placing a hold on funds.
@@ -573,6 +577,10 @@ pub mod pallet {
 	#[pallet::storage]
 	pub(crate) type ContractInfoOf<T: Config> = StorageMap<_, Identity, H160, ContractInfo<T>>;
 
+	/// The immutable data associated with a given account.
+	#[pallet::storage]
+	pub(crate) type ImmutableDataOf<T: Config> = StorageMap<_, Identity, H160, ImmutableData>;
+
 	/// Evicted contracts that await child trie deletion.
 	///
 	/// Child trie deletion is a heavy operation depending on the amount of storage items
@@ -665,6 +673,16 @@ pub mod pallet {
 					.hash()
 					.len() as u32;
 
+			let max_immutable_key_size = T::AccountId::max_encoded_len() as u32;
+			let max_immutable_size: u32 = ((max_block_ref_time /
+				(<RuntimeCosts as gas::Token<T>>::weight(&RuntimeCosts::SetImmutableData(
+					limits::IMMUTABLE_BYTES,
+				))
+				.ref_time()))
+			.saturating_mul(limits::IMMUTABLE_BYTES.saturating_add(max_immutable_key_size) as u64))
+			.try_into()
+			.expect("Immutable data size too big");
+
 			// We can use storage to store items using the available block ref_time with the
 			// `set_storage` host function.
 			let max_storage_size: u32 = ((max_block_ref_time /
@@ -674,6 +692,7 @@ pub mod pallet {
 				})
 				.ref_time()))
 			.saturating_mul(max_payload_size.saturating_add(max_key_size) as u64))
+			.saturating_add(max_immutable_size.into())
 			.try_into()
 			.expect("Storage size too big");
 
diff --git a/substrate/frame/revive/src/limits.rs b/substrate/frame/revive/src/limits.rs
index f712493d3bc86621f9dcfc60b8df2357e7c4a94b..50cdba6d0c91cb4eafd76996f0e8f0b5db5e2a30 100644
--- a/substrate/frame/revive/src/limits.rs
+++ b/substrate/frame/revive/src/limits.rs
@@ -65,6 +65,12 @@ pub const DEBUG_BUFFER_BYTES: u32 = 2 * 1024 * 1024;
 /// The page size in which PolkaVM should allocate memory chunks.
 pub const PAGE_SIZE: u32 = 4 * 1024;
 
+/// The maximum amount of immutable bytes a single contract can store.
+///
+/// The current limit of 4kb allows storing up 16 U256 immutable variables.
+/// Which should always be enough because Solidity allows for 16 local (stack) variables.
+pub const IMMUTABLE_BYTES: u32 = 4 * 1024;
+
 /// Limits that are only enforced on code upload.
 ///
 /// # Note
diff --git a/substrate/frame/revive/src/storage.rs b/substrate/frame/revive/src/storage.rs
index ef7ce2db32cff0715bc6c6254b89c8b70168cd3a..db4db3e8eac3eda8b9c955d4f99e043aa9c8ff8d 100644
--- a/substrate/frame/revive/src/storage.rs
+++ b/substrate/frame/revive/src/storage.rs
@@ -26,7 +26,7 @@ use crate::{
 	storage::meter::Diff,
 	weights::WeightInfo,
 	BalanceOf, CodeInfo, Config, ContractInfoOf, DeletionQueue, DeletionQueueCounter, Error,
-	TrieId, SENTINEL,
+	StorageDeposit, TrieId, SENTINEL,
 };
 use alloc::vec::Vec;
 use codec::{Decode, Encode, MaxEncodedLen};
@@ -36,6 +36,7 @@ use frame_support::{
 	weights::{Weight, WeightMeter},
 	CloneNoBound, DefaultNoBound,
 };
+use meter::DepositOf;
 use scale_info::TypeInfo;
 use sp_core::{ConstU32, Get, H160};
 use sp_io::KillStorageResult;
@@ -75,6 +76,8 @@ pub struct ContractInfo<T: Config> {
 	/// to the map can not be removed from the chain state and can be safely used for delegate
 	/// calls.
 	delegate_dependencies: DelegateDependencyMap<T>,
+	/// The size of the immutable data of this contract.
+	immutable_data_len: u32,
 }
 
 impl<T: Config> ContractInfo<T> {
@@ -88,7 +91,7 @@ impl<T: Config> ContractInfo<T> {
 		code_hash: sp_core::H256,
 	) -> Result<Self, DispatchError> {
 		if <ContractInfoOf<T>>::contains_key(address) {
-			return Err(Error::<T>::DuplicateContract.into())
+			return Err(Error::<T>::DuplicateContract.into());
 		}
 
 		let trie_id = {
@@ -108,6 +111,7 @@ impl<T: Config> ContractInfo<T> {
 			storage_item_deposit: Zero::zero(),
 			storage_base_deposit: Zero::zero(),
 			delegate_dependencies: Default::default(),
+			immutable_data_len: 0,
 		};
 
 		Ok(contract)
@@ -356,6 +360,35 @@ impl<T: Config> ContractInfo<T> {
 	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)
 	}
+
+	/// Returns the amount of immutable bytes of this contract.
+	pub fn immutable_data_len(&self) -> u32 {
+		self.immutable_data_len
+	}
+
+	/// Set the number of immutable bytes of this contract.
+	///
+	/// On success, returns the storage deposit to be charged.
+	///
+	/// Returns `Err(InvalidImmutableAccess)` if:
+	/// - The immutable bytes of this contract are not 0. This indicates that the immutable data
+	///   have already been set; it is only valid to set the immutable data exactly once.
+	/// - The provided `immutable_data_len` value was 0; it is invalid to set empty immutable data.
+	pub fn set_immutable_data_len(
+		&mut self,
+		immutable_data_len: u32,
+	) -> Result<DepositOf<T>, DispatchError> {
+		if self.immutable_data_len != 0 || immutable_data_len == 0 {
+			return Err(Error::<T>::InvalidImmutableAccess.into());
+		}
+
+		self.immutable_data_len = immutable_data_len;
+
+		let amount = T::DepositPerByte::get()
+			.saturating_mul(immutable_data_len.into())
+			.saturating_add(T::DepositPerItem::get());
+		Ok(StorageDeposit::Charge(amount))
+	}
 }
 
 /// Information about what happened to the pre-existing value when calling [`ContractInfo::write`].
diff --git a/substrate/frame/revive/src/storage/meter.rs b/substrate/frame/revive/src/storage/meter.rs
index a2ece03f9aaf95d2ca771475bfd9e820a45b40ea..712010bc8257454defa0ad81f466fbddc5822a9a 100644
--- a/substrate/frame/revive/src/storage/meter.rs
+++ b/substrate/frame/revive/src/storage/meter.rs
@@ -674,6 +674,7 @@ mod tests {
 		items: u32,
 		bytes_deposit: BalanceOf<Test>,
 		items_deposit: BalanceOf<Test>,
+		immutable_data_len: u32,
 	}
 
 	fn new_info(info: StorageInfo) -> ContractInfo<Test> {
@@ -686,6 +687,7 @@ mod tests {
 			storage_item_deposit: info.items_deposit,
 			storage_base_deposit: Default::default(),
 			delegate_dependencies: Default::default(),
+			immutable_data_len: info.immutable_data_len,
 		}
 	}
 
@@ -773,6 +775,7 @@ mod tests {
 				items: 5,
 				bytes_deposit: 100,
 				items_deposit: 10,
+				immutable_data_len: 0,
 			});
 			let mut nested0 = meter.nested(BalanceOf::<Test>::zero());
 			nested0.charge(&Diff {
@@ -788,6 +791,7 @@ mod tests {
 				items: 10,
 				bytes_deposit: 100,
 				items_deposit: 20,
+				immutable_data_len: 0,
 			});
 			let mut nested1 = nested0.nested(BalanceOf::<Test>::zero());
 			nested1.charge(&Diff { items_removed: 5, ..Default::default() });
@@ -798,6 +802,7 @@ mod tests {
 				items: 7,
 				bytes_deposit: 100,
 				items_deposit: 20,
+				immutable_data_len: 0,
 			});
 			let mut nested2 = nested0.nested(BalanceOf::<Test>::zero());
 			nested2.charge(&Diff { items_removed: 7, ..Default::default() });
@@ -867,6 +872,7 @@ mod tests {
 				items: 10,
 				bytes_deposit: 100,
 				items_deposit: 20,
+				immutable_data_len: 0,
 			});
 			let mut nested1 = nested0.nested(BalanceOf::<Test>::zero());
 			nested1.charge(&Diff { items_removed: 5, ..Default::default() });
diff --git a/substrate/frame/revive/src/test_utils.rs b/substrate/frame/revive/src/test_utils.rs
index 671efebdf4bd502de91fb6efe1765096576433d7..92c21297a3ece617175358ef3f95f6d34ba3bff2 100644
--- a/substrate/frame/revive/src/test_utils.rs
+++ b/substrate/frame/revive/src/test_utils.rs
@@ -54,6 +54,7 @@ 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 CHARLIE_CONTRACT_ID: AccountId32 = ee_suffix(CHARLIE_ADDR);
 
 pub const DJANGO: AccountId32 = AccountId32::new([4u8; 32]);
 pub const DJANGO_ADDR: H160 = H160([4u8; 20]);
diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs
index 5c5d144f24a27bc3405448d150abe016fac1c905..c7d1a8b2cf0db1528616f544c51c26eef88ee2de 100644
--- a/substrate/frame/revive/src/tests.rs
+++ b/substrate/frame/revive/src/tests.rs
@@ -140,9 +140,18 @@ pub mod test_utils {
 	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()
+		let info_deposit = DepositPerByte::get()
 			.saturating_mul(info_size)
-			.saturating_add(DepositPerItem::get())
+			.saturating_add(DepositPerItem::get());
+		let immutable_size = contract_info.immutable_data_len() as u64;
+		if immutable_size > 0 {
+			let immutable_deposit = DepositPerByte::get()
+				.saturating_mul(immutable_size)
+				.saturating_add(DepositPerItem::get());
+			info_deposit.saturating_add(immutable_deposit)
+		} else {
+			info_deposit
+		}
 	}
 	pub fn expected_deposit(code_len: usize) -> u64 {
 		// For code_info, the deposit for max_encoded_len is taken.
@@ -3530,8 +3539,11 @@ mod run_tests {
 			// Set enough deposit limit for the child instantiate. This should succeed.
 			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, U256::from(callee_info_len + 2 + ED + 3)).encode())
+				.storage_deposit_limit(callee_info_len + 2 + ED + 4 + 2)
+				.data(
+					(1u32, &code_hash_callee, U256::from(callee_info_len + 2 + ED + 3 + 2))
+						.encode(),
+				)
 				.build();
 
 			let returned = result.result.unwrap();
@@ -3548,6 +3560,7 @@ mod run_tests {
 			//  - callee instantiation deposit = (callee_info_len + 2)
 			//  - callee account ED
 			//  - for writing an item of 1 byte to storage = 3 Balance
+			//  - Immutable data storage item deposit
 			assert_eq!(
 				<Test as Config>::Currency::free_balance(&BOB),
 				1_000_000 - (callee_info_len + 2 + ED + 3)
@@ -4354,4 +4367,33 @@ mod run_tests {
 				.build());
 		});
 	}
+
+	#[test]
+	fn immutable_data_works() {
+		let (code, _) = compile_module("immutable_data").unwrap();
+
+		ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
+			let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
+
+			let data = [0xfe; 8];
+
+			// Create fixture: Constructor sets the immtuable data
+			let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(code))
+				.data(data.to_vec())
+				.build_and_unwrap_contract();
+
+			// Storing immmutable data charges storage deposit; verify it explicitly.
+			assert_eq!(
+				test_utils::get_balance_on_hold(
+					&HoldReason::StorageDepositReserve.into(),
+					&<Test as Config>::AddressMapper::to_account_id(&addr)
+				),
+				test_utils::contract_info_storage_deposit(&addr)
+			);
+			assert_eq!(test_utils::get_contract(&addr).immutable_data_len(), data.len() as u32);
+
+			// Call the contract: Asserts the input to equal the immutable data
+			assert_ok!(builder::call(addr).data(data.to_vec()).build());
+		});
+	}
 }
diff --git a/substrate/frame/revive/src/wasm/runtime.rs b/substrate/frame/revive/src/wasm/runtime.rs
index 56e3b685dcf64503ab1d1ff38248fe7549dcf094..485abbfda225a89a0f5b434d124ea2a00537df4f 100644
--- a/substrate/frame/revive/src/wasm/runtime.rs
+++ b/substrate/frame/revive/src/wasm/runtime.rs
@@ -390,6 +390,10 @@ pub enum RuntimeCosts {
 	LockDelegateDependency,
 	/// Weight of calling `unlock_delegate_dependency`
 	UnlockDelegateDependency,
+	/// Weight of calling `get_immutable_dependency`
+	GetImmutableData(u32),
+	/// Weight of calling `set_immutable_dependency`
+	SetImmutableData(u32),
 }
 
 /// For functions that modify storage, benchmarks are performed with one item in the
@@ -507,6 +511,8 @@ impl<T: Config> Token<T> for RuntimeCosts {
 			EcdsaToEthAddress => T::WeightInfo::seal_ecdsa_to_eth_address(),
 			LockDelegateDependency => T::WeightInfo::lock_delegate_dependency(),
 			UnlockDelegateDependency => T::WeightInfo::unlock_delegate_dependency(),
+			GetImmutableData(len) => T::WeightInfo::seal_get_immutable_data(len),
+			SetImmutableData(len) => T::WeightInfo::seal_set_immutable_data(len),
 		}
 	}
 }
@@ -1513,6 +1519,36 @@ pub mod env {
 		)?)
 	}
 
+	/// Stores the immutable data into the supplied buffer.
+	/// See [`pallet_revive_uapi::HostFn::get_immutable_data`].
+	#[api_version(0)]
+	fn get_immutable_data(
+		&mut self,
+		memory: &mut M,
+		out_ptr: u32,
+		out_len_ptr: u32,
+	) -> Result<(), TrapReason> {
+		let charged = self.charge_gas(RuntimeCosts::GetImmutableData(limits::IMMUTABLE_BYTES))?;
+		let data = self.ext.get_immutable_data()?;
+		self.adjust_gas(charged, RuntimeCosts::GetImmutableData(data.len() as u32));
+		self.write_sandbox_output(memory, out_ptr, out_len_ptr, &data, false, already_charged)?;
+		Ok(())
+	}
+
+	/// Attaches the supplied immutable data to the currently executing contract.
+	/// See [`pallet_revive_uapi::HostFn::set_immutable_data`].
+	#[api_version(0)]
+	fn set_immutable_data(&mut self, memory: &mut M, ptr: u32, len: u32) -> Result<(), TrapReason> {
+		if len > limits::IMMUTABLE_BYTES {
+			return Err(Error::<E::T>::OutOfBounds.into());
+		}
+		self.charge_gas(RuntimeCosts::SetImmutableData(len))?;
+		let buf = memory.read(ptr, len)?;
+		let data = buf.try_into().expect("bailed out earlier; qed");
+		self.ext.set_immutable_data(data)?;
+		Ok(())
+	}
+
 	/// Stores the *free* balance of the current account into the supplied buffer.
 	/// See [`pallet_revive_uapi::HostFn::balance`].
 	#[api_version(0)]
@@ -1930,7 +1966,9 @@ pub mod env {
 
 	/// Replace the contract code at the specified address with new code.
 	/// See [`pallet_revive_uapi::HostFn::set_code_hash`].
-	#[api_version(0)]
+	///
+	/// Disabled until the internal implementation takes care of collecting
+	/// the immutable data of the new code hash.
 	#[mutating]
 	fn set_code_hash(
 		&mut self,
diff --git a/substrate/frame/revive/src/weights.rs b/substrate/frame/revive/src/weights.rs
index 6586cd1fc9cec3154c695fc5f360bd71447589f3..5e549de3a9fb9a1c1cdf0891668e1bc31ff57c1a 100644
--- a/substrate/frame/revive/src/weights.rs
+++ b/substrate/frame/revive/src/weights.rs
@@ -18,7 +18,7 @@
 //! Autogenerated weights for `pallet_revive`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2024-10-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2024-10-04, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
 //! HOSTNAME: `runner-jniz7bxx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024`
@@ -69,6 +69,8 @@ pub trait WeightInfo {
 	fn seal_weight_left() -> Weight;
 	fn seal_balance() -> Weight;
 	fn seal_balance_of() -> Weight;
+	fn seal_get_immutable_data(n: u32, ) -> Weight;
+	fn seal_set_immutable_data(n: u32, ) -> Weight;
 	fn seal_value_transferred() -> Weight;
 	fn seal_minimum_balance() -> Weight;
 	fn seal_block_number() -> Weight;
@@ -124,8 +126,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `109`
 		//  Estimated: `1594`
-		// Minimum execution time: 2_783_000 picoseconds.
-		Weight::from_parts(2_883_000, 1594)
+		// Minimum execution time: 2_700_000 picoseconds.
+		Weight::from_parts(2_882_000, 1594)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 	}
 	/// Storage: `Skipped::Metadata` (r:0 w:0)
@@ -135,10 +137,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `392 + k * (69 ±0)`
 		//  Estimated: `382 + k * (70 ±0)`
-		// Minimum execution time: 13_394_000 picoseconds.
-		Weight::from_parts(305_292, 382)
-			// Standard Error: 1_217
-			.saturating_add(Weight::from_parts(1_233_492, 0).saturating_mul(k.into()))
+		// Minimum execution time: 13_819_000 picoseconds.
+		Weight::from_parts(14_021_000, 382)
+			// Standard Error: 843
+			.saturating_add(Weight::from_parts(1_222_715, 0).saturating_mul(k.into()))
 			.saturating_add(T::DbWeight::get().reads(2_u64))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into())))
 			.saturating_add(T::DbWeight::get().writes(2_u64))
@@ -146,7 +148,7 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 			.saturating_add(Weight::from_parts(0, 70).saturating_mul(k.into()))
 	}
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:1)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `Revive::CodeInfoOf` (r:1 w:0)
 	/// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`)
 	/// Storage: `Revive::PristineCode` (r:1 w:0)
@@ -158,10 +160,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// The range of component `c` is `[0, 262144]`.
 	fn call_with_code_per_byte(_c: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `834`
-		//  Estimated: `4299`
-		// Minimum execution time: 78_977_000 picoseconds.
-		Weight::from_parts(81_687_641, 4299)
+		//  Measured:  `838`
+		//  Estimated: `4303`
+		// Minimum execution time: 79_748_000 picoseconds.
+		Weight::from_parts(82_727_773, 4303)
 			.saturating_add(T::DbWeight::get().reads(5_u64))
 			.saturating_add(T::DbWeight::get().writes(2_u64))
 	}
@@ -170,7 +172,7 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// Storage: `Balances::Holds` (r:2 w:2)
 	/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(337), added: 2812, mode: `Measured`)
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:1)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `Timestamp::Now` (r:1 w:0)
 	/// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`)
 	/// Storage: `System::Account` (r:1 w:1)
@@ -183,12 +185,12 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `303`
 		//  Estimated: `6232`
-		// Minimum execution time: 179_690_000 picoseconds.
-		Weight::from_parts(149_042_544, 6232)
+		// Minimum execution time: 179_270_000 picoseconds.
+		Weight::from_parts(149_933_578, 6232)
 			// Standard Error: 11
-			.saturating_add(Weight::from_parts(33, 0).saturating_mul(c.into()))
+			.saturating_add(Weight::from_parts(16, 0).saturating_mul(c.into()))
 			// Standard Error: 11
-			.saturating_add(Weight::from_parts(4_644, 0).saturating_mul(i.into()))
+			.saturating_add(Weight::from_parts(4_675, 0).saturating_mul(i.into()))
 			.saturating_add(T::DbWeight::get().reads(6_u64))
 			.saturating_add(T::DbWeight::get().writes(6_u64))
 	}
@@ -197,7 +199,7 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// Storage: `Revive::PristineCode` (r:1 w:0)
 	/// Proof: `Revive::PristineCode` (`max_values`: None, `max_size`: Some(262180), added: 264655, mode: `Measured`)
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:1)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `Timestamp::Now` (r:1 w:0)
 	/// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`)
 	/// Storage: `System::Account` (r:1 w:1)
@@ -209,15 +211,15 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `657`
 		//  Estimated: `4111`
-		// Minimum execution time: 156_389_000 picoseconds.
-		Weight::from_parts(130_603_882, 4111)
+		// Minimum execution time: 156_112_000 picoseconds.
+		Weight::from_parts(132_715_336, 4111)
 			// Standard Error: 16
-			.saturating_add(Weight::from_parts(4_594, 0).saturating_mul(i.into()))
+			.saturating_add(Weight::from_parts(4_599, 0).saturating_mul(i.into()))
 			.saturating_add(T::DbWeight::get().reads(6_u64))
 			.saturating_add(T::DbWeight::get().writes(4_u64))
 	}
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:1)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `Revive::CodeInfoOf` (r:1 w:0)
 	/// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`)
 	/// Storage: `Revive::PristineCode` (r:1 w:0)
@@ -228,10 +230,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`)
 	fn call() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `834`
-		//  Estimated: `4299`
-		// Minimum execution time: 80_108_000 picoseconds.
-		Weight::from_parts(81_555_000, 4299)
+		//  Measured:  `838`
+		//  Estimated: `4303`
+		// Minimum execution time: 82_111_000 picoseconds.
+		Weight::from_parts(83_659_000, 4303)
 			.saturating_add(T::DbWeight::get().reads(5_u64))
 			.saturating_add(T::DbWeight::get().writes(2_u64))
 	}
@@ -246,8 +248,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `109`
 		//  Estimated: `3574`
-		// Minimum execution time: 49_297_000 picoseconds.
-		Weight::from_parts(50_873_587, 3574)
+		// Minimum execution time: 49_154_000 picoseconds.
+		Weight::from_parts(50_856_127, 3574)
 			.saturating_add(T::DbWeight::get().reads(2_u64))
 			.saturating_add(T::DbWeight::get().writes(3_u64))
 	}
@@ -261,21 +263,21 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `285`
 		//  Estimated: `3750`
-		// Minimum execution time: 42_556_000 picoseconds.
-		Weight::from_parts(43_708_000, 3750)
+		// Minimum execution time: 41_347_000 picoseconds.
+		Weight::from_parts(42_272_000, 3750)
 			.saturating_add(T::DbWeight::get().reads(2_u64))
 			.saturating_add(T::DbWeight::get().writes(3_u64))
 	}
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:1)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `Revive::CodeInfoOf` (r:2 w:2)
 	/// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`)
 	fn set_code() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `491`
-		//  Estimated: `6431`
-		// Minimum execution time: 24_623_000 picoseconds.
-		Weight::from_parts(26_390_000, 6431)
+		//  Measured:  `495`
+		//  Estimated: `6435`
+		// Minimum execution time: 25_234_000 picoseconds.
+		Weight::from_parts(26_339_000, 6435)
 			.saturating_add(T::DbWeight::get().reads(3_u64))
 			.saturating_add(T::DbWeight::get().writes(3_u64))
 	}
@@ -284,79 +286,79 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 7_590_000 picoseconds.
-		Weight::from_parts(8_005_868, 0)
-			// Standard Error: 396
-			.saturating_add(Weight::from_parts(203_612, 0).saturating_mul(r.into()))
+		// Minimum execution time: 7_509_000 picoseconds.
+		Weight::from_parts(9_047_452, 0)
+			// Standard Error: 165
+			.saturating_add(Weight::from_parts(197_103, 0).saturating_mul(r.into()))
 	}
 	fn seal_caller() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 285_000 picoseconds.
-		Weight::from_parts(305_000, 0)
+		// Minimum execution time: 257_000 picoseconds.
+		Weight::from_parts(300_000, 0)
 	}
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:0)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	fn seal_is_contract() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `272`
 		//  Estimated: `3737`
-		// Minimum execution time: 6_711_000 picoseconds.
-		Weight::from_parts(7_103_000, 3737)
+		// Minimum execution time: 6_537_000 picoseconds.
+		Weight::from_parts(7_024_000, 3737)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 	}
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:0)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	fn seal_code_hash() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `365`
-		//  Estimated: `3830`
-		// Minimum execution time: 7_572_000 picoseconds.
-		Weight::from_parts(7_888_000, 3830)
+		//  Measured:  `369`
+		//  Estimated: `3834`
+		// Minimum execution time: 7_571_000 picoseconds.
+		Weight::from_parts(8_060_000, 3834)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 	}
 	fn seal_own_code_hash() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 240_000 picoseconds.
-		Weight::from_parts(264_000, 0)
+		// Minimum execution time: 254_000 picoseconds.
+		Weight::from_parts(281_000, 0)
 	}
 	fn seal_caller_is_origin() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 324_000 picoseconds.
-		Weight::from_parts(356_000, 0)
+		// Minimum execution time: 279_000 picoseconds.
+		Weight::from_parts(338_000, 0)
 	}
 	fn seal_caller_is_root() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 273_000 picoseconds.
+		// Minimum execution time: 240_000 picoseconds.
 		Weight::from_parts(286_000, 0)
 	}
 	fn seal_address() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 255_000 picoseconds.
-		Weight::from_parts(296_000, 0)
+		// Minimum execution time: 198_000 picoseconds.
+		Weight::from_parts(262_000, 0)
 	}
 	fn seal_weight_left() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 610_000 picoseconds.
-		Weight::from_parts(701_000, 0)
+		// Minimum execution time: 593_000 picoseconds.
+		Weight::from_parts(665_000, 0)
 	}
 	fn seal_balance() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `140`
 		//  Estimated: `0`
-		// Minimum execution time: 5_207_000 picoseconds.
-		Weight::from_parts(5_403_000, 0)
+		// Minimum execution time: 5_393_000 picoseconds.
+		Weight::from_parts(5_688_000, 0)
 	}
 	/// Storage: `System::Account` (r:1 w:0)
 	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`)
@@ -364,37 +366,64 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `52`
 		//  Estimated: `3517`
-		// Minimum execution time: 3_829_000 picoseconds.
-		Weight::from_parts(3_977_000, 3517)
+		// Minimum execution time: 3_907_000 picoseconds.
+		Weight::from_parts(4_154_000, 3517)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 	}
+	/// Storage: `Revive::ImmutableDataOf` (r:1 w:0)
+	/// Proof: `Revive::ImmutableDataOf` (`max_values`: None, `max_size`: Some(4118), added: 6593, mode: `Measured`)
+	/// The range of component `n` is `[1, 4096]`.
+	fn seal_get_immutable_data(n: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `205 + n * (1 ±0)`
+		//  Estimated: `3670 + n * (1 ±0)`
+		// Minimum execution time: 5_700_000 picoseconds.
+		Weight::from_parts(6_362_270, 3670)
+			// Standard Error: 4
+			.saturating_add(Weight::from_parts(749, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(1_u64))
+			.saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into()))
+	}
+	/// Storage: `Revive::ImmutableDataOf` (r:0 w:1)
+	/// Proof: `Revive::ImmutableDataOf` (`max_values`: None, `max_size`: Some(4118), added: 6593, mode: `Measured`)
+	/// The range of component `n` is `[1, 4096]`.
+	fn seal_set_immutable_data(n: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 2_041_000 picoseconds.
+		Weight::from_parts(2_216_694, 0)
+			// Standard Error: 1
+			.saturating_add(Weight::from_parts(620, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().writes(1_u64))
+	}
 	fn seal_value_transferred() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 245_000 picoseconds.
-		Weight::from_parts(266_000, 0)
+		// Minimum execution time: 229_000 picoseconds.
+		Weight::from_parts(261_000, 0)
 	}
 	fn seal_minimum_balance() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 256_000 picoseconds.
-		Weight::from_parts(288_000, 0)
+		// Minimum execution time: 226_000 picoseconds.
+		Weight::from_parts(270_000, 0)
 	}
 	fn seal_block_number() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 265_000 picoseconds.
-		Weight::from_parts(278_000, 0)
+		// Minimum execution time: 215_000 picoseconds.
+		Weight::from_parts(273_000, 0)
 	}
 	fn seal_now() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 243_000 picoseconds.
-		Weight::from_parts(272_000, 0)
+		// Minimum execution time: 242_000 picoseconds.
+		Weight::from_parts(271_000, 0)
 	}
 	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
 	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `Measured`)
@@ -402,8 +431,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `67`
 		//  Estimated: `1552`
-		// Minimum execution time: 5_467_000 picoseconds.
-		Weight::from_parts(5_607_000, 1552)
+		// Minimum execution time: 5_438_000 picoseconds.
+		Weight::from_parts(5_695_000, 1552)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 	}
 	/// The range of component `n` is `[0, 262140]`.
@@ -411,8 +440,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 438_000 picoseconds.
-		Weight::from_parts(532_907, 0)
+		// Minimum execution time: 405_000 picoseconds.
+		Weight::from_parts(539_737, 0)
 			// Standard Error: 0
 			.saturating_add(Weight::from_parts(148, 0).saturating_mul(n.into()))
 	}
@@ -421,8 +450,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 259_000 picoseconds.
-		Weight::from_parts(629_625, 0)
+		// Minimum execution time: 222_000 picoseconds.
+		Weight::from_parts(539_301, 0)
 			// Standard Error: 0
 			.saturating_add(Weight::from_parts(294, 0).saturating_mul(n.into()))
 	}
@@ -432,18 +461,20 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`)
 	/// Storage: `Revive::DeletionQueue` (r:0 w:1)
 	/// Proof: `Revive::DeletionQueue` (`max_values`: None, `max_size`: Some(142), added: 2617, mode: `Measured`)
+	/// Storage: `Revive::ImmutableDataOf` (r:0 w:1)
+	/// Proof: `Revive::ImmutableDataOf` (`max_values`: None, `max_size`: Some(4118), added: 6593, mode: `Measured`)
 	/// The range of component `n` is `[0, 32]`.
 	fn seal_terminate(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `272 + n * (88 ±0)`
 		//  Estimated: `3738 + n * (2563 ±0)`
-		// Minimum execution time: 14_997_000 picoseconds.
-		Weight::from_parts(17_752_993, 3738)
-			// Standard Error: 9_865
-			.saturating_add(Weight::from_parts(4_159_693, 0).saturating_mul(n.into()))
+		// Minimum execution time: 15_971_000 picoseconds.
+		Weight::from_parts(18_759_349, 3738)
+			// Standard Error: 10_298
+			.saturating_add(Weight::from_parts(4_194_635, 0).saturating_mul(n.into()))
 			.saturating_add(T::DbWeight::get().reads(2_u64))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into())))
-			.saturating_add(T::DbWeight::get().writes(3_u64))
+			.saturating_add(T::DbWeight::get().writes(4_u64))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into())))
 			.saturating_add(Weight::from_parts(0, 2563).saturating_mul(n.into()))
 	}
@@ -453,20 +484,20 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 4_277_000 picoseconds.
-		Weight::from_parts(4_023_910, 0)
-			// Standard Error: 2_210
-			.saturating_add(Weight::from_parts(202_823, 0).saturating_mul(t.into()))
-			// Standard Error: 19
-			.saturating_add(Weight::from_parts(1_141, 0).saturating_mul(n.into()))
+		// Minimum execution time: 4_341_000 picoseconds.
+		Weight::from_parts(4_292_048, 0)
+			// Standard Error: 2_476
+			.saturating_add(Weight::from_parts(193_480, 0).saturating_mul(t.into()))
+			// Standard Error: 22
+			.saturating_add(Weight::from_parts(959, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `i` is `[0, 262144]`.
 	fn seal_debug_message(i: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 309_000 picoseconds.
-		Weight::from_parts(834_030, 0)
+		// Minimum execution time: 287_000 picoseconds.
+		Weight::from_parts(758_020, 0)
 			// Standard Error: 1
 			.saturating_add(Weight::from_parts(814, 0).saturating_mul(i.into()))
 	}
@@ -476,8 +507,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `744`
 		//  Estimated: `744`
-		// Minimum execution time: 7_705_000 picoseconds.
-		Weight::from_parts(7_923_000, 744)
+		// Minimum execution time: 7_944_000 picoseconds.
+		Weight::from_parts(8_358_000, 744)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 	}
 	/// Storage: `Skipped::Metadata` (r:0 w:0)
@@ -486,8 +517,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `10754`
 		//  Estimated: `10754`
-		// Minimum execution time: 44_510_000 picoseconds.
-		Weight::from_parts(45_840_000, 10754)
+		// Minimum execution time: 44_950_000 picoseconds.
+		Weight::from_parts(45_575_000, 10754)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 	}
 	/// Storage: `Skipped::Metadata` (r:0 w:0)
@@ -496,8 +527,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `744`
 		//  Estimated: `744`
-		// Minimum execution time: 8_842_000 picoseconds.
-		Weight::from_parts(9_363_000, 744)
+		// Minimum execution time: 9_095_000 picoseconds.
+		Weight::from_parts(9_484_000, 744)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -507,8 +538,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `10754`
 		//  Estimated: `10754`
-		// Minimum execution time: 46_172_000 picoseconds.
-		Weight::from_parts(47_586_000, 10754)
+		// Minimum execution time: 46_814_000 picoseconds.
+		Weight::from_parts(47_710_000, 10754)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -520,12 +551,12 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `248 + o * (1 ±0)`
 		//  Estimated: `247 + o * (1 ±0)`
-		// Minimum execution time: 9_158_000 picoseconds.
-		Weight::from_parts(9_708_320, 247)
-			// Standard Error: 36
-			.saturating_add(Weight::from_parts(499, 0).saturating_mul(n.into()))
-			// Standard Error: 36
-			.saturating_add(Weight::from_parts(672, 0).saturating_mul(o.into()))
+		// Minimum execution time: 9_496_000 picoseconds.
+		Weight::from_parts(9_875_533, 247)
+			// Standard Error: 34
+			.saturating_add(Weight::from_parts(712, 0).saturating_mul(n.into()))
+			// Standard Error: 34
+			.saturating_add(Weight::from_parts(777, 0).saturating_mul(o.into()))
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 			.saturating_add(Weight::from_parts(0, 1).saturating_mul(o.into()))
@@ -537,10 +568,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `248 + n * (1 ±0)`
 		//  Estimated: `247 + n * (1 ±0)`
-		// Minimum execution time: 8_885_000 picoseconds.
-		Weight::from_parts(9_597_656, 247)
-			// Standard Error: 48
-			.saturating_add(Weight::from_parts(649, 0).saturating_mul(n.into()))
+		// Minimum execution time: 9_185_000 picoseconds.
+		Weight::from_parts(9_912_715, 247)
+			// Standard Error: 59
+			.saturating_add(Weight::from_parts(567, 0).saturating_mul(n.into()))
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 			.saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into()))
@@ -552,10 +583,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `248 + n * (1 ±0)`
 		//  Estimated: `247 + n * (1 ±0)`
-		// Minimum execution time: 8_473_000 picoseconds.
-		Weight::from_parts(9_246_006, 247)
-			// Standard Error: 47
-			.saturating_add(Weight::from_parts(1_468, 0).saturating_mul(n.into()))
+		// Minimum execution time: 8_586_000 picoseconds.
+		Weight::from_parts(9_536_041, 247)
+			// Standard Error: 54
+			.saturating_add(Weight::from_parts(1_456, 0).saturating_mul(n.into()))
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into()))
 	}
@@ -566,10 +597,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `248 + n * (1 ±0)`
 		//  Estimated: `247 + n * (1 ±0)`
-		// Minimum execution time: 7_996_000 picoseconds.
-		Weight::from_parts(8_784_165, 247)
+		// Minimum execution time: 8_162_000 picoseconds.
+		Weight::from_parts(8_813_128, 247)
 			// Standard Error: 43
-			.saturating_add(Weight::from_parts(591, 0).saturating_mul(n.into()))
+			.saturating_add(Weight::from_parts(880, 0).saturating_mul(n.into()))
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into()))
 	}
@@ -580,10 +611,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `248 + n * (1 ±0)`
 		//  Estimated: `247 + n * (1 ±0)`
-		// Minimum execution time: 9_246_000 picoseconds.
-		Weight::from_parts(10_239_803, 247)
-			// Standard Error: 57
-			.saturating_add(Weight::from_parts(1_305, 0).saturating_mul(n.into()))
+		// Minimum execution time: 9_717_000 picoseconds.
+		Weight::from_parts(10_635_621, 247)
+			// Standard Error: 58
+			.saturating_add(Weight::from_parts(1_430, 0).saturating_mul(n.into()))
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 			.saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into()))
@@ -592,36 +623,36 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_422_000 picoseconds.
-		Weight::from_parts(1_531_000, 0)
+		// Minimum execution time: 1_503_000 picoseconds.
+		Weight::from_parts(1_592_000, 0)
 	}
 	fn set_transient_storage_full() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_858_000 picoseconds.
-		Weight::from_parts(1_944_000, 0)
+		// Minimum execution time: 1_903_000 picoseconds.
+		Weight::from_parts(1_996_000, 0)
 	}
 	fn get_transient_storage_empty() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_443_000 picoseconds.
-		Weight::from_parts(1_506_000, 0)
+		// Minimum execution time: 1_432_000 picoseconds.
+		Weight::from_parts(1_534_000, 0)
 	}
 	fn get_transient_storage_full() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_592_000 picoseconds.
-		Weight::from_parts(1_651_000, 0)
+		// Minimum execution time: 1_606_000 picoseconds.
+		Weight::from_parts(1_669_000, 0)
 	}
 	fn rollback_transient_storage() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
 		// Minimum execution time: 960_000 picoseconds.
-		Weight::from_parts(1_060_000, 0)
+		Weight::from_parts(1_089_000, 0)
 	}
 	/// The range of component `n` is `[0, 512]`.
 	/// The range of component `o` is `[0, 512]`.
@@ -629,62 +660,62 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_151_000 picoseconds.
-		Weight::from_parts(2_294_801, 0)
+		// Minimum execution time: 2_317_000 picoseconds.
+		Weight::from_parts(2_449_933, 0)
 			// Standard Error: 11
-			.saturating_add(Weight::from_parts(375, 0).saturating_mul(n.into()))
+			.saturating_add(Weight::from_parts(315, 0).saturating_mul(n.into()))
 			// Standard Error: 11
-			.saturating_add(Weight::from_parts(415, 0).saturating_mul(o.into()))
+			.saturating_add(Weight::from_parts(387, 0).saturating_mul(o.into()))
 	}
 	/// The range of component `n` is `[0, 512]`.
 	fn seal_clear_transient_storage(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_880_000 picoseconds.
-		Weight::from_parts(2_259_773, 0)
+		// Minimum execution time: 1_980_000 picoseconds.
+		Weight::from_parts(2_352_243, 0)
 			// Standard Error: 17
-			.saturating_add(Weight::from_parts(356, 0).saturating_mul(n.into()))
+			.saturating_add(Weight::from_parts(372, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 512]`.
 	fn seal_get_transient_storage(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_755_000 picoseconds.
-		Weight::from_parts(1_968_235, 0)
-			// Standard Error: 15
-			.saturating_add(Weight::from_parts(387, 0).saturating_mul(n.into()))
+		// Minimum execution time: 1_857_000 picoseconds.
+		Weight::from_parts(2_082_050, 0)
+			// Standard Error: 13
+			.saturating_add(Weight::from_parts(373, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 512]`.
 	fn seal_contains_transient_storage(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_618_000 picoseconds.
-		Weight::from_parts(1_811_972, 0)
-			// Standard Error: 12
-			.saturating_add(Weight::from_parts(174, 0).saturating_mul(n.into()))
+		// Minimum execution time: 1_693_000 picoseconds.
+		Weight::from_parts(1_892_600, 0)
+			// Standard Error: 13
+			.saturating_add(Weight::from_parts(193, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 512]`.
 	fn seal_take_transient_storage(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_482_000 picoseconds.
-		Weight::from_parts(2_682_484, 0)
-			// Standard Error: 13
-			.saturating_add(Weight::from_parts(2, 0).saturating_mul(n.into()))
+		// Minimum execution time: 2_620_000 picoseconds.
+		Weight::from_parts(2_818_388, 0)
+			// Standard Error: 15
+			.saturating_add(Weight::from_parts(39, 0).saturating_mul(n.into()))
 	}
 	fn seal_transfer() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `140`
 		//  Estimated: `0`
-		// Minimum execution time: 9_899_000 picoseconds.
-		Weight::from_parts(10_342_000, 0)
+		// Minimum execution time: 10_207_000 picoseconds.
+		Weight::from_parts(10_627_000, 0)
 	}
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:0)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `Revive::CodeInfoOf` (r:1 w:0)
 	/// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`)
 	/// Storage: `Revive::PristineCode` (r:1 w:0)
@@ -693,12 +724,12 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// The range of component `i` is `[0, 262144]`.
 	fn seal_call(t: u32, i: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `626 + t * (140 ±0)`
-		//  Estimated: `4091 + t * (140 ±0)`
-		// Minimum execution time: 33_645_000 picoseconds.
-		Weight::from_parts(34_407_662, 4091)
-			// Standard Error: 36_930
-			.saturating_add(Weight::from_parts(2_062_425, 0).saturating_mul(t.into()))
+		//  Measured:  `630 + t * (140 ±0)`
+		//  Estimated: `4095 + t * (140 ±0)`
+		// Minimum execution time: 34_452_000 picoseconds.
+		Weight::from_parts(34_837_900, 4095)
+			// Standard Error: 30_385
+			.saturating_add(Weight::from_parts(1_981_565, 0).saturating_mul(t.into()))
 			// Standard Error: 0
 			.saturating_add(Weight::from_parts(3, 0).saturating_mul(i.into()))
 			.saturating_add(T::DbWeight::get().reads(3_u64))
@@ -713,8 +744,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `457`
 		//  Estimated: `3922`
-		// Minimum execution time: 26_924_000 picoseconds.
-		Weight::from_parts(27_753_000, 3922)
+		// Minimum execution time: 27_287_000 picoseconds.
+		Weight::from_parts(28_450_000, 3922)
 			.saturating_add(T::DbWeight::get().reads(2_u64))
 	}
 	/// Storage: `Revive::CodeInfoOf` (r:1 w:1)
@@ -722,7 +753,7 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// Storage: `Revive::PristineCode` (r:1 w:0)
 	/// Proof: `Revive::PristineCode` (`max_values`: None, `max_size`: Some(262180), added: 264655, mode: `Measured`)
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:1)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `System::Account` (r:1 w:1)
 	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`)
 	/// The range of component `i` is `[0, 262144]`.
@@ -730,10 +761,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `703`
 		//  Estimated: `4160`
-		// Minimum execution time: 117_979_000 picoseconds.
-		Weight::from_parts(105_415_117, 4160)
+		// Minimum execution time: 118_660_000 picoseconds.
+		Weight::from_parts(104_638_796, 4160)
 			// Standard Error: 11
-			.saturating_add(Weight::from_parts(4_293, 0).saturating_mul(i.into()))
+			.saturating_add(Weight::from_parts(4_296, 0).saturating_mul(i.into()))
 			.saturating_add(T::DbWeight::get().reads(4_u64))
 			.saturating_add(T::DbWeight::get().writes(3_u64))
 	}
@@ -742,64 +773,64 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 620_000 picoseconds.
-		Weight::from_parts(3_414_286, 0)
+		// Minimum execution time: 683_000 picoseconds.
+		Weight::from_parts(3_836_563, 0)
 			// Standard Error: 2
-			.saturating_add(Weight::from_parts(1_463, 0).saturating_mul(n.into()))
+			.saturating_add(Weight::from_parts(1_456, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 262144]`.
 	fn seal_hash_keccak_256(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_043_000 picoseconds.
-		Weight::from_parts(3_402_639, 0)
-			// Standard Error: 2
-			.saturating_add(Weight::from_parts(3_667, 0).saturating_mul(n.into()))
+		// Minimum execution time: 1_082_000 picoseconds.
+		Weight::from_parts(5_027_764, 0)
+			// Standard Error: 3
+			.saturating_add(Weight::from_parts(3_644, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 262144]`.
 	fn seal_hash_blake2_256(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 642_000 picoseconds.
-		Weight::from_parts(3_359_294, 0)
+		// Minimum execution time: 660_000 picoseconds.
+		Weight::from_parts(3_585_640, 0)
 			// Standard Error: 2
-			.saturating_add(Weight::from_parts(1_590, 0).saturating_mul(n.into()))
+			.saturating_add(Weight::from_parts(1_586, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 262144]`.
 	fn seal_hash_blake2_128(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 606_000 picoseconds.
-		Weight::from_parts(3_789_868, 0)
-			// Standard Error: 2
-			.saturating_add(Weight::from_parts(1_575, 0).saturating_mul(n.into()))
+		// Minimum execution time: 638_000 picoseconds.
+		Weight::from_parts(3_763_242, 0)
+			// Standard Error: 3
+			.saturating_add(Weight::from_parts(1_582, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 261889]`.
 	fn seal_sr25519_verify(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 46_195_000 picoseconds.
-		Weight::from_parts(31_420_941, 0)
+		// Minimum execution time: 42_962_000 picoseconds.
+		Weight::from_parts(27_938_396, 0)
 			// Standard Error: 13
-			.saturating_add(Weight::from_parts(5_165, 0).saturating_mul(n.into()))
+			.saturating_add(Weight::from_parts(5_269, 0).saturating_mul(n.into()))
 	}
 	fn seal_ecdsa_recover() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 46_933_000 picoseconds.
-		Weight::from_parts(48_054_000, 0)
+		// Minimum execution time: 47_133_000 picoseconds.
+		Weight::from_parts(48_458_000, 0)
 	}
 	fn seal_ecdsa_to_eth_address() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 12_531_000 picoseconds.
-		Weight::from_parts(12_690_000, 0)
+		// Minimum execution time: 13_249_000 picoseconds.
+		Weight::from_parts(13_518_000, 0)
 	}
 	/// Storage: `Revive::CodeInfoOf` (r:1 w:1)
 	/// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`)
@@ -807,8 +838,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `266`
 		//  Estimated: `3731`
-		// Minimum execution time: 14_694_000 picoseconds.
-		Weight::from_parts(15_032_000, 3731)
+		// Minimum execution time: 14_696_000 picoseconds.
+		Weight::from_parts(15_106_000, 3731)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -818,8 +849,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `304`
 		//  Estimated: `3769`
-		// Minimum execution time: 10_205_000 picoseconds.
-		Weight::from_parts(10_707_000, 3769)
+		// Minimum execution time: 10_292_000 picoseconds.
+		Weight::from_parts(10_670_000, 3769)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -829,8 +860,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `304`
 		//  Estimated: `3561`
-		// Minimum execution time: 9_025_000 picoseconds.
-		Weight::from_parts(9_517_000, 3561)
+		// Minimum execution time: 9_056_000 picoseconds.
+		Weight::from_parts(9_350_000, 3561)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -839,10 +870,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 9_451_000 picoseconds.
-		Weight::from_parts(10_620_260, 0)
-			// Standard Error: 77
-			.saturating_add(Weight::from_parts(84_885, 0).saturating_mul(r.into()))
+		// Minimum execution time: 9_145_000 picoseconds.
+		Weight::from_parts(10_744_073, 0)
+			// Standard Error: 72
+			.saturating_add(Weight::from_parts(84_813, 0).saturating_mul(r.into()))
 	}
 }
 
@@ -854,8 +885,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `109`
 		//  Estimated: `1594`
-		// Minimum execution time: 2_783_000 picoseconds.
-		Weight::from_parts(2_883_000, 1594)
+		// Minimum execution time: 2_700_000 picoseconds.
+		Weight::from_parts(2_882_000, 1594)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 	}
 	/// Storage: `Skipped::Metadata` (r:0 w:0)
@@ -865,10 +896,10 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `392 + k * (69 ±0)`
 		//  Estimated: `382 + k * (70 ±0)`
-		// Minimum execution time: 13_394_000 picoseconds.
-		Weight::from_parts(305_292, 382)
-			// Standard Error: 1_217
-			.saturating_add(Weight::from_parts(1_233_492, 0).saturating_mul(k.into()))
+		// Minimum execution time: 13_819_000 picoseconds.
+		Weight::from_parts(14_021_000, 382)
+			// Standard Error: 843
+			.saturating_add(Weight::from_parts(1_222_715, 0).saturating_mul(k.into()))
 			.saturating_add(RocksDbWeight::get().reads(2_u64))
 			.saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into())))
 			.saturating_add(RocksDbWeight::get().writes(2_u64))
@@ -876,7 +907,7 @@ impl WeightInfo for () {
 			.saturating_add(Weight::from_parts(0, 70).saturating_mul(k.into()))
 	}
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:1)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `Revive::CodeInfoOf` (r:1 w:0)
 	/// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`)
 	/// Storage: `Revive::PristineCode` (r:1 w:0)
@@ -888,10 +919,10 @@ impl WeightInfo for () {
 	/// The range of component `c` is `[0, 262144]`.
 	fn call_with_code_per_byte(_c: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `834`
-		//  Estimated: `4299`
-		// Minimum execution time: 78_977_000 picoseconds.
-		Weight::from_parts(81_687_641, 4299)
+		//  Measured:  `838`
+		//  Estimated: `4303`
+		// Minimum execution time: 79_748_000 picoseconds.
+		Weight::from_parts(82_727_773, 4303)
 			.saturating_add(RocksDbWeight::get().reads(5_u64))
 			.saturating_add(RocksDbWeight::get().writes(2_u64))
 	}
@@ -900,7 +931,7 @@ impl WeightInfo for () {
 	/// Storage: `Balances::Holds` (r:2 w:2)
 	/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(337), added: 2812, mode: `Measured`)
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:1)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `Timestamp::Now` (r:1 w:0)
 	/// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`)
 	/// Storage: `System::Account` (r:1 w:1)
@@ -913,12 +944,12 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `303`
 		//  Estimated: `6232`
-		// Minimum execution time: 179_690_000 picoseconds.
-		Weight::from_parts(149_042_544, 6232)
+		// Minimum execution time: 179_270_000 picoseconds.
+		Weight::from_parts(149_933_578, 6232)
 			// Standard Error: 11
-			.saturating_add(Weight::from_parts(33, 0).saturating_mul(c.into()))
+			.saturating_add(Weight::from_parts(16, 0).saturating_mul(c.into()))
 			// Standard Error: 11
-			.saturating_add(Weight::from_parts(4_644, 0).saturating_mul(i.into()))
+			.saturating_add(Weight::from_parts(4_675, 0).saturating_mul(i.into()))
 			.saturating_add(RocksDbWeight::get().reads(6_u64))
 			.saturating_add(RocksDbWeight::get().writes(6_u64))
 	}
@@ -927,7 +958,7 @@ impl WeightInfo for () {
 	/// Storage: `Revive::PristineCode` (r:1 w:0)
 	/// Proof: `Revive::PristineCode` (`max_values`: None, `max_size`: Some(262180), added: 264655, mode: `Measured`)
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:1)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `Timestamp::Now` (r:1 w:0)
 	/// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `Measured`)
 	/// Storage: `System::Account` (r:1 w:1)
@@ -939,15 +970,15 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `657`
 		//  Estimated: `4111`
-		// Minimum execution time: 156_389_000 picoseconds.
-		Weight::from_parts(130_603_882, 4111)
+		// Minimum execution time: 156_112_000 picoseconds.
+		Weight::from_parts(132_715_336, 4111)
 			// Standard Error: 16
-			.saturating_add(Weight::from_parts(4_594, 0).saturating_mul(i.into()))
+			.saturating_add(Weight::from_parts(4_599, 0).saturating_mul(i.into()))
 			.saturating_add(RocksDbWeight::get().reads(6_u64))
 			.saturating_add(RocksDbWeight::get().writes(4_u64))
 	}
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:1)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `Revive::CodeInfoOf` (r:1 w:0)
 	/// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`)
 	/// Storage: `Revive::PristineCode` (r:1 w:0)
@@ -958,10 +989,10 @@ impl WeightInfo for () {
 	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`)
 	fn call() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `834`
-		//  Estimated: `4299`
-		// Minimum execution time: 80_108_000 picoseconds.
-		Weight::from_parts(81_555_000, 4299)
+		//  Measured:  `838`
+		//  Estimated: `4303`
+		// Minimum execution time: 82_111_000 picoseconds.
+		Weight::from_parts(83_659_000, 4303)
 			.saturating_add(RocksDbWeight::get().reads(5_u64))
 			.saturating_add(RocksDbWeight::get().writes(2_u64))
 	}
@@ -976,8 +1007,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `109`
 		//  Estimated: `3574`
-		// Minimum execution time: 49_297_000 picoseconds.
-		Weight::from_parts(50_873_587, 3574)
+		// Minimum execution time: 49_154_000 picoseconds.
+		Weight::from_parts(50_856_127, 3574)
 			.saturating_add(RocksDbWeight::get().reads(2_u64))
 			.saturating_add(RocksDbWeight::get().writes(3_u64))
 	}
@@ -991,21 +1022,21 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `285`
 		//  Estimated: `3750`
-		// Minimum execution time: 42_556_000 picoseconds.
-		Weight::from_parts(43_708_000, 3750)
+		// Minimum execution time: 41_347_000 picoseconds.
+		Weight::from_parts(42_272_000, 3750)
 			.saturating_add(RocksDbWeight::get().reads(2_u64))
 			.saturating_add(RocksDbWeight::get().writes(3_u64))
 	}
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:1)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `Revive::CodeInfoOf` (r:2 w:2)
 	/// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`)
 	fn set_code() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `491`
-		//  Estimated: `6431`
-		// Minimum execution time: 24_623_000 picoseconds.
-		Weight::from_parts(26_390_000, 6431)
+		//  Measured:  `495`
+		//  Estimated: `6435`
+		// Minimum execution time: 25_234_000 picoseconds.
+		Weight::from_parts(26_339_000, 6435)
 			.saturating_add(RocksDbWeight::get().reads(3_u64))
 			.saturating_add(RocksDbWeight::get().writes(3_u64))
 	}
@@ -1014,79 +1045,79 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 7_590_000 picoseconds.
-		Weight::from_parts(8_005_868, 0)
-			// Standard Error: 396
-			.saturating_add(Weight::from_parts(203_612, 0).saturating_mul(r.into()))
+		// Minimum execution time: 7_509_000 picoseconds.
+		Weight::from_parts(9_047_452, 0)
+			// Standard Error: 165
+			.saturating_add(Weight::from_parts(197_103, 0).saturating_mul(r.into()))
 	}
 	fn seal_caller() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 285_000 picoseconds.
-		Weight::from_parts(305_000, 0)
+		// Minimum execution time: 257_000 picoseconds.
+		Weight::from_parts(300_000, 0)
 	}
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:0)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	fn seal_is_contract() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `272`
 		//  Estimated: `3737`
-		// Minimum execution time: 6_711_000 picoseconds.
-		Weight::from_parts(7_103_000, 3737)
+		// Minimum execution time: 6_537_000 picoseconds.
+		Weight::from_parts(7_024_000, 3737)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 	}
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:0)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	fn seal_code_hash() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `365`
-		//  Estimated: `3830`
-		// Minimum execution time: 7_572_000 picoseconds.
-		Weight::from_parts(7_888_000, 3830)
+		//  Measured:  `369`
+		//  Estimated: `3834`
+		// Minimum execution time: 7_571_000 picoseconds.
+		Weight::from_parts(8_060_000, 3834)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 	}
 	fn seal_own_code_hash() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 240_000 picoseconds.
-		Weight::from_parts(264_000, 0)
+		// Minimum execution time: 254_000 picoseconds.
+		Weight::from_parts(281_000, 0)
 	}
 	fn seal_caller_is_origin() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 324_000 picoseconds.
-		Weight::from_parts(356_000, 0)
+		// Minimum execution time: 279_000 picoseconds.
+		Weight::from_parts(338_000, 0)
 	}
 	fn seal_caller_is_root() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 273_000 picoseconds.
+		// Minimum execution time: 240_000 picoseconds.
 		Weight::from_parts(286_000, 0)
 	}
 	fn seal_address() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 255_000 picoseconds.
-		Weight::from_parts(296_000, 0)
+		// Minimum execution time: 198_000 picoseconds.
+		Weight::from_parts(262_000, 0)
 	}
 	fn seal_weight_left() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 610_000 picoseconds.
-		Weight::from_parts(701_000, 0)
+		// Minimum execution time: 593_000 picoseconds.
+		Weight::from_parts(665_000, 0)
 	}
 	fn seal_balance() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `140`
 		//  Estimated: `0`
-		// Minimum execution time: 5_207_000 picoseconds.
-		Weight::from_parts(5_403_000, 0)
+		// Minimum execution time: 5_393_000 picoseconds.
+		Weight::from_parts(5_688_000, 0)
 	}
 	/// Storage: `System::Account` (r:1 w:0)
 	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`)
@@ -1094,37 +1125,64 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `52`
 		//  Estimated: `3517`
-		// Minimum execution time: 3_829_000 picoseconds.
-		Weight::from_parts(3_977_000, 3517)
+		// Minimum execution time: 3_907_000 picoseconds.
+		Weight::from_parts(4_154_000, 3517)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 	}
+	/// Storage: `Revive::ImmutableDataOf` (r:1 w:0)
+	/// Proof: `Revive::ImmutableDataOf` (`max_values`: None, `max_size`: Some(4118), added: 6593, mode: `Measured`)
+	/// The range of component `n` is `[1, 4096]`.
+	fn seal_get_immutable_data(n: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `205 + n * (1 ±0)`
+		//  Estimated: `3670 + n * (1 ±0)`
+		// Minimum execution time: 5_700_000 picoseconds.
+		Weight::from_parts(6_362_270, 3670)
+			// Standard Error: 4
+			.saturating_add(Weight::from_parts(749, 0).saturating_mul(n.into()))
+			.saturating_add(RocksDbWeight::get().reads(1_u64))
+			.saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into()))
+	}
+	/// Storage: `Revive::ImmutableDataOf` (r:0 w:1)
+	/// Proof: `Revive::ImmutableDataOf` (`max_values`: None, `max_size`: Some(4118), added: 6593, mode: `Measured`)
+	/// The range of component `n` is `[1, 4096]`.
+	fn seal_set_immutable_data(n: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 2_041_000 picoseconds.
+		Weight::from_parts(2_216_694, 0)
+			// Standard Error: 1
+			.saturating_add(Weight::from_parts(620, 0).saturating_mul(n.into()))
+			.saturating_add(RocksDbWeight::get().writes(1_u64))
+	}
 	fn seal_value_transferred() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 245_000 picoseconds.
-		Weight::from_parts(266_000, 0)
+		// Minimum execution time: 229_000 picoseconds.
+		Weight::from_parts(261_000, 0)
 	}
 	fn seal_minimum_balance() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 256_000 picoseconds.
-		Weight::from_parts(288_000, 0)
+		// Minimum execution time: 226_000 picoseconds.
+		Weight::from_parts(270_000, 0)
 	}
 	fn seal_block_number() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 265_000 picoseconds.
-		Weight::from_parts(278_000, 0)
+		// Minimum execution time: 215_000 picoseconds.
+		Weight::from_parts(273_000, 0)
 	}
 	fn seal_now() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 243_000 picoseconds.
-		Weight::from_parts(272_000, 0)
+		// Minimum execution time: 242_000 picoseconds.
+		Weight::from_parts(271_000, 0)
 	}
 	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
 	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `Measured`)
@@ -1132,8 +1190,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `67`
 		//  Estimated: `1552`
-		// Minimum execution time: 5_467_000 picoseconds.
-		Weight::from_parts(5_607_000, 1552)
+		// Minimum execution time: 5_438_000 picoseconds.
+		Weight::from_parts(5_695_000, 1552)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 	}
 	/// The range of component `n` is `[0, 262140]`.
@@ -1141,8 +1199,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 438_000 picoseconds.
-		Weight::from_parts(532_907, 0)
+		// Minimum execution time: 405_000 picoseconds.
+		Weight::from_parts(539_737, 0)
 			// Standard Error: 0
 			.saturating_add(Weight::from_parts(148, 0).saturating_mul(n.into()))
 	}
@@ -1151,8 +1209,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 259_000 picoseconds.
-		Weight::from_parts(629_625, 0)
+		// Minimum execution time: 222_000 picoseconds.
+		Weight::from_parts(539_301, 0)
 			// Standard Error: 0
 			.saturating_add(Weight::from_parts(294, 0).saturating_mul(n.into()))
 	}
@@ -1162,18 +1220,20 @@ impl WeightInfo for () {
 	/// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`)
 	/// Storage: `Revive::DeletionQueue` (r:0 w:1)
 	/// Proof: `Revive::DeletionQueue` (`max_values`: None, `max_size`: Some(142), added: 2617, mode: `Measured`)
+	/// Storage: `Revive::ImmutableDataOf` (r:0 w:1)
+	/// Proof: `Revive::ImmutableDataOf` (`max_values`: None, `max_size`: Some(4118), added: 6593, mode: `Measured`)
 	/// The range of component `n` is `[0, 32]`.
 	fn seal_terminate(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `272 + n * (88 ±0)`
 		//  Estimated: `3738 + n * (2563 ±0)`
-		// Minimum execution time: 14_997_000 picoseconds.
-		Weight::from_parts(17_752_993, 3738)
-			// Standard Error: 9_865
-			.saturating_add(Weight::from_parts(4_159_693, 0).saturating_mul(n.into()))
+		// Minimum execution time: 15_971_000 picoseconds.
+		Weight::from_parts(18_759_349, 3738)
+			// Standard Error: 10_298
+			.saturating_add(Weight::from_parts(4_194_635, 0).saturating_mul(n.into()))
 			.saturating_add(RocksDbWeight::get().reads(2_u64))
 			.saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into())))
-			.saturating_add(RocksDbWeight::get().writes(3_u64))
+			.saturating_add(RocksDbWeight::get().writes(4_u64))
 			.saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into())))
 			.saturating_add(Weight::from_parts(0, 2563).saturating_mul(n.into()))
 	}
@@ -1183,20 +1243,20 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 4_277_000 picoseconds.
-		Weight::from_parts(4_023_910, 0)
-			// Standard Error: 2_210
-			.saturating_add(Weight::from_parts(202_823, 0).saturating_mul(t.into()))
-			// Standard Error: 19
-			.saturating_add(Weight::from_parts(1_141, 0).saturating_mul(n.into()))
+		// Minimum execution time: 4_341_000 picoseconds.
+		Weight::from_parts(4_292_048, 0)
+			// Standard Error: 2_476
+			.saturating_add(Weight::from_parts(193_480, 0).saturating_mul(t.into()))
+			// Standard Error: 22
+			.saturating_add(Weight::from_parts(959, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `i` is `[0, 262144]`.
 	fn seal_debug_message(i: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 309_000 picoseconds.
-		Weight::from_parts(834_030, 0)
+		// Minimum execution time: 287_000 picoseconds.
+		Weight::from_parts(758_020, 0)
 			// Standard Error: 1
 			.saturating_add(Weight::from_parts(814, 0).saturating_mul(i.into()))
 	}
@@ -1206,8 +1266,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `744`
 		//  Estimated: `744`
-		// Minimum execution time: 7_705_000 picoseconds.
-		Weight::from_parts(7_923_000, 744)
+		// Minimum execution time: 7_944_000 picoseconds.
+		Weight::from_parts(8_358_000, 744)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 	}
 	/// Storage: `Skipped::Metadata` (r:0 w:0)
@@ -1216,8 +1276,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `10754`
 		//  Estimated: `10754`
-		// Minimum execution time: 44_510_000 picoseconds.
-		Weight::from_parts(45_840_000, 10754)
+		// Minimum execution time: 44_950_000 picoseconds.
+		Weight::from_parts(45_575_000, 10754)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 	}
 	/// Storage: `Skipped::Metadata` (r:0 w:0)
@@ -1226,8 +1286,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `744`
 		//  Estimated: `744`
-		// Minimum execution time: 8_842_000 picoseconds.
-		Weight::from_parts(9_363_000, 744)
+		// Minimum execution time: 9_095_000 picoseconds.
+		Weight::from_parts(9_484_000, 744)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -1237,8 +1297,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `10754`
 		//  Estimated: `10754`
-		// Minimum execution time: 46_172_000 picoseconds.
-		Weight::from_parts(47_586_000, 10754)
+		// Minimum execution time: 46_814_000 picoseconds.
+		Weight::from_parts(47_710_000, 10754)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -1250,12 +1310,12 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `248 + o * (1 ±0)`
 		//  Estimated: `247 + o * (1 ±0)`
-		// Minimum execution time: 9_158_000 picoseconds.
-		Weight::from_parts(9_708_320, 247)
-			// Standard Error: 36
-			.saturating_add(Weight::from_parts(499, 0).saturating_mul(n.into()))
-			// Standard Error: 36
-			.saturating_add(Weight::from_parts(672, 0).saturating_mul(o.into()))
+		// Minimum execution time: 9_496_000 picoseconds.
+		Weight::from_parts(9_875_533, 247)
+			// Standard Error: 34
+			.saturating_add(Weight::from_parts(712, 0).saturating_mul(n.into()))
+			// Standard Error: 34
+			.saturating_add(Weight::from_parts(777, 0).saturating_mul(o.into()))
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 			.saturating_add(Weight::from_parts(0, 1).saturating_mul(o.into()))
@@ -1267,10 +1327,10 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `248 + n * (1 ±0)`
 		//  Estimated: `247 + n * (1 ±0)`
-		// Minimum execution time: 8_885_000 picoseconds.
-		Weight::from_parts(9_597_656, 247)
-			// Standard Error: 48
-			.saturating_add(Weight::from_parts(649, 0).saturating_mul(n.into()))
+		// Minimum execution time: 9_185_000 picoseconds.
+		Weight::from_parts(9_912_715, 247)
+			// Standard Error: 59
+			.saturating_add(Weight::from_parts(567, 0).saturating_mul(n.into()))
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 			.saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into()))
@@ -1282,10 +1342,10 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `248 + n * (1 ±0)`
 		//  Estimated: `247 + n * (1 ±0)`
-		// Minimum execution time: 8_473_000 picoseconds.
-		Weight::from_parts(9_246_006, 247)
-			// Standard Error: 47
-			.saturating_add(Weight::from_parts(1_468, 0).saturating_mul(n.into()))
+		// Minimum execution time: 8_586_000 picoseconds.
+		Weight::from_parts(9_536_041, 247)
+			// Standard Error: 54
+			.saturating_add(Weight::from_parts(1_456, 0).saturating_mul(n.into()))
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into()))
 	}
@@ -1296,10 +1356,10 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `248 + n * (1 ±0)`
 		//  Estimated: `247 + n * (1 ±0)`
-		// Minimum execution time: 7_996_000 picoseconds.
-		Weight::from_parts(8_784_165, 247)
+		// Minimum execution time: 8_162_000 picoseconds.
+		Weight::from_parts(8_813_128, 247)
 			// Standard Error: 43
-			.saturating_add(Weight::from_parts(591, 0).saturating_mul(n.into()))
+			.saturating_add(Weight::from_parts(880, 0).saturating_mul(n.into()))
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into()))
 	}
@@ -1310,10 +1370,10 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `248 + n * (1 ±0)`
 		//  Estimated: `247 + n * (1 ±0)`
-		// Minimum execution time: 9_246_000 picoseconds.
-		Weight::from_parts(10_239_803, 247)
-			// Standard Error: 57
-			.saturating_add(Weight::from_parts(1_305, 0).saturating_mul(n.into()))
+		// Minimum execution time: 9_717_000 picoseconds.
+		Weight::from_parts(10_635_621, 247)
+			// Standard Error: 58
+			.saturating_add(Weight::from_parts(1_430, 0).saturating_mul(n.into()))
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 			.saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into()))
@@ -1322,36 +1382,36 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_422_000 picoseconds.
-		Weight::from_parts(1_531_000, 0)
+		// Minimum execution time: 1_503_000 picoseconds.
+		Weight::from_parts(1_592_000, 0)
 	}
 	fn set_transient_storage_full() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_858_000 picoseconds.
-		Weight::from_parts(1_944_000, 0)
+		// Minimum execution time: 1_903_000 picoseconds.
+		Weight::from_parts(1_996_000, 0)
 	}
 	fn get_transient_storage_empty() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_443_000 picoseconds.
-		Weight::from_parts(1_506_000, 0)
+		// Minimum execution time: 1_432_000 picoseconds.
+		Weight::from_parts(1_534_000, 0)
 	}
 	fn get_transient_storage_full() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_592_000 picoseconds.
-		Weight::from_parts(1_651_000, 0)
+		// Minimum execution time: 1_606_000 picoseconds.
+		Weight::from_parts(1_669_000, 0)
 	}
 	fn rollback_transient_storage() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
 		// Minimum execution time: 960_000 picoseconds.
-		Weight::from_parts(1_060_000, 0)
+		Weight::from_parts(1_089_000, 0)
 	}
 	/// The range of component `n` is `[0, 512]`.
 	/// The range of component `o` is `[0, 512]`.
@@ -1359,62 +1419,62 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_151_000 picoseconds.
-		Weight::from_parts(2_294_801, 0)
+		// Minimum execution time: 2_317_000 picoseconds.
+		Weight::from_parts(2_449_933, 0)
 			// Standard Error: 11
-			.saturating_add(Weight::from_parts(375, 0).saturating_mul(n.into()))
+			.saturating_add(Weight::from_parts(315, 0).saturating_mul(n.into()))
 			// Standard Error: 11
-			.saturating_add(Weight::from_parts(415, 0).saturating_mul(o.into()))
+			.saturating_add(Weight::from_parts(387, 0).saturating_mul(o.into()))
 	}
 	/// The range of component `n` is `[0, 512]`.
 	fn seal_clear_transient_storage(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_880_000 picoseconds.
-		Weight::from_parts(2_259_773, 0)
+		// Minimum execution time: 1_980_000 picoseconds.
+		Weight::from_parts(2_352_243, 0)
 			// Standard Error: 17
-			.saturating_add(Weight::from_parts(356, 0).saturating_mul(n.into()))
+			.saturating_add(Weight::from_parts(372, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 512]`.
 	fn seal_get_transient_storage(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_755_000 picoseconds.
-		Weight::from_parts(1_968_235, 0)
-			// Standard Error: 15
-			.saturating_add(Weight::from_parts(387, 0).saturating_mul(n.into()))
+		// Minimum execution time: 1_857_000 picoseconds.
+		Weight::from_parts(2_082_050, 0)
+			// Standard Error: 13
+			.saturating_add(Weight::from_parts(373, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 512]`.
 	fn seal_contains_transient_storage(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_618_000 picoseconds.
-		Weight::from_parts(1_811_972, 0)
-			// Standard Error: 12
-			.saturating_add(Weight::from_parts(174, 0).saturating_mul(n.into()))
+		// Minimum execution time: 1_693_000 picoseconds.
+		Weight::from_parts(1_892_600, 0)
+			// Standard Error: 13
+			.saturating_add(Weight::from_parts(193, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 512]`.
 	fn seal_take_transient_storage(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_482_000 picoseconds.
-		Weight::from_parts(2_682_484, 0)
-			// Standard Error: 13
-			.saturating_add(Weight::from_parts(2, 0).saturating_mul(n.into()))
+		// Minimum execution time: 2_620_000 picoseconds.
+		Weight::from_parts(2_818_388, 0)
+			// Standard Error: 15
+			.saturating_add(Weight::from_parts(39, 0).saturating_mul(n.into()))
 	}
 	fn seal_transfer() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `140`
 		//  Estimated: `0`
-		// Minimum execution time: 9_899_000 picoseconds.
-		Weight::from_parts(10_342_000, 0)
+		// Minimum execution time: 10_207_000 picoseconds.
+		Weight::from_parts(10_627_000, 0)
 	}
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:0)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `Revive::CodeInfoOf` (r:1 w:0)
 	/// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`)
 	/// Storage: `Revive::PristineCode` (r:1 w:0)
@@ -1423,12 +1483,12 @@ impl WeightInfo for () {
 	/// The range of component `i` is `[0, 262144]`.
 	fn seal_call(t: u32, i: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `626 + t * (140 ±0)`
-		//  Estimated: `4091 + t * (140 ±0)`
-		// Minimum execution time: 33_645_000 picoseconds.
-		Weight::from_parts(34_407_662, 4091)
-			// Standard Error: 36_930
-			.saturating_add(Weight::from_parts(2_062_425, 0).saturating_mul(t.into()))
+		//  Measured:  `630 + t * (140 ±0)`
+		//  Estimated: `4095 + t * (140 ±0)`
+		// Minimum execution time: 34_452_000 picoseconds.
+		Weight::from_parts(34_837_900, 4095)
+			// Standard Error: 30_385
+			.saturating_add(Weight::from_parts(1_981_565, 0).saturating_mul(t.into()))
 			// Standard Error: 0
 			.saturating_add(Weight::from_parts(3, 0).saturating_mul(i.into()))
 			.saturating_add(RocksDbWeight::get().reads(3_u64))
@@ -1443,8 +1503,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `457`
 		//  Estimated: `3922`
-		// Minimum execution time: 26_924_000 picoseconds.
-		Weight::from_parts(27_753_000, 3922)
+		// Minimum execution time: 27_287_000 picoseconds.
+		Weight::from_parts(28_450_000, 3922)
 			.saturating_add(RocksDbWeight::get().reads(2_u64))
 	}
 	/// Storage: `Revive::CodeInfoOf` (r:1 w:1)
@@ -1452,7 +1512,7 @@ impl WeightInfo for () {
 	/// Storage: `Revive::PristineCode` (r:1 w:0)
 	/// Proof: `Revive::PristineCode` (`max_values`: None, `max_size`: Some(262180), added: 264655, mode: `Measured`)
 	/// Storage: `Revive::ContractInfoOf` (r:1 w:1)
-	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1775), added: 4250, mode: `Measured`)
+	/// Proof: `Revive::ContractInfoOf` (`max_values`: None, `max_size`: Some(1779), added: 4254, mode: `Measured`)
 	/// Storage: `System::Account` (r:1 w:1)
 	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `Measured`)
 	/// The range of component `i` is `[0, 262144]`.
@@ -1460,10 +1520,10 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `703`
 		//  Estimated: `4160`
-		// Minimum execution time: 117_979_000 picoseconds.
-		Weight::from_parts(105_415_117, 4160)
+		// Minimum execution time: 118_660_000 picoseconds.
+		Weight::from_parts(104_638_796, 4160)
 			// Standard Error: 11
-			.saturating_add(Weight::from_parts(4_293, 0).saturating_mul(i.into()))
+			.saturating_add(Weight::from_parts(4_296, 0).saturating_mul(i.into()))
 			.saturating_add(RocksDbWeight::get().reads(4_u64))
 			.saturating_add(RocksDbWeight::get().writes(3_u64))
 	}
@@ -1472,64 +1532,64 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 620_000 picoseconds.
-		Weight::from_parts(3_414_286, 0)
+		// Minimum execution time: 683_000 picoseconds.
+		Weight::from_parts(3_836_563, 0)
 			// Standard Error: 2
-			.saturating_add(Weight::from_parts(1_463, 0).saturating_mul(n.into()))
+			.saturating_add(Weight::from_parts(1_456, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 262144]`.
 	fn seal_hash_keccak_256(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_043_000 picoseconds.
-		Weight::from_parts(3_402_639, 0)
-			// Standard Error: 2
-			.saturating_add(Weight::from_parts(3_667, 0).saturating_mul(n.into()))
+		// Minimum execution time: 1_082_000 picoseconds.
+		Weight::from_parts(5_027_764, 0)
+			// Standard Error: 3
+			.saturating_add(Weight::from_parts(3_644, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 262144]`.
 	fn seal_hash_blake2_256(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 642_000 picoseconds.
-		Weight::from_parts(3_359_294, 0)
+		// Minimum execution time: 660_000 picoseconds.
+		Weight::from_parts(3_585_640, 0)
 			// Standard Error: 2
-			.saturating_add(Weight::from_parts(1_590, 0).saturating_mul(n.into()))
+			.saturating_add(Weight::from_parts(1_586, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 262144]`.
 	fn seal_hash_blake2_128(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 606_000 picoseconds.
-		Weight::from_parts(3_789_868, 0)
-			// Standard Error: 2
-			.saturating_add(Weight::from_parts(1_575, 0).saturating_mul(n.into()))
+		// Minimum execution time: 638_000 picoseconds.
+		Weight::from_parts(3_763_242, 0)
+			// Standard Error: 3
+			.saturating_add(Weight::from_parts(1_582, 0).saturating_mul(n.into()))
 	}
 	/// The range of component `n` is `[0, 261889]`.
 	fn seal_sr25519_verify(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 46_195_000 picoseconds.
-		Weight::from_parts(31_420_941, 0)
+		// Minimum execution time: 42_962_000 picoseconds.
+		Weight::from_parts(27_938_396, 0)
 			// Standard Error: 13
-			.saturating_add(Weight::from_parts(5_165, 0).saturating_mul(n.into()))
+			.saturating_add(Weight::from_parts(5_269, 0).saturating_mul(n.into()))
 	}
 	fn seal_ecdsa_recover() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 46_933_000 picoseconds.
-		Weight::from_parts(48_054_000, 0)
+		// Minimum execution time: 47_133_000 picoseconds.
+		Weight::from_parts(48_458_000, 0)
 	}
 	fn seal_ecdsa_to_eth_address() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 12_531_000 picoseconds.
-		Weight::from_parts(12_690_000, 0)
+		// Minimum execution time: 13_249_000 picoseconds.
+		Weight::from_parts(13_518_000, 0)
 	}
 	/// Storage: `Revive::CodeInfoOf` (r:1 w:1)
 	/// Proof: `Revive::CodeInfoOf` (`max_values`: None, `max_size`: Some(96), added: 2571, mode: `Measured`)
@@ -1537,8 +1597,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `266`
 		//  Estimated: `3731`
-		// Minimum execution time: 14_694_000 picoseconds.
-		Weight::from_parts(15_032_000, 3731)
+		// Minimum execution time: 14_696_000 picoseconds.
+		Weight::from_parts(15_106_000, 3731)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -1548,8 +1608,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `304`
 		//  Estimated: `3769`
-		// Minimum execution time: 10_205_000 picoseconds.
-		Weight::from_parts(10_707_000, 3769)
+		// Minimum execution time: 10_292_000 picoseconds.
+		Weight::from_parts(10_670_000, 3769)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -1559,8 +1619,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `304`
 		//  Estimated: `3561`
-		// Minimum execution time: 9_025_000 picoseconds.
-		Weight::from_parts(9_517_000, 3561)
+		// Minimum execution time: 9_056_000 picoseconds.
+		Weight::from_parts(9_350_000, 3561)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -1569,9 +1629,9 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 9_451_000 picoseconds.
-		Weight::from_parts(10_620_260, 0)
-			// Standard Error: 77
-			.saturating_add(Weight::from_parts(84_885, 0).saturating_mul(r.into()))
+		// Minimum execution time: 9_145_000 picoseconds.
+		Weight::from_parts(10_744_073, 0)
+			// Standard Error: 72
+			.saturating_add(Weight::from_parts(84_813, 0).saturating_mul(r.into()))
 	}
 }
diff --git a/substrate/frame/revive/uapi/src/host.rs b/substrate/frame/revive/uapi/src/host.rs
index 816fdec3aaaf3a8dcc660065cde4ae97a26e39bb..2106b8fb49b7929975cbebba112038ced6c0bfbe 100644
--- a/substrate/frame/revive/uapi/src/host.rs
+++ b/substrate/frame/revive/uapi/src/host.rs
@@ -56,6 +56,30 @@ pub trait HostFn: private::Sealed {
 	///   otherwise.
 	fn lock_delegate_dependency(code_hash: &[u8; 32]);
 
+	/// Get the contract immutable data.
+	///
+	/// Traps if:
+	/// - Called from within the deploy export.
+	/// - Called by contracts that didn't set immutable data by calling `set_immutable_data` during
+	///   their constructor execution.
+	///
+	/// # Parameters
+	/// - `output`: A reference to the output buffer to write the immutable bytes.
+	fn get_immutable_data(output: &mut &mut [u8]);
+
+	/// Set the contract immutable data.
+	///
+	/// It is only valid to set non-empty immutable data in the constructor once.
+	///
+	/// Traps if:
+	/// - Called from within the call export.
+	/// - Called more than once.
+	/// - The provided data was empty.
+	///
+	/// # Parameters
+	/// - `data`: A reference to the data to be stored as immutable bytes.
+	fn set_immutable_data(data: &[u8]);
+
 	/// Stores the **reducible** balance of the current account into the supplied buffer.
 	///
 	/// # Parameters
diff --git a/substrate/frame/revive/uapi/src/host/riscv32.rs b/substrate/frame/revive/uapi/src/host/riscv32.rs
index d5ea94c1a9103e7347c8d26cfb619b4536cfeae3..866b0ee8dd1762ad8fafcf820ecce0410a3cb038 100644
--- a/substrate/frame/revive/uapi/src/host/riscv32.rs
+++ b/substrate/frame/revive/uapi/src/host/riscv32.rs
@@ -81,6 +81,8 @@ mod sys {
 		pub fn address(out_ptr: *mut u8);
 		pub fn weight_to_fee(ref_time: u64, proof_size: u64, out_ptr: *mut u8);
 		pub fn weight_left(out_ptr: *mut u8, out_len_ptr: *mut u32);
+		pub fn get_immutable_data(out_ptr: *mut u8, out_len_ptr: *mut u32);
+		pub fn set_immutable_data(ptr: *const u8, len: u32);
 		pub fn balance(out_ptr: *mut u8);
 		pub fn balance_of(addr_ptr: *const u8, out_ptr: *mut u8);
 		pub fn chain_id(out_ptr: *mut u8);
@@ -502,6 +504,16 @@ impl HostFn for HostFnImpl {
 		ret_val.into_bool()
 	}
 
+	fn get_immutable_data(output: &mut &mut [u8]) {
+		let mut output_len = output.len() as u32;
+		unsafe { sys::get_immutable_data(output.as_mut_ptr(), &mut output_len) };
+		extract_from_slice(output, output_len as usize);
+	}
+
+	fn set_immutable_data(data: &[u8]) {
+		unsafe { sys::set_immutable_data(data.as_ptr(), data.len() as u32) }
+	}
+
 	fn balance_of(address: &[u8; 20], output: &mut [u8; 32]) {
 		unsafe { sys::balance_of(address.as_ptr(), output.as_mut_ptr()) };
 	}