pezkuwi_sdk_docs/reference_docs/transaction_extensions.rs
1//! Transaction extensions are, briefly, a means for different chains to extend the "basic"
2//! extrinsic format with custom data that can be checked by the runtime.
3//!
4//! # FRAME provided transaction extensions
5//!
6//! FRAME by default already provides the following transaction extensions:
7//!
8//! - [`CheckGenesis`](pezframe_system::CheckGenesis): Ensures that a transaction was sent for the
9//! same network. Determined based on genesis.
10//!
11//! - [`CheckMortality`](pezframe_system::CheckMortality): Extends a transaction with a configurable
12//! mortality.
13//!
14//! - [`CheckNonZeroSender`](pezframe_system::CheckNonZeroSender): Ensures that the sender of a
15//! transaction is not the *all zero account* (all bytes of the accountid are zero).
16//!
17//! - [`CheckNonce`](pezframe_system::CheckNonce): Extends a transaction with a nonce to prevent
18//! replay of transactions and to provide ordering of transactions.
19//!
20//! - [`CheckSpecVersion`](pezframe_system::CheckSpecVersion): Ensures that a transaction was built
21//! for the currently active runtime.
22//!
23//! - [`CheckTxVersion`](pezframe_system::CheckTxVersion): Ensures that the transaction signer used
24//! the correct encoding of the call.
25//!
26//! - [`CheckWeight`](pezframe_system::CheckWeight): Ensures that the transaction fits into the
27//! block before dispatching it.
28//!
29//! - [`ChargeTransactionPayment`](pezpallet_transaction_payment::ChargeTransactionPayment): Charges
30//! transaction fees from the signer based on the weight of the call using the native token.
31//!
32//! - [`ChargeAssetTxPayment`](pezpallet_asset_tx_payment::ChargeAssetTxPayment): Charges
33//! transaction fees from the signer based on the weight of the call using any supported asset
34//! (including the native token).
35//!
36//! - [`ChargeAssetTxPayment`(using
37//! conversion)](pezpallet_asset_conversion_tx_payment::ChargeAssetTxPayment): Charges transaction
38//! fees from the signer based on the weight of the call using any supported asset (including the
39//! native token). The asset is converted to the native token using a pool.
40//!
41//! - [`SkipCheckIfFeeless`](pezpallet_skip_feeless_payment::SkipCheckIfFeeless): Allows
42//! transactions to be processed without paying any fee. This requires that the `call` that should
43//! be dispatched is augmented with the
44//! [`feeless_if`](pezframe_support::pezpallet_macros::feeless_if) attribute.
45//!
46//! - [`CheckMetadataHash`](pezframe_metadata_hash_extension::CheckMetadataHash): Extends
47//! transactions to include the so-called metadata hash. This is required by chains to support the
48//! generic Ledger application and other similar offline wallets.
49//!
50//! - [`WeightReclaim`](pezframe_system::WeightReclaim): A transaction extension for the relay chain
51//! that reclaims unused weight after executing a transaction.
52//!
53//! - [`StorageWeightReclaim`](pezcumulus_pezpallet_weight_reclaim::StorageWeightReclaim): A
54//! transaction extension for teyrchains that reclaims unused storage weight after executing a
55//! transaction.
56//!
57//! For more information about these extensions, follow the link to the type documentation.
58//!
59//! # Building a custom transaction extension
60//!
61//! Defining a couple of very simple transaction extensions looks like the following:
62#![doc = docify::embed!("./src/reference_docs/transaction_extensions.rs", transaction_extensions_example)]
63
64#[docify::export]
65pub mod transaction_extensions_example {
66 use codec::{Decode, DecodeWithMemTracking, Encode};
67 use pezsp_runtime::{
68 impl_tx_ext_default,
69 traits::{Dispatchable, TransactionExtension},
70 transaction_validity::TransactionValidityError,
71 };
72 use scale_info::TypeInfo;
73
74 // This doesn't actually check anything, but simply allows
75 // some arbitrary `u32` to be added to the extrinsic payload
76 #[derive(Debug, Encode, Decode, DecodeWithMemTracking, Clone, Eq, PartialEq, TypeInfo)]
77 pub struct AddToPayload(pub u32);
78
79 impl<Call: Dispatchable> TransactionExtension<Call> for AddToPayload {
80 const IDENTIFIER: &'static str = "AddToPayload";
81 type Implicit = ();
82 type Pre = ();
83 type Val = ();
84
85 impl_tx_ext_default!(Call; weight validate prepare);
86 }
87
88 // This is the opposite; nothing will be added to the extrinsic payload,
89 // but the Implicit type (`1234u32`) will be added to the
90 // payload to be signed.
91 #[derive(Debug, Encode, Decode, DecodeWithMemTracking, Clone, Eq, PartialEq, TypeInfo)]
92 pub struct AddToSignaturePayload;
93
94 impl<Call: Dispatchable> TransactionExtension<Call> for AddToSignaturePayload {
95 const IDENTIFIER: &'static str = "AddToSignaturePayload";
96 type Implicit = u32;
97
98 fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
99 Ok(1234)
100 }
101 type Pre = ();
102 type Val = ();
103
104 impl_tx_ext_default!(Call; weight validate prepare);
105 }
106}