pallet_contracts_for_drink/
lib.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! # Contracts Pallet
19//!
20//! The Contracts module provides functionality for the runtime to deploy and execute WebAssembly
21//! smart-contracts.
22//!
23//! - [`Config`]
24//! - [`Call`]
25//!
26//! ## Overview
27//!
28//! This module extends accounts based on the [`frame_support::traits::fungible`] traits to have
29//! smart-contract functionality. It can be used with other modules that implement accounts based on
30//! the [`frame_support::traits::fungible`] traits. These "smart-contract accounts" have the ability
31//! to instantiate smart-contracts and make calls to other contract and non-contract accounts.
32//!
33//! The smart-contract code is stored once, and later retrievable via its hash.
34//! This means that multiple smart-contracts can be instantiated from the same hash, without
35//! replicating the code each time.
36//!
37//! When a smart-contract is called, its associated code is retrieved via the code hash and gets
38//! executed. This call can alter the storage entries of the smart-contract account, instantiate new
39//! smart-contracts, or call other smart-contracts.
40//!
41//! Finally, when an account is reaped, its associated code and storage of the smart-contract
42//! account will also be deleted.
43//!
44//! ### Weight
45//!
46//! Senders must specify a [`Weight`] limit with every call, as all instructions invoked by the
47//! smart-contract require weight. Unused weight is refunded after the call, regardless of the
48//! execution outcome.
49//!
50//! If the weight limit is reached, then all calls and state changes (including balance transfers)
51//! are only reverted at the current call's contract level. For example, if contract A calls B and B
52//! runs out of gas mid-call, then all of B's calls are reverted. Assuming correct error handling by
53//! contract A, A's other calls and state changes still persist.
54//!
55//! ### Notable Scenarios
56//!
57//! Contract call failures are not always cascading. When failures occur in a sub-call, they do not
58//! "bubble up", and the call will only revert at the specific contract level. For example, if
59//! contract A calls contract B, and B fails, A can decide how to handle that failure, either
60//! proceeding or reverting A's changes.
61//!
62//! ## Interface
63//!
64//! ### Dispatchable functions
65//!
66//! * [`Pallet::instantiate_with_code`] - Deploys a new contract from the supplied Wasm binary,
67//! optionally transferring
68//! some balance. This instantiates a new smart contract account with the supplied code and
69//! calls its constructor to initialize the contract.
70//! * [`Pallet::instantiate`] - The same as `instantiate_with_code` but instead of uploading new
71//! code an existing `code_hash` is supplied.
72//! * [`Pallet::call`] - Makes a call to an account, optionally transferring some balance.
73//! * [`Pallet::upload_code`] - Uploads new code without instantiating a contract from it.
74//! * [`Pallet::remove_code`] - Removes the stored code and refunds the deposit to its owner. Only
75//!   allowed to code owner.
76//! * [`Pallet::set_code`] - Changes the code of an existing contract. Only allowed to `Root`
77//!   origin.
78//! * [`Pallet::migrate`] - Runs migration steps of current multi-block migration in priority,
79//!   before [`Hooks::on_idle`][frame_support::traits::Hooks::on_idle] activates.
80//!
81//! ## Usage
82//!
83//! * [`ink!`](https://use.ink) is language that enables writing Wasm-based smart contracts in plain
84//!   Rust.
85
86#![allow(rustdoc::private_intra_doc_links)]
87#![cfg_attr(not(feature = "std"), no_std)]
88#![cfg_attr(feature = "runtime-benchmarks", recursion_limit = "1024")]
89
90mod address;
91mod benchmarking;
92mod exec;
93mod gas;
94mod schedule;
95mod storage;
96mod wasm;
97
98pub mod chain_extension;
99pub mod debug;
100pub mod migration;
101pub mod weights;
102
103#[cfg(test)]
104mod tests;
105use crate::{
106	exec::{
107		AccountIdOf, ErrorOrigin, ExecError, Executable, Ext, Key, MomentOf, Stack as ExecStack,
108	},
109	gas::GasMeter,
110	storage::{meter::Meter as StorageMeter, ContractInfo, DeletionQueueManager},
111	wasm::{CodeInfo, WasmBlob},
112};
113use codec::{Codec, Decode, Encode, HasCompact, MaxEncodedLen};
114use environmental::*;
115use frame_support::{
116	dispatch::{GetDispatchInfo, Pays, PostDispatchInfo, RawOrigin, WithPostDispatchInfo},
117	ensure,
118	error::BadOrigin,
119	traits::{
120		fungible::{Inspect, Mutate, MutateHold},
121		ConstU32, Contains, Get, Randomness, Time,
122	},
123	weights::Weight,
124	BoundedVec, DefaultNoBound, RuntimeDebugNoBound,
125};
126use frame_system::{
127	ensure_signed,
128	pallet_prelude::{BlockNumberFor, OriginFor},
129	EventRecord, Pallet as System,
130};
131use pallet_contracts_primitives::{
132	Code, CodeUploadResult, CodeUploadReturnValue, ContractAccessError, ContractExecResult,
133	ContractInstantiateResult, ContractResult, ExecReturnValue, GetStorageResult,
134	InstantiateReturnValue, StorageDeposit,
135};
136use scale_info::TypeInfo;
137use smallvec::Array;
138use sp_runtime::{
139	traits::{Convert, Dispatchable, Hash, Saturating, StaticLookup, Zero},
140	DispatchError, RuntimeDebug,
141};
142use sp_std::{fmt::Debug, prelude::*};
143
144pub use crate::{
145	address::{AddressGenerator, DefaultAddressGenerator},
146	debug::Tracing,
147	exec::Frame,
148	migration::{MigrateSequence, Migration, NoopMigration},
149	pallet::*,
150	schedule::{HostFnWeights, InstructionWeights, Limits, Schedule},
151	wasm::Determinism,
152};
153pub use weights::WeightInfo;
154
155#[cfg(doc)]
156pub use crate::wasm::api_doc;
157
158type CodeHash<T> = <T as frame_system::Config>::Hash;
159type TrieId = BoundedVec<u8, ConstU32<128>>;
160type BalanceOf<T> =
161	<<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
162type CodeVec<T> = BoundedVec<u8, <T as Config>::MaxCodeLen>;
163type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;
164type DebugBufferVec<T> = BoundedVec<u8, <T as Config>::MaxDebugBufferLen>;
165type EventRecordOf<T> =
166	EventRecord<<T as frame_system::Config>::RuntimeEvent, <T as frame_system::Config>::Hash>;
167
168/// The old weight type.
169///
170/// This is a copy of the [`frame_support::weights::OldWeight`] type since the contracts pallet
171/// needs to support it indefinitely.
172type OldWeight = u64;
173
174/// Used as a sentinel value when reading and writing contract memory.
175///
176/// It is usually used to signal `None` to a contract when only a primitive is allowed
177/// and we don't want to go through encoding a full Rust type. Using `u32::Max` is a safe
178/// sentinel because contracts are never allowed to use such a large amount of resources
179/// that this value makes sense for a memory location or length.
180const SENTINEL: u32 = u32::MAX;
181
182/// The target that is used for the log output emitted by this crate.
183///
184/// Hence you can use this target to selectively increase the log level for this crate.
185///
186/// Example: `RUST_LOG=runtime::contracts=debug my_code --dev`
187const LOG_TARGET: &str = "runtime::contracts";
188
189/// Wrapper around `PhantomData` to prevent it being filtered by `scale-info`.
190///
191/// `scale-info` filters out `PhantomData` fields because usually we are only interested
192/// in sized types. However, when trying to communicate **types** as opposed to **values**
193/// we want to have those zero sized types be included.
194#[derive(Encode, Decode, DefaultNoBound, TypeInfo)]
195#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
196pub struct EnvironmentType<T>(PhantomData<T>);
197
198/// List of all runtime configurable types that are used in the communication between
199/// `pallet-contracts` and any given contract.
200///
201/// Since those types are configurable they can vary between
202/// chains all using `pallet-contracts`. Hence we need a mechanism to communicate those types
203/// in a way that can be consumed by offchain tooling.
204///
205/// This type only exists in order to appear in the metadata where it can be read by
206/// offchain tooling.
207#[derive(Encode, Decode, DefaultNoBound, TypeInfo)]
208#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
209#[scale_info(skip_type_params(T))]
210pub struct Environment<T: Config> {
211	account_id: EnvironmentType<AccountIdOf<T>>,
212	balance: EnvironmentType<BalanceOf<T>>,
213	hash: EnvironmentType<<T as frame_system::Config>::Hash>,
214	hasher: EnvironmentType<<T as frame_system::Config>::Hashing>,
215	timestamp: EnvironmentType<MomentOf<T>>,
216	block_number: EnvironmentType<BlockNumberFor<T>>,
217}
218
219#[frame_support::pallet]
220pub mod pallet {
221	use super::*;
222	use crate::debug::Debugger;
223	use frame_support::pallet_prelude::*;
224	use frame_system::pallet_prelude::*;
225	use sp_runtime::Perbill;
226
227	/// The current storage version.
228	pub(crate) const STORAGE_VERSION: StorageVersion = StorageVersion::new(15);
229
230	#[pallet::pallet]
231	#[pallet::storage_version(STORAGE_VERSION)]
232	pub struct Pallet<T>(_);
233
234	#[pallet::config]
235	pub trait Config: frame_system::Config {
236		/// The time implementation used to supply timestamps to contracts through `seal_now`.
237		type Time: Time;
238
239		/// The generator used to supply randomness to contracts through `seal_random`.
240		///
241		/// # Deprecated
242		///
243		/// Codes using the randomness functionality cannot be uploaded. Neither can contracts
244		/// be instantiated from existing codes that use this deprecated functionality. It will
245		/// be removed eventually. Hence for new `pallet-contracts` deployments it is okay
246		/// to supply a dummy implementation for this type (because it is never used).
247		type Randomness: Randomness<Self::Hash, BlockNumberFor<Self>>;
248
249		/// The fungible in which fees are paid and contract balances are held.
250		type Currency: Inspect<Self::AccountId>
251			+ Mutate<Self::AccountId>
252			+ MutateHold<Self::AccountId, Reason = Self::RuntimeHoldReason>;
253
254		/// The overarching event type.
255		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
256
257		/// The overarching call type.
258		type RuntimeCall: Dispatchable<RuntimeOrigin = Self::RuntimeOrigin, PostInfo = PostDispatchInfo>
259			+ GetDispatchInfo
260			+ codec::Decode
261			+ IsType<<Self as frame_system::Config>::RuntimeCall>;
262
263		/// Filter that is applied to calls dispatched by contracts.
264		///
265		/// Use this filter to control which dispatchables are callable by contracts.
266		/// This is applied in **addition** to [`frame_system::Config::BaseCallFilter`].
267		/// It is recommended to treat this as a whitelist.
268		///
269		/// # Stability
270		///
271		/// The runtime **must** make sure that all dispatchables that are callable by
272		/// contracts remain stable. In addition [`Self::RuntimeCall`] itself must remain stable.
273		/// This means that no existing variants are allowed to switch their positions.
274		///
275		/// # Note
276		///
277		/// Note that dispatchables that are called via contracts do not spawn their
278		/// own wasm instance for each call (as opposed to when called via a transaction).
279		/// Therefore please make sure to be restrictive about which dispatchables are allowed
280		/// in order to not introduce a new DoS vector like memory allocation patterns that can
281		/// be exploited to drive the runtime into a panic.
282		type CallFilter: Contains<<Self as frame_system::Config>::RuntimeCall>;
283
284		/// Used to answer contracts' queries regarding the current weight price. This is **not**
285		/// used to calculate the actual fee and is only for informational purposes.
286		type WeightPrice: Convert<Weight, BalanceOf<Self>>;
287
288		/// Describes the weights of the dispatchables of this module and is also used to
289		/// construct a default cost schedule.
290		type WeightInfo: WeightInfo;
291
292		/// Type that allows the runtime authors to add new host functions for a contract to call.
293		type ChainExtension: chain_extension::ChainExtension<Self> + Default;
294
295		/// Cost schedule and limits.
296		#[pallet::constant]
297		type Schedule: Get<Schedule<Self>>;
298
299		/// The type of the call stack determines the maximum nesting depth of contract calls.
300		///
301		/// The allowed depth is `CallStack::size() + 1`.
302		/// Therefore a size of `0` means that a contract cannot use call or instantiate.
303		/// In other words only the origin called "root contract" is allowed to execute then.
304		///
305		/// This setting along with [`MaxCodeLen`](#associatedtype.MaxCodeLen) directly affects
306		/// memory usage of your runtime.
307		type CallStack: Array<Item = Frame<Self>>;
308
309		/// The amount of balance a caller has to pay for each byte of storage.
310		///
311		/// # Note
312		///
313		/// Changing this value for an existing chain might need a storage migration.
314		#[pallet::constant]
315		type DepositPerByte: Get<BalanceOf<Self>>;
316
317		/// Fallback value to limit the storage deposit if it's not being set by the caller.
318		#[pallet::constant]
319		type DefaultDepositLimit: Get<BalanceOf<Self>>;
320
321		/// The amount of balance a caller has to pay for each storage item.
322		///
323		/// # Note
324		///
325		/// Changing this value for an existing chain might need a storage migration.
326		#[pallet::constant]
327		type DepositPerItem: Get<BalanceOf<Self>>;
328
329		/// The percentage of the storage deposit that should be held for using a code hash.
330		/// Instantiating a contract, or calling [`chain_extension::Ext::add_delegate_dependency`]
331		/// protects the code from being removed. In order to prevent abuse these actions are
332		/// protected with a percentage of the code deposit.
333		#[pallet::constant]
334		type CodeHashLockupDepositPercent: Get<Perbill>;
335
336		/// The address generator used to generate the addresses of contracts.
337		type AddressGenerator: AddressGenerator<Self>;
338
339		/// The maximum length of a contract code in bytes.
340		///
341		/// The value should be chosen carefully taking into the account the overall memory limit
342		/// your runtime has, as well as the [maximum allowed callstack
343		/// depth](#associatedtype.CallStack). Look into the `integrity_test()` for some insights.
344		#[pallet::constant]
345		type MaxCodeLen: Get<u32>;
346
347		/// The maximum allowable length in bytes for storage keys.
348		#[pallet::constant]
349		type MaxStorageKeyLen: Get<u32>;
350
351		/// The maximum number of delegate_dependencies that a contract can lock with
352		/// [`chain_extension::Ext::add_delegate_dependency`].
353		#[pallet::constant]
354		type MaxDelegateDependencies: Get<u32>;
355
356		/// Make contract callable functions marked as `#[unstable]` available.
357		///
358		/// Contracts that use `#[unstable]` functions won't be able to be uploaded unless
359		/// this is set to `true`. This is only meant for testnets and dev nodes in order to
360		/// experiment with new features.
361		///
362		/// # Warning
363		///
364		/// Do **not** set to `true` on productions chains.
365		#[pallet::constant]
366		type UnsafeUnstableInterface: Get<bool>;
367
368		/// The maximum length of the debug buffer in bytes.
369		#[pallet::constant]
370		type MaxDebugBufferLen: Get<u32>;
371
372		/// Overarching hold reason.
373		type RuntimeHoldReason: From<HoldReason>;
374
375		/// The sequence of migration steps that will be applied during a migration.
376		///
377		/// # Examples
378		/// ```
379		/// use pallet_contracts::migration::{v10, v11};
380		/// # struct Runtime {};
381		/// # struct Currency {};
382		/// type Migrations = (v10::Migration<Runtime, Currency>, v11::Migration<Runtime>);
383		/// ```
384		///
385		/// If you have a single migration step, you can use a tuple with a single element:
386		/// ```
387		/// use pallet_contracts::migration::v10;
388		/// # struct Runtime {};
389		/// # struct Currency {};
390		/// type Migrations = (v10::Migration<Runtime, Currency>,);
391		/// ```
392		type Migrations: MigrateSequence;
393
394		/// # Note
395		/// For most production chains, it's recommended to use the `()` implementation of this
396		/// trait. This implementation offers additional logging when the log target
397		/// "runtime::contracts" is set to trace.
398		type Debug: Debugger<Self>;
399
400		/// Type that bundles together all the runtime configurable interface types.
401		///
402		/// This is not a real config. We just mention the type here as constant so that
403		/// its type appears in the metadata. Only valid value is `()`.
404		#[pallet::constant]
405		type Environment: Get<Environment<Self>>;
406	}
407
408	#[pallet::hooks]
409	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
410		fn on_idle(_block: BlockNumberFor<T>, mut remaining_weight: Weight) -> Weight {
411			use migration::MigrateResult::*;
412
413			loop {
414				let (result, weight) = Migration::<T>::migrate(remaining_weight);
415				remaining_weight.saturating_reduce(weight);
416
417				match result {
418					// There is not enough weight to perform a migration, or make any progress, we
419					// just return the remaining weight.
420					NoMigrationPerformed | InProgress { steps_done: 0 } => return remaining_weight,
421					// Migration is still in progress, we can start the next step.
422					InProgress { .. } => continue,
423					// Either no migration is in progress, or we are done with all migrations, we
424					// can do some more other work with the remaining weight.
425					Completed | NoMigrationInProgress => break,
426				}
427			}
428
429			ContractInfo::<T>::process_deletion_queue_batch(remaining_weight)
430				.saturating_add(T::WeightInfo::on_process_deletion_queue_batch())
431		}
432
433		fn integrity_test() {
434			Migration::<T>::integrity_test();
435
436			// Total runtime memory limit
437			let max_runtime_mem: u32 = T::Schedule::get().limits.runtime_memory;
438			// Memory limits for a single contract:
439			// Value stack size: 1Mb per contract, default defined in wasmi
440			const MAX_STACK_SIZE: u32 = 1024 * 1024;
441			// Heap limit is normally 16 mempages of 64kb each = 1Mb per contract
442			let max_heap_size = T::Schedule::get().limits.max_memory_size();
443			// Max call depth is CallStack::size() + 1
444			let max_call_depth = u32::try_from(T::CallStack::size().saturating_add(1))
445				.expect("CallStack size is too big");
446
447			// Check that given configured `MaxCodeLen`, runtime heap memory limit can't be broken.
448			//
449			// In worst case, the decoded Wasm contract code would be `x16` times larger than the
450			// encoded one. This is because even a single-byte wasm instruction has 16-byte size in
451			// wasmi. This gives us `MaxCodeLen*16` safety margin.
452			//
453			// Next, the pallet keeps the Wasm blob for each
454			// contract, hence we add up `MaxCodeLen` to the safety margin.
455			//
456			// Finally, the inefficiencies of the freeing-bump allocator
457			// being used in the client for the runtime memory allocations, could lead to possible
458			// memory allocations for contract code grow up to `x4` times in some extreme cases,
459			// which gives us total multiplier of `17*4` for `MaxCodeLen`.
460			//
461			// That being said, for every contract executed in runtime, at least `MaxCodeLen*17*4`
462			// memory should be available. Note that maximum allowed heap memory and stack size per
463			// each contract (stack frame) should also be counted.
464			//
465			// Finally, we allow 50% of the runtime memory to be utilized by the contracts call
466			// stack, keeping the rest for other facilities, such as PoV, etc.
467			//
468			// This gives us the following formula:
469			//
470			// `(MaxCodeLen * 17 * 4 + MAX_STACK_SIZE + max_heap_size) * max_call_depth <
471			// max_runtime_mem/2`
472			//
473			// Hence the upper limit for the `MaxCodeLen` can be defined as follows:
474			let code_len_limit = max_runtime_mem
475				.saturating_div(2)
476				.saturating_div(max_call_depth)
477				.saturating_sub(max_heap_size)
478				.saturating_sub(MAX_STACK_SIZE)
479				.saturating_div(17 * 4);
480
481			assert!(
482				T::MaxCodeLen::get() < code_len_limit,
483				"Given `CallStack` height {:?}, `MaxCodeLen` should be set less than {:?} \
484				 (current value is {:?}), to avoid possible runtime oom issues.",
485				max_call_depth,
486				code_len_limit,
487				T::MaxCodeLen::get(),
488			);
489
490			// Debug buffer should at least be large enough to accommodate a simple error message
491			const MIN_DEBUG_BUF_SIZE: u32 = 256;
492			assert!(
493				T::MaxDebugBufferLen::get() > MIN_DEBUG_BUF_SIZE,
494				"Debug buffer should have minimum size of {} (current setting is {})",
495				MIN_DEBUG_BUF_SIZE,
496				T::MaxDebugBufferLen::get(),
497			)
498		}
499	}
500
501	#[pallet::call]
502	impl<T: Config> Pallet<T>
503	where
504		<BalanceOf<T> as HasCompact>::Type: Clone + Eq + PartialEq + Debug + TypeInfo + Encode,
505	{
506		/// Deprecated version if [`Self::call`] for use in an in-storage `Call`.
507		#[pallet::call_index(0)]
508		#[pallet::weight(T::WeightInfo::call().saturating_add(<Pallet<T>>::compat_weight_limit(*gas_limit)))]
509		#[allow(deprecated)]
510		#[deprecated(note = "1D weight is used in this extrinsic, please migrate to `call`")]
511		pub fn call_old_weight(
512			origin: OriginFor<T>,
513			dest: AccountIdLookupOf<T>,
514			#[pallet::compact] value: BalanceOf<T>,
515			#[pallet::compact] gas_limit: OldWeight,
516			storage_deposit_limit: Option<<BalanceOf<T> as codec::HasCompact>::Type>,
517			data: Vec<u8>,
518		) -> DispatchResultWithPostInfo {
519			Self::call(
520				origin,
521				dest,
522				value,
523				<Pallet<T>>::compat_weight_limit(gas_limit),
524				storage_deposit_limit,
525				data,
526			)
527		}
528
529		/// Deprecated version if [`Self::instantiate_with_code`] for use in an in-storage `Call`.
530		#[pallet::call_index(1)]
531		#[pallet::weight(
532			T::WeightInfo::instantiate_with_code(code.len() as u32, data.len() as u32, salt.len() as u32)
533			.saturating_add(<Pallet<T>>::compat_weight_limit(*gas_limit))
534		)]
535		#[allow(deprecated)]
536		#[deprecated(
537			note = "1D weight is used in this extrinsic, please migrate to `instantiate_with_code`"
538		)]
539		pub fn instantiate_with_code_old_weight(
540			origin: OriginFor<T>,
541			#[pallet::compact] value: BalanceOf<T>,
542			#[pallet::compact] gas_limit: OldWeight,
543			storage_deposit_limit: Option<<BalanceOf<T> as codec::HasCompact>::Type>,
544			code: Vec<u8>,
545			data: Vec<u8>,
546			salt: Vec<u8>,
547		) -> DispatchResultWithPostInfo {
548			Self::instantiate_with_code(
549				origin,
550				value,
551				<Pallet<T>>::compat_weight_limit(gas_limit),
552				storage_deposit_limit,
553				code,
554				data,
555				salt,
556			)
557		}
558
559		/// Deprecated version if [`Self::instantiate`] for use in an in-storage `Call`.
560		#[pallet::call_index(2)]
561		#[pallet::weight(
562			T::WeightInfo::instantiate(data.len() as u32, salt.len() as u32).saturating_add(<Pallet<T>>::compat_weight_limit(*gas_limit))
563		)]
564		#[allow(deprecated)]
565		#[deprecated(note = "1D weight is used in this extrinsic, please migrate to `instantiate`")]
566		pub fn instantiate_old_weight(
567			origin: OriginFor<T>,
568			#[pallet::compact] value: BalanceOf<T>,
569			#[pallet::compact] gas_limit: OldWeight,
570			storage_deposit_limit: Option<<BalanceOf<T> as codec::HasCompact>::Type>,
571			code_hash: CodeHash<T>,
572			data: Vec<u8>,
573			salt: Vec<u8>,
574		) -> DispatchResultWithPostInfo {
575			Self::instantiate(
576				origin,
577				value,
578				<Pallet<T>>::compat_weight_limit(gas_limit),
579				storage_deposit_limit,
580				code_hash,
581				data,
582				salt,
583			)
584		}
585
586		/// Upload new `code` without instantiating a contract from it.
587		///
588		/// If the code does not already exist a deposit is reserved from the caller
589		/// and unreserved only when [`Self::remove_code`] is called. The size of the reserve
590		/// depends on the size of the supplied `code`.
591		///
592		/// If the code already exists in storage it will still return `Ok` and upgrades
593		/// the in storage version to the current
594		/// [`InstructionWeights::version`](InstructionWeights).
595		///
596		/// - `determinism`: If this is set to any other value but [`Determinism::Enforced`] then
597		///   the only way to use this code is to delegate call into it from an offchain execution.
598		///   Set to [`Determinism::Enforced`] if in doubt.
599		///
600		/// # Note
601		///
602		/// Anyone can instantiate a contract from any uploaded code and thus prevent its removal.
603		/// To avoid this situation a constructor could employ access control so that it can
604		/// only be instantiated by permissioned entities. The same is true when uploading
605		/// through [`Self::instantiate_with_code`].
606		#[pallet::call_index(3)]
607		#[pallet::weight(T::WeightInfo::upload_code(code.len() as u32))]
608		pub fn upload_code(
609			origin: OriginFor<T>,
610			code: Vec<u8>,
611			storage_deposit_limit: Option<<BalanceOf<T> as codec::HasCompact>::Type>,
612			determinism: Determinism,
613		) -> DispatchResult {
614			Migration::<T>::ensure_migrated()?;
615			let origin = ensure_signed(origin)?;
616			Self::bare_upload_code(origin, code, storage_deposit_limit.map(Into::into), determinism)
617				.map(|_| ())
618		}
619
620		/// Remove the code stored under `code_hash` and refund the deposit to its owner.
621		///
622		/// A code can only be removed by its original uploader (its owner) and only if it is
623		/// not used by any contract.
624		#[pallet::call_index(4)]
625		#[pallet::weight(T::WeightInfo::remove_code())]
626		pub fn remove_code(
627			origin: OriginFor<T>,
628			code_hash: CodeHash<T>,
629		) -> DispatchResultWithPostInfo {
630			Migration::<T>::ensure_migrated()?;
631			let origin = ensure_signed(origin)?;
632			<WasmBlob<T>>::remove(&origin, code_hash)?;
633			// we waive the fee because removing unused code is beneficial
634			Ok(Pays::No.into())
635		}
636
637		/// Privileged function that changes the code of an existing contract.
638		///
639		/// This takes care of updating refcounts and all other necessary operations. Returns
640		/// an error if either the `code_hash` or `dest` do not exist.
641		///
642		/// # Note
643		///
644		/// This does **not** change the address of the contract in question. This means
645		/// that the contract address is no longer derived from its code hash after calling
646		/// this dispatchable.
647		#[pallet::call_index(5)]
648		#[pallet::weight(T::WeightInfo::set_code())]
649		pub fn set_code(
650			origin: OriginFor<T>,
651			dest: AccountIdLookupOf<T>,
652			code_hash: CodeHash<T>,
653		) -> DispatchResult {
654			Migration::<T>::ensure_migrated()?;
655			ensure_root(origin)?;
656			let dest = T::Lookup::lookup(dest)?;
657			<ContractInfoOf<T>>::try_mutate(&dest, |contract| {
658				let contract = if let Some(contract) = contract {
659					contract
660				} else {
661					return Err(<Error<T>>::ContractNotFound.into())
662				};
663				<ExecStack<T, WasmBlob<T>>>::increment_refcount(code_hash)?;
664				<ExecStack<T, WasmBlob<T>>>::decrement_refcount(contract.code_hash);
665				Self::deposit_event(
666					vec![T::Hashing::hash_of(&dest), code_hash, contract.code_hash],
667					Event::ContractCodeUpdated {
668						contract: dest.clone(),
669						new_code_hash: code_hash,
670						old_code_hash: contract.code_hash,
671					},
672				);
673				contract.code_hash = code_hash;
674				Ok(())
675			})
676		}
677
678		/// Makes a call to an account, optionally transferring some balance.
679		///
680		/// # Parameters
681		///
682		/// * `dest`: Address of the contract to call.
683		/// * `value`: The balance to transfer from the `origin` to `dest`.
684		/// * `gas_limit`: The gas limit enforced when executing the constructor.
685		/// * `storage_deposit_limit`: The maximum amount of balance that can be charged from the
686		///   caller to pay for the storage consumed.
687		/// * `data`: The input data to pass to the contract.
688		///
689		/// * If the account is a smart-contract account, the associated code will be
690		/// executed and any value will be transferred.
691		/// * If the account is a regular account, any value will be transferred.
692		/// * If no account exists and the call value is not less than `existential_deposit`,
693		/// a regular account will be created and any value will be transferred.
694		#[pallet::call_index(6)]
695		#[pallet::weight(T::WeightInfo::call().saturating_add(*gas_limit))]
696		pub fn call(
697			origin: OriginFor<T>,
698			dest: AccountIdLookupOf<T>,
699			#[pallet::compact] value: BalanceOf<T>,
700			gas_limit: Weight,
701			storage_deposit_limit: Option<<BalanceOf<T> as codec::HasCompact>::Type>,
702			data: Vec<u8>,
703		) -> DispatchResultWithPostInfo {
704			Migration::<T>::ensure_migrated()?;
705			let common = CommonInput {
706				origin: Origin::from_runtime_origin(origin)?,
707				value,
708				data,
709				gas_limit: gas_limit.into(),
710				storage_deposit_limit: storage_deposit_limit.map(Into::into),
711				debug_message: None,
712			};
713			let dest = T::Lookup::lookup(dest)?;
714			let mut output =
715				CallInput::<T> { dest, determinism: Determinism::Enforced }.run_guarded(common);
716			if let Ok(retval) = &output.result {
717				if retval.did_revert() {
718					output.result = Err(<Error<T>>::ContractReverted.into());
719				}
720			}
721			output.gas_meter.into_dispatch_result(output.result, T::WeightInfo::call())
722		}
723
724		/// Instantiates a new contract from the supplied `code` optionally transferring
725		/// some balance.
726		///
727		/// This dispatchable has the same effect as calling [`Self::upload_code`] +
728		/// [`Self::instantiate`]. Bundling them together provides efficiency gains. Please
729		/// also check the documentation of [`Self::upload_code`].
730		///
731		/// # Parameters
732		///
733		/// * `value`: The balance to transfer from the `origin` to the newly created contract.
734		/// * `gas_limit`: The gas limit enforced when executing the constructor.
735		/// * `storage_deposit_limit`: The maximum amount of balance that can be charged/reserved
736		///   from the caller to pay for the storage consumed.
737		/// * `code`: The contract code to deploy in raw bytes.
738		/// * `data`: The input data to pass to the contract constructor.
739		/// * `salt`: Used for the address derivation. See [`Pallet::contract_address`].
740		///
741		/// Instantiation is executed as follows:
742		///
743		/// - The supplied `code` is deployed, and a `code_hash` is created for that code.
744		/// - If the `code_hash` already exists on the chain the underlying `code` will be shared.
745		/// - The destination address is computed based on the sender, code_hash and the salt.
746		/// - The smart-contract account is created at the computed address.
747		/// - The `value` is transferred to the new account.
748		/// - The `deploy` function is executed in the context of the newly-created account.
749		#[pallet::call_index(7)]
750		#[pallet::weight(
751			T::WeightInfo::instantiate_with_code(code.len() as u32, data.len() as u32, salt.len() as u32)
752			.saturating_add(*gas_limit)
753		)]
754		pub fn instantiate_with_code(
755			origin: OriginFor<T>,
756			#[pallet::compact] value: BalanceOf<T>,
757			gas_limit: Weight,
758			storage_deposit_limit: Option<<BalanceOf<T> as codec::HasCompact>::Type>,
759			code: Vec<u8>,
760			data: Vec<u8>,
761			salt: Vec<u8>,
762		) -> DispatchResultWithPostInfo {
763			Migration::<T>::ensure_migrated()?;
764			let origin = ensure_signed(origin)?;
765			let code_len = code.len() as u32;
766
767			let (module, upload_deposit) = Self::try_upload_code(
768				origin.clone(),
769				code,
770				storage_deposit_limit.clone().map(Into::into),
771				Determinism::Enforced,
772				None,
773			)?;
774
775			// Reduces the storage deposit limit by the amount that was reserved for the upload.
776			let storage_deposit_limit =
777				storage_deposit_limit.map(|limit| limit.into().saturating_sub(upload_deposit));
778
779			let data_len = data.len() as u32;
780			let salt_len = salt.len() as u32;
781			let common = CommonInput {
782				origin: Origin::from_account_id(origin),
783				value,
784				data,
785				gas_limit,
786				storage_deposit_limit,
787				debug_message: None,
788			};
789
790			let mut output =
791				InstantiateInput::<T> { code: WasmCode::Wasm(module), salt }.run_guarded(common);
792			if let Ok(retval) = &output.result {
793				if retval.1.did_revert() {
794					output.result = Err(<Error<T>>::ContractReverted.into());
795				}
796			}
797
798			output.gas_meter.into_dispatch_result(
799				output.result.map(|(_address, output)| output),
800				T::WeightInfo::instantiate_with_code(code_len, data_len, salt_len),
801			)
802		}
803
804		/// Instantiates a contract from a previously deployed wasm binary.
805		///
806		/// This function is identical to [`Self::instantiate_with_code`] but without the
807		/// code deployment step. Instead, the `code_hash` of an on-chain deployed wasm binary
808		/// must be supplied.
809		#[pallet::call_index(8)]
810		#[pallet::weight(
811			T::WeightInfo::instantiate(data.len() as u32, salt.len() as u32).saturating_add(*gas_limit)
812		)]
813		pub fn instantiate(
814			origin: OriginFor<T>,
815			#[pallet::compact] value: BalanceOf<T>,
816			gas_limit: Weight,
817			storage_deposit_limit: Option<<BalanceOf<T> as codec::HasCompact>::Type>,
818			code_hash: CodeHash<T>,
819			data: Vec<u8>,
820			salt: Vec<u8>,
821		) -> DispatchResultWithPostInfo {
822			Migration::<T>::ensure_migrated()?;
823			let data_len = data.len() as u32;
824			let salt_len = salt.len() as u32;
825			let common = CommonInput {
826				origin: Origin::from_runtime_origin(origin)?,
827				value,
828				data,
829				gas_limit,
830				storage_deposit_limit: storage_deposit_limit.map(Into::into),
831				debug_message: None,
832			};
833			let mut output = InstantiateInput::<T> { code: WasmCode::CodeHash(code_hash), salt }
834				.run_guarded(common);
835			if let Ok(retval) = &output.result {
836				if retval.1.did_revert() {
837					output.result = Err(<Error<T>>::ContractReverted.into());
838				}
839			}
840			output.gas_meter.into_dispatch_result(
841				output.result.map(|(_address, output)| output),
842				T::WeightInfo::instantiate(data_len, salt_len),
843			)
844		}
845
846		/// When a migration is in progress, this dispatchable can be used to run migration steps.
847		/// Calls that contribute to advancing the migration have their fees waived, as it's helpful
848		/// for the chain. Note that while the migration is in progress, the pallet will also
849		/// leverage the `on_idle` hooks to run migration steps.
850		#[pallet::call_index(9)]
851		#[pallet::weight(T::WeightInfo::migrate().saturating_add(*weight_limit))]
852		pub fn migrate(origin: OriginFor<T>, weight_limit: Weight) -> DispatchResultWithPostInfo {
853			use migration::MigrateResult::*;
854			ensure_signed(origin)?;
855
856			let weight_limit = weight_limit.saturating_add(T::WeightInfo::migrate());
857			let (result, weight) = Migration::<T>::migrate(weight_limit);
858
859			match result {
860				Completed =>
861					Ok(PostDispatchInfo { actual_weight: Some(weight), pays_fee: Pays::No }),
862				InProgress { steps_done, .. } if steps_done > 0 =>
863					Ok(PostDispatchInfo { actual_weight: Some(weight), pays_fee: Pays::No }),
864				InProgress { .. } =>
865					Ok(PostDispatchInfo { actual_weight: Some(weight), pays_fee: Pays::Yes }),
866				NoMigrationInProgress | NoMigrationPerformed => {
867					let err: DispatchError = <Error<T>>::NoMigrationPerformed.into();
868					Err(err.with_weight(T::WeightInfo::migrate()))
869				},
870			}
871		}
872	}
873
874	#[pallet::event]
875	pub enum Event<T: Config> {
876		/// Contract deployed by address at the specified address.
877		Instantiated { deployer: T::AccountId, contract: T::AccountId },
878
879		/// Contract has been removed.
880		///
881		/// # Note
882		///
883		/// The only way for a contract to be removed and emitting this event is by calling
884		/// `seal_terminate`.
885		Terminated {
886			/// The contract that was terminated.
887			contract: T::AccountId,
888			/// The account that received the contracts remaining balance
889			beneficiary: T::AccountId,
890		},
891
892		/// Code with the specified hash has been stored.
893		CodeStored { code_hash: T::Hash, deposit_held: BalanceOf<T>, uploader: T::AccountId },
894
895		/// A custom event emitted by the contract.
896		ContractEmitted {
897			/// The contract that emitted the event.
898			contract: T::AccountId,
899			/// Data supplied by the contract. Metadata generated during contract compilation
900			/// is needed to decode it.
901			data: Vec<u8>,
902		},
903
904		/// A code with the specified hash was removed.
905		CodeRemoved { code_hash: T::Hash, deposit_released: BalanceOf<T>, remover: T::AccountId },
906
907		/// A contract's code was updated.
908		ContractCodeUpdated {
909			/// The contract that has been updated.
910			contract: T::AccountId,
911			/// New code hash that was set for the contract.
912			new_code_hash: T::Hash,
913			/// Previous code hash of the contract.
914			old_code_hash: T::Hash,
915		},
916
917		/// A contract was called either by a plain account or another contract.
918		///
919		/// # Note
920		///
921		/// Please keep in mind that like all events this is only emitted for successful
922		/// calls. This is because on failure all storage changes including events are
923		/// rolled back.
924		Called {
925			/// The caller of the `contract`.
926			caller: Origin<T>,
927			/// The contract that was called.
928			contract: T::AccountId,
929		},
930
931		/// A contract delegate called a code hash.
932		///
933		/// # Note
934		///
935		/// Please keep in mind that like all events this is only emitted for successful
936		/// calls. This is because on failure all storage changes including events are
937		/// rolled back.
938		DelegateCalled {
939			/// The contract that performed the delegate call and hence in whose context
940			/// the `code_hash` is executed.
941			contract: T::AccountId,
942			/// The code hash that was delegate called.
943			code_hash: CodeHash<T>,
944		},
945
946		/// Some funds have been transferred and held as storage deposit.
947		StorageDepositTransferredAndHeld {
948			from: T::AccountId,
949			to: T::AccountId,
950			amount: BalanceOf<T>,
951		},
952
953		/// Some storage deposit funds have been transferred and released.
954		StorageDepositTransferredAndReleased {
955			from: T::AccountId,
956			to: T::AccountId,
957			amount: BalanceOf<T>,
958		},
959	}
960
961	#[pallet::error]
962	pub enum Error<T> {
963		/// Invalid schedule supplied, e.g. with zero weight of a basic operation.
964		InvalidSchedule,
965		/// Invalid combination of flags supplied to `seal_call` or `seal_delegate_call`.
966		InvalidCallFlags,
967		/// The executed contract exhausted its gas limit.
968		OutOfGas,
969		/// The output buffer supplied to a contract API call was too small.
970		OutputBufferTooSmall,
971		/// Performing the requested transfer failed. Probably because there isn't enough
972		/// free balance in the sender's account.
973		TransferFailed,
974		/// Performing a call was denied because the calling depth reached the limit
975		/// of what is specified in the schedule.
976		MaxCallDepthReached,
977		/// No contract was found at the specified address.
978		ContractNotFound,
979		/// The code supplied to `instantiate_with_code` exceeds the limit specified in the
980		/// current schedule.
981		CodeTooLarge,
982		/// No code could be found at the supplied code hash.
983		CodeNotFound,
984		/// No code info could be found at the supplied code hash.
985		CodeInfoNotFound,
986		/// A buffer outside of sandbox memory was passed to a contract API function.
987		OutOfBounds,
988		/// Input passed to a contract API function failed to decode as expected type.
989		DecodingFailed,
990		/// Contract trapped during execution.
991		ContractTrapped,
992		/// The size defined in `T::MaxValueSize` was exceeded.
993		ValueTooLarge,
994		/// Termination of a contract is not allowed while the contract is already
995		/// on the call stack. Can be triggered by `seal_terminate`.
996		TerminatedWhileReentrant,
997		/// `seal_call` forwarded this contracts input. It therefore is no longer available.
998		InputForwarded,
999		/// The subject passed to `seal_random` exceeds the limit.
1000		RandomSubjectTooLong,
1001		/// The amount of topics passed to `seal_deposit_events` exceeds the limit.
1002		TooManyTopics,
1003		/// The chain does not provide a chain extension. Calling the chain extension results
1004		/// in this error. Note that this usually  shouldn't happen as deploying such contracts
1005		/// is rejected.
1006		NoChainExtension,
1007		/// A contract with the same AccountId already exists.
1008		DuplicateContract,
1009		/// A contract self destructed in its constructor.
1010		///
1011		/// This can be triggered by a call to `seal_terminate`.
1012		TerminatedInConstructor,
1013		/// A call tried to invoke a contract that is flagged as non-reentrant.
1014		/// The only other cause is that a call from a contract into the runtime tried to call back
1015		/// into `pallet-contracts`. This would make the whole pallet reentrant with regard to
1016		/// contract code execution which is not supported.
1017		ReentranceDenied,
1018		/// Origin doesn't have enough balance to pay the required storage deposits.
1019		StorageDepositNotEnoughFunds,
1020		/// More storage was created than allowed by the storage deposit limit.
1021		StorageDepositLimitExhausted,
1022		/// Code removal was denied because the code is still in use by at least one contract.
1023		CodeInUse,
1024		/// The contract ran to completion but decided to revert its storage changes.
1025		/// Please note that this error is only returned from extrinsics. When called directly
1026		/// or via RPC an `Ok` will be returned. In this case the caller needs to inspect the flags
1027		/// to determine whether a reversion has taken place.
1028		ContractReverted,
1029		/// The contract's code was found to be invalid during validation.
1030		///
1031		/// The most likely cause of this is that an API was used which is not supported by the
1032		/// node. This happens if an older node is used with a new version of ink!. Try updating
1033		/// your node to the newest available version.
1034		///
1035		/// A more detailed error can be found on the node console if debug messages are enabled
1036		/// by supplying `-lruntime::contracts=debug`.
1037		CodeRejected,
1038		/// An indetermistic code was used in a context where this is not permitted.
1039		Indeterministic,
1040		/// A pending migration needs to complete before the extrinsic can be called.
1041		MigrationInProgress,
1042		/// Migrate dispatch call was attempted but no migration was performed.
1043		NoMigrationPerformed,
1044		/// The contract has reached its maximum number of delegate dependencies.
1045		MaxDelegateDependenciesReached,
1046		/// The dependency was not found in the contract's delegate dependencies.
1047		DelegateDependencyNotFound,
1048		/// The contract already depends on the given delegate dependency.
1049		DelegateDependencyAlreadyExists,
1050		/// Can not add a delegate dependency to the code hash of the contract itself.
1051		CannotAddSelfAsDelegateDependency,
1052	}
1053
1054	/// A reason for the pallet contracts placing a hold on funds.
1055	#[pallet::composite_enum]
1056	pub enum HoldReason {
1057		/// The Pallet has reserved it for storing code on-chain.
1058		CodeUploadDepositReserve,
1059		/// The Pallet has reserved it for storage deposit.
1060		StorageDepositReserve,
1061	}
1062
1063	/// A mapping from a contract's code hash to its code.
1064	#[pallet::storage]
1065	pub(crate) type PristineCode<T: Config> = StorageMap<_, Identity, CodeHash<T>, CodeVec<T>>;
1066
1067	/// A mapping from a contract's code hash to its code info.
1068	#[pallet::storage]
1069	pub(crate) type CodeInfoOf<T: Config> = StorageMap<_, Identity, CodeHash<T>, CodeInfo<T>>;
1070
1071	/// This is a **monotonic** counter incremented on contract instantiation.
1072	///
1073	/// This is used in order to generate unique trie ids for contracts.
1074	/// The trie id of a new contract is calculated from hash(account_id, nonce).
1075	/// The nonce is required because otherwise the following sequence would lead to
1076	/// a possible collision of storage:
1077	///
1078	/// 1. Create a new contract.
1079	/// 2. Terminate the contract.
1080	/// 3. Immediately recreate the contract with the same account_id.
1081	///
1082	/// This is bad because the contents of a trie are deleted lazily and there might be
1083	/// storage of the old instantiation still in it when the new contract is created. Please
1084	/// note that we can't replace the counter by the block number because the sequence above
1085	/// can happen in the same block. We also can't keep the account counter in memory only
1086	/// because storage is the only way to communicate across different extrinsics in the
1087	/// same block.
1088	///
1089	/// # Note
1090	///
1091	/// Do not use it to determine the number of contracts. It won't be decremented if
1092	/// a contract is destroyed.
1093	#[pallet::storage]
1094	pub(crate) type Nonce<T: Config> = StorageValue<_, u64, ValueQuery>;
1095
1096	/// The code associated with a given account.
1097	///
1098	/// TWOX-NOTE: SAFE since `AccountId` is a secure hash.
1099	#[pallet::storage]
1100	pub(crate) type ContractInfoOf<T: Config> =
1101		StorageMap<_, Twox64Concat, T::AccountId, ContractInfo<T>>;
1102
1103	/// Evicted contracts that await child trie deletion.
1104	///
1105	/// Child trie deletion is a heavy operation depending on the amount of storage items
1106	/// stored in said trie. Therefore this operation is performed lazily in `on_idle`.
1107	#[pallet::storage]
1108	pub(crate) type DeletionQueue<T: Config> = StorageMap<_, Twox64Concat, u32, TrieId>;
1109
1110	/// A pair of monotonic counters used to track the latest contract marked for deletion
1111	/// and the latest deleted contract in queue.
1112	#[pallet::storage]
1113	pub(crate) type DeletionQueueCounter<T: Config> =
1114		StorageValue<_, DeletionQueueManager<T>, ValueQuery>;
1115
1116	/// A migration can span across multiple blocks. This storage defines a cursor to track the
1117	/// progress of the migration, enabling us to resume from the last completed position.
1118	#[pallet::storage]
1119	pub(crate) type MigrationInProgress<T: Config> =
1120		StorageValue<_, migration::Cursor, OptionQuery>;
1121}
1122
1123/// The type of origins supported by the contracts pallet.
1124#[derive(Clone, Encode, Decode, PartialEq, TypeInfo, RuntimeDebugNoBound)]
1125pub enum Origin<T: Config> {
1126	Root,
1127	Signed(T::AccountId),
1128}
1129
1130impl<T: Config> Origin<T> {
1131	/// Creates a new Signed Caller from an AccountId.
1132	pub fn from_account_id(account_id: T::AccountId) -> Self {
1133		Origin::Signed(account_id)
1134	}
1135	/// Creates a new Origin from a `RuntimeOrigin`.
1136	pub fn from_runtime_origin(o: OriginFor<T>) -> Result<Self, DispatchError> {
1137		match o.into() {
1138			Ok(RawOrigin::Root) => Ok(Self::Root),
1139			Ok(RawOrigin::Signed(t)) => Ok(Self::Signed(t)),
1140			_ => Err(BadOrigin.into()),
1141		}
1142	}
1143	/// Returns the AccountId of a Signed Origin or an error if the origin is Root.
1144	pub fn account_id(&self) -> Result<&T::AccountId, DispatchError> {
1145		match self {
1146			Origin::Signed(id) => Ok(id),
1147			Origin::Root => Err(DispatchError::RootNotAllowed),
1148		}
1149	}
1150}
1151
1152/// Context of a contract invocation.
1153struct CommonInput<'a, T: Config> {
1154	origin: Origin<T>,
1155	value: BalanceOf<T>,
1156	data: Vec<u8>,
1157	gas_limit: Weight,
1158	storage_deposit_limit: Option<BalanceOf<T>>,
1159	debug_message: Option<&'a mut DebugBufferVec<T>>,
1160}
1161
1162/// Input specific to a call into contract.
1163struct CallInput<T: Config> {
1164	dest: T::AccountId,
1165	determinism: Determinism,
1166}
1167
1168/// Reference to an existing code hash or a new wasm module.
1169enum WasmCode<T: Config> {
1170	Wasm(WasmBlob<T>),
1171	CodeHash(CodeHash<T>),
1172}
1173
1174/// Input specific to a contract instantiation invocation.
1175struct InstantiateInput<T: Config> {
1176	code: WasmCode<T>,
1177	salt: Vec<u8>,
1178}
1179
1180/// Determines whether events should be collected during execution.
1181#[derive(
1182	Copy, Clone, PartialEq, Eq, RuntimeDebug, Decode, Encode, MaxEncodedLen, scale_info::TypeInfo,
1183)]
1184pub enum CollectEvents {
1185	/// Collect events.
1186	///
1187	/// # Note
1188	///
1189	/// Events should only be collected when called off-chain, as this would otherwise
1190	/// collect all the Events emitted in the block so far and put them into the PoV.
1191	///
1192	/// **Never** use this mode for on-chain execution.
1193	UnsafeCollect,
1194	/// Skip event collection.
1195	Skip,
1196}
1197
1198/// Determines whether debug messages will be collected.
1199#[derive(
1200	Copy, Clone, PartialEq, Eq, RuntimeDebug, Decode, Encode, MaxEncodedLen, scale_info::TypeInfo,
1201)]
1202pub enum DebugInfo {
1203	/// Collect debug messages.
1204	/// # Note
1205	///
1206	/// This should only ever be set to `UnsafeDebug` when executing as an RPC because
1207	/// it adds allocations and could be abused to drive the runtime into an OOM panic.
1208	UnsafeDebug,
1209	/// Skip collection of debug messages.
1210	Skip,
1211}
1212
1213/// Return type of private helper functions.
1214struct InternalOutput<T: Config, O> {
1215	/// The gas meter that was used to execute the call.
1216	gas_meter: GasMeter<T>,
1217	/// The storage deposit used by the call.
1218	storage_deposit: StorageDeposit<BalanceOf<T>>,
1219	/// The result of the call.
1220	result: Result<O, ExecError>,
1221}
1222
1223/// Helper trait to wrap contract execution entry points into a single function
1224/// [`Invokable::run_guarded`].
1225trait Invokable<T: Config>: Sized {
1226	/// What is returned as a result of a successful invocation.
1227	type Output;
1228
1229	/// Single entry point to contract execution.
1230	/// Downstream execution flow is branched by implementations of [`Invokable`] trait:
1231	///
1232	/// - [`InstantiateInput::run`] runs contract instantiation,
1233	/// - [`CallInput::run`] runs contract call.
1234	///
1235	/// We enforce a re-entrancy guard here by initializing and checking a boolean flag through a
1236	/// global reference.
1237	fn run_guarded(self, common: CommonInput<T>) -> InternalOutput<T, Self::Output> {
1238		// Set up a global reference to the boolean flag used for the re-entrancy guard.
1239		environmental!(executing_contract: bool);
1240
1241		let gas_limit = common.gas_limit;
1242
1243		// Check whether the origin is allowed here. The logic of the access rules
1244		// is in the `ensure_origin`, this could vary for different implementations of this
1245		// trait. For example, some actions might not allow Root origin as they could require an
1246		// AccountId associated with the origin.
1247		if let Err(e) = self.ensure_origin(common.origin.clone()) {
1248			return InternalOutput {
1249				gas_meter: GasMeter::new(gas_limit),
1250				storage_deposit: Default::default(),
1251				result: Err(ExecError { error: e.into(), origin: ErrorOrigin::Caller }),
1252			}
1253		}
1254
1255		executing_contract::using_once(&mut false, || {
1256			executing_contract::with(|f| {
1257				// Fail if already entered contract execution
1258				if *f {
1259					return Err(())
1260				}
1261				// We are entering contract execution
1262				*f = true;
1263				Ok(())
1264			})
1265			.expect("Returns `Ok` if called within `using_once`. It is syntactically obvious that this is the case; qed")
1266			.map_or_else(
1267				|_| InternalOutput {
1268					gas_meter: GasMeter::new(gas_limit),
1269					storage_deposit: Default::default(),
1270					result: Err(ExecError {
1271						error: <Error<T>>::ReentranceDenied.into(),
1272						origin: ErrorOrigin::Caller,
1273					}),
1274				},
1275				// Enter contract call.
1276				|_| self.run(common, GasMeter::new(gas_limit)),
1277			)
1278		})
1279	}
1280
1281	/// Method that does the actual call to a contract. It can be either a call to a deployed
1282	/// contract or a instantiation of a new one.
1283	///
1284	/// Called by dispatchables and public functions through the [`Invokable::run_guarded`].
1285	fn run(self, common: CommonInput<T>, gas_meter: GasMeter<T>)
1286		-> InternalOutput<T, Self::Output>;
1287
1288	/// This method ensures that the given `origin` is allowed to invoke the current `Invokable`.
1289	///
1290	/// Called by dispatchables and public functions through the [`Invokable::run_guarded`].
1291	fn ensure_origin(&self, origin: Origin<T>) -> Result<(), DispatchError>;
1292}
1293
1294impl<T: Config> Invokable<T> for CallInput<T> {
1295	type Output = ExecReturnValue;
1296
1297	fn run(
1298		self,
1299		common: CommonInput<T>,
1300		mut gas_meter: GasMeter<T>,
1301	) -> InternalOutput<T, Self::Output> {
1302		let CallInput { dest, determinism } = self;
1303		let CommonInput { origin, value, data, debug_message, .. } = common;
1304		let mut storage_meter =
1305			match StorageMeter::new(&origin, common.storage_deposit_limit, common.value) {
1306				Ok(meter) => meter,
1307				Err(err) =>
1308					return InternalOutput {
1309						result: Err(err.into()),
1310						gas_meter,
1311						storage_deposit: Default::default(),
1312					},
1313			};
1314		let schedule = T::Schedule::get();
1315		let result = ExecStack::<T, WasmBlob<T>>::run_call(
1316			origin.clone(),
1317			dest.clone(),
1318			&mut gas_meter,
1319			&mut storage_meter,
1320			&schedule,
1321			value,
1322			data.clone(),
1323			debug_message,
1324			determinism,
1325		);
1326
1327		match storage_meter.try_into_deposit(&origin) {
1328			Ok(storage_deposit) => InternalOutput { gas_meter, storage_deposit, result },
1329			Err(err) => InternalOutput {
1330				gas_meter,
1331				storage_deposit: Default::default(),
1332				result: Err(err.into()),
1333			},
1334		}
1335	}
1336
1337	fn ensure_origin(&self, _origin: Origin<T>) -> Result<(), DispatchError> {
1338		Ok(())
1339	}
1340}
1341
1342impl<T: Config> Invokable<T> for InstantiateInput<T> {
1343	type Output = (AccountIdOf<T>, ExecReturnValue);
1344
1345	fn run(
1346		self,
1347		common: CommonInput<T>,
1348		mut gas_meter: GasMeter<T>,
1349	) -> InternalOutput<T, Self::Output> {
1350		let mut storage_deposit = Default::default();
1351		let try_exec = || {
1352			let schedule = T::Schedule::get();
1353			let InstantiateInput { salt, .. } = self;
1354			let CommonInput { origin: contract_origin, .. } = common;
1355			let origin = contract_origin.account_id()?;
1356
1357			let executable = match self.code {
1358				WasmCode::Wasm(module) => module,
1359				WasmCode::CodeHash(code_hash) => WasmBlob::from_storage(code_hash, &mut gas_meter)?,
1360			};
1361
1362			let contract_origin = Origin::from_account_id(origin.clone());
1363			let mut storage_meter =
1364				StorageMeter::new(&contract_origin, common.storage_deposit_limit, common.value)?;
1365			let CommonInput { value, data, debug_message, .. } = common;
1366			let result = ExecStack::<T, WasmBlob<T>>::run_instantiate(
1367				origin.clone(),
1368				executable,
1369				&mut gas_meter,
1370				&mut storage_meter,
1371				&schedule,
1372				value,
1373				data.clone(),
1374				&salt,
1375				debug_message,
1376			);
1377
1378			storage_deposit = storage_meter.try_into_deposit(&contract_origin)?;
1379			result
1380		};
1381		InternalOutput { result: try_exec(), gas_meter, storage_deposit }
1382	}
1383
1384	fn ensure_origin(&self, origin: Origin<T>) -> Result<(), DispatchError> {
1385		match origin {
1386			Origin::Signed(_) => Ok(()),
1387			Origin::Root => Err(DispatchError::RootNotAllowed),
1388		}
1389	}
1390}
1391
1392macro_rules! ensure_no_migration_in_progress {
1393	() => {
1394		if Migration::<T>::in_progress() {
1395			return ContractResult {
1396				gas_consumed: Zero::zero(),
1397				gas_required: Zero::zero(),
1398				storage_deposit: Default::default(),
1399				debug_message: Vec::new(),
1400				result: Err(Error::<T>::MigrationInProgress.into()),
1401				events: None,
1402			}
1403		}
1404	};
1405}
1406
1407impl<T: Config> Pallet<T> {
1408	/// Perform a call to a specified contract.
1409	///
1410	/// This function is similar to [`Self::call`], but doesn't perform any address lookups
1411	/// and better suitable for calling directly from Rust.
1412	///
1413	/// # Note
1414	///
1415	/// If `debug` is set to `DebugInfo::UnsafeDebug` it returns additional human readable debugging
1416	/// information.
1417	///
1418	/// If `collect_events` is set to `CollectEvents::UnsafeCollect` it collects all the Events
1419	/// emitted in the block so far and the ones emitted during the execution of this contract.
1420	pub fn bare_call(
1421		origin: T::AccountId,
1422		dest: T::AccountId,
1423		value: BalanceOf<T>,
1424		gas_limit: Weight,
1425		storage_deposit_limit: Option<BalanceOf<T>>,
1426		data: Vec<u8>,
1427		debug: DebugInfo,
1428		collect_events: CollectEvents,
1429		determinism: Determinism,
1430	) -> ContractExecResult<BalanceOf<T>, EventRecordOf<T>> {
1431		ensure_no_migration_in_progress!();
1432
1433		let mut debug_message = if matches!(debug, DebugInfo::UnsafeDebug) {
1434			Some(DebugBufferVec::<T>::default())
1435		} else {
1436			None
1437		};
1438		let origin = Origin::from_account_id(origin);
1439		let common = CommonInput {
1440			origin,
1441			value,
1442			data,
1443			gas_limit,
1444			storage_deposit_limit,
1445			debug_message: debug_message.as_mut(),
1446		};
1447		let output = CallInput::<T> { dest, determinism }.run_guarded(common);
1448		let events = if matches!(collect_events, CollectEvents::UnsafeCollect) {
1449			Some(System::<T>::read_events_no_consensus().map(|e| *e).collect())
1450		} else {
1451			None
1452		};
1453
1454		ContractExecResult {
1455			result: output.result.map_err(|r| r.error),
1456			gas_consumed: output.gas_meter.gas_consumed(),
1457			gas_required: output.gas_meter.gas_required(),
1458			storage_deposit: output.storage_deposit,
1459			debug_message: debug_message.unwrap_or_default().to_vec(),
1460			events,
1461		}
1462	}
1463
1464	/// Instantiate a new contract.
1465	///
1466	/// This function is similar to [`Self::instantiate`], but doesn't perform any address lookups
1467	/// and better suitable for calling directly from Rust.
1468	///
1469	/// It returns the execution result, account id and the amount of used weight.
1470	///
1471	/// # Note
1472	///
1473	/// If `debug` is set to `DebugInfo::UnsafeDebug` it returns additional human readable debugging
1474	/// information.
1475	///
1476	/// If `collect_events` is set to `CollectEvents::UnsafeCollect` it collects all the Events
1477	/// emitted in the block so far.
1478	pub fn bare_instantiate(
1479		origin: T::AccountId,
1480		value: BalanceOf<T>,
1481		gas_limit: Weight,
1482		mut storage_deposit_limit: Option<BalanceOf<T>>,
1483		code: Code<CodeHash<T>>,
1484		data: Vec<u8>,
1485		salt: Vec<u8>,
1486		debug: DebugInfo,
1487		collect_events: CollectEvents,
1488	) -> ContractInstantiateResult<T::AccountId, BalanceOf<T>, EventRecordOf<T>> {
1489		ensure_no_migration_in_progress!();
1490
1491		let mut debug_message = if debug == DebugInfo::UnsafeDebug {
1492			Some(DebugBufferVec::<T>::default())
1493		} else {
1494			None
1495		};
1496		// collect events if CollectEvents is UnsafeCollect
1497		let events = || {
1498			if collect_events == CollectEvents::UnsafeCollect {
1499				Some(System::<T>::read_events_no_consensus().map(|e| *e).collect())
1500			} else {
1501				None
1502			}
1503		};
1504
1505		let (code, upload_deposit): (WasmCode<T>, BalanceOf<T>) = match code {
1506			Code::Upload(code) => {
1507				let result = Self::try_upload_code(
1508					origin.clone(),
1509					code,
1510					storage_deposit_limit.map(Into::into),
1511					Determinism::Enforced,
1512					debug_message.as_mut(),
1513				);
1514
1515				let (module, deposit) = match result {
1516					Ok(result) => result,
1517					Err(error) =>
1518						return ContractResult {
1519							gas_consumed: Zero::zero(),
1520							gas_required: Zero::zero(),
1521							storage_deposit: Default::default(),
1522							debug_message: debug_message.unwrap_or(Default::default()).into(),
1523							result: Err(error),
1524							events: events(),
1525						},
1526				};
1527
1528				storage_deposit_limit =
1529					storage_deposit_limit.map(|l| l.saturating_sub(deposit.into()));
1530				(WasmCode::Wasm(module), deposit)
1531			},
1532			Code::Existing(hash) => (WasmCode::CodeHash(hash), Default::default()),
1533		};
1534
1535		let common = CommonInput {
1536			origin: Origin::from_account_id(origin),
1537			value,
1538			data,
1539			gas_limit,
1540			storage_deposit_limit,
1541			debug_message: debug_message.as_mut(),
1542		};
1543
1544		let output = InstantiateInput::<T> { code, salt }.run_guarded(common);
1545		ContractInstantiateResult {
1546			result: output
1547				.result
1548				.map(|(account_id, result)| InstantiateReturnValue { result, account_id })
1549				.map_err(|e| e.error),
1550			gas_consumed: output.gas_meter.gas_consumed(),
1551			gas_required: output.gas_meter.gas_required(),
1552			storage_deposit: output
1553				.storage_deposit
1554				.saturating_add(&StorageDeposit::Charge(upload_deposit)),
1555			debug_message: debug_message.unwrap_or_default().to_vec(),
1556			events: events(),
1557		}
1558	}
1559
1560	/// Upload new code without instantiating a contract from it.
1561	///
1562	/// This function is similar to [`Self::upload_code`], but doesn't perform any address lookups
1563	/// and better suitable for calling directly from Rust.
1564	pub fn bare_upload_code(
1565		origin: T::AccountId,
1566		code: Vec<u8>,
1567		storage_deposit_limit: Option<BalanceOf<T>>,
1568		determinism: Determinism,
1569	) -> CodeUploadResult<CodeHash<T>, BalanceOf<T>> {
1570		Migration::<T>::ensure_migrated()?;
1571		let (module, deposit) =
1572			Self::try_upload_code(origin, code, storage_deposit_limit, determinism, None)?;
1573		Ok(CodeUploadReturnValue { code_hash: *module.code_hash(), deposit })
1574	}
1575
1576	/// Uploads new code and returns the Wasm blob and deposit amount collected.
1577	fn try_upload_code(
1578		origin: T::AccountId,
1579		code: Vec<u8>,
1580		storage_deposit_limit: Option<BalanceOf<T>>,
1581		determinism: Determinism,
1582		mut debug_message: Option<&mut DebugBufferVec<T>>,
1583	) -> Result<(WasmBlob<T>, BalanceOf<T>), DispatchError> {
1584		let schedule = T::Schedule::get();
1585		let mut module =
1586			WasmBlob::from_code(code, &schedule, origin, determinism).map_err(|(err, msg)| {
1587				debug_message.as_mut().map(|d| d.try_extend(msg.bytes()));
1588				err
1589			})?;
1590		let deposit = module.store_code()?;
1591		if let Some(storage_deposit_limit) = storage_deposit_limit {
1592			ensure!(storage_deposit_limit >= deposit, <Error<T>>::StorageDepositLimitExhausted);
1593		}
1594
1595		Ok((module, deposit))
1596	}
1597
1598	/// Query storage of a specified contract under a specified key.
1599	pub fn get_storage(address: T::AccountId, key: Vec<u8>) -> GetStorageResult {
1600		if Migration::<T>::in_progress() {
1601			return Err(ContractAccessError::MigrationInProgress)
1602		}
1603		let contract_info =
1604			ContractInfoOf::<T>::get(&address).ok_or(ContractAccessError::DoesntExist)?;
1605
1606		let maybe_value = contract_info.read(
1607			&Key::<T>::try_from_var(key)
1608				.map_err(|_| ContractAccessError::KeyDecodingFailed)?
1609				.into(),
1610		);
1611		Ok(maybe_value)
1612	}
1613
1614	/// Determine the address of a contract.
1615	///
1616	/// This is the address generation function used by contract instantiation. See
1617	/// [`DefaultAddressGenerator`] for the default implementation.
1618	pub fn contract_address(
1619		deploying_address: &T::AccountId,
1620		code_hash: &CodeHash<T>,
1621		input_data: &[u8],
1622		salt: &[u8],
1623	) -> T::AccountId {
1624		T::AddressGenerator::contract_address(deploying_address, code_hash, input_data, salt)
1625	}
1626
1627	/// Returns the code hash of the contract specified by `account` ID.
1628	pub fn code_hash(account: &AccountIdOf<T>) -> Option<CodeHash<T>> {
1629		ContractInfo::<T>::load_code_hash(account)
1630	}
1631
1632	/// Store code for benchmarks which does not validate the code.
1633	#[cfg(feature = "runtime-benchmarks")]
1634	fn store_code_raw(
1635		code: Vec<u8>,
1636		owner: T::AccountId,
1637	) -> frame_support::dispatch::DispatchResult {
1638		let schedule = T::Schedule::get();
1639		WasmBlob::<T>::from_code_unchecked(code, &schedule, owner)?.store_code()?;
1640		Ok(())
1641	}
1642
1643	/// Deposit a pallet contracts event. Handles the conversion to the overarching event type.
1644	fn deposit_event(topics: Vec<T::Hash>, event: Event<T>) {
1645		<frame_system::Pallet<T>>::deposit_event_indexed(
1646			&topics,
1647			<T as Config>::RuntimeEvent::from(event).into(),
1648		)
1649	}
1650
1651	/// Return the existential deposit of [`Config::Currency`].
1652	fn min_balance() -> BalanceOf<T> {
1653		<T::Currency as Inspect<AccountIdOf<T>>>::minimum_balance()
1654	}
1655
1656	/// Convert gas_limit from 1D Weight to a 2D Weight.
1657	///
1658	/// Used by backwards compatible extrinsics. We cannot just set the proof_size weight limit to
1659	/// zero or an old `Call` will just fail with OutOfGas.
1660	fn compat_weight_limit(gas_limit: OldWeight) -> Weight {
1661		Weight::from_parts(gas_limit, u64::from(T::MaxCodeLen::get()) * 2)
1662	}
1663}
1664
1665sp_api::decl_runtime_apis! {
1666	/// The API used to dry-run contract interactions.
1667	#[api_version(2)]
1668	pub trait ContractsApi<AccountId, Balance, BlockNumber, Hash, EventRecord> where
1669		AccountId: Codec,
1670		Balance: Codec,
1671		BlockNumber: Codec,
1672		Hash: Codec,
1673		EventRecord: Codec,
1674	{
1675		/// Perform a call from a specified account to a given contract.
1676		///
1677		/// See [`crate::Pallet::bare_call`].
1678		fn call(
1679			origin: AccountId,
1680			dest: AccountId,
1681			value: Balance,
1682			gas_limit: Option<Weight>,
1683			storage_deposit_limit: Option<Balance>,
1684			input_data: Vec<u8>,
1685		) -> ContractExecResult<Balance, EventRecord>;
1686
1687		/// Instantiate a new contract.
1688		///
1689		/// See `[crate::Pallet::bare_instantiate]`.
1690		fn instantiate(
1691			origin: AccountId,
1692			value: Balance,
1693			gas_limit: Option<Weight>,
1694			storage_deposit_limit: Option<Balance>,
1695			code: Code<Hash>,
1696			data: Vec<u8>,
1697			salt: Vec<u8>,
1698		) -> ContractInstantiateResult<AccountId, Balance, EventRecord>;
1699
1700		/// Upload new code without instantiating a contract from it.
1701		///
1702		/// See [`crate::Pallet::bare_upload_code`].
1703		fn upload_code(
1704			origin: AccountId,
1705			code: Vec<u8>,
1706			storage_deposit_limit: Option<Balance>,
1707			determinism: Determinism,
1708		) -> CodeUploadResult<Hash, Balance>;
1709
1710		/// Query a given storage key in a given contract.
1711		///
1712		/// Returns `Ok(Some(Vec<u8>))` if the storage value exists under the given key in the
1713		/// specified account and `Ok(None)` if it doesn't. If the account specified by the address
1714		/// doesn't exist, or doesn't have a contract then `Err` is returned.
1715		fn get_storage(
1716			address: AccountId,
1717			key: Vec<u8>,
1718		) -> GetStorageResult;
1719	}
1720}