Inherents,Transactions,extrinsics
Amit Nadiger
Polyglot(Rust??, Move, C++, C, Kotlin, Java) Blockchain, Polkadot, UTXO, Substrate, Sui, Aptos, Wasm, Proxy-wasm,AndroidTV, Dvb, STB, Linux, Cas, Engineering management.
Inherents
In Substrate, "inherents" refer to the intrinsic data or information that must be included in each block of the blockchain. Inherents are different from regular transactions because they are not initiated by users or external parties but are inherent to the operation of the blockchain itself. They provide essential data for t.he blockchain to function properly and include information that all nodes must agree upon, such as the timestamp, block number, and other consensus-related data.
Each inherent is added to a produced block. Each runtime decides on which inherents it wants to attach to its blocks. All data that is required for the runtime to create the inherents is stored in the InherentData. This InherentData is constructed by the node and given to the runtime.
Types that provide data for inherents, should implement InherentDataProvider and need to be registered at InherentDataProviders.
In the runtime, modules need to implement ProvideInherent when they can create and/or check inherents. By implementing ProvideInherent, a module is not enforced to create an inherent. A module can also just check given inherents. For using a module as inherent provider, it needs to be registered by the construct_runtime! macro. The macro documentation gives more information on how that is done.
Here are some key points about inherents in Substrate:
1. Types of Inherents: Inherents can include various types of data, such as below : Timestamp: The exact time when the block was produced.
Block Number: The number of the current block.
Randomness: Randomness values used in consensus mechanisms.
Authorship: Information about the author of the block.
Seal: Data generated by block authoring mechanisms like Proof of Work (PoW) or Proof of Stake (PoS).
Finality Proof: Proof of finalized blocks in some consensus algorithms.
Transaction Queue: Pre-selected transactions for the block.
Custom Data: Any other data that needs to be included in every block.
2.Consensus and Validity: Inherents play a critical role in reaching consensus among different nodes on the state of the blockchain. All nodes must agree on the inherent data for a block to be considered valid and part of the blockchain.
3.Generated and Checked by the Runtime: Inherents are generated and checked by the runtime of the blockchain. The runtime ensures that all required inherents are included and valid before a block is finalized.
4.Inherent Data Extraction: During block authoring, the node generates the necessary inherents and includes them in the block header. During block validation, nodes verify that the inherents are valid and consistent with the current state.
5.Inherent Data Processing: The inherent data is processed by the runtime when the block is executed. The inherent data can affect the state transitions and operations within the block.
6.Custom Inherents: Substrate allows developers to define custom inherents to include additional information required for specific use cases or features.//! APIs and utilities for working with Substrate's Inherents in Tuxedo based chains.
Below is the defination from source code :
# Substrate inherents Inherents are a Substrate feature that allows block authors to insert some transactions directly into the body of the block. Inherents are similar to pre-runtime digests which allow authors to insert info into the block header. However inherents go in the block body and therefore must be transactions.
Classic usecases for inherents are injecting and updating environmental information such as a block timestamp, information about the relay chain (if the current chain is a parachain), or information about who should receive the block reward.
In order to allow the runtime to construct such transactions while keeping the cleint opaque, there are special APIs for creating inherents and performing off-chain validation of inherents. That's right, inherents also offer a special API to have their environmental data checked off-chain before the block is executed.
Complexities in UTXO chains !: In account based systems, the classic way to use an inherent is that the block inserts a transaction providing some data like a timestamp.When the extrinsic executed it, overwrites the previously stored timestamp in a dedicated storage item.
In UTXO chains, there are no storage items, and all state is local to a UTXO. This is the case with, for example, the timestamp as well.This means that when the author calls into the runtime with a timestamp, the transaction that is returned must include the correct reference to the UTXO that contained the previous best timestamp. This is the crux of the problem: there is no easy way to know the location of the previous timestamp in the utxo-space from inside the runtime.
# Scraping the Parent Block:The solution is to provide the entirety of the previous block to the runtime when asking it to construct inherents.This module provides an inherent data provider that does just this. Any Tuxedo runtime that uses inherents (At least ones that update environmental data), needs to include this foundational previous block inherent data provider so that the Tuxedo executive can scrape it to find the output references of the previous inherent transactions.
Transactions
Transactions in a blockchain are fundamental units of data that represent a transfer of value or the execution of a specific action within the blockchain network. Transactions are the building blocks of the blockchain and are used to record changes to the ledger in a secure and verifiable manner. Each transaction typically includes information about the sender, recipient, amount of value being transferred, and any additional data required for the specific action being performed.
Here are the key components of a transaction in a blockchain:
Once a transaction is created and signed, it needs to be validated and confirmed by the network's consensus mechanism. In proof-of-work blockchains like Bitcoin, miners compete to solve complex mathematical puzzles to add a new block of transactions to the blockchain. In proof-of-stake and other consensus mechanisms, validators take turns proposing and validating blocks.
Once a transaction is included in a validated block, it becomes a permanent part of the blockchain's history. Transactions collectively form a chronological record of all activities within the blockchain network, allowing participants to trace the flow of value and verify the integrity of the ledger.
It's important to note that different blockchain networks may have variations in the structure and details of transactions based on their specific features and use cases.
extrinsic
In the context of blockchain, particularly in Substrate-based blockchains like Polkadot, an "extrinsic" is a fundamental concept used to describe actions or transactions that originate from an external source and are submitted to the blockchain for processing. Extrinsic is a term specific to Substrate's framework, and it plays a significant role in how interactions are handled on the blockchain.
Here's a more detailed explanation:
Extrinsics are a crucial concept in Substrate-based blockchains as they enable the dynamic execution of actions by external entities. They provide a way for users and external systems to interact with the blockchain in a secure and controlled manner, while also ensuring that actions are verifiable and traceable on the blockchain's immutable ledger.
OriginFor<T>
领英推荐
In Substrate, there are different types of origins, such as:
Ex: Transfer of token from one account to another . We are using whether the transaction or extrinsic is signed or not .
#[pallet::weight(0)]
pub fn transfer(
? ? origin: OriginFor<T>,
? ? to: T::AccountId,
? ? unique_id: [u8; 16],
) -> DispatchResult {
? ? // Make sure the caller is from a signed origin
? ? let from = ensure_signed(origin)?;
? ? let token = TokenMap::<T>::get(&unique_id).ok_or(Error::<T>::NoToken)?;
? ? ensure!(token.owner == from, Error::<T>::NotOwner);
? ? Self::do_transfer(unique_id, to)?;
? ? Ok(())
}
Using the origin parameter allows your extrinsic functions to differentiate between different callers or sources of the transactions. This helps in applying access control, permissions, and determining how the operation should be treated based on who initiated it.
It is important to understand about some supporting libs used in implementing pallet:
The frame_system module provides the basic infrastructure for blockchain operations and state management, while the frame_support module offers a set of tools and abstractions that make it easier to create complex runtime modules. Both modules are foundational for building custom pallets and extending the functionality of a Substrate-based blockchain.
We will discuss them in detail in next articles, but let me give just overview of system pallets
Need to include them in the cargo.toml of pallet as below:
[dependencies]
frame-support = { default-features = false, version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0"}
frame-system = { default-features = false, version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v1.0.0" }
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive",]
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }}
[features]
default = ["std"]
std = [
? "frame-support/std",
? "frame-system/std",
? "codec/std",
? "scale-info/std",
]
codec and scale-info are modules that provide tools and abstractions for handling data serialization and deserialization. As you already know Serialization is the process of converting complex data structures into a format that can be easily stored, transmitted, or shared, while deserialization is the reverse process of reconstructing the original data from its serialized form. These modules are essential for efficient and consistent data management within Substrate-based blockchains.
How authorization, validation of transaction happens in substrate?
In Substrate, the process of validating and processing transactions involves several components working together. Let's break down the process step by step:
1. Transaction Pool:
2. Block Production and Consensus:
3. Block Finalization:
4. Local Database Update:
It's important to note that the exact details and configuration of these processes can vary based on the specific runtime configuration and consensus mechanisms chosen for the Substrate-based blockchain. The modular nature of Substrate allows developers to customize and configure these components according to their network's requirements.
Additionally, while validators play a significant role in block production and finality, it's not just validators that validate transactions. The network as a whole, including full nodes and potentially other specialized nodes, contributes to the validation process to ensure the security and correctness of the blockchain's operation.
Difference between extrinsics and inherent:
In the Substrate framework, both extrinsics and inherents are mechanisms for including information in blocks, but they serve different purposes and have different characteristics.
Extrinsics:
Definition: Extrinsics are transactions or operations submitted by users to the blockchain. They represent actions that users want to perform on the blockchain, such as transferring funds, invoking a smart contract, or any other state-changing operation.
Origin: Extrinsics typically originate from external users or entities interacting with the blockchain. They are submitted through the runtime via the transaction pool.
Inclusion: Extrinsics are included in blocks through the transaction inclusion process, where they are validated, executed, and their effects on the state are recorded.
Usage: Extrinsics are used for actions that need to be recorded in the blockchain's state and have a direct impact on the state transition.
Inherents:
Definition: Inherents are pieces of information that are inherent to the block itself and are not submitted by external users. They are included in the block header and represent contextual information about the block.
Origin: Inherents are usually generated by the block author (the entity producing the block) and are not directly submitted by external users. They provide context about the block, such as the timestamp, block number, or any other data relevant to the block as a whole.
Inclusion: Inherents are included in the block header during the block production process. They are not subject to the transaction pool or extrinsic validation.
Usage: Inherents are used for information that is shared across the entire block, providing context and metadata that is relevant to the entire block rather than to specific transactions.
Thanks for reading till end , will try to touch different topics in next articles.