From 8cc42555f87ebafad0519b0f42cdf015d09b1dde Mon Sep 17 00:00:00 2001 From: Bruno Galvao Date: Fri, 7 Nov 2025 12:30:44 +0700 Subject: [PATCH 1/4] add benchmark your pallet --- .ai/categories/parachains.md | 817 +- .ai/categories/smart-contracts.md | 154 + .ai/categories/tooling.md | 2 +- ...untime-add-smart-contract-functionality.md | 18 +- ...ime-pallet-development-benchmark-pallet.md | 811 +- ...time-pallet-development-create-a-pallet.md | 2 +- ...t-contracts-cookbook-dapps-zero-to-hero.md | 2 +- .../smart-contracts-for-eth-devs-migration.md | 148 +- .ai/site-index.json | 12302 +++++++--------- llms-full.jsonl | 121 +- llms.txt | 8 +- .../pallet-development/benchmark-pallet.md | 724 +- .../pallet-development/create-a-pallet.md | 2 +- 13 files changed, 7394 insertions(+), 7717 deletions(-) diff --git a/.ai/categories/parachains.md b/.ai/categories/parachains.md index 1bf9e54f8..9bad55195 100644 --- a/.ai/categories/parachains.md +++ b/.ai/categories/parachains.md @@ -1256,9 +1256,9 @@ Any language that can compile to PolkaVM bytecode and utilize `pallet-revive`'s ### Key Benefits -- **Unified Platform**: Deploys both PolkaVM-optimized and EVM-compatible contracts using a single pallet. +- **Unified platform**: Deploys both PolkaVM-optimized and EVM-compatible contracts using a single pallet. - **Performance**: PolkaVM execution provides improved performance compared to the traditional EVM, leveraging the [RISC-V](https://en.wikipedia.org/wiki/RISC-V){target=\_blank} architecture to map instructions to the CPU and requires little transpiling. -- **Ethereum Compatibility**: Supports full integration with Ethereum tooling via RPC adapter. +- **Ethereum compatibility**: Supports full integration with Ethereum tooling via RPC adapter. ### Implementation Examples @@ -1276,7 +1276,7 @@ Frontier offers flexible integration depending on your compatibility needs: For basic EVM support using Polkadot SDK native APIs: -- **[`pallet-evm`](https://github.com/polkadot-evm/frontier/tree/master/frame/evm){target=\_blank}**: Provides the core EVM execution environment +- **[`pallet-evm`](https://github.com/polkadot-evm/frontier/tree/master/frame/evm){target=\_blank}**: Provides the core EVM execution environment. This configuration allows EVM contract execution but requires using Polkadot SDK-specific APIs for interaction. @@ -1290,20 +1290,20 @@ For complete Ethereum ecosystem integration with Ethereum RPC support: ### Key Benefits -- **Ethereum tooling compatibility**: Full compatibility with MetaMask, Hardhat, Remix, Truffle, and other Ethereum development tools -- **Minimal-friction migration**: Deployment of existing Ethereum dApps with minimal or no modifications -- **Native Ethereum formats**: Support for Ethereum transaction formats, signatures, and gas mechanics -- **Block emulation**: Ethereum-style block structure within Substrate's block production +- **Ethereum tooling compatibility**: Full compatibility with MetaMask, Hardhat, Remix, Foundry, and other Ethereum development tools. +- **Minimal-friction migration**: Deployment of existing Ethereum dApps with minimal or no modifications. +- **Native Ethereum formats**: Support for Ethereum transaction formats, signatures, and gas mechanics. +- **Block emulation**: Ethereum-style block structure within Substrate's block production. ### Implementation Examples Production implementations demonstrate Frontier's capabilities: -- **Moonbeam**: See their implementation of [`pallet-evm`](https://github.com/moonbeam-foundation/moonbeam/blob/9e2ddbc9ae8bf65f11701e7ccde50075e5fe2790/runtime/moonbeam/src/lib.rs#L532){target=\_blank} and [`pallet-ethereum`](https://github.com/moonbeam-foundation/moonbeam/blob/9e2ddbc9ae8bf65f11701e7ccde50075e5fe2790/runtime/moonbeam/src/lib.rs#L698){target=\_blank} +- **Moonbeam**: See their implementation of [`pallet-evm`](https://github.com/moonbeam-foundation/moonbeam/blob/9e2ddbc9ae8bf65f11701e7ccde50075e5fe2790/runtime/moonbeam/src/lib.rs#L532){target=\_blank} and [`pallet-ethereum`](https://github.com/moonbeam-foundation/moonbeam/blob/9e2ddbc9ae8bf65f11701e7ccde50075e5fe2790/runtime/moonbeam/src/lib.rs#L698){target=\_blank}. ## pallet-contracts (Legacy) -[`pallet-contracts`](https://docs.rs/pallet-contracts/latest/pallet_contracts/index.html#contracts-pallet){target=\_blank} is the original Wasm-based smart contract pallet for Polkadot SDK chains. While still functional, it's considered legacy as development efforts have shifted to pallet-revive. +[`pallet-contracts`](https://docs.rs/pallet-contracts/latest/pallet_contracts/index.html#contracts-pallet){target=\_blank} is the original Wasm-based smart contract pallet for Polkadot SDK chains. While still functional, it's considered legacy as development efforts have shifted to `pallet-revive`. ### Implementation Example @@ -1326,310 +1326,687 @@ For reference, Astar's implementation of [`pallet-contracts`](https://github.com --- -Page Title: Benchmarking FRAME Pallets +Page Title: Benchmark Your Pallet - Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md - Canonical (HTML): https://docs.polkadot.com/parachains/customize-runtime/pallet-development/benchmark-pallet/ -- Summary: Learn how to use FRAME's benchmarking framework to measure extrinsic execution costs and provide accurate weights for on-chain computations. - -# Benchmarking +- Summary: Learn how to benchmark your custom pallet extrinsics to generate accurate weight calculations for production use. ## Introduction -Benchmarking is a critical component of developing efficient and secure blockchain runtimes. In the Polkadot ecosystem, accurately benchmarking your custom pallets ensures that each extrinsic has a precise [weight](/reference/glossary/#weight){target=\_blank}, representing its computational and storage demands. This process is vital for maintaining the blockchain's performance and preventing potential vulnerabilities, such as Denial of Service (DoS) attacks. +Benchmarking is the process of measuring the computational resources (execution time and storage) required by your pallet's extrinsics. Accurate [weight](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/index.html){target=\_blank} calculations are essential for ensuring your blockchain can process transactions efficiently while protecting against denial-of-service attacks. -The Polkadot SDK leverages the [FRAME](/reference/glossary/#frame-framework-for-runtime-aggregation-of-modularized-entities){target=\_blank} benchmarking framework, offering tools to measure and assign weights to extrinsics. These weights help determine the maximum number of transactions or system-level calls processed within a block. This guide covers how to use FRAME's [benchmarking framework](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank}, from setting up your environment to writing and running benchmarks for your custom pallets. You'll understand how to generate accurate weights by the end, ensuring your runtime remains performant and secure. +This guide continues the pallet development series, building on the [Create a Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet), [Mock Your Runtime](/parachains/customize-runtime/pallet-development/mock-runtime), and [Test Your Pallet](/parachains/customize-runtime/pallet-development/pallet-testing) tutorials. You'll learn how to benchmark the counter pallet extrinsics and integrate the generated weights into your runtime. -## The Case for Benchmarking +## Prerequisites -Benchmarking helps validate that the required execution time for different functions is within reasonable boundaries to ensure your blockchain runtime can handle transactions efficiently and securely. By accurately measuring the weight of each extrinsic, you can prevent service interruptions caused by computationally intensive calls that exceed block time limits. Without benchmarking, runtime performance could be vulnerable to DoS attacks, where malicious users exploit functions with unoptimized weights. +Before you begin, ensure you have: -Benchmarking also ensures predictable transaction fees. Weights derived from benchmark tests accurately reflect the resource usage of function calls, allowing fair fee calculation. This approach discourages abuse while maintaining network reliability. +- Completed the previous pallet development tutorials +- Basic understanding of computational complexity +- Familiarity with Rust's testing framework -### Benchmarking and Weight +## Why Benchmark? -In Polkadot SDK-based chains, weight quantifies the computational effort needed to process transactions. This weight includes factors such as: +In blockchain systems, every operation consumes resources. Weight is the mechanism Polkadot SDK uses to measure and limit resource consumption. Without accurate weights: -- Computational complexity. -- Storage complexity (proof size). -- Database reads and writes. -- Hardware specifications. +- **Security Risk**: Malicious actors could submit transactions that consume excessive resources, blocking legitimate transactions or halting the chain +- **Inefficiency**: Over-estimated weights waste block space and reduce throughput +- **User Experience**: Inaccurate weights lead to incorrect fee calculations -Benchmarking uses real-world testing to simulate worst-case scenarios for extrinsics. The framework generates a linear model for weight calculation by running multiple iterations with varied parameters. These worst-case weights ensure blocks remain within execution limits, enabling the runtime to maintain throughput under varying loads. Excess fees can be refunded if a call uses fewer resources than expected, offering users a fair cost model. - -Because weight is a generic unit of measurement based on computation time for a specific physical machine, the weight of any function can change based on the specifications of hardware used for benchmarking. By modeling the expected weight of each runtime function, the blockchain can calculate the number of transactions or system-level calls it can execute within a certain period. +Benchmarking provides empirical measurements of your extrinsics under various conditions, ensuring weights reflect real-world resource consumption. + +## Understanding Weights + +The [weight system](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html){target=\_blank} serves multiple purposes: + +- **DoS Protection**: Limits the computational work per block, preventing attackers from overwhelming the network +- **Fee Calculation**: Determines transaction fees based on actual resource usage +- **Block Production**: Helps block authors maximize throughput while staying within block limits + +Weights are expressed as [`Weight::from_parts(ref_time, proof_size)`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.from_parts){target=\_blank} where: + +- [`ref_time`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.ref_time){target=\_blank}: Computational time measured in picoseconds +- [`proof_size`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.proof_size){target=\_blank}: Storage proof size in bytes + +## Step 1: Create the Benchmarking Module + +Create a new file `benchmarking.rs` in your pallet's `src` directory. This module will contain all the [benchmarking definitions](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank} for your pallet: + +```rust title="pallets/pallet-custom/src/benchmarking.rs" +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use frame::deps::frame_benchmarking::v2::*; +use frame::benchmarking::prelude::RawOrigin; + +#[benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn set_counter_value() { + let new_value: u32 = 100; + + #[extrinsic_call] + _(RawOrigin::Root, new_value); + + assert_eq!(CounterValue::::get(), new_value); + } + + #[benchmark] + fn increment() { + let caller: T::AccountId = whitelisted_caller(); + let amount: u32 = 50; + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), amount); + + assert_eq!(CounterValue::::get(), amount); + assert_eq!(UserInteractions::::get(caller), 1); + } + + #[benchmark] + fn decrement() { + // First set the counter to a non-zero value + CounterValue::::put(100); + + let caller: T::AccountId = whitelisted_caller(); + let amount: u32 = 30; -Within FRAME, each function call that is dispatched must have a `#[pallet::weight]` annotation that can return the expected weight for the worst-case scenario execution of that function given its inputs: + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), amount); + + assert_eq!(CounterValue::::get(), 70); + assert_eq!(UserInteractions::::get(caller), 1); + } -```rust hl_lines="2" -#[pallet::call_index(0)] -#[pallet::weight(T::WeightInfo::do_something())] -pub fn do_something(origin: OriginFor) -> DispatchResultWithPostInfo { Ok(()) } + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); +} ``` -The `WeightInfo` file is automatically generated during benchmarking. Based on these tests, this file provides accurate weights for each extrinsic. +**Key components:** + +- **`#![cfg(feature = "runtime-benchmarks")]`**: Ensures benchmarking code only compiles when the feature is enabled +- **[`#[benchmarks]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmarks.html){target=\_blank}**: Marks the module containing benchmark definitions +- **[`#[benchmark]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmark.html){target=\_blank}**: Defines individual benchmark functions +- **[`#[extrinsic_call]`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.extrinsic_call.html){target=\_blank}**: Marks the actual extrinsic invocation to measure +- **[`whitelisted_caller()`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/fn.whitelisted_caller.html){target=\_blank}**: Generates a funded account for benchmarking +- **[`impl_benchmark_test_suite!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.impl_benchmark_test_suite.html){target=\_blank}**: Generates test functions to verify benchmarks work correctly -## Benchmarking Process +## Step 2: Define the Weight Trait -Benchmarking a pallet involves the following steps: +The [`WeightInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/trait.WeightInfo.html){target=\_blank} trait provides an abstraction layer that allows weights to be swapped at runtime configuration. This enables you to use placeholder weights during development and testing, then switch to auto-generated benchmarked weights in production without modifying the pallet code itself. -1. Creating a `benchmarking.rs` file within your pallet's structure. -2. Writing a benchmarking test for each extrinsic. -3. Executing the benchmarking tool to calculate weights based on performance metrics. +Add a `weights` module to your pallet that defines the `WeightInfo` trait: -The benchmarking tool runs multiple iterations to model worst-case execution times and determine the appropriate weight. By default, the benchmarking pipeline is deactivated. To activate it, compile your runtime with the `runtime-benchmarks` feature flag. +```rust title="pallets/pallet-custom/src/lib.rs" +#[frame::pallet] +pub mod pallet { + use frame::prelude::*; + pub use weights::WeightInfo; -### Prepare Your Environment + pub mod weights { + use frame::prelude::*; -Install the [`frame-omni-bencher`](https://crates.io/crates/frame-omni-bencher){target=\_blank} command-line tool: + pub trait WeightInfo { + fn set_counter_value() -> Weight; + fn increment() -> Weight; + fn decrement() -> Weight; + } -```bash -cargo install frame-omni-bencher + impl WeightInfo for () { + fn set_counter_value() -> Weight { + Weight::from_parts(10_000, 0) + } + fn increment() -> Weight { + Weight::from_parts(15_000, 0) + } + fn decrement() -> Weight { + Weight::from_parts(15_000, 0) + } + } + } + + // ... rest of pallet +} ``` -Before writing benchmark tests, you need to ensure the `frame-benchmarking` crate is included in your pallet's `Cargo.toml` similar to the following: +The `()` implementation provides placeholder weights for development. Later, this will be replaced with auto-generated weights from benchmarking. + +## Step 3: Add WeightInfo to Config + +By making `WeightInfo` an associated type in the `Config` trait, you allow each runtime that uses your pallet to specify which weight implementation to use. Different deployment environments (testnets, production chains, or different hardware configurations) may have different performance characteristics and can use different weight calculations. -```toml title="Cargo.toml" -frame-benchmarking = { version = "37.0.0", default-features = false } +Update your pallet's `Config` trait to include `WeightInfo`: + +```rust title="pallets/pallet-custom/src/lib.rs" +#[pallet::config] +pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + #[pallet::constant] + type CounterMaxValue: Get; + + type WeightInfo: weights::WeightInfo; +} ``` -You must also ensure that you add the `runtime-benchmarks` feature flag as follows under the `[features]` section of your pallet's `Cargo.toml`: +## Step 4: Update Extrinsic Weight Annotations -```toml title="Cargo.toml" -runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] +By calling `T::WeightInfo::function_name()` instead of using hardcoded `Weight::from_parts()` values, your extrinsics automatically use whichever weight implementation is configured in the runtime. This allows you to easily switch between placeholder weights for testing and benchmarked weights for production without changing any pallet code. + +Replace the placeholder weights in your extrinsics with calls to the `WeightInfo` trait: + +```rust title="pallets/pallet-custom/src/lib.rs" +#[pallet::call] +impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::set_counter_value())] + pub fn set_counter_value(origin: OriginFor, new_value: u32) -> DispatchResult { + // ... implementation + } + + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::increment())] + pub fn increment(origin: OriginFor, amount: u32) -> DispatchResult { + // ... implementation + } + + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::decrement())] + pub fn decrement(origin: OriginFor, amount: u32) -> DispatchResult { + // ... implementation + } +} +``` + +## Step 5: Include the Benchmarking Module + +The `#[cfg(feature = "runtime-benchmarks")]` attribute ensures that benchmarking code is only compiled when explicitly needed. This keeps your production runtime lean by excluding benchmarking infrastructure from normal builds, as it's only needed when generating weights. + +At the top of your `lib.rs`, add the module declaration: + +```rust title="pallets/pallet-custom/src/lib.rs" +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; +use alloc::vec::Vec; + +pub use pallet::*; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +// ... rest of the pallet ``` -Lastly, ensure that `frame-benchmarking` is included in `std = []`: +## Step 6: Configure Pallet Dependencies + +The feature flag system in Cargo allows you to conditionally compile code based on which features are enabled. By defining a `runtime-benchmarks` feature that cascades to FRAME's benchmarking features, you create a clean way to build your pallet with or without benchmarking support, ensuring all necessary dependencies are available when needed but excluded from production builds. + +Update your pallet's `Cargo.toml` to enable the benchmarking feature: -```toml title="Cargo.toml" +```toml title="pallets/pallet-custom/Cargo.toml" +[dependencies] +codec = { features = ["derive"], workspace = true } +scale-info = { features = ["derive"], workspace = true } +frame = { features = ["experimental", "runtime"], workspace = true } + +[features] +default = ["std"] +runtime-benchmarks = [ + "frame/runtime-benchmarks", +] std = [ - # ... - "frame-benchmarking?/std", - # ... + "codec/std", + "scale-info/std", + "frame/std", ] ``` -Once complete, you have the required dependencies for writing benchmark tests for your pallet. +## Step 7: Update Mock Runtime -### Write Benchmark Tests +In your mock runtime for testing, use the placeholder `()` implementation of `WeightInfo` since unit tests focus on verifying functional correctness rather than performance characteristics. This keeps tests fast and focused on validating logic. -Create a `benchmarking.rs` file in your pallet's `src/`. Your directory structure should look similar to the following: +Add the `WeightInfo` type to your test configuration in `mock.rs`: +```rust title="pallets/pallet-custom/src/mock.rs" +impl pallet_custom::Config for Test { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = (); +} ``` -my-pallet/ -├── src/ -│ ├── lib.rs # Main pallet implementation -│ └── benchmarking.rs # Benchmarking -└── Cargo.toml + +## Step 8: Configure Runtime Benchmarking + +To execute benchmarks, your pallet must be integrated into the runtime's benchmarking infrastructure. This involves three configuration steps: + +### Update Runtime Cargo.toml + +When you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included. + +Add your pallet to the runtime's `runtime-benchmarks` feature in `runtime/Cargo.toml`: + +```toml title="runtime/Cargo.toml" +runtime-benchmarks = [ + "cumulus-pallet-parachain-system/runtime-benchmarks", + "hex-literal", + "pallet-parachain-template/runtime-benchmarks", + "polkadot-sdk/runtime-benchmarks", + "pallet-custom/runtime-benchmarks", +] ``` -With the directory structure set, you can use the [`polkadot-sdk-parachain-template`](https://github.com/paritytech/polkadot-sdk-parachain-template/tree/master/pallets){target=\_blank} to get started as follows: +### Update Runtime Configuration -```rust title="benchmarking.rs (starter template)" -//! Benchmarking setup for pallet-template -#![cfg(feature = "runtime-benchmarks")] +Start with the placeholder implementation during development. After successfully running benchmarks and generating the weights file, you'll update this to use the benchmarked weights. -use super::*; -use frame_benchmarking::v2::*; +In `runtime/src/configs/mod.rs`, add the `WeightInfo` type: -#[benchmarks] -mod benchmarks { - use super::*; - #[cfg(test)] - use crate::pallet::Pallet as Template; - use frame_system::RawOrigin; - - #[benchmark] - fn do_something() { - let caller: T::AccountId = whitelisted_caller(); - #[extrinsic_call] - do_something(RawOrigin::Signed(caller), 100); - - assert_eq!(Something::::get().map(|v| v.block_number), Some(100u32.into())); - } - - #[benchmark] - fn cause_error() { - Something::::put(CompositeStruct { block_number: 100u32.into() }); - let caller: T::AccountId = whitelisted_caller(); - #[extrinsic_call] - cause_error(RawOrigin::Signed(caller)); - - assert_eq!(Something::::get().map(|v| v.block_number), Some(101u32.into())); - } - - impl_benchmark_test_suite!(Template, crate::mock::new_test_ext(), crate::mock::Test); +```rust title="runtime/src/configs/mod.rs" +impl pallet_custom::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = (); } ``` -In your benchmarking tests, employ these best practices: +### Register Benchmarks -- **Write custom testing functions**: The function `do_something` in the preceding example is a placeholder. Similar to writing unit tests, you must write custom functions to benchmark test your extrinsics. Access the mock runtime and use functions such as `whitelisted_caller()` to sign transactions and facilitate testing. -- **Use the `#[extrinsic_call]` macro**: This macro is used when calling the extrinsic itself and is a required part of a benchmarking function. See the [`extrinsic_call`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html#extrinsic_call-and-block){target=\_blank} docs for more details. -- **Validate extrinsic behavior**: The `assert_eq` expression ensures that the extrinsic is working properly within the benchmark context. +The `define_benchmarks!` macro creates the infrastructure that allows the benchmarking CLI tool to discover and execute your pallet's benchmarks. -Add the `benchmarking` module to your pallet. In the pallet `lib.rs` file add the following: +Add your pallet to the benchmark list in `runtime/src/benchmarks.rs`: -```rust -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; +```rust title="runtime/src/benchmarks.rs" +polkadot_sdk::frame_benchmarking::define_benchmarks!( + [frame_system, SystemBench::] + [pallet_balances, Balances] + // ... other pallets + [pallet_custom, CustomPallet] +); ``` -### Add Benchmarks to Runtime +## Step 9: Run Benchmarks -Before running the benchmarking tool, you must integrate benchmarks with your runtime as follows: +### Test Benchmark Compilation -1. Navigate to your `runtime/src` directory and check if a `benchmarks.rs` file exists. If not, create one. This file will contain the macro that registers all pallets for benchmarking along with their respective configurations: +The `impl_benchmark_test_suite!` macro generates unit tests for each benchmark. Running these tests verifies that your benchmarks compile correctly, execute without panicking, and pass their assertions, catching issues early before building the full runtime. - ```rust title="benchmarks.rs" - frame_benchmarking::define_benchmarks!( - [frame_system, SystemBench::] - [pallet_parachain_template, TemplatePallet] - [pallet_balances, Balances] - [pallet_session, SessionBench::] - [pallet_timestamp, Timestamp] - [pallet_message_queue, MessageQueue] - [pallet_sudo, Sudo] - [pallet_collator_selection, CollatorSelection] - [cumulus_pallet_parachain_system, ParachainSystem] - [cumulus_pallet_xcmp_queue, XcmpQueue] - ); - ``` +First, verify your benchmarks compile and run as tests: - For example, to add a new pallet named `pallet_parachain_template` for benchmarking, include it in the macro as shown: - ```rust title="benchmarks.rs" hl_lines="3" - frame_benchmarking::define_benchmarks!( - [frame_system, SystemBench::] - [pallet_parachain_template, TemplatePallet] - ); - ``` +```bash +cargo test -p pallet-custom --features runtime-benchmarks +``` - !!!warning "Updating `define_benchmarks!` macro is required" - Any pallet that needs to be benchmarked must be included in the [`define_benchmarks!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.define_benchmarks.html){target=\_blank} macro. The CLI will only be able to access and benchmark pallets that are registered here. +You should see your benchmark tests passing: -2. Check your runtime's `lib.rs` file to ensure the `benchmarks` module is imported. The import should look like this: +``` +test benchmarking::benchmarks::bench_set_counter_value ... ok +test benchmarking::benchmarks::bench_increment ... ok +test benchmarking::benchmarks::bench_decrement ... ok +``` - ```rust title="lib.rs" - #[cfg(feature = "runtime-benchmarks")] - mod benchmarks; - ``` +### Build the Runtime with Benchmarks - The `runtime-benchmarks` feature gate ensures benchmark tests are isolated from production runtime code. +This build includes all the benchmarking infrastructure and special host functions needed for measurement. The resulting WASM runtime contains your benchmark code and can communicate with the benchmarking tool's execution environment. This is a special build used only for benchmarking - you'll create a different build later for actually running your chain. -3. Enable runtime benchmarking for your pallet in `runtime/Cargo.toml`: +Compile the runtime with benchmarking enabled to generate the WASM binary: - ```toml - runtime-benchmarks = [ - # ... - "pallet_parachain_template/runtime-benchmarks", - ] +```bash +cargo build --release --features runtime-benchmarks +``` - ``` +This produces the runtime WASM file needed for benchmarking, typically located at: +``` +target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm +``` -### Run Benchmarks +### Install the Benchmarking Tool -You can now compile your runtime with the `runtime-benchmarks` feature flag. This feature flag is crucial as the benchmarking tool will look for this feature being enabled to know when it should run benchmark tests. Follow these steps to compile the runtime with benchmarking enabled: +[`frame-omni-bencher`](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} is the official Polkadot SDK tool specifically designed for FRAME pallet benchmarking. It provides a standardized way to execute benchmarks, measure execution times and storage operations, and generate properly formatted weight files with full integration into the FRAME weight system. -1. Run `build` with the feature flag included: +Install the `frame-omni-bencher` CLI tool: - ```bash - cargo build --features runtime-benchmarks --release - ``` +```bash +cargo install frame-omni-bencher --locked +``` -2. Create a `weights.rs` file in your pallet's `src/` directory. This file will store the auto-generated weight calculations: +### Download the Weight Template - ```bash - touch weights.rs - ``` +The weight template is a Handlebars file that transforms raw benchmark data into a properly formatted Rust source file. It defines the structure of the generated `weights.rs` file, including imports, trait definitions, documentation comments, and formatting. Using the official template ensures your weight files follow Polkadot SDK conventions and include all necessary metadata like benchmark execution parameters, storage operation counts, and hardware information. -3. Before running the benchmarking tool, you'll need a template file that defines how weight information should be formatted. Download the official template from the Polkadot SDK repository and save it in your project folders for future use: +Download the official weight template file: - ```bash - curl https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \ - --output ./pallets/benchmarking/frame-weight-template.hbs - ``` +```bash +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \ +--output ./pallets/pallet-custom/frame-weight-template.hbs +``` -4. Run the benchmarking tool to measure extrinsic weights: +### Hardware Requirements for Benchmarking - ```bash - frame-omni-bencher v1 benchmark pallet \ - --runtime INSERT_PATH_TO_WASM_RUNTIME \ - --pallet INSERT_NAME_OF_PALLET \ +!!! warning "Critical: Benchmark on Production-Like Hardware" + Benchmarks must be executed on hardware similar to what will run your chain in production. Weight measurements are hardware-dependent, and benchmarking on different hardware can lead to dangerous under-estimation or wasteful over-estimation of weights. + +Weights represent the actual computational time and resources consumed by extrinsics. These measurements vary significantly across different hardware configurations: + +- **CPU Performance**: Different processors execute instructions at different speeds. A faster development laptop will produce lower weight values than production server hardware +- **Storage Speed**: Database read/write performance varies between NVMe SSDs, SATA SSDs, and HDDs, affecting storage-related weights +- **Memory Bandwidth**: RAM speed impacts how quickly data can be accessed during execution +- **CPU Cache**: Cache size and architecture differences affect repeated operations + +Benchmarking on faster hardware than production leads to under-estimated weights - attackers could submit extrinsics that consume more resources than the weights suggest, potentially causing blocks to take longer than expected to produce or even halting the chain. Conversely, benchmarking on slower hardware creates over-estimated weights, resulting in unnecessarily high transaction fees and wasted block capacity. + +**Best practices:** + +1. **Match production specifications**: If your chain will run on specific validator hardware, benchmark on identical or very similar machines +2. **Use reference hardware**: The Polkadot ecosystem often uses standardized reference hardware specifications for consistency. Consider following these standards if your chain will connect to Polkadot or Kusama +3. **Dedicated benchmarking environment**: Run benchmarks on a machine without other heavy processes to ensure consistent measurements +4. **Document your hardware**: The generated weight files include hardware information in comments. Review this to ensure it matches your production environment +5. **Re-benchmark when hardware changes**: If your validator hardware specifications change, re-run benchmarks and update weights + +For development and testing purposes, you can run benchmarks on any available hardware to verify that your benchmark functions work correctly. However, before deploying to production, always re-run benchmarks on production-equivalent hardware. + +### Execute Benchmarks + +Benchmarks execute against the compiled WASM runtime rather than native code because WASM is what actually runs in production on the blockchain. WASM execution can have different performance characteristics than native code due to compilation and sandboxing overhead, so benchmarking the WASM ensures your weight measurements reflect real-world conditions. + +Run benchmarks for your pallet to generate weight files: + +```bash +frame-omni-bencher v1 benchmark pallet \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ + --pallet pallet_custom \ --extrinsic "" \ - --template ./frame-weight-template.hbs \ - --output weights.rs - ``` + --template ./pallets/pallet-custom/frame-weight-template.hbs \ + --output ./pallets/pallet-custom/src/weights.rs +``` - !!! tip "Flag definitions" - - **`--runtime`**: The path to your runtime's Wasm. - - **`--pallet`**: The name of the pallet you wish to benchmark. This pallet must be configured in your runtime and defined in `define_benchmarks`. - - **`--extrinsic`**: Which extrinsic to test. Using `""` implies all extrinsics will be benchmarked. - - **`--template`**: Defines how weight information should be formatted. - - **`--output`**: Where the output of the auto-generated weights will reside. +**Command breakdown:** -The generated `weights.rs` file contains weight annotations for your extrinsics, ready to be added to your pallet. The output should be similar to the following. Some output is omitted for brevity: +- `v1`: Specifies the benchmarking framework version (v2 API) +- `benchmark pallet`: Subcommand indicating you want to benchmark pallet extrinsics +- `--runtime`: Path to the compiled WASM runtime file that includes your pallet and benchmarks +- `--pallet pallet_custom`: Name of the pallet to benchmark (must match the name used in `define_benchmarks!`) +- `--extrinsic ""`: Empty string benchmarks all extrinsics in the pallet; you can specify a single extrinsic name to benchmark only that one +- `--template`: Path to the Handlebars template that formats the output +- `--output`: Destination file path for the generated weights module -
- frame-omni-bencher v1 benchmark pallet \ - --runtime INSERT_PATH_TO_WASM_RUNTIME \ - --pallet "INSERT_NAME_OF_PALLET" \ - --extrinsic "" \ - --template ./frame-weight-template.hbs \ - --output ./weights.rs - ... - 2025-01-15T16:41:33.557045Z INFO polkadot_sdk_frame::benchmark::pallet: [ 0 % ] Starting benchmark: pallet_parachain_template::do_something - 2025-01-15T16:41:33.564644Z INFO polkadot_sdk_frame::benchmark::pallet: [ 50 % ] Starting benchmark: pallet_parachain_template::cause_error - ... - Created file: "weights.rs" - -
+### Advanced Options + +You can customize benchmark execution with additional parameters for more detailed measurements: + +```bash +frame-omni-bencher v1 benchmark pallet \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ + --pallet pallet_custom \ + --extrinsic "" \ + --steps 50 \ + --repeat 20 \ + --template ./pallets/pallet-custom/frame-weight-template.hbs \ + --output ./pallets/pallet-custom/src/weights.rs +``` -#### Add Benchmark Weights to Pallet +**Additional parameters:** -Once the `weights.rs` is generated, you must integrate it with your pallet. +- `--steps 50`: Number of different input values to test when using linear components (default: 50). More steps provide finer granularity for detecting complexity trends but increase benchmarking time +- `--repeat 20`: Number of repetitions for each measurement (default: 20). More repetitions improve statistical accuracy by averaging out variance, reducing the impact of system noise and providing more reliable weight estimates +- `--heap-pages 4096`: WASM heap pages allocation. Affects available memory during execution +- `--wasm-execution compiled`: WASM execution method. Use `compiled` for performance closest to production conditions -1. To begin the integration, import the `weights` module and the `WeightInfo` trait, then add both to your pallet's `Config` trait. Complete the following steps to set up the configuration: +## Step 10: Use Generated Weights - ```rust title="lib.rs" - pub mod weights; +After running benchmarks, a `weights.rs` file is generated containing measured weights. The generated weights are based on actual measurements of your code running on real hardware, accounting for the specific complexity of your logic, storage access patterns, and computational requirements. Estimates or placeholder values cannot capture these nuances and will either waste block space (over-estimation) or create security risks (under-estimation). + +The file includes: + +- Detailed documentation about the benchmark execution environment (date, hardware, parameters) +- The `WeightInfo` trait definition matching your benchmark functions +- `SubstrateWeight` implementation with measured weights from your benchmarks +- Database read/write costs calculated based on observed storage operations +- Component complexity annotations for variable inputs (if you use linear components) +- A fallback `()` implementation for testing environments + +### Integrate the Generated Weights + +Unlike the benchmarking module (which is only needed when running benchmarks), the weights module must be available in all builds because the runtime needs to call the weight functions during normal operation to calculate transaction fees and enforce block limits. + +Add the weights module to your pallet's `lib.rs`: + +```rust title="pallets/pallet-custom/src/lib.rs" +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; +use alloc::vec::Vec; + +pub use pallet::*; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +pub mod weights; + +#[frame::pallet] +pub mod pallet { + use super::*; + use frame::prelude::*; use crate::weights::WeightInfo; + // ... rest of pallet +} +``` - /// Configure the pallet by specifying the parameters and types on which it depends. - #[pallet::config] - pub trait Config: frame_system::Config { - // ... - /// A type representing the weights required by the dispatchables of this pallet. - type WeightInfo: WeightInfo; +### Update Runtime Configuration + +This change activates your benchmarked weights in the production runtime. Now when users submit transactions that call your pallet's extrinsics, the runtime will use the actual measured weights to calculate fees and enforce block limits. + +Update your runtime configuration to use the generated weights instead of the placeholder `()` implementation: + +```rust title="runtime/src/configs/mod.rs" +impl pallet_custom::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = pallet_custom::weights::SubstrateWeight; +} +``` + +### Example Generated Weight File + +The generated `weights.rs` file will look similar to this: + +```rust title="pallets/pallet-custom/src/weights.rs" +//! Autogenerated weights for `pallet_custom` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20` + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +pub trait WeightInfo { + fn set_counter_value() -> Weight; + fn increment() -> Weight; + fn decrement() -> Weight; +} + +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn set_counter_value() -> Weight { + Weight::from_parts(8_234_000, 0) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) } - ``` -2. Next, you must add this to the `#[pallet::weight]` annotation in all the extrinsics via the `Config` as follows: + fn increment() -> Weight { + Weight::from_parts(12_456_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } - ```rust hl_lines="2" title="lib.rs" - #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::do_something())] - pub fn do_something(origin: OriginFor) -> DispatchResultWithPostInfo { Ok(()) } - ``` + fn decrement() -> Weight { + Weight::from_parts(11_987_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} +``` -3. Finally, configure the actual weight values in your runtime. In `runtime/src/config/mod.rs`, add the following code: +**Note**: The actual numbers will vary based on your hardware and implementation complexity. The [`DbWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.RuntimeDbWeight.html){target=\_blank} accounts for database read and write operations. - ```rust title="mod.rs" - // Configure pallet. - impl pallet_parachain_template::Config for Runtime { - // ... - type WeightInfo = pallet_parachain_template::weights::SubstrateWeight; +## Benchmarking Best Practices + +### 1. Test Worst-Case Scenarios + +Benchmarks should always measure maximum possible resource consumption. If you benchmark average or best-case scenarios, malicious users could craft transactions that hit worst-case paths in your code, consuming more resources than the weights indicate and potentially slowing down or halting block production. + +```rust +#[benchmark] +fn complex_operation() { + // Set up worst-case storage state + for i in 0..100 { + SomeStorage::::insert(i, vec![0u8; 1000]); } - ``` -## Where to Go Next + let caller = whitelisted_caller(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller)); +} +``` + +### 2. Use Linear Components for Variable Complexity + +Many extrinsics have variable costs depending on input parameters. [Linear components](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/trait.BenchmarkingSetup.html){target=\_blank} tell the benchmarking framework to test your extrinsic with different values of `n`, measure the execution time for each, and calculate a formula like `Weight = base_weight + (n * per_item_weight)`. This produces dynamic weights that accurately reflect the actual work being done. + +When extrinsic complexity depends on input size, use linear components: + +```rust title="pallets/pallet-custom/src/benchmarking.rs" +#[benchmark] +fn process_items(n: Linear<0, 100>) { + let caller = whitelisted_caller(); + let items: Vec = (0..n).collect(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), items); +} +``` + +### 3. Verify Results + +Assertions ensure that your benchmark is actually testing the code path you think it's testing. If your extrinsic fails silently or takes an early return, the benchmark would measure the wrong scenario and produce inaccurate weights. + +Always assert the expected state after extrinsic execution: + +```rust title="pallets/pallet-custom/src/benchmarking.rs" +#[benchmark] +fn my_extrinsic() { + let caller = whitelisted_caller(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone())); + + // Verify the extrinsic had the expected effect + assert_eq!(MyStorage::::get(&caller), expected_value); +} +``` + +### 4. Minimize Setup Code + +While the benchmarking framework tries to isolate the extrinsic execution, excessive setup code can add noise to measurements. More importantly, setup code that doesn't reflect real-world pre-conditions can lead to benchmarking unrealistic scenarios. + +Only include necessary setup in benchmarks: + +```rust title="pallets/pallet-custom/src/benchmarking.rs" +#[benchmark] +fn efficient_benchmark() { + // Minimal setup + let caller = whitelisted_caller(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller)); + + // Minimal assertions +} +``` + +## Run Your Chain Locally + +Now that you've added the pallet to your runtime, you can launch your parachain locally to test the new functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}. For instructions on setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\_blank}, refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\_blank} guide. + +### Build the Production Runtime + +The `runtime-benchmarks` feature flag adds special host functions (like `ext_benchmarking_current_time` and `ext_benchmarking_get_read_and_written_keys`) that are only available in the benchmarking execution environment. These functions allow the benchmarking framework to precisely measure execution time and track storage operations. However, regular nodes don't provide these host functions, so a runtime compiled with benchmarking features will fail to start on a production node. + +Before running your chain, rebuild the runtime **without** the `runtime-benchmarks` feature: + +```bash +cargo build --release +``` + +!!! note "Build Types" + Understanding the difference between builds is critical: + + - `cargo build --release --features runtime-benchmarks` - Compiles with benchmarking host functions for measurement. Use this ONLY when running benchmarks with `frame-omni-bencher` + - `cargo build --release` - Compiles production runtime without benchmarking features. Use this for running your actual chain + +This produces a production-ready WASM runtime at `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm`. + +### Generate a Chain Specification + +The chain specification defines the initial state and configuration of your blockchain, including the runtime WASM code, genesis storage, and network parameters. By generating a new chain spec with your updated runtime (now containing your benchmarked pallet), you ensure that nodes starting from this spec will use the correct version of your code with proper weight calculations. + +Create a new chain specification file with the updated runtime: + +```bash +chain-spec-builder create -t development \ +--relay-chain paseo \ +--para-id 1000 \ +--runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ +named-preset development +``` + +This command generates a chain specification file, `chain_spec.json`, for your parachain with the updated runtime. + +### Start the Parachain Node + +Launch the parachain using the Polkadot Omni Node with the generated chain specification by running the following command: + +```bash +polkadot-omni-node --chain ./chain_spec.json --dev +``` + +The node will start and display initialization information including: + +- The chain specification name +- The node identity and peer ID +- Database location +- Network endpoints (JSON-RPC and Prometheus) + +### Verify Block Production + +Once the node is running, you should see log messages indicating successful block production: + +``` +[Parachain] 🔨 Initializing Genesis block/state (state: 0x47ce…ec8d, header-hash: 0xeb12…fecc) +[Parachain] 🎁 Prepared block for proposing at 1 (3 ms) ... +[Parachain] 🏆 Imported #1 (0xeb12…fecc → 0xee51…98d2) +[Parachain] 🎁 Prepared block for proposing at 2 (3 ms) ... +[Parachain] 🏆 Imported #2 (0xee51…98d2 → 0x35e0…cc32) +``` + +The parachain will produce new blocks every few seconds. You can now interact with your pallet's extrinsics through the JSON-RPC endpoint at `http://127.0.0.1:9944` using tools like [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\_blank}. + +## Related Resources -- View the Rust Docs for a more comprehensive, low-level view of the [FRAME V2 Benchmarking Suite](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=_blank}. -- Read the [FRAME Benchmarking and Weights](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_benchmarking_weight/index.html){target=_blank} reference document, a concise guide which details how weights and benchmarking work. +- [FRAME Benchmarking Documentation](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/index.html){target=\_blank} +- [Weight Struct Documentation](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html){target=\_blank} +- [Benchmarking v2 API](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank} +- [frame-omni-bencher Tool](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} --- @@ -3968,7 +4345,7 @@ This command validates all pallet configurations and prepares the build for depl ## Run Your Chain Locally -Launch your parachain locally to test the new pallet functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}. +Launch your parachain locally to test the new pallet functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}. For instructions on setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\_blank}, refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\_blank} guide. ### Generate a Chain Specification diff --git a/.ai/categories/smart-contracts.md b/.ai/categories/smart-contracts.md index 18e603f60..3a3f35da2 100644 --- a/.ai/categories/smart-contracts.md +++ b/.ai/categories/smart-contracts.md @@ -10585,6 +10585,160 @@ Your local development environment is now active and accessible at `http://local You can connect wallets, deploy contracts using Remix or Hardhat, and interact with your smart contracts as you would on any Ethereum-compatible network. +--- + +Page Title: Migration FAQs and Considerations + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-migration.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/for-eth-devs/migration/ +- Summary: Learn how to migrate your existing Ethereum contracts to the Polkadot Hub using REVM and PolkaVM by following these considerations. + +# Migration FAQs and Considerations + +## Introduction + +This guide helps Ethereum developers migrate their smart contracts to Polkadot Hub. Most contracts work without modifications on the REVM backend, while the PolkaVM backend offers enhanced performance with minimal adaptation for standard patterns. + +## Migration Considerations + +Take into account the following considerations before migrating your contracts: + +- Standard ERC-20, ERC-721, ERC-1155 tokens work without changes. +- DeFi protocols, DEXs, and AMMs migrate seamlessly. +- DAOs and governance contracts are fully compatible. +- Most Solidity contracts deploy identically to Ethereum. + +## Migration Checklist + +Before migrating your contracts, review this checklist: + +- Factory contracts using PVM bytecode need pre-uploaded dependencies. +- Contracts using `EXTCODECOPY` for runtime manipulation require review (for projects that will use PVM bytecode, not EVM bytecode). +- Replace `transfer()` and `send()` with proper reentrancy guards (for projects that will use PVM bytecode, not EVM bytecode). + +## Migration FAQs + +### Which backend should I choose? + +- Choose REVM if you want: + + - Zero-modification deployment of existing Ethereum contracts. + - Exact EVM behavior for audited code. + - Compatibility with tools that inspect EVM bytecode. + - Rapid deployment without optimization. + +- Choose PolkaVM if you want: + + - Better performance for computation-heavy applications. + - Lower execution costs for intensive operations. + - Access to next-generation smart contract features. + +If you are unsure which to choose, start with REVM for immediate compatibility, then consider PolkaVM for performance optimization once deployed. + +### Do I need to rewrite my Solidity code? + +No, for most contracts. Standard Solidity patterns work on both backends. + +### What about factory contracts? + +- **REVM**: Factory contracts work identically to Ethereum with no changes needed. + + The original factory pattern is: + + ```solidity + contract TokenFactory { + function createToken(string memory name) public returns (address) { + // Creates new contract at runtime + Token newToken = new Token(name); + return address(newToken); + } + } + ``` + +- **PolkaVM**: Factory contracts require pre-uploading dependent contracts. + + Here's how to adapt the original factory pattern: + + ```solidity + contract TokenFactory { + // Reference pre-uploaded Token contract by hash + bytes32 public tokenCodeHash; + + constructor(bytes32 _tokenCodeHash) { + tokenCodeHash = _tokenCodeHash; + } + + function createToken(string memory name) public returns (address) { + // Instantiate from pre-uploaded code + Token newToken = new Token{salt: keccak256(abi.encode(name))}(name); + return address(newToken); + } + } + ``` + +The deployment steps for PolkaVM factories are: + +1. Upload the contract code to the chain. +2. Note the returned code hash. +3. Deploy the Factory contract with the contract code hash. +4. Factory can now instantiate contracts using the pre-uploaded code. + +### How do gas costs compare? + +For more information on gas costs, see the [Gas Model](/smart-contracts/for-eth-devs/gas-model/){target=\_blank} page. + +### Which Solidity features are not supported? + +For REVM, any Solidity feature will function smoothly without requiring changes or adaptations. For PVM, there are considerations, as was mentioned above. + +For PolkaVM, there are some considerations: + +- `EXTCODECOPY`: Only works in constructor code. +- Runtime code modification: Use on-chain constructors instead. +- **Gas stipends**: `address.send()` and `address.transfer()` don't provide reentrancy protection. +- **Unsupported operations**: `pc`, `extcodecopy`, `selfdestruct`, `blobhash`, and `blobbasefee` (blob-related operations). + +### How do I handle the existential deposit? + +Polkadot requires accounts to maintain a minimum balance (existential deposit or ED) to remain active. + +This is handled automatically for you: + +- Balance queries via Ethereum RPC automatically deduct the ED. +- New account transfers include ED in transaction fees. +- Contract-to-contract transfers draw ED from the transaction signer. + +You typically don't need to do anything special, but be aware: + +- Accounts below ED threshold are automatically deleted. +- ED is around 0.01 DOT (varies by network). +- Your contracts don't need to manage this explicitly. + +### Can I use my existing development tools? + +Yes. Both backends support: + +- **Wallets**: [MetaMask](https://metamask.io/){target=\_blank}, [Talisman](https://talisman.xyz/){target=\_blank}, [SubWallet](https://www.subwallet.app/){target=\_blank} +- **Development frameworks**: [Hardhat](/smart-contracts/cookbook/smart-contracts/deploy-basic/hardhat/){target=\_blank}, [Foundry](/smart-contracts/cookbook/smart-contracts/deploy-basic/foundry/){target=\_blank}, [Remix](/smart-contracts/cookbook/smart-contracts/deploy-basic/remix/){target=\_blank} (just consider that for PVM bytecode, you will use the Polkadot version of the tooling) +- **Libraries**: [ethers.js](/smart-contracts/libraries/ethers-js/){target=\_blank}, [web3.js](/smart-contracts/libraries/web3-js/){target=\_blank}, [viem](/smart-contracts/libraries/viem/){target=\_blank} +- **Testing tools**: Your existing test suites work + +Connect to Polkadot Hub's Ethereum JSON-RPC endpoint and use your familiar workflow. + +## Conclusion + +Most Ethereum contracts migrate to Polkadot Hub with minimal or no changes. Use REVM for seamless compatibility or PolkaVM for enhanced performance. + +There are a few key points to keep in mind during migration: + +- Replace `transfer()` and `send()` with `.call{value}("")` and use reentrancy guards (for projects that will use PVM bytecode, not EVM bytecode). +- PolkaVM factory contracts using PVM bytecode need pre-uploaded dependencies. +- Don't hardcode gas values. +- Test thoroughly on [TestNet](/smart-contracts/connect/#__tabbed_1_1){target=\_blank} before mainnet deployment. + +Your existing Solidity knowledge and tooling transfer directly to Polkadot Hub, making migration straightforward for standard smart contract patterns. + + --- Page Title: Networks diff --git a/.ai/categories/tooling.md b/.ai/categories/tooling.md index 41ae91e34..6f6a392c3 100644 --- a/.ai/categories/tooling.md +++ b/.ai/categories/tooling.md @@ -25913,7 +25913,7 @@ export default buildModule("StorageModule", (m) => { Deploy the contract to Polkadot Hub TestNet: ```bash -npx hardhat ignition deploy ./ignition/modules/Storage.ts --network polkadotHub +npx hardhat ignition deploy ./ignition/modules/Storage.ts --network polkadotTestNet ``` You should see output similar to: diff --git a/.ai/pages/parachains-customize-runtime-add-smart-contract-functionality.md b/.ai/pages/parachains-customize-runtime-add-smart-contract-functionality.md index eda88f870..e4d53a6e1 100644 --- a/.ai/pages/parachains-customize-runtime-add-smart-contract-functionality.md +++ b/.ai/pages/parachains-customize-runtime-add-smart-contract-functionality.md @@ -50,9 +50,9 @@ Any language that can compile to PolkaVM bytecode and utilize `pallet-revive`'s ### Key Benefits -- **Unified Platform**: Deploys both PolkaVM-optimized and EVM-compatible contracts using a single pallet. +- **Unified platform**: Deploys both PolkaVM-optimized and EVM-compatible contracts using a single pallet. - **Performance**: PolkaVM execution provides improved performance compared to the traditional EVM, leveraging the [RISC-V](https://en.wikipedia.org/wiki/RISC-V){target=\_blank} architecture to map instructions to the CPU and requires little transpiling. -- **Ethereum Compatibility**: Supports full integration with Ethereum tooling via RPC adapter. +- **Ethereum compatibility**: Supports full integration with Ethereum tooling via RPC adapter. ### Implementation Examples @@ -70,7 +70,7 @@ Frontier offers flexible integration depending on your compatibility needs: For basic EVM support using Polkadot SDK native APIs: -- **[`pallet-evm`](https://github.com/polkadot-evm/frontier/tree/master/frame/evm){target=\_blank}**: Provides the core EVM execution environment +- **[`pallet-evm`](https://github.com/polkadot-evm/frontier/tree/master/frame/evm){target=\_blank}**: Provides the core EVM execution environment. This configuration allows EVM contract execution but requires using Polkadot SDK-specific APIs for interaction. @@ -84,20 +84,20 @@ For complete Ethereum ecosystem integration with Ethereum RPC support: ### Key Benefits -- **Ethereum tooling compatibility**: Full compatibility with MetaMask, Hardhat, Remix, Truffle, and other Ethereum development tools -- **Minimal-friction migration**: Deployment of existing Ethereum dApps with minimal or no modifications -- **Native Ethereum formats**: Support for Ethereum transaction formats, signatures, and gas mechanics -- **Block emulation**: Ethereum-style block structure within Substrate's block production +- **Ethereum tooling compatibility**: Full compatibility with MetaMask, Hardhat, Remix, Foundry, and other Ethereum development tools. +- **Minimal-friction migration**: Deployment of existing Ethereum dApps with minimal or no modifications. +- **Native Ethereum formats**: Support for Ethereum transaction formats, signatures, and gas mechanics. +- **Block emulation**: Ethereum-style block structure within Substrate's block production. ### Implementation Examples Production implementations demonstrate Frontier's capabilities: -- **Moonbeam**: See their implementation of [`pallet-evm`](https://github.com/moonbeam-foundation/moonbeam/blob/9e2ddbc9ae8bf65f11701e7ccde50075e5fe2790/runtime/moonbeam/src/lib.rs#L532){target=\_blank} and [`pallet-ethereum`](https://github.com/moonbeam-foundation/moonbeam/blob/9e2ddbc9ae8bf65f11701e7ccde50075e5fe2790/runtime/moonbeam/src/lib.rs#L698){target=\_blank} +- **Moonbeam**: See their implementation of [`pallet-evm`](https://github.com/moonbeam-foundation/moonbeam/blob/9e2ddbc9ae8bf65f11701e7ccde50075e5fe2790/runtime/moonbeam/src/lib.rs#L532){target=\_blank} and [`pallet-ethereum`](https://github.com/moonbeam-foundation/moonbeam/blob/9e2ddbc9ae8bf65f11701e7ccde50075e5fe2790/runtime/moonbeam/src/lib.rs#L698){target=\_blank}. ## pallet-contracts (Legacy) -[`pallet-contracts`](https://docs.rs/pallet-contracts/latest/pallet_contracts/index.html#contracts-pallet){target=\_blank} is the original Wasm-based smart contract pallet for Polkadot SDK chains. While still functional, it's considered legacy as development efforts have shifted to pallet-revive. +[`pallet-contracts`](https://docs.rs/pallet-contracts/latest/pallet_contracts/index.html#contracts-pallet){target=\_blank} is the original Wasm-based smart contract pallet for Polkadot SDK chains. While still functional, it's considered legacy as development efforts have shifted to `pallet-revive`. ### Implementation Example diff --git a/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md b/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md index 748981792..263d742a9 100644 --- a/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md +++ b/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md @@ -1,305 +1,682 @@ --- -title: Benchmarking FRAME Pallets -description: Learn how to use FRAME's benchmarking framework to measure extrinsic execution costs and provide accurate weights for on-chain computations. +title: Benchmark Your Pallet +description: Learn how to benchmark your custom pallet extrinsics to generate accurate weight calculations for production use. categories: Parachains url: https://docs.polkadot.com/parachains/customize-runtime/pallet-development/benchmark-pallet/ --- -# Benchmarking - ## Introduction -Benchmarking is a critical component of developing efficient and secure blockchain runtimes. In the Polkadot ecosystem, accurately benchmarking your custom pallets ensures that each extrinsic has a precise [weight](/reference/glossary/#weight){target=\_blank}, representing its computational and storage demands. This process is vital for maintaining the blockchain's performance and preventing potential vulnerabilities, such as Denial of Service (DoS) attacks. +Benchmarking is the process of measuring the computational resources (execution time and storage) required by your pallet's extrinsics. Accurate [weight](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/index.html){target=\_blank} calculations are essential for ensuring your blockchain can process transactions efficiently while protecting against denial-of-service attacks. + +This guide continues the pallet development series, building on the [Create a Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet), [Mock Your Runtime](/parachains/customize-runtime/pallet-development/mock-runtime), and [Test Your Pallet](/parachains/customize-runtime/pallet-development/pallet-testing) tutorials. You'll learn how to benchmark the counter pallet extrinsics and integrate the generated weights into your runtime. + +## Prerequisites + +Before you begin, ensure you have: + +- Completed the previous pallet development tutorials +- Basic understanding of computational complexity +- Familiarity with Rust's testing framework + +## Why Benchmark? + +In blockchain systems, every operation consumes resources. Weight is the mechanism Polkadot SDK uses to measure and limit resource consumption. Without accurate weights: + +- **Security Risk**: Malicious actors could submit transactions that consume excessive resources, blocking legitimate transactions or halting the chain +- **Inefficiency**: Over-estimated weights waste block space and reduce throughput +- **User Experience**: Inaccurate weights lead to incorrect fee calculations + +Benchmarking provides empirical measurements of your extrinsics under various conditions, ensuring weights reflect real-world resource consumption. + +## Understanding Weights + +The [weight system](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html){target=\_blank} serves multiple purposes: + +- **DoS Protection**: Limits the computational work per block, preventing attackers from overwhelming the network +- **Fee Calculation**: Determines transaction fees based on actual resource usage +- **Block Production**: Helps block authors maximize throughput while staying within block limits + +Weights are expressed as [`Weight::from_parts(ref_time, proof_size)`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.from_parts){target=\_blank} where: -The Polkadot SDK leverages the [FRAME](/reference/glossary/#frame-framework-for-runtime-aggregation-of-modularized-entities){target=\_blank} benchmarking framework, offering tools to measure and assign weights to extrinsics. These weights help determine the maximum number of transactions or system-level calls processed within a block. This guide covers how to use FRAME's [benchmarking framework](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank}, from setting up your environment to writing and running benchmarks for your custom pallets. You'll understand how to generate accurate weights by the end, ensuring your runtime remains performant and secure. +- [`ref_time`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.ref_time){target=\_blank}: Computational time measured in picoseconds +- [`proof_size`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.proof_size){target=\_blank}: Storage proof size in bytes -## The Case for Benchmarking +## Step 1: Create the Benchmarking Module -Benchmarking helps validate that the required execution time for different functions is within reasonable boundaries to ensure your blockchain runtime can handle transactions efficiently and securely. By accurately measuring the weight of each extrinsic, you can prevent service interruptions caused by computationally intensive calls that exceed block time limits. Without benchmarking, runtime performance could be vulnerable to DoS attacks, where malicious users exploit functions with unoptimized weights. +Create a new file `benchmarking.rs` in your pallet's `src` directory. This module will contain all the [benchmarking definitions](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank} for your pallet: -Benchmarking also ensures predictable transaction fees. Weights derived from benchmark tests accurately reflect the resource usage of function calls, allowing fair fee calculation. This approach discourages abuse while maintaining network reliability. +```rust title="pallets/pallet-custom/src/benchmarking.rs" +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use frame::deps::frame_benchmarking::v2::*; +use frame::benchmarking::prelude::RawOrigin; + +#[benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn set_counter_value() { + let new_value: u32 = 100; -### Benchmarking and Weight + #[extrinsic_call] + _(RawOrigin::Root, new_value); + + assert_eq!(CounterValue::::get(), new_value); + } + + #[benchmark] + fn increment() { + let caller: T::AccountId = whitelisted_caller(); + let amount: u32 = 50; + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), amount); + + assert_eq!(CounterValue::::get(), amount); + assert_eq!(UserInteractions::::get(caller), 1); + } -In Polkadot SDK-based chains, weight quantifies the computational effort needed to process transactions. This weight includes factors such as: + #[benchmark] + fn decrement() { + // First set the counter to a non-zero value + CounterValue::::put(100); -- Computational complexity. -- Storage complexity (proof size). -- Database reads and writes. -- Hardware specifications. + let caller: T::AccountId = whitelisted_caller(); + let amount: u32 = 30; -Benchmarking uses real-world testing to simulate worst-case scenarios for extrinsics. The framework generates a linear model for weight calculation by running multiple iterations with varied parameters. These worst-case weights ensure blocks remain within execution limits, enabling the runtime to maintain throughput under varying loads. Excess fees can be refunded if a call uses fewer resources than expected, offering users a fair cost model. - -Because weight is a generic unit of measurement based on computation time for a specific physical machine, the weight of any function can change based on the specifications of hardware used for benchmarking. By modeling the expected weight of each runtime function, the blockchain can calculate the number of transactions or system-level calls it can execute within a certain period. + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), amount); -Within FRAME, each function call that is dispatched must have a `#[pallet::weight]` annotation that can return the expected weight for the worst-case scenario execution of that function given its inputs: + assert_eq!(CounterValue::::get(), 70); + assert_eq!(UserInteractions::::get(caller), 1); + } -```rust hl_lines="2" -#[pallet::call_index(0)] -#[pallet::weight(T::WeightInfo::do_something())] -pub fn do_something(origin: OriginFor) -> DispatchResultWithPostInfo { Ok(()) } + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); +} ``` -The `WeightInfo` file is automatically generated during benchmarking. Based on these tests, this file provides accurate weights for each extrinsic. +**Key components:** + +- **`#![cfg(feature = "runtime-benchmarks")]`**: Ensures benchmarking code only compiles when the feature is enabled +- **[`#[benchmarks]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmarks.html){target=\_blank}**: Marks the module containing benchmark definitions +- **[`#[benchmark]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmark.html){target=\_blank}**: Defines individual benchmark functions +- **[`#[extrinsic_call]`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.extrinsic_call.html){target=\_blank}**: Marks the actual extrinsic invocation to measure +- **[`whitelisted_caller()`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/fn.whitelisted_caller.html){target=\_blank}**: Generates a funded account for benchmarking +- **[`impl_benchmark_test_suite!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.impl_benchmark_test_suite.html){target=\_blank}**: Generates test functions to verify benchmarks work correctly + +## Step 2: Define the Weight Trait + +The [`WeightInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/trait.WeightInfo.html){target=\_blank} trait provides an abstraction layer that allows weights to be swapped at runtime configuration. This enables you to use placeholder weights during development and testing, then switch to auto-generated benchmarked weights in production without modifying the pallet code itself. + +Add a `weights` module to your pallet that defines the `WeightInfo` trait: + +```rust title="pallets/pallet-custom/src/lib.rs" +#[frame::pallet] +pub mod pallet { + use frame::prelude::*; + pub use weights::WeightInfo; + + pub mod weights { + use frame::prelude::*; + + pub trait WeightInfo { + fn set_counter_value() -> Weight; + fn increment() -> Weight; + fn decrement() -> Weight; + } + + impl WeightInfo for () { + fn set_counter_value() -> Weight { + Weight::from_parts(10_000, 0) + } + fn increment() -> Weight { + Weight::from_parts(15_000, 0) + } + fn decrement() -> Weight { + Weight::from_parts(15_000, 0) + } + } + } -## Benchmarking Process + // ... rest of pallet +} +``` -Benchmarking a pallet involves the following steps: +The `()` implementation provides placeholder weights for development. Later, this will be replaced with auto-generated weights from benchmarking. -1. Creating a `benchmarking.rs` file within your pallet's structure. -2. Writing a benchmarking test for each extrinsic. -3. Executing the benchmarking tool to calculate weights based on performance metrics. +## Step 3: Add WeightInfo to Config -The benchmarking tool runs multiple iterations to model worst-case execution times and determine the appropriate weight. By default, the benchmarking pipeline is deactivated. To activate it, compile your runtime with the `runtime-benchmarks` feature flag. +By making `WeightInfo` an associated type in the `Config` trait, you allow each runtime that uses your pallet to specify which weight implementation to use. Different deployment environments (testnets, production chains, or different hardware configurations) may have different performance characteristics and can use different weight calculations. -### Prepare Your Environment +Update your pallet's `Config` trait to include `WeightInfo`: -Install the [`frame-omni-bencher`](https://crates.io/crates/frame-omni-bencher){target=\_blank} command-line tool: +```rust title="pallets/pallet-custom/src/lib.rs" +#[pallet::config] +pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; -```bash -cargo install frame-omni-bencher + #[pallet::constant] + type CounterMaxValue: Get; + + type WeightInfo: weights::WeightInfo; +} ``` -Before writing benchmark tests, you need to ensure the `frame-benchmarking` crate is included in your pallet's `Cargo.toml` similar to the following: +## Step 4: Update Extrinsic Weight Annotations + +By calling `T::WeightInfo::function_name()` instead of using hardcoded `Weight::from_parts()` values, your extrinsics automatically use whichever weight implementation is configured in the runtime. This allows you to easily switch between placeholder weights for testing and benchmarked weights for production without changing any pallet code. + +Replace the placeholder weights in your extrinsics with calls to the `WeightInfo` trait: + +```rust title="pallets/pallet-custom/src/lib.rs" +#[pallet::call] +impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::set_counter_value())] + pub fn set_counter_value(origin: OriginFor, new_value: u32) -> DispatchResult { + // ... implementation + } + + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::increment())] + pub fn increment(origin: OriginFor, amount: u32) -> DispatchResult { + // ... implementation + } -```toml title="Cargo.toml" -frame-benchmarking = { version = "37.0.0", default-features = false } + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::decrement())] + pub fn decrement(origin: OriginFor, amount: u32) -> DispatchResult { + // ... implementation + } +} ``` -You must also ensure that you add the `runtime-benchmarks` feature flag as follows under the `[features]` section of your pallet's `Cargo.toml`: +## Step 5: Include the Benchmarking Module -```toml title="Cargo.toml" -runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] +The `#[cfg(feature = "runtime-benchmarks")]` attribute ensures that benchmarking code is only compiled when explicitly needed. This keeps your production runtime lean by excluding benchmarking infrastructure from normal builds, as it's only needed when generating weights. + +At the top of your `lib.rs`, add the module declaration: + +```rust title="pallets/pallet-custom/src/lib.rs" +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; +use alloc::vec::Vec; + +pub use pallet::*; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +// ... rest of the pallet ``` -Lastly, ensure that `frame-benchmarking` is included in `std = []`: +## Step 6: Configure Pallet Dependencies + +The feature flag system in Cargo allows you to conditionally compile code based on which features are enabled. By defining a `runtime-benchmarks` feature that cascades to FRAME's benchmarking features, you create a clean way to build your pallet with or without benchmarking support, ensuring all necessary dependencies are available when needed but excluded from production builds. + +Update your pallet's `Cargo.toml` to enable the benchmarking feature: + +```toml title="pallets/pallet-custom/Cargo.toml" +[dependencies] +codec = { features = ["derive"], workspace = true } +scale-info = { features = ["derive"], workspace = true } +frame = { features = ["experimental", "runtime"], workspace = true } -```toml title="Cargo.toml" +[features] +default = ["std"] +runtime-benchmarks = [ + "frame/runtime-benchmarks", +] std = [ - # ... - "frame-benchmarking?/std", - # ... + "codec/std", + "scale-info/std", + "frame/std", ] ``` -Once complete, you have the required dependencies for writing benchmark tests for your pallet. +## Step 7: Update Mock Runtime -### Write Benchmark Tests +In your mock runtime for testing, use the placeholder `()` implementation of `WeightInfo` since unit tests focus on verifying functional correctness rather than performance characteristics. This keeps tests fast and focused on validating logic. -Create a `benchmarking.rs` file in your pallet's `src/`. Your directory structure should look similar to the following: +Add the `WeightInfo` type to your test configuration in `mock.rs`: +```rust title="pallets/pallet-custom/src/mock.rs" +impl pallet_custom::Config for Test { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = (); +} ``` -my-pallet/ -├── src/ -│ ├── lib.rs # Main pallet implementation -│ └── benchmarking.rs # Benchmarking -└── Cargo.toml + +## Step 8: Configure Runtime Benchmarking + +To execute benchmarks, your pallet must be integrated into the runtime's benchmarking infrastructure. This involves three configuration steps: + +### Update Runtime Cargo.toml + +When you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included. + +Add your pallet to the runtime's `runtime-benchmarks` feature in `runtime/Cargo.toml`: + +```toml title="runtime/Cargo.toml" +runtime-benchmarks = [ + "cumulus-pallet-parachain-system/runtime-benchmarks", + "hex-literal", + "pallet-parachain-template/runtime-benchmarks", + "polkadot-sdk/runtime-benchmarks", + "pallet-custom/runtime-benchmarks", +] ``` -With the directory structure set, you can use the [`polkadot-sdk-parachain-template`](https://github.com/paritytech/polkadot-sdk-parachain-template/tree/master/pallets){target=\_blank} to get started as follows: +### Update Runtime Configuration -```rust title="benchmarking.rs (starter template)" -//! Benchmarking setup for pallet-template -#![cfg(feature = "runtime-benchmarks")] +Start with the placeholder implementation during development. After successfully running benchmarks and generating the weights file, you'll update this to use the benchmarked weights. -use super::*; -use frame_benchmarking::v2::*; +In `runtime/src/configs/mod.rs`, add the `WeightInfo` type: -#[benchmarks] -mod benchmarks { - use super::*; - #[cfg(test)] - use crate::pallet::Pallet as Template; - use frame_system::RawOrigin; - - #[benchmark] - fn do_something() { - let caller: T::AccountId = whitelisted_caller(); - #[extrinsic_call] - do_something(RawOrigin::Signed(caller), 100); - - assert_eq!(Something::::get().map(|v| v.block_number), Some(100u32.into())); - } - - #[benchmark] - fn cause_error() { - Something::::put(CompositeStruct { block_number: 100u32.into() }); - let caller: T::AccountId = whitelisted_caller(); - #[extrinsic_call] - cause_error(RawOrigin::Signed(caller)); - - assert_eq!(Something::::get().map(|v| v.block_number), Some(101u32.into())); - } - - impl_benchmark_test_suite!(Template, crate::mock::new_test_ext(), crate::mock::Test); +```rust title="runtime/src/configs/mod.rs" +impl pallet_custom::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = (); } ``` -In your benchmarking tests, employ these best practices: +### Register Benchmarks -- **Write custom testing functions**: The function `do_something` in the preceding example is a placeholder. Similar to writing unit tests, you must write custom functions to benchmark test your extrinsics. Access the mock runtime and use functions such as `whitelisted_caller()` to sign transactions and facilitate testing. -- **Use the `#[extrinsic_call]` macro**: This macro is used when calling the extrinsic itself and is a required part of a benchmarking function. See the [`extrinsic_call`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html#extrinsic_call-and-block){target=\_blank} docs for more details. -- **Validate extrinsic behavior**: The `assert_eq` expression ensures that the extrinsic is working properly within the benchmark context. +The `define_benchmarks!` macro creates the infrastructure that allows the benchmarking CLI tool to discover and execute your pallet's benchmarks. -Add the `benchmarking` module to your pallet. In the pallet `lib.rs` file add the following: +Add your pallet to the benchmark list in `runtime/src/benchmarks.rs`: -```rust -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; +```rust title="runtime/src/benchmarks.rs" +polkadot_sdk::frame_benchmarking::define_benchmarks!( + [frame_system, SystemBench::] + [pallet_balances, Balances] + // ... other pallets + [pallet_custom, CustomPallet] +); ``` -### Add Benchmarks to Runtime +## Step 9: Run Benchmarks -Before running the benchmarking tool, you must integrate benchmarks with your runtime as follows: +### Test Benchmark Compilation -1. Navigate to your `runtime/src` directory and check if a `benchmarks.rs` file exists. If not, create one. This file will contain the macro that registers all pallets for benchmarking along with their respective configurations: +The `impl_benchmark_test_suite!` macro generates unit tests for each benchmark. Running these tests verifies that your benchmarks compile correctly, execute without panicking, and pass their assertions, catching issues early before building the full runtime. - ```rust title="benchmarks.rs" - frame_benchmarking::define_benchmarks!( - [frame_system, SystemBench::] - [pallet_parachain_template, TemplatePallet] - [pallet_balances, Balances] - [pallet_session, SessionBench::] - [pallet_timestamp, Timestamp] - [pallet_message_queue, MessageQueue] - [pallet_sudo, Sudo] - [pallet_collator_selection, CollatorSelection] - [cumulus_pallet_parachain_system, ParachainSystem] - [cumulus_pallet_xcmp_queue, XcmpQueue] - ); - ``` +First, verify your benchmarks compile and run as tests: - For example, to add a new pallet named `pallet_parachain_template` for benchmarking, include it in the macro as shown: - ```rust title="benchmarks.rs" hl_lines="3" - frame_benchmarking::define_benchmarks!( - [frame_system, SystemBench::] - [pallet_parachain_template, TemplatePallet] - ); - ``` +```bash +cargo test -p pallet-custom --features runtime-benchmarks +``` - !!!warning "Updating `define_benchmarks!` macro is required" - Any pallet that needs to be benchmarked must be included in the [`define_benchmarks!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.define_benchmarks.html){target=\_blank} macro. The CLI will only be able to access and benchmark pallets that are registered here. +You should see your benchmark tests passing: -2. Check your runtime's `lib.rs` file to ensure the `benchmarks` module is imported. The import should look like this: +``` +test benchmarking::benchmarks::bench_set_counter_value ... ok +test benchmarking::benchmarks::bench_increment ... ok +test benchmarking::benchmarks::bench_decrement ... ok +``` - ```rust title="lib.rs" - #[cfg(feature = "runtime-benchmarks")] - mod benchmarks; - ``` +### Build the Runtime with Benchmarks - The `runtime-benchmarks` feature gate ensures benchmark tests are isolated from production runtime code. +This build includes all the benchmarking infrastructure and special host functions needed for measurement. The resulting WASM runtime contains your benchmark code and can communicate with the benchmarking tool's execution environment. This is a special build used only for benchmarking - you'll create a different build later for actually running your chain. -3. Enable runtime benchmarking for your pallet in `runtime/Cargo.toml`: +Compile the runtime with benchmarking enabled to generate the WASM binary: - ```toml - runtime-benchmarks = [ - # ... - "pallet_parachain_template/runtime-benchmarks", - ] +```bash +cargo build --release --features runtime-benchmarks +``` - ``` +This produces the runtime WASM file needed for benchmarking, typically located at: +``` +target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm +``` -### Run Benchmarks +### Install the Benchmarking Tool -You can now compile your runtime with the `runtime-benchmarks` feature flag. This feature flag is crucial as the benchmarking tool will look for this feature being enabled to know when it should run benchmark tests. Follow these steps to compile the runtime with benchmarking enabled: +[`frame-omni-bencher`](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} is the official Polkadot SDK tool specifically designed for FRAME pallet benchmarking. It provides a standardized way to execute benchmarks, measure execution times and storage operations, and generate properly formatted weight files with full integration into the FRAME weight system. -1. Run `build` with the feature flag included: +Install the `frame-omni-bencher` CLI tool: + +```bash +cargo install frame-omni-bencher --locked +``` + +### Download the Weight Template + +The weight template is a Handlebars file that transforms raw benchmark data into a properly formatted Rust source file. It defines the structure of the generated `weights.rs` file, including imports, trait definitions, documentation comments, and formatting. Using the official template ensures your weight files follow Polkadot SDK conventions and include all necessary metadata like benchmark execution parameters, storage operation counts, and hardware information. + +Download the official weight template file: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \ +--output ./pallets/pallet-custom/frame-weight-template.hbs +``` - ```bash - cargo build --features runtime-benchmarks --release - ``` +### Hardware Requirements for Benchmarking -2. Create a `weights.rs` file in your pallet's `src/` directory. This file will store the auto-generated weight calculations: +!!! warning "Critical: Benchmark on Production-Like Hardware" + Benchmarks must be executed on hardware similar to what will run your chain in production. Weight measurements are hardware-dependent, and benchmarking on different hardware can lead to dangerous under-estimation or wasteful over-estimation of weights. - ```bash - touch weights.rs - ``` +Weights represent the actual computational time and resources consumed by extrinsics. These measurements vary significantly across different hardware configurations: -3. Before running the benchmarking tool, you'll need a template file that defines how weight information should be formatted. Download the official template from the Polkadot SDK repository and save it in your project folders for future use: +- **CPU Performance**: Different processors execute instructions at different speeds. A faster development laptop will produce lower weight values than production server hardware +- **Storage Speed**: Database read/write performance varies between NVMe SSDs, SATA SSDs, and HDDs, affecting storage-related weights +- **Memory Bandwidth**: RAM speed impacts how quickly data can be accessed during execution +- **CPU Cache**: Cache size and architecture differences affect repeated operations - ```bash - curl https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \ - --output ./pallets/benchmarking/frame-weight-template.hbs - ``` +Benchmarking on faster hardware than production leads to under-estimated weights - attackers could submit extrinsics that consume more resources than the weights suggest, potentially causing blocks to take longer than expected to produce or even halting the chain. Conversely, benchmarking on slower hardware creates over-estimated weights, resulting in unnecessarily high transaction fees and wasted block capacity. -4. Run the benchmarking tool to measure extrinsic weights: +**Best practices:** - ```bash - frame-omni-bencher v1 benchmark pallet \ - --runtime INSERT_PATH_TO_WASM_RUNTIME \ - --pallet INSERT_NAME_OF_PALLET \ +1. **Match production specifications**: If your chain will run on specific validator hardware, benchmark on identical or very similar machines +2. **Use reference hardware**: The Polkadot ecosystem often uses standardized reference hardware specifications for consistency. Consider following these standards if your chain will connect to Polkadot or Kusama +3. **Dedicated benchmarking environment**: Run benchmarks on a machine without other heavy processes to ensure consistent measurements +4. **Document your hardware**: The generated weight files include hardware information in comments. Review this to ensure it matches your production environment +5. **Re-benchmark when hardware changes**: If your validator hardware specifications change, re-run benchmarks and update weights + +For development and testing purposes, you can run benchmarks on any available hardware to verify that your benchmark functions work correctly. However, before deploying to production, always re-run benchmarks on production-equivalent hardware. + +### Execute Benchmarks + +Benchmarks execute against the compiled WASM runtime rather than native code because WASM is what actually runs in production on the blockchain. WASM execution can have different performance characteristics than native code due to compilation and sandboxing overhead, so benchmarking the WASM ensures your weight measurements reflect real-world conditions. + +Run benchmarks for your pallet to generate weight files: + +```bash +frame-omni-bencher v1 benchmark pallet \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ + --pallet pallet_custom \ --extrinsic "" \ - --template ./frame-weight-template.hbs \ - --output weights.rs - ``` - - !!! tip "Flag definitions" - - **`--runtime`**: The path to your runtime's Wasm. - - **`--pallet`**: The name of the pallet you wish to benchmark. This pallet must be configured in your runtime and defined in `define_benchmarks`. - - **`--extrinsic`**: Which extrinsic to test. Using `""` implies all extrinsics will be benchmarked. - - **`--template`**: Defines how weight information should be formatted. - - **`--output`**: Where the output of the auto-generated weights will reside. - -The generated `weights.rs` file contains weight annotations for your extrinsics, ready to be added to your pallet. The output should be similar to the following. Some output is omitted for brevity: - -
- frame-omni-bencher v1 benchmark pallet \ - --runtime INSERT_PATH_TO_WASM_RUNTIME \ - --pallet "INSERT_NAME_OF_PALLET" \ - --extrinsic "" \ - --template ./frame-weight-template.hbs \ - --output ./weights.rs - ... - 2025-01-15T16:41:33.557045Z INFO polkadot_sdk_frame::benchmark::pallet: [ 0 % ] Starting benchmark: pallet_parachain_template::do_something - 2025-01-15T16:41:33.564644Z INFO polkadot_sdk_frame::benchmark::pallet: [ 50 % ] Starting benchmark: pallet_parachain_template::cause_error - ... - Created file: "weights.rs" - -
- -#### Add Benchmark Weights to Pallet - -Once the `weights.rs` is generated, you must integrate it with your pallet. - -1. To begin the integration, import the `weights` module and the `WeightInfo` trait, then add both to your pallet's `Config` trait. Complete the following steps to set up the configuration: - - ```rust title="lib.rs" - pub mod weights; + --template ./pallets/pallet-custom/frame-weight-template.hbs \ + --output ./pallets/pallet-custom/src/weights.rs +``` + +**Command breakdown:** + +- `v1`: Specifies the benchmarking framework version (v2 API) +- `benchmark pallet`: Subcommand indicating you want to benchmark pallet extrinsics +- `--runtime`: Path to the compiled WASM runtime file that includes your pallet and benchmarks +- `--pallet pallet_custom`: Name of the pallet to benchmark (must match the name used in `define_benchmarks!`) +- `--extrinsic ""`: Empty string benchmarks all extrinsics in the pallet; you can specify a single extrinsic name to benchmark only that one +- `--template`: Path to the Handlebars template that formats the output +- `--output`: Destination file path for the generated weights module + +### Advanced Options + +You can customize benchmark execution with additional parameters for more detailed measurements: + +```bash +frame-omni-bencher v1 benchmark pallet \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ + --pallet pallet_custom \ + --extrinsic "" \ + --steps 50 \ + --repeat 20 \ + --template ./pallets/pallet-custom/frame-weight-template.hbs \ + --output ./pallets/pallet-custom/src/weights.rs +``` + +**Additional parameters:** + +- `--steps 50`: Number of different input values to test when using linear components (default: 50). More steps provide finer granularity for detecting complexity trends but increase benchmarking time +- `--repeat 20`: Number of repetitions for each measurement (default: 20). More repetitions improve statistical accuracy by averaging out variance, reducing the impact of system noise and providing more reliable weight estimates +- `--heap-pages 4096`: WASM heap pages allocation. Affects available memory during execution +- `--wasm-execution compiled`: WASM execution method. Use `compiled` for performance closest to production conditions + +## Step 10: Use Generated Weights + +After running benchmarks, a `weights.rs` file is generated containing measured weights. The generated weights are based on actual measurements of your code running on real hardware, accounting for the specific complexity of your logic, storage access patterns, and computational requirements. Estimates or placeholder values cannot capture these nuances and will either waste block space (over-estimation) or create security risks (under-estimation). + +The file includes: + +- Detailed documentation about the benchmark execution environment (date, hardware, parameters) +- The `WeightInfo` trait definition matching your benchmark functions +- `SubstrateWeight` implementation with measured weights from your benchmarks +- Database read/write costs calculated based on observed storage operations +- Component complexity annotations for variable inputs (if you use linear components) +- A fallback `()` implementation for testing environments + +### Integrate the Generated Weights + +Unlike the benchmarking module (which is only needed when running benchmarks), the weights module must be available in all builds because the runtime needs to call the weight functions during normal operation to calculate transaction fees and enforce block limits. + +Add the weights module to your pallet's `lib.rs`: + +```rust title="pallets/pallet-custom/src/lib.rs" +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; +use alloc::vec::Vec; + +pub use pallet::*; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +pub mod weights; + +#[frame::pallet] +pub mod pallet { + use super::*; + use frame::prelude::*; use crate::weights::WeightInfo; + // ... rest of pallet +} +``` + +### Update Runtime Configuration - /// Configure the pallet by specifying the parameters and types on which it depends. - #[pallet::config] - pub trait Config: frame_system::Config { - // ... - /// A type representing the weights required by the dispatchables of this pallet. - type WeightInfo: WeightInfo; +This change activates your benchmarked weights in the production runtime. Now when users submit transactions that call your pallet's extrinsics, the runtime will use the actual measured weights to calculate fees and enforce block limits. + +Update your runtime configuration to use the generated weights instead of the placeholder `()` implementation: + +```rust title="runtime/src/configs/mod.rs" +impl pallet_custom::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = pallet_custom::weights::SubstrateWeight; +} +``` + +### Example Generated Weight File + +The generated `weights.rs` file will look similar to this: + +```rust title="pallets/pallet-custom/src/weights.rs" +//! Autogenerated weights for `pallet_custom` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20` + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +pub trait WeightInfo { + fn set_counter_value() -> Weight; + fn increment() -> Weight; + fn decrement() -> Weight; +} + +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn set_counter_value() -> Weight { + Weight::from_parts(8_234_000, 0) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) } - ``` -2. Next, you must add this to the `#[pallet::weight]` annotation in all the extrinsics via the `Config` as follows: + fn increment() -> Weight { + Weight::from_parts(12_456_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } - ```rust hl_lines="2" title="lib.rs" - #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::do_something())] - pub fn do_something(origin: OriginFor) -> DispatchResultWithPostInfo { Ok(()) } - ``` + fn decrement() -> Weight { + Weight::from_parts(11_987_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} +``` + +**Note**: The actual numbers will vary based on your hardware and implementation complexity. The [`DbWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.RuntimeDbWeight.html){target=\_blank} accounts for database read and write operations. + +## Benchmarking Best Practices -3. Finally, configure the actual weight values in your runtime. In `runtime/src/config/mod.rs`, add the following code: +### 1. Test Worst-Case Scenarios - ```rust title="mod.rs" - // Configure pallet. - impl pallet_parachain_template::Config for Runtime { - // ... - type WeightInfo = pallet_parachain_template::weights::SubstrateWeight; +Benchmarks should always measure maximum possible resource consumption. If you benchmark average or best-case scenarios, malicious users could craft transactions that hit worst-case paths in your code, consuming more resources than the weights indicate and potentially slowing down or halting block production. + +```rust +#[benchmark] +fn complex_operation() { + // Set up worst-case storage state + for i in 0..100 { + SomeStorage::::insert(i, vec![0u8; 1000]); } - ``` -## Where to Go Next + let caller = whitelisted_caller(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller)); +} +``` + +### 2. Use Linear Components for Variable Complexity + +Many extrinsics have variable costs depending on input parameters. [Linear components](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/trait.BenchmarkingSetup.html){target=\_blank} tell the benchmarking framework to test your extrinsic with different values of `n`, measure the execution time for each, and calculate a formula like `Weight = base_weight + (n * per_item_weight)`. This produces dynamic weights that accurately reflect the actual work being done. + +When extrinsic complexity depends on input size, use linear components: + +```rust title="pallets/pallet-custom/src/benchmarking.rs" +#[benchmark] +fn process_items(n: Linear<0, 100>) { + let caller = whitelisted_caller(); + let items: Vec = (0..n).collect(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), items); +} +``` + +### 3. Verify Results + +Assertions ensure that your benchmark is actually testing the code path you think it's testing. If your extrinsic fails silently or takes an early return, the benchmark would measure the wrong scenario and produce inaccurate weights. + +Always assert the expected state after extrinsic execution: + +```rust title="pallets/pallet-custom/src/benchmarking.rs" +#[benchmark] +fn my_extrinsic() { + let caller = whitelisted_caller(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone())); + + // Verify the extrinsic had the expected effect + assert_eq!(MyStorage::::get(&caller), expected_value); +} +``` + +### 4. Minimize Setup Code + +While the benchmarking framework tries to isolate the extrinsic execution, excessive setup code can add noise to measurements. More importantly, setup code that doesn't reflect real-world pre-conditions can lead to benchmarking unrealistic scenarios. + +Only include necessary setup in benchmarks: + +```rust title="pallets/pallet-custom/src/benchmarking.rs" +#[benchmark] +fn efficient_benchmark() { + // Minimal setup + let caller = whitelisted_caller(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller)); + + // Minimal assertions +} +``` + +## Run Your Chain Locally + +Now that you've added the pallet to your runtime, you can launch your parachain locally to test the new functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}. For instructions on setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\_blank}, refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\_blank} guide. + +### Build the Production Runtime + +The `runtime-benchmarks` feature flag adds special host functions (like `ext_benchmarking_current_time` and `ext_benchmarking_get_read_and_written_keys`) that are only available in the benchmarking execution environment. These functions allow the benchmarking framework to precisely measure execution time and track storage operations. However, regular nodes don't provide these host functions, so a runtime compiled with benchmarking features will fail to start on a production node. + +Before running your chain, rebuild the runtime **without** the `runtime-benchmarks` feature: + +```bash +cargo build --release +``` + +!!! note "Build Types" + Understanding the difference between builds is critical: + + - `cargo build --release --features runtime-benchmarks` - Compiles with benchmarking host functions for measurement. Use this ONLY when running benchmarks with `frame-omni-bencher` + - `cargo build --release` - Compiles production runtime without benchmarking features. Use this for running your actual chain + +This produces a production-ready WASM runtime at `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm`. + +### Generate a Chain Specification + +The chain specification defines the initial state and configuration of your blockchain, including the runtime WASM code, genesis storage, and network parameters. By generating a new chain spec with your updated runtime (now containing your benchmarked pallet), you ensure that nodes starting from this spec will use the correct version of your code with proper weight calculations. + +Create a new chain specification file with the updated runtime: + +```bash +chain-spec-builder create -t development \ +--relay-chain paseo \ +--para-id 1000 \ +--runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ +named-preset development +``` + +This command generates a chain specification file, `chain_spec.json`, for your parachain with the updated runtime. + +### Start the Parachain Node + +Launch the parachain using the Polkadot Omni Node with the generated chain specification by running the following command: + +```bash +polkadot-omni-node --chain ./chain_spec.json --dev +``` + +The node will start and display initialization information including: + +- The chain specification name +- The node identity and peer ID +- Database location +- Network endpoints (JSON-RPC and Prometheus) + +### Verify Block Production + +Once the node is running, you should see log messages indicating successful block production: + +``` +[Parachain] 🔨 Initializing Genesis block/state (state: 0x47ce…ec8d, header-hash: 0xeb12…fecc) +[Parachain] 🎁 Prepared block for proposing at 1 (3 ms) ... +[Parachain] 🏆 Imported #1 (0xeb12…fecc → 0xee51…98d2) +[Parachain] 🎁 Prepared block for proposing at 2 (3 ms) ... +[Parachain] 🏆 Imported #2 (0xee51…98d2 → 0x35e0…cc32) +``` + +The parachain will produce new blocks every few seconds. You can now interact with your pallet's extrinsics through the JSON-RPC endpoint at `http://127.0.0.1:9944` using tools like [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\_blank}. + +## Related Resources -- View the Rust Docs for a more comprehensive, low-level view of the [FRAME V2 Benchmarking Suite](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=_blank}. -- Read the [FRAME Benchmarking and Weights](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_benchmarking_weight/index.html){target=_blank} reference document, a concise guide which details how weights and benchmarking work. +- [FRAME Benchmarking Documentation](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/index.html){target=\_blank} +- [Weight Struct Documentation](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html){target=\_blank} +- [Benchmarking v2 API](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank} +- [frame-omni-bencher Tool](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} diff --git a/.ai/pages/parachains-customize-runtime-pallet-development-create-a-pallet.md b/.ai/pages/parachains-customize-runtime-pallet-development-create-a-pallet.md index 6b36c500f..6dd373bcb 100644 --- a/.ai/pages/parachains-customize-runtime-pallet-development-create-a-pallet.md +++ b/.ai/pages/parachains-customize-runtime-pallet-development-create-a-pallet.md @@ -671,7 +671,7 @@ This command validates all pallet configurations and prepares the build for depl ## Run Your Chain Locally -Launch your parachain locally to test the new pallet functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}. +Launch your parachain locally to test the new pallet functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}. For instructions on setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\_blank}, refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\_blank} guide. ### Generate a Chain Specification diff --git a/.ai/pages/smart-contracts-cookbook-dapps-zero-to-hero.md b/.ai/pages/smart-contracts-cookbook-dapps-zero-to-hero.md index d2c8e9ade..b0cc72fa0 100644 --- a/.ai/pages/smart-contracts-cookbook-dapps-zero-to-hero.md +++ b/.ai/pages/smart-contracts-cookbook-dapps-zero-to-hero.md @@ -213,7 +213,7 @@ export default buildModule("StorageModule", (m) => { Deploy the contract to Polkadot Hub TestNet: ```bash -npx hardhat ignition deploy ./ignition/modules/Storage.ts --network polkadotHub +npx hardhat ignition deploy ./ignition/modules/Storage.ts --network polkadotTestNet ``` You should see output similar to: diff --git a/.ai/pages/smart-contracts-for-eth-devs-migration.md b/.ai/pages/smart-contracts-for-eth-devs-migration.md index e791fd24d..58c91eb15 100644 --- a/.ai/pages/smart-contracts-for-eth-devs-migration.md +++ b/.ai/pages/smart-contracts-for-eth-devs-migration.md @@ -1,5 +1,151 @@ --- +title: Migration FAQs and Considerations +description: Learn how to migrate your existing Ethereum contracts to the Polkadot Hub using REVM and PolkaVM by following these considerations. +categories: Smart Contracts url: https://docs.polkadot.com/smart-contracts/for-eth-devs/migration/ --- -TODO +# Migration FAQs and Considerations + +## Introduction + +This guide helps Ethereum developers migrate their smart contracts to Polkadot Hub. Most contracts work without modifications on the REVM backend, while the PolkaVM backend offers enhanced performance with minimal adaptation for standard patterns. + +## Migration Considerations + +Take into account the following considerations before migrating your contracts: + +- Standard ERC-20, ERC-721, ERC-1155 tokens work without changes. +- DeFi protocols, DEXs, and AMMs migrate seamlessly. +- DAOs and governance contracts are fully compatible. +- Most Solidity contracts deploy identically to Ethereum. + +## Migration Checklist + +Before migrating your contracts, review this checklist: + +- Factory contracts using PVM bytecode need pre-uploaded dependencies. +- Contracts using `EXTCODECOPY` for runtime manipulation require review (for projects that will use PVM bytecode, not EVM bytecode). +- Replace `transfer()` and `send()` with proper reentrancy guards (for projects that will use PVM bytecode, not EVM bytecode). + +## Migration FAQs + +### Which backend should I choose? + +- Choose REVM if you want: + + - Zero-modification deployment of existing Ethereum contracts. + - Exact EVM behavior for audited code. + - Compatibility with tools that inspect EVM bytecode. + - Rapid deployment without optimization. + +- Choose PolkaVM if you want: + + - Better performance for computation-heavy applications. + - Lower execution costs for intensive operations. + - Access to next-generation smart contract features. + +If you are unsure which to choose, start with REVM for immediate compatibility, then consider PolkaVM for performance optimization once deployed. + +### Do I need to rewrite my Solidity code? + +No, for most contracts. Standard Solidity patterns work on both backends. + +### What about factory contracts? + +- **REVM**: Factory contracts work identically to Ethereum with no changes needed. + + The original factory pattern is: + + ```solidity + contract TokenFactory { + function createToken(string memory name) public returns (address) { + // Creates new contract at runtime + Token newToken = new Token(name); + return address(newToken); + } + } + ``` + +- **PolkaVM**: Factory contracts require pre-uploading dependent contracts. + + Here's how to adapt the original factory pattern: + + ```solidity + contract TokenFactory { + // Reference pre-uploaded Token contract by hash + bytes32 public tokenCodeHash; + + constructor(bytes32 _tokenCodeHash) { + tokenCodeHash = _tokenCodeHash; + } + + function createToken(string memory name) public returns (address) { + // Instantiate from pre-uploaded code + Token newToken = new Token{salt: keccak256(abi.encode(name))}(name); + return address(newToken); + } + } + ``` + +The deployment steps for PolkaVM factories are: + +1. Upload the contract code to the chain. +2. Note the returned code hash. +3. Deploy the Factory contract with the contract code hash. +4. Factory can now instantiate contracts using the pre-uploaded code. + +### How do gas costs compare? + +For more information on gas costs, see the [Gas Model](/smart-contracts/for-eth-devs/gas-model/){target=\_blank} page. + +### Which Solidity features are not supported? + +For REVM, any Solidity feature will function smoothly without requiring changes or adaptations. For PVM, there are considerations, as was mentioned above. + +For PolkaVM, there are some considerations: + +- `EXTCODECOPY`: Only works in constructor code. +- Runtime code modification: Use on-chain constructors instead. +- **Gas stipends**: `address.send()` and `address.transfer()` don't provide reentrancy protection. +- **Unsupported operations**: `pc`, `extcodecopy`, `selfdestruct`, `blobhash`, and `blobbasefee` (blob-related operations). + +### How do I handle the existential deposit? + +Polkadot requires accounts to maintain a minimum balance (existential deposit or ED) to remain active. + +This is handled automatically for you: + +- Balance queries via Ethereum RPC automatically deduct the ED. +- New account transfers include ED in transaction fees. +- Contract-to-contract transfers draw ED from the transaction signer. + +You typically don't need to do anything special, but be aware: + +- Accounts below ED threshold are automatically deleted. +- ED is around 0.01 DOT (varies by network). +- Your contracts don't need to manage this explicitly. + +### Can I use my existing development tools? + +Yes. Both backends support: + +- **Wallets**: [MetaMask](https://metamask.io/){target=\_blank}, [Talisman](https://talisman.xyz/){target=\_blank}, [SubWallet](https://www.subwallet.app/){target=\_blank} +- **Development frameworks**: [Hardhat](/smart-contracts/cookbook/smart-contracts/deploy-basic/hardhat/){target=\_blank}, [Foundry](/smart-contracts/cookbook/smart-contracts/deploy-basic/foundry/){target=\_blank}, [Remix](/smart-contracts/cookbook/smart-contracts/deploy-basic/remix/){target=\_blank} (just consider that for PVM bytecode, you will use the Polkadot version of the tooling) +- **Libraries**: [ethers.js](/smart-contracts/libraries/ethers-js/){target=\_blank}, [web3.js](/smart-contracts/libraries/web3-js/){target=\_blank}, [viem](/smart-contracts/libraries/viem/){target=\_blank} +- **Testing tools**: Your existing test suites work + +Connect to Polkadot Hub's Ethereum JSON-RPC endpoint and use your familiar workflow. + +## Conclusion + +Most Ethereum contracts migrate to Polkadot Hub with minimal or no changes. Use REVM for seamless compatibility or PolkaVM for enhanced performance. + +There are a few key points to keep in mind during migration: + +- Replace `transfer()` and `send()` with `.call{value}("")` and use reentrancy guards (for projects that will use PVM bytecode, not EVM bytecode). +- PolkaVM factory contracts using PVM bytecode need pre-uploaded dependencies. +- Don't hardcode gas values. +- Test thoroughly on [TestNet](/smart-contracts/connect/#__tabbed_1_1){target=\_blank} before mainnet deployment. + +Your existing Solidity knowledge and tooling transfer directly to Polkadot Hub, making migration straightforward for standard smart contract patterns. diff --git a/.ai/site-index.json b/.ai/site-index.json index 64e35be44..1882988e9 100644 --- a/.ai/site-index.json +++ b/.ai/site-index.json @@ -17,7 +17,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -38,7 +37,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -59,7 +57,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -80,7 +77,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -101,7 +97,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -122,7 +117,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -234,7 +228,6 @@ "estimated_token_count_total": 4830 }, "hash": "sha256:a6bf7623a535e7a9162c0913b07bd59d43c8535025ad8225fb3e5adc83084c7a", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -306,7 +299,6 @@ "estimated_token_count_total": 7755 }, "hash": "sha256:086a87823ab67ceac102358030e316583cd733c0ec326316e7f29061fe7f6934", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -327,7 +319,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -389,7 +380,6 @@ "estimated_token_count_total": 5207 }, "hash": "sha256:91f59a76dd33641ca2b5bf6d58230f65034fa3cc5f8313525fb57e854a878a56", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -481,7 +471,6 @@ "estimated_token_count_total": 2132 }, "hash": "sha256:1b9efd2fe00b251d3b4054c9cfcb55f9b5a1384238eeaca81a6f1542fc36d75c", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -502,7 +491,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -569,7 +557,6 @@ "estimated_token_count_total": 4063 }, "hash": "sha256:bd07cdae71bf63786994865d2f33fba5f7bf8855dce6399414ad44ab0ec6635c", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -626,7 +613,6 @@ "estimated_token_count_total": 2225 }, "hash": "sha256:e916033f54c2874eb5ce9a43d58af058eb935429f73b7b1acc7da1592218e0b8", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -674,7 +660,6 @@ "estimated_token_count_total": 1523 }, "hash": "sha256:d9d85827d2c14bff8dd6b3301617345430cf63db603e37859720713004ecafae", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -694,9 +679,7 @@ "headings": 0, "estimated_token_count_total": 0 }, - "hash": "sha256:2b017d8a89f8734b9cbb501f03612a22657d2f8d4d85c51e490e4c8ca4bf771b", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", "token_estimator": "heuristic-v1" }, { @@ -754,7 +737,6 @@ "estimated_token_count_total": 1635 }, "hash": "sha256:46252e238b0b51105148dc622da6d8809c55ec11da7ec7b2953c35ca52f5f585", - "last_modified": "2025-10-28T14:42:10+00:00", "token_estimator": "heuristic-v1" }, { @@ -797,7 +779,6 @@ "estimated_token_count_total": 1491 }, "hash": "sha256:db37b2f5888f283b5eb5bd84a5f8c81fc66b2313e3f94f510a73dfeb310ae3f0", - "last_modified": "2025-10-28T14:42:11+00:00", "token_estimator": "heuristic-v1" }, { @@ -864,7 +845,6 @@ "estimated_token_count_total": 955 }, "hash": "sha256:72ee7394fd1308c111a8d548cb4dc63c6b9bc5b6e2bb556dd1baacbaedb92286", - "last_modified": "2025-10-28T14:42:11+00:00", "token_estimator": "heuristic-v1" }, { @@ -916,7 +896,6 @@ "estimated_token_count_total": 876 }, "hash": "sha256:d6cb22337280a19bdf24981dcba98f337d48ee4f79ce7ac040466ef1cb4b330b", - "last_modified": "2025-10-28T14:42:11+00:00", "token_estimator": "heuristic-v1" }, { @@ -998,7 +977,6 @@ "estimated_token_count_total": 2744 }, "hash": "sha256:1a2d34ccab19bd71263763bbc294977acf34f5800398f51398753594cfc7d7a6", - "last_modified": "2025-10-28T14:42:11+00:00", "token_estimator": "heuristic-v1" }, { @@ -1070,7 +1048,6 @@ "estimated_token_count_total": 608 }, "hash": "sha256:7bba6105d99721373aa6f494627d20af97b1851c19703f26be26c32f0c83524b", - "last_modified": "2025-10-28T14:42:11+00:00", "token_estimator": "heuristic-v1" }, { @@ -1137,7 +1114,6 @@ "estimated_token_count_total": 558 }, "hash": "sha256:b79fe56c9604712825bdf30d17667fd8f237fce9691be0d8d042d38691dbba7a", - "last_modified": "2025-10-28T14:42:11+00:00", "token_estimator": "heuristic-v1" }, { @@ -1189,7 +1165,58 @@ "estimated_token_count_total": 348 }, "hash": "sha256:11cd8d428fa9c3e70490da5c63ce4597cd89ec46306d2bb49b016ced6aa68c3d", - "last_modified": "2025-10-28T14:42:11+00:00", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-interoperability-versions-v5", + "title": "XCMv5", + "slug": "develop-interoperability-versions-v5", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-interoperability-versions-v5.md", + "html_url": "https://docs.polkadot.com/develop/interoperability/versions/v5/", + "preview": "The latest iteration of XCM is version 5. The main RFCs defining the changes in version 5 are the following:", + "outline": [ + { + "depth": 2, + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 2970, + "words": 438, + "headings": 1, + "estimated_token_count_total": 12 + }, + "hash": "sha256:3821c2ef97699091b76e1de58e6d95e866df69d39fca16f2a15c156b71da5b22", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-interoperability-versions", + "title": "XCM Versions", + "slug": "develop-interoperability-versions", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-interoperability-versions.md", + "html_url": "https://docs.polkadot.com/develop/interoperability/versions/", + "preview": "XCM is a versioned language that evolves to meet the growing needs of cross-chain communication in the Polkadot ecosystem. Understanding XCM versioning is essential for developers building interoperable applications to keep up with the latest improvements.", + "outline": [ + { + "depth": 2, + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 835, + "words": 114, + "headings": 1, + "estimated_token_count_total": 12 + }, + "hash": "sha256:634e299f347beb8ad690697943bb7f99915d62d40cda4227179619ed18abe2ff", "token_estimator": "heuristic-v1" }, { @@ -1237,7 +1264,6 @@ "estimated_token_count_total": 1365 }, "hash": "sha256:5f8fa89fc725c5c559975012fe2f9ae92c3b62f10024b5688dcd118331118f1a", - "last_modified": "2025-10-28T14:42:11+00:00", "token_estimator": "heuristic-v1" }, { @@ -1290,7 +1316,6 @@ "estimated_token_count_total": 4979 }, "hash": "sha256:ed3b7c8101b69f9c907cca7c5edfef67fdb5e7bc3c8df8d9fbad297f9dd3c80a", - "last_modified": "2025-10-28T14:42:11+00:00", "token_estimator": "heuristic-v1" }, { @@ -1347,7 +1372,6 @@ "estimated_token_count_total": 1781 }, "hash": "sha256:35c71a215558cd0642d363e4515ad240093995d42720e6495cd2994c859243e4", - "last_modified": "2025-10-28T14:42:11+00:00", "token_estimator": "heuristic-v1" }, { @@ -1394,7 +1418,6 @@ "estimated_token_count_total": 1447 }, "hash": "sha256:0e39aee80fbcf3dfaa19133f31d664914ed45b42a1a929270f05d8ae876b89e2", - "last_modified": "2025-10-28T14:42:11+00:00", "token_estimator": "heuristic-v1" }, { @@ -1441,7 +1464,6 @@ "estimated_token_count_total": 1082 }, "hash": "sha256:ec82957c768c2c07a272e7a28659c812b223df836e21372b1642f0bb249d7b39", - "last_modified": "2025-10-28T14:42:11+00:00", "token_estimator": "heuristic-v1" }, { @@ -1483,7 +1505,63 @@ "estimated_token_count_total": 4178 }, "hash": "sha256:d480791a76082937b47c77f7cf3794e701f193452ed347fcb1c04c3c67577bf5", - "last_modified": "2025-10-28T14:42:11+00:00", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-interoperability-xcm-guides-from-apps", + "title": "From Apps", + "slug": "develop-interoperability-xcm-guides-from-apps", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-interoperability-xcm-guides-from-apps.md", + "html_url": "https://docs.polkadot.com/develop/interoperability/xcm-guides/from-apps/", + "preview": "This section shows how to interact with XCM from applications, providing practical guidance for implementing cross-chain functionality in your dApps and services.", + "outline": [ + { + "depth": 2, + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 511, + "words": 70, + "headings": 1, + "estimated_token_count_total": 12 + }, + "hash": "sha256:63584f5b1dab7b67b18b35b47dfc19d00ad5c013804772f0d653a11ac3fca38d", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-interoperability-xcm-guides", + "title": "XCM Guides", + "slug": "develop-interoperability-xcm-guides", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-interoperability-xcm-guides.md", + "html_url": "https://docs.polkadot.com/develop/interoperability/xcm-guides/", + "preview": "This section provides comprehensive guides for implementing XCM functionality, including application development patterns, fee management, asset transfers, and cross-chain transaction handling.", + "outline": [ + { + "depth": 2, + "title": "In This Section", + "anchor": "in-this-section" + }, + { + "depth": 2, + "title": "Additional Resources", + "anchor": "additional-resources" + } + ], + "stats": { + "chars": 1663, + "words": 215, + "headings": 2, + "estimated_token_count_total": 340 + }, + "hash": "sha256:d4c2d7fd46ddf60f638f948c88ba3940de6d69f140923ba8df52ed787b0afede", "token_estimator": "heuristic-v1" }, { @@ -1551,7 +1629,37 @@ "estimated_token_count_total": 6510 }, "hash": "sha256:353ad782303ef79bce1262bfa945e6f11b3c3c9ca1edf5705b778c46bada6200", - "last_modified": "2025-10-28T14:42:12+00:00", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-interoperability", + "title": "Interoperability", + "slug": "develop-interoperability", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-interoperability.md", + "html_url": "https://docs.polkadot.com/develop/interoperability/", + "preview": "This section covers everything you need to know about building and implementing [Cross-Consensus Messaging (XCM)](/parachains/interoperability/get-started/){target=\\_blank} solutions in the Polkadot ecosystem. Whether you're working on establishing cross-chain channels, sending and receiving XCM messages, or testing and debugging your cross-chain configurations, you'll find the essential resources and tools here to support your interoperability needs, regardless of your development focus.", + "outline": [ + { + "depth": 2, + "title": "In This Section", + "anchor": "in-this-section" + }, + { + "depth": 2, + "title": "Additional Resources", + "anchor": "additional-resources" + } + ], + "stats": { + "chars": 2363, + "words": 323, + "headings": 2, + "estimated_token_count_total": 402 + }, + "hash": "sha256:5da6bdeec1deee5ef3d7ab1a43f546067bcef91acdc67df4ce114ee8f8669e82", "token_estimator": "heuristic-v1" }, { @@ -1614,19 +1722,19 @@ "estimated_token_count_total": 1520 }, "hash": "sha256:ed09ef7a6abe21204006186fd5791ada7597688fad67e30244dc449c51330309", - "last_modified": "2025-10-28T14:42:12+00:00", "token_estimator": "heuristic-v1" }, { - "id": "develop-parachains-customize-parachain-add-existing-pallets", - "title": "Add a Pallet to the Runtime", - "slug": "develop-parachains-customize-parachain-add-existing-pallets", + "id": "develop-parachains-customize-parachain-overview", + "title": "Overview of FRAME", + "slug": "develop-parachains-customize-parachain-overview", "categories": [ + "Basics", "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-customize-parachain-add-existing-pallets.md", - "html_url": "https://docs.polkadot.com/develop/parachains/customize-parachain/add-existing-pallets/", - "preview": "The [Polkadot SDK Solochain Template](https://github.com/paritytech/polkadot-sdk-solochain-template){target=\\_blank} provides a functional runtime that includes default FRAME development modules (pallets) to help you get started with building a custom blockchain.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-customize-parachain-overview.md", + "html_url": "https://docs.polkadot.com/develop/parachains/customize-parachain/overview/", + "preview": "The runtime is the heart of any Polkadot SDK-based blockchain, handling the essential logic that governs state changes and transaction processing. With Polkadot SDK’s [FRAME (Framework for Runtime Aggregation of Modularized Entities)](/reference/glossary/#frame-framework-for-runtime-aggregation-of-modularized-entities){target=\\_bank}, developers gain access to a powerful suite of tools for building custom blockchain runtimes. FRAME offers a modular architecture, featuring reusable pallets and su", "outline": [ { "depth": 2, @@ -1635,91 +1743,38 @@ }, { "depth": 2, - "title": "Configuring Runtime Dependencies", - "anchor": "configuring-runtime-dependencies" - }, - { - "depth": 2, - "title": "Dependencies for a New Pallet", - "anchor": "dependencies-for-a-new-pallet" - }, - { - "depth": 2, - "title": "Config Trait for Pallets", - "anchor": "config-trait-for-pallets" + "title": "FRAME Runtime Architecture", + "anchor": "frame-runtime-architecture" }, { "depth": 3, - "title": "Utility Pallet Example", - "anchor": "utility-pallet-example" - }, - { - "depth": 2, - "title": "Parameter Configuration for Pallets", - "anchor": "parameter-configuration-for-pallets" - }, - { - "depth": 2, - "title": "Pallet Config in the Runtime", - "anchor": "pallet-config-in-the-runtime" + "title": "Pallets", + "anchor": "pallets" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 11939, - "words": 1615, - "headings": 8, - "estimated_token_count_total": 2598 - }, - "hash": "sha256:b2b3d8c048863e7760f633b12ab2a0202c741be3050ea4beafb9a7265cfe96b5", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-parachains-customize-parachain-add-pallet-instances", - "title": "Add Multiple Pallet Instances", - "slug": "develop-parachains-customize-parachain-add-pallet-instances", - "categories": [ - "Parachains" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-customize-parachain-add-pallet-instances.md", - "html_url": "https://docs.polkadot.com/develop/parachains/customize-parachain/add-pallet-instances/", - "preview": "Running multiple instances of the same pallet within a runtime is a powerful technique in Polkadot SDK development. This approach lets you reuse pallet functionality without reimplementing it, enabling diverse use cases with the same codebase. The Polkadot SDK provides developer-friendly traits for creating instantiable pallets and, in most cases, handles unique storage allocation for different instances automatically. This guide teaches you how to implement and configure multiple instances of a", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "depth": 3, + "title": "Support Libraries", + "anchor": "support-libraries" }, { "depth": 2, - "title": "Understanding Instantiable Pallets", - "anchor": "understanding-instantiable-pallets" + "title": "Compose a Runtime with Pallets", + "anchor": "compose-a-runtime-with-pallets" }, { "depth": 2, - "title": "Adding Instantiable Pallets to Your Runtime", - "anchor": "adding-instantiable-pallets-to-your-runtime" - }, - { - "depth": 3, - "title": "Define Pallet Parameters", - "anchor": "define-pallet-parameters" + "title": "Starting from Templates", + "anchor": "starting-from-templates" }, { "depth": 3, - "title": "Configure the Pallet Instances", - "anchor": "configure-the-pallet-instances" + "title": "Solochain Templates", + "anchor": "solochain-templates" }, { "depth": 3, - "title": "Add Pallet Instances to the Runtime", - "anchor": "add-pallet-instances-to-the-runtime" + "title": "Parachain Templates", + "anchor": "parachain-templates" }, { "depth": 2, @@ -1728,69 +1783,55 @@ } ], "stats": { - "chars": 6294, - "words": 729, - "headings": 7, - "estimated_token_count_total": 1219 + "chars": 9427, + "words": 1267, + "headings": 9, + "estimated_token_count_total": 2019 }, - "hash": "sha256:262e7a3ad3d0a0102897c52c7589e3f94c7827c441398b3b446b205f6c6753d3", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:d03ea172f2af9f4648e730d60033a80c2c1e64efa9241fed0c1ba40a5f846ae5", "token_estimator": "heuristic-v1" }, { - "id": "develop-parachains-customize-parachain-add-smart-contract-functionality", - "title": "Add Smart Contract Functionality", - "slug": "develop-parachains-customize-parachain-add-smart-contract-functionality", + "id": "develop-parachains-customize-parachain", + "title": "Customize Your Parachain", + "slug": "develop-parachains-customize-parachain", "categories": [ - "Parachains" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-customize-parachain-add-smart-contract-functionality.md", - "html_url": "https://docs.polkadot.com/develop/parachains/customize-parachain/add-smart-contract-functionality/", - "preview": "When building your custom blockchain with the Polkadot SDK, you have the flexibility to add smart contract capabilities through specialized pallets. These pallets allow blockchain users to deploy and execute smart contracts, enhancing your chain's functionality and programmability.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-customize-parachain.md", + "html_url": "https://docs.polkadot.com/develop/parachains/customize-parachain/", + "preview": "Learn how to build a custom parachain with Polkadot SDK's FRAME framework, which includes pallet development, testing, smart contracts, and runtime customization. Pallets are modular components within the FRAME ecosystem that contain specific blockchain functionalities. This modularity grants developers increased flexibility and control around which behaviors to include in the core logic of their parachain.", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "EVM Smart Contracts", - "anchor": "evm-smart-contracts" - }, - { - "depth": 2, - "title": "Wasm Smart Contracts", - "anchor": "wasm-smart-contracts" + "title": "In This Section", + "anchor": "in-this-section" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Additional Resources", + "anchor": "additional-resources" } ], "stats": { - "chars": 3896, - "words": 523, - "headings": 4, - "estimated_token_count_total": 905 + "chars": 1899, + "words": 259, + "headings": 2, + "estimated_token_count_total": 335 }, - "hash": "sha256:ad8e6d9c77d5451c5f4d17f8e6311b21e6ad24eae8780fd4c3ae6013744822cf", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:9a08b66442c564c7116c686d8914b74ad617326f450d0894b05e753462f69aac", "token_estimator": "heuristic-v1" }, { - "id": "develop-parachains-customize-parachain-make-custom-pallet", - "title": "Make a Custom Pallet", - "slug": "develop-parachains-customize-parachain-make-custom-pallet", + "id": "develop-parachains-deployment-build-deterministic-runtime", + "title": "Build a deterministic runtime", + "slug": "develop-parachains-deployment-build-deterministic-runtime", "categories": [ "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-customize-parachain-make-custom-pallet.md", - "html_url": "https://docs.polkadot.com/develop/parachains/customize-parachain/make-custom-pallet/", - "preview": "FRAME provides a powerful set of tools for blockchain development, including a library of pre-built pallets. However, its true strength lies in the ability to create custom pallets tailored to your specific needs. This section will guide you through creating your own custom pallet, allowing you to extend your blockchain's functionality in unique ways.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-deployment-build-deterministic-runtime.md", + "html_url": "https://docs.polkadot.com/develop/parachains/deployment/build-deterministic-runtime/", + "preview": "By default, the Rust compiler produces optimized Wasm binaries. These binaries are suitable for working in an isolated environment, such as local development. However, the Wasm binaries the compiler builds by default aren't guaranteed to be deterministically reproducible. Each time the compiler generates the Wasm runtime, it might produce a slightly different Wasm byte code. This is problematic in a blockchain network where all nodes must use exactly the same raw chain specification file.", "outline": [ { "depth": 2, @@ -1799,67 +1840,64 @@ }, { "depth": 2, - "title": "Initial Setup", - "anchor": "initial-setup" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Pallet Configuration", - "anchor": "pallet-configuration" + "title": "Tooling for Wasm Runtime", + "anchor": "tooling-for-wasm-runtime" }, { "depth": 2, - "title": "Pallet Events", - "anchor": "pallet-events" + "title": "Working with the Docker Container", + "anchor": "working-with-the-docker-container" }, { "depth": 2, - "title": "Pallet Errors", - "anchor": "pallet-errors" + "title": "Prepare the Environment", + "anchor": "prepare-the-environment" }, { "depth": 2, - "title": "Pallet Storage", - "anchor": "pallet-storage" + "title": "Start a Deterministic Build", + "anchor": "start-a-deterministic-build" }, { "depth": 2, - "title": "Pallet Dispatchable Extrinsics", - "anchor": "pallet-dispatchable-extrinsics" + "title": "Use srtool in GitHub Actions", + "anchor": "use-srtool-in-github-actions" }, { "depth": 2, - "title": "Pallet Implementation Overview", - "anchor": "pallet-implementation-overview" + "title": "Use the srtool Image via Docker Hub", + "anchor": "use-the-srtool-image-via-docker-hub" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "depth": 3, + "title": "Naming Convention for Images", + "anchor": "naming-convention-for-images" } ], "stats": { - "chars": 17824, - "words": 2311, + "chars": 8470, + "words": 1227, "headings": 9, - "estimated_token_count_total": 3995 + "estimated_token_count_total": 1944 }, - "hash": "sha256:19997d390abf2847824024ba923f46a61106ef77544d256d50b371210816b309", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:4fc8cab40e982e860b64d9aede1058fe7fa82ec321ac215b919db00c4df0a9c0", "token_estimator": "heuristic-v1" }, { - "id": "develop-parachains-customize-parachain-overview", - "title": "Overview of FRAME", - "slug": "develop-parachains-customize-parachain-overview", + "id": "develop-parachains-deployment-coretime-renewal", + "title": "Coretime Renewal", + "slug": "develop-parachains-deployment-coretime-renewal", "categories": [ - "Basics", "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-customize-parachain-overview.md", - "html_url": "https://docs.polkadot.com/develop/parachains/customize-parachain/overview/", - "preview": "The runtime is the heart of any Polkadot SDK-based blockchain, handling the essential logic that governs state changes and transaction processing. With Polkadot SDK’s [FRAME (Framework for Runtime Aggregation of Modularized Entities)](/reference/glossary/#frame-framework-for-runtime-aggregation-of-modularized-entities){target=\\_bank}, developers gain access to a powerful suite of tools for building custom blockchain runtimes. FRAME offers a modular architecture, featuring reusable pallets and su", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-deployment-coretime-renewal.md", + "html_url": "https://docs.polkadot.com/develop/parachains/deployment/coretime-renewal/", + "preview": "Coretime can be purchased in bulk for a period of 28 days, providing access to Polkadot's shared security and interoperability for Polkadot parachains. The bulk purchase of coretime includes a rent-control mechanism that keeps future purchases within a predictable price range of the initial purchase. This allows cores to be renewed at a known price without competing against other participants in the open market.", "outline": [ { "depth": 2, @@ -1868,162 +1906,28 @@ }, { "depth": 2, - "title": "FRAME Runtime Architecture", - "anchor": "frame-runtime-architecture" - }, - { - "depth": 3, - "title": "Pallets", - "anchor": "pallets" + "title": "Bulk Sale Phases", + "anchor": "bulk-sale-phases" }, { - "depth": 3, - "title": "Support Libraries", - "anchor": "support-libraries" + "depth": 2, + "title": "Renewal Timing", + "anchor": "renewal-timing" }, { "depth": 2, - "title": "Compose a Runtime with Pallets", - "anchor": "compose-a-runtime-with-pallets" + "title": "Manual Renewal", + "anchor": "manual-renewal" }, { "depth": 2, - "title": "Starting from Templates", - "anchor": "starting-from-templates" + "title": "Auto-Renewal", + "anchor": "auto-renewal" }, { "depth": 3, - "title": "Solochain Templates", - "anchor": "solochain-templates" - }, - { - "depth": 3, - "title": "Parachain Templates", - "anchor": "parachain-templates" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 9427, - "words": 1267, - "headings": 9, - "estimated_token_count_total": 2019 - }, - "hash": "sha256:0becb82886d34e2ed23d963efd2c14120112e6e080ea4072e864531299b59753", - "last_modified": "2025-10-28T14:42:12+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-parachains-deployment-build-deterministic-runtime", - "title": "Build a deterministic runtime", - "slug": "develop-parachains-deployment-build-deterministic-runtime", - "categories": [ - "Parachains" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-deployment-build-deterministic-runtime.md", - "html_url": "https://docs.polkadot.com/develop/parachains/deployment/build-deterministic-runtime/", - "preview": "By default, the Rust compiler produces optimized Wasm binaries. These binaries are suitable for working in an isolated environment, such as local development. However, the Wasm binaries the compiler builds by default aren't guaranteed to be deterministically reproducible. Each time the compiler generates the Wasm runtime, it might produce a slightly different Wasm byte code. This is problematic in a blockchain network where all nodes must use exactly the same raw chain specification file.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Tooling for Wasm Runtime", - "anchor": "tooling-for-wasm-runtime" - }, - { - "depth": 2, - "title": "Working with the Docker Container", - "anchor": "working-with-the-docker-container" - }, - { - "depth": 2, - "title": "Prepare the Environment", - "anchor": "prepare-the-environment" - }, - { - "depth": 2, - "title": "Start a Deterministic Build", - "anchor": "start-a-deterministic-build" - }, - { - "depth": 2, - "title": "Use srtool in GitHub Actions", - "anchor": "use-srtool-in-github-actions" - }, - { - "depth": 2, - "title": "Use the srtool Image via Docker Hub", - "anchor": "use-the-srtool-image-via-docker-hub" - }, - { - "depth": 3, - "title": "Naming Convention for Images", - "anchor": "naming-convention-for-images" - } - ], - "stats": { - "chars": 8470, - "words": 1227, - "headings": 9, - "estimated_token_count_total": 1944 - }, - "hash": "sha256:4fc8cab40e982e860b64d9aede1058fe7fa82ec321ac215b919db00c4df0a9c0", - "last_modified": "2025-10-28T14:42:12+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-parachains-deployment-coretime-renewal", - "title": "Coretime Renewal", - "slug": "develop-parachains-deployment-coretime-renewal", - "categories": [ - "Parachains" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-deployment-coretime-renewal.md", - "html_url": "https://docs.polkadot.com/develop/parachains/deployment/coretime-renewal/", - "preview": "Coretime can be purchased in bulk for a period of 28 days, providing access to Polkadot's shared security and interoperability for Polkadot parachains. The bulk purchase of coretime includes a rent-control mechanism that keeps future purchases within a predictable price range of the initial purchase. This allows cores to be renewed at a known price without competing against other participants in the open market.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Bulk Sale Phases", - "anchor": "bulk-sale-phases" - }, - { - "depth": 2, - "title": "Renewal Timing", - "anchor": "renewal-timing" - }, - { - "depth": 2, - "title": "Manual Renewal", - "anchor": "manual-renewal" - }, - { - "depth": 2, - "title": "Auto-Renewal", - "anchor": "auto-renewal" - }, - { - "depth": 3, - "title": "Set Up an HRMP Channel", - "anchor": "set-up-an-hrmp-channel" + "title": "Set Up an HRMP Channel", + "anchor": "set-up-an-hrmp-channel" }, { "depth": 3, @@ -2053,7 +1957,6 @@ "estimated_token_count_total": 3068 }, "hash": "sha256:9918593a46c12a1756552ddfaf7421ad6262600735b6f1fec030911420fe1736", - "last_modified": "2025-10-28T14:42:12+00:00", "token_estimator": "heuristic-v1" }, { @@ -2135,7 +2038,6 @@ "estimated_token_count_total": 3025 }, "hash": "sha256:a60fe36a5ba6d1cafe12eab75300afd24a46d3ace1e791087adb7e3e538afcc3", - "last_modified": "2025-10-28T14:42:12+00:00", "token_estimator": "heuristic-v1" }, { @@ -2187,7 +2089,6 @@ "estimated_token_count_total": 1289 }, "hash": "sha256:39c58dbe2ddcd542d7074d08d72f1811318dc8a3130419025480fd5cbe9fc3e7", - "last_modified": "2025-10-28T14:42:12+00:00", "token_estimator": "heuristic-v1" }, { @@ -2223,152 +2124,7 @@ "headings": 3, "estimated_token_count_total": 966 }, - "hash": "sha256:358ed14147b96b47deb61df9a1ea0e1103a139ea5edb78c5d50a48d5a779b80d", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-parachains-install-polkadot-sdk", - "title": "Install Polkadot SDK Dependencies", - "slug": "develop-parachains-install-polkadot-sdk", - "categories": [ - "Basics", - "Tooling" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-install-polkadot-sdk.md", - "html_url": "https://docs.polkadot.com/develop/parachains/install-polkadot-sdk/", - "preview": "This guide provides step-by-step instructions for installing the dependencies you need to work with the Polkadot SDK-based chains on macOS, Linux, and Windows. Follow the appropriate section for your operating system to ensure all necessary tools are installed and configured properly.", - "outline": [ - { - "depth": 2, - "title": "macOS", - "anchor": "macos" - }, - { - "depth": 3, - "title": "Before You Begin", - "anchor": "before-you-begin" - }, - { - "depth": 3, - "title": "Install Required Packages and Rust", - "anchor": "install-required-packages-and-rust" - }, - { - "depth": 2, - "title": "Linux", - "anchor": "linux" - }, - { - "depth": 3, - "title": "Before You Begin {: #before-you-begin-linux }", - "anchor": "before-you-begin-before-you-begin-linux" - }, - { - "depth": 3, - "title": "Install Required Packages and Rust {: #install-required-packages-and-rust-linux }", - "anchor": "install-required-packages-and-rust-install-required-packages-and-rust-linux" - }, - { - "depth": 2, - "title": "Windows (WSL)", - "anchor": "windows-wsl" - }, - { - "depth": 3, - "title": "Before You Begin {: #before-you-begin-windows }", - "anchor": "before-you-begin-before-you-begin-windows" - }, - { - "depth": 3, - "title": "Set Up Windows Subsystem for Linux", - "anchor": "set-up-windows-subsystem-for-linux" - }, - { - "depth": 3, - "title": "Install Required Packages and Rust {: #install-required-packages-and-rust-windows }", - "anchor": "install-required-packages-and-rust-install-required-packages-and-rust-windows" - }, - { - "depth": 2, - "title": "Verifying Installation", - "anchor": "verifying-installation" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 12756, - "words": 1840, - "headings": 12, - "estimated_token_count_total": 2709 - }, - "hash": "sha256:2ee5656f749b4bca445172f2bc66c7fc39af40ff173626662ae4c399f49cf909", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-parachains-intro-polkadot-sdk", - "title": "Introduction to Polkadot SDK", - "slug": "develop-parachains-intro-polkadot-sdk", - "categories": [ - "Basics", - "Tooling" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-intro-polkadot-sdk.md", - "html_url": "https://docs.polkadot.com/develop/parachains/intro-polkadot-sdk/", - "preview": "The [Polkadot SDK](https://github.com/paritytech/polkadot-sdk/tree/polkadot-stable2506-2){target=\\_blank} is a powerful and versatile developer kit designed to facilitate building on the Polkadot network. It provides the necessary components for creating custom blockchains, parachains, generalized rollups, and more. Written in the Rust programming language, it puts security and robustness at the forefront of its design.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Polkadot SDK Overview", - "anchor": "polkadot-sdk-overview" - }, - { - "depth": 3, - "title": "Substrate", - "anchor": "substrate" - }, - { - "depth": 3, - "title": "FRAME", - "anchor": "frame" - }, - { - "depth": 3, - "title": "Cumulus", - "anchor": "cumulus" - }, - { - "depth": 2, - "title": "Why Use Polkadot SDK?", - "anchor": "why-use-polkadot-sdk" - }, - { - "depth": 2, - "title": "Create a Custom Blockchain Using the SDK", - "anchor": "create-a-custom-blockchain-using-the-sdk" - } - ], - "stats": { - "chars": 8758, - "words": 1156, - "headings": 7, - "estimated_token_count_total": 1892 - }, - "hash": "sha256:74de798c287cae75729e7db54019507f03a361dbbd1f2bb58c4694605f83efab", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:b25618dc598f4f946da06f854211645768214e0b51d06b684b0cab668b66124c", "token_estimator": "heuristic-v1" }, { @@ -2420,7 +2176,6 @@ "estimated_token_count_total": 4719 }, "hash": "sha256:bfad885d8053d052c55dbffc3c09e6196586795c3a1d07ab6ad58f9006ec3345", - "last_modified": "2025-10-28T14:42:12+00:00", "token_estimator": "heuristic-v1" }, { @@ -2482,7 +2237,6 @@ "estimated_token_count_total": 1819 }, "hash": "sha256:b0c1535fa8e969a9bdeee426a5a35a42b4649121fb8ce6fd2b15fdeba35b5d5f", - "last_modified": "2025-10-28T14:42:12+00:00", "token_estimator": "heuristic-v1" }, { @@ -2513,9 +2267,7 @@ "headings": 2, "estimated_token_count_total": 236 }, - "hash": "sha256:07e63e1e99b9acf1cc3b5ef8fa1f06ff22182b2a801582ce800eba37d7d39408", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:3b0a9e8037c7634c33ac6674170bd763599fca914855d9d2fbf490d359140130", "token_estimator": "heuristic-v1" }, { @@ -2546,9 +2298,7 @@ "headings": 2, "estimated_token_count_total": 211 }, - "hash": "sha256:55dc252fdecf1590048ce8d009b822e90231442abe81e9593cf1635944a31336", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:0ce1fe38de00827a0735b9fa8076492205c2450c61da9fbd1937d9f38cfe7825", "token_estimator": "heuristic-v1" }, { @@ -2579,61 +2329,29 @@ "headings": 2, "estimated_token_count_total": 330 }, - "hash": "sha256:f4964f894f7cd2fdfd699c017b4bd25cffc322b03a5a88a36c682cf952832ccc", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:75a6fa2f21b67009be62e07bab01655a10b2c35a5292dc1f7ca57df846d709f3", "token_estimator": "heuristic-v1" }, { - "id": "develop-parachains-testing-benchmarking", - "title": "Benchmarking FRAME Pallets", - "slug": "develop-parachains-testing-benchmarking", + "id": "develop-smart-contracts-connect-to-kusama", + "title": "Connect to Kusama", + "slug": "develop-smart-contracts-connect-to-kusama", "categories": [ - "Parachains" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-testing-benchmarking.md", - "html_url": "https://docs.polkadot.com/develop/parachains/testing/benchmarking/", - "preview": "Benchmarking is a critical component of developing efficient and secure blockchain runtimes. In the Polkadot ecosystem, accurately benchmarking your custom pallets ensures that each extrinsic has a precise [weight](/polkadot-protocol/glossary/#weight){target=\\_blank}, representing its computational and storage demands. This process is vital for maintaining the blockchain's performance and preventing potential vulnerabilities, such as Denial of Service (DoS) attacks.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-connect-to-kusama.md", + "html_url": "https://docs.polkadot.com/develop/smart-contracts/connect-to-kusama/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Networks Details", + "anchor": "networks-details" }, { "depth": 2, - "title": "The Case for Benchmarking", - "anchor": "the-case-for-benchmarking" - }, - { - "depth": 3, - "title": "Benchmarking and Weight", - "anchor": "benchmarking-and-weight" - }, - { - "depth": 2, - "title": "Benchmarking Process", - "anchor": "benchmarking-process" - }, - { - "depth": 3, - "title": "Prepare Your Environment", - "anchor": "prepare-your-environment" - }, - { - "depth": 3, - "title": "Write Benchmark Tests", - "anchor": "write-benchmark-tests" - }, - { - "depth": 3, - "title": "Add Benchmarks to Runtime", - "anchor": "add-benchmarks-to-runtime" - }, - { - "depth": 3, - "title": "Run Benchmarks", - "anchor": "run-benchmarks" + "title": "Important Deployment Considerations", + "anchor": "important-deployment-considerations" }, { "depth": 2, @@ -2642,217 +2360,206 @@ } ], "stats": { - "chars": 14731, - "words": 1881, - "headings": 9, - "estimated_token_count_total": 3342 + "chars": 3601, + "words": 476, + "headings": 3, + "estimated_token_count_total": 514 }, - "hash": "sha256:9d6daa3f4daf149ae822b60060d14ff022bd4b3440cecdc969a48c105eb82a21", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:e8ffeaa3a17e20437a59f2c95a63821eb75bf3c33001e748c23958b2b99ac3c2", "token_estimator": "heuristic-v1" }, { - "id": "develop-parachains-testing-mock-runtime", - "title": "Mock Runtime for Pallet Testing", - "slug": "develop-parachains-testing-mock-runtime", + "id": "develop-smart-contracts-dev-environments", + "title": "Dev Environments", + "slug": "develop-smart-contracts-dev-environments", "categories": [ - "Parachains" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-testing-mock-runtime.md", - "html_url": "https://docs.polkadot.com/develop/parachains/testing/mock-runtime/", - "preview": "Testing is essential in Polkadot SDK development to ensure your blockchain operates as intended and effectively handles various potential scenarios. This guide walks you through setting up an environment to test pallets within the [runtime](/polkadot-protocol/glossary#runtime){target=_blank}, allowing you to evaluate how different pallets, their configurations, and system components interact to ensure reliable blockchain functionality.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-dev-environments.md", + "html_url": "https://docs.polkadot.com/develop/smart-contracts/dev-environments/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. Explore the tools and frameworks available for building and testing smart contracts on the Polkadot network. These environments streamline the development process, from writing and compiling to testing and deploying smart contracts. The guides in this section will help you evaluate each tool's strengths, making it easier to choose t", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "What to Consider", + "anchor": "what-to-consider" }, { "depth": 2, - "title": "Configuring a Mock Runtime", - "anchor": "configuring-a-mock-runtime" + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 1601, + "words": 154, + "headings": 2, + "estimated_token_count_total": 323 + }, + "hash": "sha256:5c3a10769e30b4da62e6c188e99310354e6e9af4595c7920c2977a54b8e1853c", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-smart-contracts-faqs", + "title": "Polkadot Hub Smart Contract FAQs", + "slug": "develop-smart-contracts-faqs", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-faqs.md", + "html_url": "https://docs.polkadot.com/develop/smart-contracts/faqs/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. !!! note For a list of known incompatibilities, please refer to the [Solidity and Yul IR translation incompatibilities](/polkadot-protocol/smart-contract-basics/evm-vs-polkavm/#solidity-and-yul-ir-translation-incompatibilities){target=\\_blank} section.", + "outline": [ + { + "depth": 2, + "title": "General Questions", + "anchor": "general-questions" }, { "depth": 3, - "title": "Testing Module", - "anchor": "testing-module" + "title": "What are the different types of smart contracts I can build on Polkadot?", + "anchor": "what-are-the-different-types-of-smart-contracts-i-can-build-on-polkadot" }, { "depth": 3, - "title": "Genesis Storage", - "anchor": "genesis-storage" + "title": "Should I build a smart contract or a parachain?", + "anchor": "should-i-build-a-smart-contract-or-a-parachain" }, { "depth": 3, - "title": "Pallet Configuration", - "anchor": "pallet-configuration" + "title": "What's the difference between Polkadot Hub smart contracts and other EVM chains?", + "anchor": "whats-the-difference-between-polkadot-hub-smart-contracts-and-other-evm-chains" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 7493, - "words": 904, - "headings": 6, - "estimated_token_count_total": 1572 - }, - "hash": "sha256:68fc67390e24741081c9a04d78951e76c7d4ff7cf6eddaba7dcbbdc1812c71d3", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-parachains-testing-pallet-testing", - "title": "Pallet Testing", - "slug": "develop-parachains-testing-pallet-testing", - "categories": [ - "Parachains" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-parachains-testing-pallet-testing.md", - "html_url": "https://docs.polkadot.com/develop/parachains/testing/pallet-testing/", - "preview": "Unit testing in the Polkadot SDK helps ensure that the functions provided by a pallet behave as expected. It also confirms that data and events associated with a pallet are processed correctly during interactions. The Polkadot SDK offers a set of APIs to create a test environment to simulate runtime and mock transaction execution for extrinsics and queries.", - "outline": [ + "title": "Development Environment", + "anchor": "development-environment" + }, { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "depth": 3, + "title": "Can I use my existing Ethereum development tools?", + "anchor": "can-i-use-my-existing-ethereum-development-tools" + }, + { + "depth": 3, + "title": "How do I set up local development?", + "anchor": "how-do-i-set-up-local-development" + }, + { + "depth": 3, + "title": "What networks are available for testing and deployment?", + "anchor": "what-networks-are-available-for-testing-and-deployment" }, { "depth": 2, - "title": "Writing Unit Tests", - "anchor": "writing-unit-tests" + "title": "Technical Implementation", + "anchor": "technical-implementation" }, { "depth": 3, - "title": "Test Initialization", - "anchor": "test-initialization" + "title": "How do Ethereum addresses work on Polkadot?", + "anchor": "how-do-ethereum-addresses-work-on-polkadot" }, { "depth": 3, - "title": "Function Call Testing", - "anchor": "function-call-testing" + "title": "What are the key differences in the gas model?", + "anchor": "what-are-the-key-differences-in-the-gas-model" }, { "depth": 3, - "title": "Storage Testing", - "anchor": "storage-testing" + "title": "How does contract deployment work?", + "anchor": "how-does-contract-deployment-work" }, { "depth": 3, - "title": "Event Testing", - "anchor": "event-testing" + "title": "Which Solidity features are not supported?", + "anchor": "which-solidity-features-are-not-supported" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 6871, - "words": 909, - "headings": 7, - "estimated_token_count_total": 1559 - }, - "hash": "sha256:0024f5e4c12ab7b019e5ee183e7c78d175e1125868c5458b97d3accd9fac75bc", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-smart-contracts-connect-to-kusama", - "title": "Connect to Kusama", - "slug": "develop-smart-contracts-connect-to-kusama", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-connect-to-kusama.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/connect-to-kusama/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ", - "outline": [ + "depth": 3, + "title": "How do I handle the existential deposit requirement?", + "anchor": "how-do-i-handle-the-existential-deposit-requirement" + }, { "depth": 2, - "title": "Networks Details", - "anchor": "networks-details" + "title": "Migration and Compatibility", + "anchor": "migration-and-compatibility" }, { - "depth": 2, - "title": "Important Deployment Considerations", - "anchor": "important-deployment-considerations" + "depth": 3, + "title": "Can I migrate my existing Ethereum contracts?", + "anchor": "can-i-migrate-my-existing-ethereum-contracts" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 3601, - "words": 476, - "headings": 3, - "estimated_token_count_total": 514 - }, - "hash": "sha256:e8ffeaa3a17e20437a59f2c95a63821eb75bf3c33001e748c23958b2b99ac3c2", - "last_modified": "2025-10-28T14:42:12+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-smart-contracts-connect-to-polkadot", - "title": "Connect to Polkadot", - "slug": "develop-smart-contracts-connect-to-polkadot", - "categories": [ - "Smart Contracts" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-connect-to-polkadot.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/connect-to-polkadot/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ", - "outline": [ + "title": "Troubleshooting", + "anchor": "troubleshooting" + }, { - "depth": 2, - "title": "Networks Details", - "anchor": "networks-details" + "depth": 3, + "title": "Why are my gas calculations different?", + "anchor": "why-are-my-gas-calculations-different" }, { - "depth": 2, - "title": "Test Tokens", - "anchor": "test-tokens" + "depth": 3, + "title": "I deployed a contract with MetaMask, and got a `code size` error - why?", + "anchor": "i-deployed-a-contract-with-metamask-and-got-a-code-size-error-why" + }, + { + "depth": 3, + "title": "I found a bug, where can I log it?", + "anchor": "i-found-a-bug-where-can-i-log-it" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Known Issues", + "anchor": "known-issues" + }, + { + "depth": 3, + "title": "Runtime Behavior", + "anchor": "runtime-behavior" + }, + { + "depth": 3, + "title": "Development Tools", + "anchor": "development-tools" + }, + { + "depth": 3, + "title": "Contract Patterns", + "anchor": "contract-patterns" + }, + { + "depth": 3, + "title": "Compilation", + "anchor": "compilation" } ], "stats": { - "chars": 3496, - "words": 482, - "headings": 3, - "estimated_token_count_total": 570 + "chars": 7480, + "words": 984, + "headings": 25, + "estimated_token_count_total": 1618 }, - "hash": "sha256:1247dfb5f5ac040bca81cd1002153e0ee53f4052b2a3d40b623834bd7f00d065", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:5cc63ff0a377ef0ec96a064748e13b88bc852bd1862c6e344066855a7fe93b19", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-dev-environments-foundry", - "title": "Use Foundry with Polkadot Hub", - "slug": "develop-smart-contracts-dev-environments-foundry", + "id": "develop-smart-contracts-libraries", + "title": "Libraries", + "slug": "develop-smart-contracts-libraries", "categories": [ "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-dev-environments.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/dev-environments/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. Explore the tools and frameworks available for building and testing smart contracts on the Polkadot network. These environments streamline the development process, from writing and compiling to testing and deploying smart contracts. The guides in this section will help you evaluate each tool's strengths, making it easier to choose t", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-libraries.md", + "html_url": "https://docs.polkadot.com/develop/smart-contracts/libraries/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. Explore the key libraries for interacting with smart contracts on Polkadot-based networks. These libraries simplify contract calls, event listening, and transaction handling.", "outline": [ { "depth": 2, - "title": "What to Consider", - "anchor": "what-to-consider" + "title": "Library Comparison", + "anchor": "library-comparison" }, { "depth": 2, @@ -2861,322 +2568,352 @@ } ], "stats": { - "chars": 1601, - "words": 154, + "chars": 2056, + "words": 203, "headings": 2, - "estimated_token_count_total": 323 + "estimated_token_count_total": 415 }, - "hash": "sha256:72e41f816f07026d96c803f399c71852aa1151c464e79cec3e1746b282d5eaae", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:23137f6c74412fd98c0b6aeee3ff59938e44b817ec42974c453f9b0f66e36513", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-dev-environments-hardhat", - "title": "Use Hardhat with Polkadot Hub", - "slug": "develop-smart-contracts-dev-environments-hardhat", + "id": "develop-smart-contracts-precompiles-interact-with-precompiles", + "title": "Interact with Precompiles", + "slug": "develop-smart-contracts-precompiles-interact-with-precompiles", "categories": [ - "Smart Contracts", - "Tooling" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-dev-environments-hardhat.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/dev-environments/hardhat/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**.
- :octicons-code-16:{ .lg .middle } __Test and Deploy with Hardhat__", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-precompiles-interact-with-precompiles.md", + "html_url": "https://docs.polkadot.com/develop/smart-contracts/precompiles/interact-with-precompiles/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", "outline": [ { "depth": 2, - "title": "Overview", - "anchor": "overview" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" + "title": "Basic Precompile Interaction Pattern", + "anchor": "basic-precompile-interaction-pattern" }, { "depth": 2, - "title": "Set Up Hardhat", - "anchor": "set-up-hardhat" + "title": "ECRecover (0x01)", + "anchor": "ecrecover-0x01" }, { "depth": 2, - "title": "Compile Your Contract", - "anchor": "compile-your-contract" + "title": "SHA-256 (0x02)", + "anchor": "sha-256-0x02" }, { "depth": 2, - "title": "Set Up a Testing Environment", - "anchor": "set-up-a-testing-environment" + "title": "RIPEMD-160 (0x03)", + "anchor": "ripemd-160-0x03" }, { "depth": 2, - "title": "Test Your Contract", - "anchor": "test-your-contract" + "title": "Identity (Data Copy) (0x04)", + "anchor": "identity-data-copy-0x04" }, { "depth": 2, - "title": "Deploy to a Local Node", - "anchor": "deploy-to-a-local-node" + "title": "Modular Exponentiation (0x05)", + "anchor": "modular-exponentiation-0x05" }, { "depth": 2, - "title": "Deploying to a Live Network", - "anchor": "deploying-to-a-live-network" + "title": "BN128 Addition (0x06)", + "anchor": "bn128-addition-0x06" }, { "depth": 2, - "title": "Interacting with Your Contract", - "anchor": "interacting-with-your-contract" + "title": "BN128 Scalar Multiplication (0x07)", + "anchor": "bn128-scalar-multiplication-0x07" }, { "depth": 2, - "title": "Upgrading the Plugin", - "anchor": "upgrading-the-plugin" + "title": "BN128 Pairing Check (0x08)", + "anchor": "bn128-pairing-check-0x08" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Blake2F (0x09)", + "anchor": "blake2f-0x09" + }, + { + "depth": 2, + "title": "Conclusion", + "anchor": "conclusion" } ], "stats": { - "chars": 18520, - "words": 2475, - "headings": 11, - "estimated_token_count_total": 4188 + "chars": 18054, + "words": 2190, + "headings": 12, + "estimated_token_count_total": 3847 }, - "hash": "sha256:fe008393aa37c27bb71b4483d4e2c4fbcda94f8c1be461fdd07eff40efbb4e26", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:4b705b8dbe9b0ad8d19a897d91f3c64dbc4541297dadacbea2a31b4778e50a46", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-dev-environments-remix", - "title": "Use the Polkadot Remix IDE", - "slug": "develop-smart-contracts-dev-environments-remix", + "id": "develop-smart-contracts", + "title": "Smart Contracts", + "slug": "develop-smart-contracts", "categories": [ - "Smart Contracts", - "Tooling" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-dev-environments-remix.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/dev-environments/remix/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**.
- :octicons-code-16:{ .lg .middle } __Deploy NFTs Using Remix IDE__", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts.md", + "html_url": "https://docs.polkadot.com/develop/smart-contracts/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. Polkadot allows scalable execution of smart contracts, offering cross-chain compatibility and lower fees than legacy L1 platforms. Polkadot provides developers with flexibility in building smart contracts, supporting both Solidity contracts executed by the [PolkaVM](/smart-contracts/for-eth-devs/#polkavm){target=\\_blank} (a Polkadot", "outline": [ { "depth": 2, - "title": "Overview", - "anchor": "overview" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Accessing Remix IDE", - "anchor": "accessing-remix-ide" - }, - { - "depth": 2, - "title": "Creating a New Contract", - "anchor": "creating-a-new-contract" - }, - { - "depth": 2, - "title": "Compiling Your Contract", - "anchor": "compiling-your-contract" + "title": "Smart Contract Development Process", + "anchor": "smart-contract-development-process" }, { "depth": 2, - "title": "Deploying Contracts", - "anchor": "deploying-contracts" - }, + "title": "Additional Resources", + "anchor": "additional-resources" + } + ], + "stats": { + "chars": 1867, + "words": 247, + "headings": 2, + "estimated_token_count_total": 189 + }, + "hash": "sha256:4b56a119cbc63d87de98554cf4019e48ddb4f7cee11a51553ea234f91d78f8b8", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-toolkit-api-libraries", + "title": "API Libraries", + "slug": "develop-toolkit-api-libraries", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-api-libraries.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/api-libraries/", + "preview": "Explore the powerful API libraries designed for interacting with the Polkadot network. These libraries offer developers versatile tools to build, query, and manage blockchain interactions. Whether you’re working with JavaScript, TypeScript, Python, or RESTful services, they provide the flexibility to efficiently interact with and retrieve data from Polkadot-based chains.", + "outline": [ { "depth": 2, - "title": "Interacting with Contracts", - "anchor": "interacting-with-contracts" + "title": "In This Section", + "anchor": "in-this-section" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Additional Resources", + "anchor": "additional-resources" } ], "stats": { - "chars": 6732, - "words": 913, - "headings": 8, - "estimated_token_count_total": 1375 + "chars": 1082, + "words": 139, + "headings": 2, + "estimated_token_count_total": 187 }, - "hash": "sha256:8e6bfed5fa59bb748e80698ea702f62ce6951c48bdb955ee9ef0d3516e856887", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:746788d1068fe3eaafc34eb461566d1682c27fcad7d448e65810b9662b45dd85", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-faqs", - "title": "Polkadot Hub Smart Contract FAQs", - "slug": "develop-smart-contracts-faqs", + "id": "develop-toolkit-integrations-storage", + "title": "Storage", + "slug": "develop-toolkit-integrations-storage", "categories": [ - "Smart Contracts" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-faqs.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/faqs/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. !!! note For a list of known incompatibilities, please refer to the [Solidity and Yul IR translation incompatibilities](/polkadot-protocol/smart-contract-basics/evm-vs-polkavm/#solidity-and-yul-ir-translation-incompatibilities){target=\\_blank} section.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-integrations-storage.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/integrations/storage/", + "preview": "Polkadot offers developers a range of decentralized storage solutions to manage dApp data, host front ends, and store large files in a censorship-resistant and resilient manner. These integrations are essential for building fully decentralized applications, ensuring that all components of your dApp, from the front end to the data, are not reliant on centralized servers.", "outline": [ { "depth": 2, - "title": "General Questions", - "anchor": "general-questions" + "title": "Key Storage Solutions", + "anchor": "key-storage-solutions" }, { - "depth": 3, - "title": "What are the different types of smart contracts I can build on Polkadot?", - "anchor": "what-are-the-different-types-of-smart-contracts-i-can-build-on-polkadot" + "depth": 2, + "title": "Crust Network", + "anchor": "crust-network" }, { "depth": 3, - "title": "Should I build a smart contract or a parachain?", - "anchor": "should-i-build-a-smart-contract-or-a-parachain" + "title": "Key Features of Crust", + "anchor": "key-features-of-crust" }, { "depth": 3, - "title": "What's the difference between Polkadot Hub smart contracts and other EVM chains?", - "anchor": "whats-the-difference-between-polkadot-hub-smart-contracts-and-other-evm-chains" + "title": "Use Cases", + "anchor": "use-cases" }, { "depth": 2, - "title": "Development Environment", - "anchor": "development-environment" - }, - { - "depth": 3, - "title": "Can I use my existing Ethereum development tools?", - "anchor": "can-i-use-my-existing-ethereum-development-tools" - }, - { - "depth": 3, - "title": "How do I set up local development?", - "anchor": "how-do-i-set-up-local-development" + "title": "IPFS", + "anchor": "ipfs" }, { "depth": 3, - "title": "What networks are available for testing and deployment?", - "anchor": "what-networks-are-available-for-testing-and-deployment" + "title": "Using IPFS with Polkadot", + "anchor": "using-ipfs-with-polkadot" }, { "depth": 2, - "title": "Technical Implementation", - "anchor": "technical-implementation" - }, + "title": "Other Solutions", + "anchor": "other-solutions" + } + ], + "stats": { + "chars": 4369, + "words": 642, + "headings": 7, + "estimated_token_count_total": 847 + }, + "hash": "sha256:a206dd86fc3d80aed22384000839ca0c9c75c69ad461abd9810d96c03cf6a3bd", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-toolkit-integrations-transaction-construction", + "title": "Transaction Construction", + "slug": "develop-toolkit-integrations-transaction-construction", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-integrations-transaction-construction.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/integrations/transaction-construction/", + "preview": "This page will discuss the transaction format in Polkadot and how to create, sign, and broadcast transactions, as well as highlight some of the commands and tools available for integrators.", + "outline": [ { - "depth": 3, - "title": "How do Ethereum addresses work on Polkadot?", - "anchor": "how-do-ethereum-addresses-work-on-polkadot" + "depth": 2, + "title": "Introduction", + "anchor": "introduction" }, { - "depth": 3, - "title": "What are the key differences in the gas model?", - "anchor": "what-are-the-key-differences-in-the-gas-model" + "depth": 2, + "title": "Transaction Format", + "anchor": "transaction-format" }, { "depth": 3, - "title": "How does contract deployment work?", - "anchor": "how-does-contract-deployment-work" + "title": "Mode and Metadata Hash", + "anchor": "mode-and-metadata-hash" }, { "depth": 3, - "title": "Which Solidity features are not supported?", - "anchor": "which-solidity-features-are-not-supported" + "title": "Serialized Transactions and Metadata", + "anchor": "serialized-transactions-and-metadata" }, { "depth": 3, - "title": "How do I handle the existential deposit requirement?", - "anchor": "how-do-i-handle-the-existential-deposit-requirement" + "title": "Transaction Flow", + "anchor": "transaction-flow" }, { "depth": 2, - "title": "Migration and Compatibility", - "anchor": "migration-and-compatibility" + "title": "Polkadot-JS Tools", + "anchor": "polkadot-js-tools" }, { "depth": 3, - "title": "Can I migrate my existing Ethereum contracts?", - "anchor": "can-i-migrate-my-existing-ethereum-contracts" + "title": "Creating a Transaction, Signing, and Submitting", + "anchor": "creating-a-transaction-signing-and-submitting" }, { "depth": 2, - "title": "Troubleshooting", - "anchor": "troubleshooting" - }, - { - "depth": 3, - "title": "Why are my gas calculations different?", - "anchor": "why-are-my-gas-calculations-different" + "title": "Txwrapper", + "anchor": "txwrapper" }, { "depth": 3, - "title": "I deployed a contract with MetaMask, and got a `code size` error - why?", - "anchor": "i-deployed-a-contract-with-metamask-and-got-a-code-size-error-why" - }, - { - "depth": 3, - "title": "I found a bug, where can I log it?", - "anchor": "i-found-a-bug-where-can-i-log-it" + "title": "Creating a Transaction, Signing, and Submitting", + "anchor": "creating-a-transaction-signing-and-submitting-2" }, { "depth": 2, - "title": "Known Issues", - "anchor": "known-issues" - }, - { - "depth": 3, - "title": "Runtime Behavior", - "anchor": "runtime-behavior" - }, - { - "depth": 3, - "title": "Development Tools", - "anchor": "development-tools" - }, + "title": "Additional Libraries for Submitting a Transaction", + "anchor": "additional-libraries-for-submitting-a-transaction" + } + ], + "stats": { + "chars": 27671, + "words": 2949, + "headings": 10, + "estimated_token_count_total": 6280 + }, + "hash": "sha256:9b03477d13a285fced6bf845c3827084f790a626989dc2c09ef9ff53643045f4", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-toolkit-integrations", + "title": "Integrations", + "slug": "develop-toolkit-integrations", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-integrations.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/integrations/", + "preview": "Polkadot offers a wide range of integrations that allow developers to enhance their decentralized applications (dApps) and leverage the full capabilities of the ecosystem. Whether you’re looking to extend your application’s functionality, integrate with other chains, or access specialized services, these integrations provide the tools and resources you need to build efficiently and effectively. Explore the available options to find the solutions that best suit your development needs.", + "outline": [ { - "depth": 3, - "title": "Contract Patterns", - "anchor": "contract-patterns" + "depth": 2, + "title": "Key Integration Solutions", + "anchor": "key-integration-solutions" }, { - "depth": 3, - "title": "Compilation", - "anchor": "compilation" + "depth": 2, + "title": "In This Section", + "anchor": "in-this-section" } ], "stats": { - "chars": 7480, - "words": 984, - "headings": 25, - "estimated_token_count_total": 1618 + "chars": 988, + "words": 135, + "headings": 2, + "estimated_token_count_total": 92 }, - "hash": "sha256:5cc63ff0a377ef0ec96a064748e13b88bc852bd1862c6e344066855a7fe93b19", - "last_modified": "2025-10-28T14:42:12+00:00", + "hash": "sha256:0de8c1655a1524784010b6cec5fa522b2f764e32f18913f0d262283e0ec0779e", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-libraries", - "title": "Libraries", - "slug": "develop-smart-contracts-libraries", + "id": "develop-toolkit-interoperability", + "title": "Interoperability", + "slug": "develop-toolkit-interoperability", "categories": [ "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-libraries.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/libraries/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. Explore the key libraries for interacting with smart contracts on Polkadot-based networks. These libraries simplify contract calls, event listening, and transaction handling.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-interoperability.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/interoperability/", + "preview": "Polkadot's XCM tooling ecosystem redefines the boundaries of cross-chain communication and asset movement. With unparalleled flexibility and scalability, these advanced tools empower developers to build decentralized applications that connect parachains, relay chains, and external networks. By bridging siloed blockchains, Polkadot paves the way for a unified, interoperable ecosystem that accelerates innovation and collaboration.", "outline": [ { "depth": 2, - "title": "Library Comparison", - "anchor": "library-comparison" - }, + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 1010, + "words": 128, + "headings": 1, + "estimated_token_count_total": 12 + }, + "hash": "sha256:c72d7d30a019fe1db8ab3993f91dfd4f1bdb4a932aaa685d3baaa0578091d5ce", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-toolkit-parachains-e2e-testing", + "title": "E2E Testing on Polkadot SDK Chains", + "slug": "develop-toolkit-parachains-e2e-testing", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-e2e-testing.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/e2e-testing/", + "preview": ":::INSERT_IN_THIS_SECTION:::", + "outline": [ { "depth": 2, "title": "In This Section", @@ -3184,87 +2921,117 @@ } ], "stats": { - "chars": 31726, - "words": 3942, - "headings": 35, - "estimated_token_count_total": 9750 + "chars": 64, + "words": 6, + "headings": 1, + "estimated_token_count_total": 12 }, - "hash": "sha256:1fb7a20bc4a799a771954720428029419ec73afa640e589590c43dd041a7e307", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:cc49fdcc63a43247d80de2f309b9c7501d3054782746d80c003d95f3c43da90d", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-libraries-ethers-js", - "title": "Deploy Contracts to Polkadot Hub with Ethers.js", - "slug": "develop-smart-contracts-libraries-ethers-js", + "id": "develop-toolkit-parachains-fork-chains-chopsticks", + "title": "Chopsticks", + "slug": "develop-toolkit-parachains-fork-chains-chopsticks", "categories": [ - "Smart Contracts", - "Tooling" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-libraries-ethers-js.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/libraries/ethers-js/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-fork-chains-chopsticks.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/fork-chains/chopsticks/", + "preview": "Chopsticks is a powerful tool that lets you create local copies of running Polkadot SDK-based networks. By forking live chains locally, you can safely test features, analyze network behavior, and simulate complex scenarios without affecting production networks.", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "What Can I Do with Chopsticks?", + "anchor": "what-can-i-do-with-chopsticks" }, { "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" + "title": "In This Section", + "anchor": "in-this-section" }, { "depth": 2, - "title": "Project Structure", - "anchor": "project-structure" - }, + "title": "Additional Resources", + "anchor": "additional-resources" + } + ], + "stats": { + "chars": 1495, + "words": 201, + "headings": 3, + "estimated_token_count_total": 291 + }, + "hash": "sha256:b568596033cdf68e60d72bcb7ee62a794def2bd3ff5b3317ef15895f58a12c57", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-toolkit-parachains-fork-chains", + "title": "Fork Chains for Testing", + "slug": "develop-toolkit-parachains-fork-chains", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-fork-chains.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/fork-chains/", + "preview": "Explore tools for forking live blockchain networks. These tools enable you to replicate real-world conditions in a local environment for accurate testing and debugging. They also allow you to analyze network behavior, test new features, and simulate complex scenarios in a controlled environment without affecting production systems.", + "outline": [ { "depth": 2, - "title": "Set Up the Project", - "anchor": "set-up-the-project" + "title": "Why Fork a Live Chain?", + "anchor": "why-fork-a-live-chain" }, { "depth": 2, - "title": "Install Dependencies", - "anchor": "install-dependencies" + "title": "In This Section", + "anchor": "in-this-section" }, { "depth": 2, - "title": "Set Up the Ethers.js Provider", - "anchor": "set-up-the-ethersjs-provider" - }, + "title": "Additional Resources", + "anchor": "additional-resources" + } + ], + "stats": { + "chars": 1269, + "words": 173, + "headings": 3, + "estimated_token_count_total": 183 + }, + "hash": "sha256:d29a845b00b24e03f9877a5331c33619918decf453657969115d5ec18033ba28", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-toolkit-parachains-quickstart-pop-cli", + "title": "Quickstart Parachain Development with Pop CLI", + "slug": "develop-toolkit-parachains-quickstart-pop-cli", + "categories": [ + "Parachains", + "Tooling" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-quickstart-pop-cli.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/quickstart/pop-cli/", + "preview": "[Pop CLI](https://onpop.io/cli/){target=\\_blank} is a powerful command-line tool designed explicitly for rapid parachain development within the Polkadot ecosystem. It addresses essential developer needs by providing streamlined commands to set up development environments, scaffold parachain templates, and manage local blockchain networks.", + "outline": [ { "depth": 2, - "title": "Compile Contracts", - "anchor": "compile-contracts" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 3, - "title": "Install the Revive Library", - "anchor": "install-the-revive-library" + "title": "Install Pop CLI", + "anchor": "install-pop-cli" }, { "depth": 3, - "title": "Sample Storage Smart Contract", - "anchor": "sample-storage-smart-contract" + "title": "Set Up Your Development Environment", + "anchor": "set-up-your-development-environment" }, { "depth": 3, - "title": "Compile the Smart Contract", - "anchor": "compile-the-smart-contract" - }, - { - "depth": 2, - "title": "Deploy the Compiled Contract", - "anchor": "deploy-the-compiled-contract" - }, - { - "depth": 2, - "title": "Interact with the Contract", - "anchor": "interact-with-the-contract" + "title": "Initialize a Project", + "anchor": "initialize-a-project" }, { "depth": 2, @@ -3273,27 +3040,50 @@ } ], "stats": { - "chars": 20464, - "words": 2334, - "headings": 13, - "estimated_token_count_total": 4475 + "chars": 4236, + "words": 610, + "headings": 5, + "estimated_token_count_total": 999 }, - "hash": "sha256:f0cee7ccb3cd294e8f909a220bb63987239ef8155c187a04f8c4864ffdcde288", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:6d6c66430a7302f29113924c5208e64d7c244497e50c61ab2f45c4b5141620e4", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-libraries-viem", - "title": "viem for Polkadot Hub Smart Contracts", - "slug": "develop-smart-contracts-libraries-viem", + "id": "develop-toolkit-parachains-quickstart", + "title": "Quickstart Parachain Development", + "slug": "develop-toolkit-parachains-quickstart", "categories": [ - "Smart Contracts", - "Tooling" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-libraries-viem.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/libraries/viem/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-quickstart.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/quickstart/", + "preview": ":::INSERT_IN_THIS_SECTION:::", + "outline": [ + { + "depth": 2, + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 85, + "words": 7, + "headings": 1, + "estimated_token_count_total": 12 + }, + "hash": "sha256:91de375b7f822ed56b5e6b4d609d0d36e806d3f77041b4e180b6679b10a3e1c8", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-toolkit-parachains-remote-proxies", + "title": "Remote Proxies", + "slug": "develop-toolkit-parachains-remote-proxies", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-remote-proxies.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/remote-proxies/", + "preview": "!!!warning \"Kusama Implementation Only\" Remote proxies are currently only available on Kusama and its parachains (such as Kusama Asset Hub). This feature is not yet deployed on Polkadot MainNet. The examples and implementations described in this guide are specific to the Kusama ecosystem.", "outline": [ { "depth": 2, @@ -3302,92 +3092,59 @@ }, { "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" + "title": "Remote Proxy Architecture", + "anchor": "remote-proxy-architecture" }, { "depth": 2, - "title": "Project Structure", - "anchor": "project-structure" + "title": "Implementation Workflow", + "anchor": "implementation-workflow" }, { "depth": 2, - "title": "Set Up the Project", - "anchor": "set-up-the-project" + "title": "Practical Implementation", + "anchor": "practical-implementation" }, { - "depth": 2, - "title": "Install Dependencies", - "anchor": "install-dependencies" - }, - { - "depth": 2, - "title": "Initialize Project", - "anchor": "initialize-project" - }, - { - "depth": 2, - "title": "Set Up the Chain Configuration", - "anchor": "set-up-the-chain-configuration" - }, - { - "depth": 2, - "title": "Set Up the viem Client", - "anchor": "set-up-the-viem-client" - }, - { - "depth": 2, - "title": "Set Up a Wallet", - "anchor": "set-up-a-wallet" - }, - { - "depth": 2, - "title": "Sample Smart Contract", - "anchor": "sample-smart-contract" - }, - { - "depth": 2, - "title": "Compile the Contract", - "anchor": "compile-the-contract" + "depth": 3, + "title": "Prerequisites", + "anchor": "prerequisites" }, { - "depth": 2, - "title": "Deploy the Contract", - "anchor": "deploy-the-contract" + "depth": 3, + "title": "Installation and Setup", + "anchor": "installation-and-setup" }, { - "depth": 2, - "title": "Interact with the Contract", - "anchor": "interact-with-the-contract" + "depth": 3, + "title": "Implementation Example", + "anchor": "implementation-example" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Resources", + "anchor": "resources" } ], "stats": { - "chars": 16645, - "words": 1945, - "headings": 14, - "estimated_token_count_total": 3900 + "chars": 9063, + "words": 1113, + "headings": 8, + "estimated_token_count_total": 1863 }, - "hash": "sha256:a7541553a50a250521c0a280f997d614763c643b1028147f3fb61391950bda15", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:7086406b31e7aa9089b221ffaa548ee5540a3d147ec1e93136f481c883f2e434", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-libraries-wagmi", - "title": "Wagmi for Polkadot Hub Smart Contracts", - "slug": "develop-smart-contracts-libraries-wagmi", + "id": "develop-toolkit-parachains-rpc-calls", + "title": "RPC Calls to Polkadot SDK chains.", + "slug": "develop-toolkit-parachains-rpc-calls", "categories": [ - "Smart Contracts", - "Tooling" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-libraries-wagmi.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/libraries/wagmi/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-rpc-calls.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/rpc-calls/", + "preview": "[Remote Procedure Call](https://en.wikipedia.org/wiki/Remote_procedure_call){target=\\_blank} (RPC) interfaces are the primary way to interact programmatically with Polkadot SDK-based parachains and relay chains. RPC calls allow you to query chain state, submit transactions, and monitor network health from external applications or scripts.", "outline": [ { "depth": 2, @@ -3396,72 +3153,85 @@ }, { "depth": 2, - "title": "Set Up the Project", - "anchor": "set-up-the-project" + "title": "How Do RPC Calls Work?", + "anchor": "how-do-rpc-calls-work" }, { "depth": 2, - "title": "Install Dependencies", - "anchor": "install-dependencies" + "title": "Making RPC Calls with Curl", + "anchor": "making-rpc-calls-with-curl" }, { "depth": 2, - "title": "Configure Wagmi for Polkadot Hub", - "anchor": "configure-wagmi-for-polkadot-hub" + "title": "Essential RPC Methods", + "anchor": "essential-rpc-methods" }, { - "depth": 2, - "title": "Set Up the Wagmi Provider", - "anchor": "set-up-the-wagmi-provider" + "depth": 3, + "title": "system_health", + "anchor": "system_health" }, { - "depth": 2, - "title": "Connect a Wallet", - "anchor": "connect-a-wallet" + "depth": 3, + "title": "chain_getBlock", + "anchor": "chain_getblock" }, { - "depth": 2, - "title": "Fetch Blockchain Data", - "anchor": "fetch-blockchain-data" + "depth": 3, + "title": "state_getStorage", + "anchor": "state_getstorage" }, { - "depth": 2, - "title": "Interact with Deployed Contract", - "anchor": "interact-with-deployed-contract" + "depth": 3, + "title": "author_submitExtrinsic", + "anchor": "author_submitextrinsic" + }, + { + "depth": 3, + "title": "state_getMetadata", + "anchor": "state_getmetadata" }, { "depth": 2, - "title": "Integrate Components", - "anchor": "integrate-components" + "title": "Check Available RPC Calls", + "anchor": "check-available-rpc-calls" + }, + { + "depth": 3, + "title": "Using curl", + "anchor": "using-curl" + }, + { + "depth": 3, + "title": "Using Polkadot.js Apps", + "anchor": "using-polkadotjs-apps" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Resources", + "anchor": "resources" } ], "stats": { - "chars": 13604, - "words": 1515, - "headings": 10, - "estimated_token_count_total": 3250 + "chars": 6496, + "words": 909, + "headings": 13, + "estimated_token_count_total": 1870 }, - "hash": "sha256:bc771f912627fa09cad64adab1bc81c052f650d6c5a3b4f0c91883a98f6628da", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:3b766e00e55a224201bc6744386a6dabc7da54ed9199b16abab3b94cff449eca", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-libraries-web3-js", - "title": "Web3.js", - "slug": "develop-smart-contracts-libraries-web3-js", + "id": "develop-toolkit-parachains-spawn-chains-zombienet-write-tests", + "title": "Write Tests", + "slug": "develop-toolkit-parachains-spawn-chains-zombienet-write-tests", "categories": [ - "Smart Contracts", + "Parachains", "Tooling" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-libraries-web3-js.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/libraries/web3-js/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. !!! warning Web3.js has been [sunset](https://blog.chainsafe.io/web3-js-sunset/){target=\\_blank}. You can find guides on using [Ethers.js](/develop/smart-contracts/libraries/ethers-js){target=\\_blank} and [viem](/develop/smart-contracts/libraries/viem){target=\\_blank} in the [Libraries](/develop/smart-contracts/libraries/){target=\\_", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-spawn-chains-zombienet-write-tests.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/spawn-chains/zombienet/write-tests/", + "preview": "Testing is a critical step in blockchain development, ensuring reliability, performance, and security. Zombienet simplifies this process with its intuitive Domain Specific Language (DSL), enabling developers to write natural-language test scripts tailored to their network needs.", "outline": [ { "depth": 2, @@ -3470,391 +3240,438 @@ }, { "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Project Structure", - "anchor": "project-structure" - }, - { - "depth": 2, - "title": "Set Up the Project", - "anchor": "set-up-the-project" + "title": "Testing DSL", + "anchor": "testing-dsl" }, { "depth": 2, - "title": "Install Dependencies", - "anchor": "install-dependencies" + "title": "The Test File", + "anchor": "the-test-file" }, { - "depth": 2, - "title": "Set Up the Web3 Provider", - "anchor": "set-up-the-web3-provider" + "depth": 3, + "title": "Name", + "anchor": "name" }, { - "depth": 2, - "title": "Compile Contracts", - "anchor": "compile-contracts" + "depth": 3, + "title": "Assertions", + "anchor": "assertions" }, { - "depth": 2, - "title": "Contract Deployment", - "anchor": "contract-deployment" + "depth": 3, + "title": "Commands", + "anchor": "commands" }, { "depth": 2, - "title": "Interact with the Contract", - "anchor": "interact-with-the-contract" + "title": "Running a Test", + "anchor": "running-a-test" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Example Test Files", + "anchor": "example-test-files" } ], "stats": { - "chars": 13347, - "words": 1586, - "headings": 10, - "estimated_token_count_total": 3033 + "chars": 11297, + "words": 1491, + "headings": 8, + "estimated_token_count_total": 2661 }, - "hash": "sha256:bc87533eaf42a979a0c17f50ecdc668c364889257c7e0d27b81129770660fd53", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:04e85c4cddb58252f8253d78a3924bb56952dac2a3e9a057704a91a0d1f21d75", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-libraries-web3-py", - "title": "Web3.py", - "slug": "develop-smart-contracts-libraries-web3-py", + "id": "develop-toolkit-parachains-spawn-chains-zombienet", + "title": "Zombienet", + "slug": "develop-toolkit-parachains-spawn-chains-zombienet", "categories": [ - "Smart Contracts", - "Tooling" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-libraries-web3-py.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/libraries/web3-py/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-spawn-chains-zombienet.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/spawn-chains/zombienet/", + "preview": "Zombienet is a testing framework that lets you quickly spin up ephemeral blockchain networks for development and testing. With support for multiple deployment targets, such as Kubernetes, Podman, and native environments, Zombienet makes it easy to validate your blockchain implementation in a controlled environment.", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Set Up the Project", - "anchor": "set-up-the-project" - }, - { - "depth": 2, - "title": "Set Up the Web3 Provider", - "anchor": "set-up-the-web3-provider" - }, - { - "depth": 2, - "title": "Contract Deployment", - "anchor": "contract-deployment" + "title": "What Can I Do with Zombienet?", + "anchor": "what-can-i-do-with-zombienet" }, { "depth": 2, - "title": "Interact with the Contract", - "anchor": "interact-with-the-contract" + "title": "In This Section", + "anchor": "in-this-section" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Additional Resources", + "anchor": "additional-resources" } ], "stats": { - "chars": 11652, - "words": 1335, - "headings": 6, - "estimated_token_count_total": 2512 + "chars": 1237, + "words": 164, + "headings": 3, + "estimated_token_count_total": 193 }, - "hash": "sha256:5d13a0873a78a9802b06686d7caafbf4d23b6ba1edf7d3518943301f2b0110c4", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:1355969b6b0e723b42815b960c15eb128e4d936d0d707cd66e43820cff765ee3", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-local-development-node", - "title": "Local Development Node", - "slug": "develop-smart-contracts-local-development-node", + "id": "develop-toolkit-parachains-spawn-chains", + "title": "Spawn Networks for Testing", + "slug": "develop-toolkit-parachains-spawn-chains", "categories": [ - "Smart Contracts" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-local-development-node.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/local-development-node/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-spawn-chains.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/spawn-chains/", + "preview": "Testing blockchain networks in a controlled environment is essential for development and validation. The Polkadot ecosystem provides specialized tools that enable you to spawn test networks, helping you verify functionality and catch issues before deploying to production.", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Why Spawn a Network?", + "anchor": "why-spawn-a-network" }, { "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" + "title": "In This Section", + "anchor": "in-this-section" }, { "depth": 2, - "title": "Install the Revive Dev Node and ETH-RPC Adapter", - "anchor": "install-the-revive-dev-node-and-eth-rpc-adapter" + "title": "Additional Resources", + "anchor": "additional-resources" + } + ], + "stats": { + "chars": 1180, + "words": 155, + "headings": 3, + "estimated_token_count_total": 171 + }, + "hash": "sha256:f11bfd20cb9a0932ce263b2dd763729320261bb25e1fa0039a45ccc609541391", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop-toolkit-parachains", + "title": "Parachains", + "slug": "develop-toolkit-parachains", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/", + "preview": "Within the Polkadot ecosystem, you'll find a robust set of development tools that empower developers to build, test, and deploy blockchain applications efficiently. Whether you're designing a custom parachain, testing new features, or validating network configurations, these tools streamline the development process and ensure your blockchain setup is secure and optimized.", + "outline": [ + { + "depth": 2, + "title": "Quick Links", + "anchor": "quick-links" }, { "depth": 2, - "title": "Run the Local Node", - "anchor": "run-the-local-node" + "title": "In This Section", + "anchor": "in-this-section" } ], "stats": { - "chars": 9064, - "words": 1433, - "headings": 4, - "estimated_token_count_total": 2432 + "chars": 986, + "words": 136, + "headings": 2, + "estimated_token_count_total": 106 }, - "hash": "sha256:809d0ff921587f29045df1d31a5a9fe32ee13fa7b9698aa27ff9f60b2aa7a4d8", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:88dda8aeab06294ccb773d8732d4791b052351ed0b1307d62019a637c9be341a", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-overview", - "title": "Smart Contracts Overview", - "slug": "develop-smart-contracts-overview", + "id": "develop-toolkit", + "title": "Toolkit", + "slug": "develop-toolkit", "categories": [ - "Basics", - "Smart Contracts" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-overview.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/overview/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit.md", + "html_url": "https://docs.polkadot.com/develop/toolkit/", + "preview": "Explore Polkadot's core development toolkit, designed to support a variety of developers and use cases within the ecosystem. Whether you're building blockchain infrastructure, developing cross-chain applications, or integrating with external services, this section offers essential tools and resources to help you succeed.", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 902, + "words": 113, + "headings": 1, + "estimated_token_count_total": 12 + }, + "hash": "sha256:20c667a337791538e3997f1f449bf69b248ccc4cc806e22615075f24fd3f0202", + "token_estimator": "heuristic-v1" + }, + { + "id": "develop", + "title": "Develop", + "slug": "develop", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop.md", + "html_url": "https://docs.polkadot.com/develop/", + "preview": "This guide is a starting point for developers who wish to build in the Polkadot ecosystem. To get the most from this section:", + "outline": [ { "depth": 2, - "title": "Native Smart Contracts", - "anchor": "native-smart-contracts" - }, - { - "depth": 3, "title": "Introduction", - "anchor": "introduction-2" - }, - { - "depth": 3, - "title": "Smart Contract Development", - "anchor": "smart-contract-development" + "anchor": "introduction" }, { - "depth": 3, - "title": "Technical Architecture", - "anchor": "technical-architecture" + "depth": 2, + "title": "Development Pathways", + "anchor": "development-pathways" }, { "depth": 3, - "title": "Development Tools and Resources", - "anchor": "development-tools-and-resources" + "title": "Parachain Developers", + "anchor": "parachain-developers" }, { "depth": 3, - "title": "Cross-Chain Capabilities", - "anchor": "cross-chain-capabilities" + "title": "Smart Contract Developers", + "anchor": "smart-contract-developers" }, { "depth": 3, - "title": "Use Cases", - "anchor": "use-cases" - }, - { - "depth": 2, - "title": "Other Smart Contract Environments", - "anchor": "other-smart-contract-environments" + "title": "Application Developers", + "anchor": "application-developers" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "In This Section", + "anchor": "in-this-section" } ], "stats": { - "chars": 6294, - "words": 802, - "headings": 10, - "estimated_token_count_total": 1118 + "chars": 6923, + "words": 882, + "headings": 6, + "estimated_token_count_total": 1843 }, - "hash": "sha256:0468268436ffdb759cad8390a838d5fba2391118baa8fd8cd494b36397b10329", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:1784f7b9e0552ab893c9d7d252299d53e36b6f57ef57c49cd5e36805399675ab", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts-precompiles-interact-with-precompiles", - "title": "Interact with Precompiles", - "slug": "develop-smart-contracts-precompiles-interact-with-precompiles", + "id": "get-support-ai-ready-docs", + "title": "AI Ready Docs", + "slug": "get-support-ai-ready-docs", "categories": [ - "Smart Contracts" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-precompiles-interact-with-precompiles.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/precompiles/interact-with-precompiles/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/get-support-ai-ready-docs.md", + "html_url": "https://docs.polkadot.com/get-support/ai-ready-docs/", + "preview": "Polkadot provides files to make documentation content available in a structure optimized for use with large language models (LLMs) and AI tools. These resources help build AI assistants, power code search, or enable custom tooling trained on Polkadot’s documentation.", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "How to Use These Files", + "anchor": "how-to-use-these-files" }, { "depth": 2, - "title": "Basic Precompile Interaction Pattern", - "anchor": "basic-precompile-interaction-pattern" - }, + "title": "Download LLM Files", + "anchor": "download-llm-files" + } + ], + "stats": { + "chars": 7998, + "words": 825, + "headings": 2, + "estimated_token_count_total": 2232 + }, + "hash": "sha256:5a8da69a5cea8bd598ee4d102b9abed5d1a29153802a567e22bb4ee720410b32", + "token_estimator": "heuristic-v1" + }, + { + "id": "get-support-explore-resources", + "title": "Subscribe to Updates", + "slug": "get-support-explore-resources", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/get-support-explore-resources.md", + "html_url": "https://docs.polkadot.com/get-support/explore-resources/", + "preview": "Looking for answers beyond the documentation? These platforms are full of useful content and experienced developers sharing insights.", + "outline": [ { "depth": 2, - "title": "ECRecover (0x01)", - "anchor": "ecrecover-0x01" + "title": "🧠 Stack Exchange", + "anchor": "stack-exchange" }, { "depth": 2, - "title": "SHA-256 (0x02)", - "anchor": "sha-256-0x02" + "title": "🧵 Reddit: r/Polkadot", + "anchor": "reddit-rpolkadot" }, { "depth": 2, - "title": "RIPEMD-160 (0x03)", - "anchor": "ripemd-160-0x03" + "title": "💬 Discord (Community Threads Only)", + "anchor": "discord-community-threads-only" }, { "depth": 2, - "title": "Identity (Data Copy) (0x04)", - "anchor": "identity-data-copy-0x04" + "title": "🎥 YouTube: @PolkadotNetwork", + "anchor": "youtube-polkadotnetwork" }, { "depth": 2, - "title": "Modular Exponentiation (0x05)", - "anchor": "modular-exponentiation-0x05" + "title": "Community-Led Platforms and Ecosystem Updates", + "anchor": "community-led-platforms-and-ecosystem-updates" }, { - "depth": 2, - "title": "BN128 Addition (0x06)", - "anchor": "bn128-addition-0x06" + "depth": 3, + "title": "🔷 X (Twitter): Official Accounts", + "anchor": "x-twitter-official-accounts" }, { - "depth": 2, - "title": "BN128 Scalar Multiplication (0x07)", - "anchor": "bn128-scalar-multiplication-0x07" + "depth": 3, + "title": "🔁 X (Twitter): Community Accounts", + "anchor": "x-twitter-community-accounts" }, { - "depth": 2, - "title": "BN128 Pairing Check (0x08)", - "anchor": "bn128-pairing-check-0x08" + "depth": 3, + "title": "🗣️ Polkadot Forum", + "anchor": "polkadot-forum" }, { - "depth": 2, - "title": "Blake2F (0x09)", - "anchor": "blake2f-0x09" + "depth": 3, + "title": "🧑‍⚖️ Polkassembly: OpenGov", + "anchor": "polkassembly-opengov" }, { - "depth": 2, - "title": "Conclusion", - "anchor": "conclusion" + "depth": 3, + "title": "📸 Instagram", + "anchor": "instagram" } ], "stats": { - "chars": 18054, - "words": 2190, - "headings": 12, - "estimated_token_count_total": 3847 + "chars": 2456, + "words": 295, + "headings": 10, + "estimated_token_count_total": 579 }, - "hash": "sha256:4b705b8dbe9b0ad8d19a897d91f3c64dbc4541297dadacbea2a31b4778e50a46", - "last_modified": "2025-10-28T14:42:13+00:00", + "hash": "sha256:4c33d0ec5026128b3bfdb1dfc1f4b29487404eaa8043071d536e8638356c6e1f", "token_estimator": "heuristic-v1" }, { - "id": "develop-smart-contracts", - "title": "Smart Contracts", - "slug": "develop-smart-contracts", + "id": "get-support-get-in-touch", + "title": "Get in Touch", + "slug": "get-support-get-in-touch", "categories": [ "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts.md", - "html_url": "https://docs.polkadot.com/develop/smart-contracts/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. Polkadot allows scalable execution of smart contracts, offering cross-chain compatibility and lower fees than legacy L1 platforms. Polkadot provides developers with flexibility in building smart contracts, supporting both Solidity contracts executed by the [PolkaVM](/smart-contracts/for-eth-devs/#polkavm){target=\\_blank} (a Polkadot", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/get-support-get-in-touch.md", + "html_url": "https://docs.polkadot.com/get-support/get-in-touch/", + "preview": "Use one of the channels below to get live technical support or ask questions.", "outline": [ { "depth": 2, - "title": "Smart Contract Development Process", - "anchor": "smart-contract-development-process" + "title": "Need Help Fast?", + "anchor": "need-help-fast" }, { "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" + "title": "📱 Telegram: Polkadot Developer Support", + "anchor": "telegram-polkadot-developer-support" + }, + { + "depth": 2, + "title": "🔌 Discord: Polkadot Official Server", + "anchor": "discord-polkadot-official-server" + }, + { + "depth": 2, + "title": "🧬 Matrix: Polkadot Developer Support", + "anchor": "matrix-polkadot-developer-support" } ], "stats": { - "chars": 1867, - "words": 247, - "headings": 2, - "estimated_token_count_total": 189 + "chars": 1949, + "words": 258, + "headings": 4, + "estimated_token_count_total": 557 }, - "hash": "sha256:605d2cbb7eabb2ea0fd928bc3ecdf9ee8b095e3dd9643f2b0918fef7b5a3f4a8", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:993e93b05c8fbdfc2f7510c61ac86bc4c2ff0f03e573695b2f260933c8b62f78", "token_estimator": "heuristic-v1" }, { - "id": "develop-toolkit-api-libraries", - "title": "API Libraries", - "slug": "develop-toolkit-api-libraries", + "id": "get-support", + "title": "Support", + "slug": "get-support", "categories": [ "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-api-libraries.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/api-libraries/", - "preview": "Explore the powerful API libraries designed for interacting with the Polkadot network. These libraries offer developers versatile tools to build, query, and manage blockchain interactions. Whether you’re working with JavaScript, TypeScript, Python, or RESTful services, they provide the flexibility to efficiently interact with and retrieve data from Polkadot-based chains.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/get-support.md", + "html_url": "https://docs.polkadot.com/get-support/", + "preview": "Use one of the channels below to get live technical support or ask questions.", "outline": [ { "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" + "title": "Need More than Just Documentation?", + "anchor": "need-more-than-just-documentation" }, { "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" + "title": "What You Can Do Here", + "anchor": "what-you-can-do-here" + }, + { + "depth": 2, + "title": "Help Us Improve", + "anchor": "help-us-improve" } ], "stats": { - "chars": 7299, - "words": 1047, - "headings": 6, - "estimated_token_count_total": 1638 + "chars": 1658, + "words": 244, + "headings": 3, + "estimated_token_count_total": 280 }, - "hash": "sha256:807cee6869059dd933905d1cf6c76e3b86e02baee3de3113f7e5b4c8697fbd22", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:5bdc575ac798a971867a15651c2b4d5139bf0b1fe6854d1865deff280ae6d7f6", "token_estimator": "heuristic-v1" }, { - "id": "develop-toolkit-api-libraries-dedot", - "title": "Dedot", - "slug": "develop-toolkit-api-libraries-dedot", + "id": "index", + "title": "Polkadot Developer Docs", + "slug": "index", "categories": [ - "Tooling", - "Dapps" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-api-libraries-dedot.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/api-libraries/dedot/", - "preview": "[Dedot](https://github.com/dedotdev/dedot){target=\\_blank} is a next-generation JavaScript client for Polkadot and Polkadot SDK-based blockchains. Designed to elevate the dApp development experience, Dedot is built and optimized to be lightweight and tree-shakable, offering precise types and APIs suggestions for individual Polkadot SDK-based blockchains and [ink! smart contracts](https://use.ink/){target=\\_blank}.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/index.md", + "html_url": "https://docs.polkadot.com/index/", + "preview": "Explore everything you need to start building on top of Polkadot, a protocol that provides parachains with shared security and interoperability using XCM.", + "outline": [], + "stats": { + "chars": 0, + "words": 0, + "headings": 0, + "estimated_token_count_total": 0 + }, + "hash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "token_estimator": "heuristic-v1" + }, + { + "id": "nodes-and-validators-run-a-node-bootnode", + "title": "Set Up a Bootnode", + "slug": "nodes-and-validators-run-a-node-bootnode", + "categories": [ + "Infrastructure" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-node-bootnode.md", + "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-node/bootnode/", + "preview": "Bootnodes are essential for helping blockchain nodes discover peers and join the network. When a node starts, it needs to find other nodes, and bootnodes provide an initial point of contact. Once connected, a node can expand its peer connections and play its role in the network, like participating as a validator.", "outline": [ { "depth": 2, @@ -3862,68 +3679,65 @@ "anchor": "introduction" }, { - "depth": 3, - "title": "Key Features", - "anchor": "key-features" + "depth": 2, + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Installation", - "anchor": "installation" + "title": "Accessing the Bootnode", + "anchor": "accessing-the-bootnode" }, { "depth": 2, - "title": "Get Started", - "anchor": "get-started" + "title": "Node Key", + "anchor": "node-key" }, { - "depth": 3, - "title": "Initialize a Client Instance", - "anchor": "initialize-a-client-instance" + "depth": 2, + "title": "Running the Bootnode", + "anchor": "running-the-bootnode" }, { - "depth": 3, - "title": "Enable Type and API Suggestions", - "anchor": "enable-type-and-api-suggestions" + "depth": 2, + "title": "Testing Bootnode Connection", + "anchor": "testing-bootnode-connection" }, { "depth": 3, - "title": "Read On-Chain Data", - "anchor": "read-on-chain-data" + "title": "P2P", + "anchor": "p2p" }, { "depth": 3, - "title": "Sign and Send Transactions", - "anchor": "sign-and-send-transactions" + "title": "P2P/WS", + "anchor": "p2pws" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "depth": 3, + "title": "P2P/WSS", + "anchor": "p2pwss" } ], "stats": { - "chars": 8855, - "words": 1100, + "chars": 4538, + "words": 647, "headings": 9, - "estimated_token_count_total": 2300 + "estimated_token_count_total": 1044 }, - "hash": "sha256:ba24e31e2ad94fbf1d73f1878da92dd2e1476db00170780bbdf0e65ab18bc961", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:d84a5af1a0237a911d25a68c077f508ebbce608f673ef4f9055e8e434daa96b9", "token_estimator": "heuristic-v1" }, { - "id": "develop-toolkit-api-libraries-papi", - "title": "Polkadot-API", - "slug": "develop-toolkit-api-libraries-papi", + "id": "nodes-and-validators-run-a-node-full-node", + "title": "Set Up a Node", + "slug": "nodes-and-validators-run-a-node-full-node", "categories": [ - "Tooling", - "Dapps" + "Infrastructure" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-api-libraries-papi.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/api-libraries/papi/", - "preview": "[Polkadot-API](https://github.com/polkadot-api/polkadot-api){target=\\_blank} (PAPI) is a set of libraries built to be modular, composable, and grounded in a “light-client first” approach. Its primary aim is to equip dApp developers with an extensive toolkit for building fully decentralized applications.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-node-full-node.md", + "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-node/full-node/", + "preview": "Running a node on Polkadot provides direct interaction with the network, enhanced privacy, and full control over RPC requests, transactions, and data queries. As the backbone of the network, nodes ensure decentralized data propagation, transaction validation, and seamless communication across the ecosystem.", "outline": [ { "depth": 2, @@ -3932,125 +3746,120 @@ }, { "depth": 2, - "title": "Get Started", - "anchor": "get-started" + "title": "Set Up a Node", + "anchor": "set-up-a-node" }, { "depth": 3, - "title": "API Instantiation", - "anchor": "api-instantiation" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 3, - "title": "Reading Chain Data", - "anchor": "reading-chain-data" + "title": "Install and Build the Polkadot Binary", + "anchor": "install-and-build-the-polkadot-binary" }, { "depth": 3, - "title": "Sending Transactions", - "anchor": "sending-transactions" + "title": "Use Docker", + "anchor": "use-docker" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Configure and Run Your Node", + "anchor": "configure-and-run-your-node" + }, + { + "depth": 3, + "title": "RPC Configurations", + "anchor": "rpc-configurations" + }, + { + "depth": 2, + "title": "Sync Your Node", + "anchor": "sync-your-node" + }, + { + "depth": 3, + "title": "Connect to Your Node", + "anchor": "connect-to-your-node" } ], "stats": { - "chars": 8957, - "words": 1156, - "headings": 6, - "estimated_token_count_total": 1987 + "chars": 15947, + "words": 2482, + "headings": 9, + "estimated_token_count_total": 4197 }, - "hash": "sha256:2ca93b09d3bb9159bbf53816886a9b242bb3c13b996c51fd52962e049e2d5477", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:b83e3f77bd30ac8c8fb00a193bbec33cd641d94f1a37ac611dea32326c3d77b0", "token_estimator": "heuristic-v1" }, { - "id": "develop-toolkit-api-libraries-polkadart", - "title": "Polkadart", - "slug": "develop-toolkit-api-libraries-polkadart", + "id": "nodes-and-validators-run-a-node-secure-wss", + "title": "Set Up Secure WebSocket", + "slug": "nodes-and-validators-run-a-node-secure-wss", "categories": [ - "Tooling", - "Dapps" + "Infrastructure" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-api-libraries-polkadart.md", - "html_url": "https://docs.polkadot.com/reference/tools/polkadart/", - "preview": "Polkadart is the most comprehensive Dart/Flutter SDK for interacting with Polkadot, Substrate, and other compatible blockchain networks. Designed with a Dart-first approach and type-safe APIs, it provides everything developers need to build powerful decentralized applications.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-node-secure-wss.md", + "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-node/secure-wss/", + "preview": "Ensuring secure WebSocket communication is crucial for maintaining the integrity and security of a Polkadot or Kusama node when interacting with remote clients. This guide walks you through setting up a secure WebSocket (WSS) connection for your node by leveraging SSL encryption with popular web server proxies like nginx or Apache.", "outline": [ { "depth": 2, - "title": "Installation", - "anchor": "installation" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Get Started", - "anchor": "get-started" - }, - { - "depth": 3, - "title": "Type Generation", - "anchor": "type-generation" - }, - { - "depth": 3, - "title": "Run Generator", - "anchor": "run-generator" - }, - { - "depth": 3, - "title": "Use Generated Types", - "anchor": "use-generated-types" + "title": "Secure a WebSocket Port", + "anchor": "secure-a-websocket-port" }, { "depth": 3, - "title": "Creating an API Instance", - "anchor": "creating-an-api-instance" + "title": "Obtain an SSL Certificate", + "anchor": "obtain-an-ssl-certificate" }, { - "depth": 3, - "title": "Reading Chain Data", - "anchor": "reading-chain-data" + "depth": 2, + "title": "Install a Proxy Server", + "anchor": "install-a-proxy-server" }, { "depth": 3, - "title": "Subscribe to New Blocks", - "anchor": "subscribe-to-new-blocks" + "title": "Use nginx", + "anchor": "use-nginx" }, { "depth": 3, - "title": "Send a Transaction", - "anchor": "send-a-transaction" + "title": "Use Apache2", + "anchor": "use-apache2" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Connect to the Node", + "anchor": "connect-to-the-node" } ], "stats": { - "chars": 5178, - "words": 624, - "headings": 10, - "estimated_token_count_total": 1084 + "chars": 5568, + "words": 774, + "headings": 7, + "estimated_token_count_total": 1280 }, - "hash": "sha256:7f533abe61586af8438e350c41b741d74a8edb839f9dc4139bc4619ba3748258", - "last_modified": "2025-10-28T14:15:59+00:00", + "hash": "sha256:992082e4ad87348b283f6c37ea886ae0e7bf016852b6470000876f3d169c65a4", "token_estimator": "heuristic-v1" }, { - "id": "develop-toolkit-api-libraries-polkadot-js-api", - "title": "Polkadot.js API", - "slug": "develop-toolkit-api-libraries-polkadot-js-api", + "id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management", + "title": "Validator Key Management", + "slug": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management", "categories": [ - "Tooling", - "Dapps" + "Infrastructure" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-api-libraries-polkadot-js-api.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/api-libraries/polkadot-js-api/", - "preview": "!!! warning \"Maintenance Mode Only\" The Polkadot.js API is now in maintenance mode and is no longer actively developed. New projects should use [Dedot](/develop/toolkit/api-libraries/dedot){target=\\_blank} (TypeScript-first API) or [Polkadot API](/develop/toolkit/api-libraries/papi){target=\\_blank} (modern, type-safe API) as actively maintained alternatives.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management.md", + "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/", + "preview": "After setting up your node environment as shown in the [Setup](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\\_blank} section, you'll need to configure multiple keys for your validator to operate properly. This includes setting up session keys, which are essential for participating in the consensus process, and configuring a node key that maintains a stable network identity. This guide walks you through the key management process, showing you how to g", "outline": [ { "depth": 2, @@ -4058,68 +3867,60 @@ "anchor": "introduction" }, { - "depth": 3, - "title": "Dynamic API Generation", - "anchor": "dynamic-api-generation" + "depth": 2, + "title": "Set Session Keys", + "anchor": "set-session-keys" }, { "depth": 3, - "title": "Available API Categories", - "anchor": "available-api-categories" - }, - { - "depth": 2, - "title": "Installation", - "anchor": "installation" + "title": "Generate Session Keys", + "anchor": "generate-session-keys" }, { - "depth": 2, - "title": "Get Started", - "anchor": "get-started" + "depth": 3, + "title": "Submit Transaction to Set Keys", + "anchor": "submit-transaction-to-set-keys" }, { "depth": 3, - "title": "Creating an API Instance", - "anchor": "creating-an-api-instance" + "title": "Verify Session Key Setup", + "anchor": "verify-session-key-setup" }, { - "depth": 3, - "title": "Reading Chain Data", - "anchor": "reading-chain-data" + "depth": 2, + "title": "Set the Node Key", + "anchor": "set-the-node-key" }, { "depth": 3, - "title": "Sending Transactions", - "anchor": "sending-transactions" + "title": "Generate the Node Key", + "anchor": "generate-the-node-key" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "depth": 3, + "title": "Set Node Key", + "anchor": "set-node-key" } ], "stats": { - "chars": 5042, - "words": 684, - "headings": 9, - "estimated_token_count_total": 1166 + "chars": 8227, + "words": 1183, + "headings": 8, + "estimated_token_count_total": 1840 }, - "hash": "sha256:ed3986f30880fefca5975fcdc847c68b4aca65862c63e3002b25391b0521781d", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:0fb5a83835aab263c0b9aa886028c8aa8a2d6d0897d7b9fff4b5258835d30dfe", "token_estimator": "heuristic-v1" }, { - "id": "develop-toolkit-api-libraries-py-substrate-interface", - "title": "Python Substrate Interface", - "slug": "develop-toolkit-api-libraries-py-substrate-interface", + "id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", + "title": "Set Up a Validator", + "slug": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", "categories": [ - "Tooling", - "Dapps" + "Infrastructure" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-api-libraries-py-substrate-interface.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/api-libraries/py-substrate-interface/", - "preview": "The [Python Substrate Interface](https://github.com/polkascan/py-substrate-interface){target=\\_blank} is a powerful library that enables interaction with Polkadot SDK-based chains. It provides essential functionality for:", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator.md", + "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/", + "preview": "Setting up a Polkadot validator node is essential for securing the network and earning staking rewards. This guide walks you through the technical steps to set up a validator, from installing the necessary software to managing keys and synchronizing your node with the chain.", "outline": [ { "depth": 2, @@ -4128,111 +3929,79 @@ }, { "depth": 2, - "title": "Installation", - "anchor": "installation" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Get Started", - "anchor": "get-started" - }, - { - "depth": 3, - "title": "Establishing Connection", - "anchor": "establishing-connection" + "title": "Initial Setup", + "anchor": "initial-setup" }, { "depth": 3, - "title": "Reading Chain State", - "anchor": "reading-chain-state" + "title": "Install Network Time Protocol Client", + "anchor": "install-network-time-protocol-client" }, { "depth": 3, - "title": "Submitting Transactions", - "anchor": "submitting-transactions" + "title": "Verify Landlock is Activated", + "anchor": "verify-landlock-is-activated" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 4302, - "words": 541, - "headings": 7, - "estimated_token_count_total": 942 - }, - "hash": "sha256:8987fc35cd28602054ee018031f773e2e3837425107c51d0e2ac68a94b86e9c0", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-api-libraries-sidecar", - "title": "Sidecar Rest API", - "slug": "develop-toolkit-api-libraries-sidecar", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-api-libraries-sidecar.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/api-libraries/sidecar/", - "preview": "The [Sidecar Rest API](https://github.com/paritytech/substrate-api-sidecar){target=\\_blank} is a service that provides a REST interface for interacting with Polkadot SDK-based blockchains. With this API, developers can easily access a broad range of endpoints for nodes, accounts, transactions, parachains, and more.", - "outline": [ + "title": "Install the Polkadot Binaries", + "anchor": "install-the-polkadot-binaries" + }, { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "depth": 3, + "title": "Install from Official Releases", + "anchor": "install-from-official-releases" }, { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" + "depth": 3, + "title": "Install with Package Managers", + "anchor": "install-with-package-managers" }, { - "depth": 2, - "title": "Installation", - "anchor": "installation" + "depth": 3, + "title": "Install with Ansible", + "anchor": "install-with-ansible" }, { - "depth": 2, - "title": "Usage", - "anchor": "usage" + "depth": 3, + "title": "Install with Docker", + "anchor": "install-with-docker" }, { "depth": 3, - "title": "Endpoints", - "anchor": "endpoints" + "title": "Build from Sources", + "anchor": "build-from-sources" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Verify Installation", + "anchor": "verify-installation" } ], "stats": { - "chars": 7309, - "words": 1033, - "headings": 6, - "estimated_token_count_total": 1945 + "chars": 11921, + "words": 1678, + "headings": 12, + "estimated_token_count_total": 2592 }, - "hash": "sha256:b8759f61ab57b636228b69d5770c74591998b912cd4596e89eb2ec011da7ef73", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:d2c1c91734bc8185057d8eeec6829ea91e0316f7ba884c5dc3922a5e5778815e", "token_estimator": "heuristic-v1" }, { - "id": "develop-toolkit-api-libraries-subxt", - "title": "Subxt Rust API", - "slug": "develop-toolkit-api-libraries-subxt", + "id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", + "title": "Start Validating", + "slug": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", "categories": [ - "Tooling", - "Dapps" + "Infrastructure" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-api-libraries-subxt.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/api-libraries/subxt/", - "preview": "Subxt is a Rust library designed to interact with Polkadot SDK-based blockchains. It provides a type-safe interface for submitting transactions, querying on-chain state, and performing other blockchain interactions. By leveraging Rust's strong type system, subxt ensures that your code is validated at compile time, reducing runtime errors and improving reliability.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating.md", + "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/", + "preview": "After configuring your node keys as shown in the [Key Management](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/){target=\\_blank} section and ensuring your system is set up, you're ready to begin the validator setup process. This guide will walk you through choosing a network, synchronizing your node with the blockchain, bonding your DOT tokens, and starting your validator.", "outline": [ { "depth": 2, @@ -4241,2073 +4010,118 @@ }, { "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" + "title": "Choose a Network", + "anchor": "choose-a-network" }, { "depth": 2, - "title": "Installation", - "anchor": "installation" + "title": "Synchronize Chain Data", + "anchor": "synchronize-chain-data" + }, + { + "depth": 3, + "title": "Database Snapshot Services", + "anchor": "database-snapshot-services" }, { "depth": 2, - "title": "Get Started", - "anchor": "get-started" + "title": "Bond DOT", + "anchor": "bond-dot" }, { "depth": 3, - "title": "Download Chain Metadata", - "anchor": "download-chain-metadata" + "title": "Bonding DOT on Polkadot.js Apps", + "anchor": "bonding-dot-on-polkadotjs-apps" }, { - "depth": 3, - "title": "Generate Type-Safe Interfaces", - "anchor": "generate-type-safe-interfaces" + "depth": 2, + "title": "Validate", + "anchor": "validate" }, { "depth": 3, - "title": "Initialize the Subxt Client", - "anchor": "initialize-the-subxt-client" + "title": "Verify Sync via Telemetry", + "anchor": "verify-sync-via-telemetry" }, { "depth": 3, - "title": "Read Chain Data", - "anchor": "read-chain-data" + "title": "Activate using Polkadot.js Apps", + "anchor": "activate-using-polkadotjs-apps" }, { "depth": 3, - "title": "Submit Transactions", - "anchor": "submit-transactions" + "title": "Monitor Validation Status and Slots", + "anchor": "monitor-validation-status-and-slots" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Run a Validator Using Systemd", + "anchor": "run-a-validator-using-systemd" + }, + { + "depth": 3, + "title": "Create the Systemd Service File", + "anchor": "create-the-systemd-service-file" + }, + { + "depth": 3, + "title": "Run the Service", + "anchor": "run-the-service" } ], "stats": { - "chars": 9174, - "words": 1175, - "headings": 10, - "estimated_token_count_total": 2187 + "chars": 15821, + "words": 2446, + "headings": 13, + "estimated_token_count_total": 3861 }, - "hash": "sha256:56269d9ea47f5b4e92cd7d5a1e65ab06d181a9c380f90bb3ef285529b12299f7", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:c74cfa542fe7a5235b81120f0004576aea83e0d35458201689b68d87f2969749", "token_estimator": "heuristic-v1" }, { - "id": "develop-toolkit-integrations-indexers", - "title": "Indexers", - "slug": "develop-toolkit-integrations-indexers", + "id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating", + "title": "Stop Validating", + "slug": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating", "categories": [ - "Tooling", - "Dapps" + "Infrastructure" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-integrations-indexers.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/integrations/indexers/", - "preview": "Blockchain data is inherently sequential and distributed, with information stored chronologically across numerous blocks. While retrieving data from a single block through JSON-RPC API calls is straightforward, more complex queries that span multiple blocks present significant challenges:", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating.md", + "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/stop-validating/", + "preview": "If you're ready to stop validating on Polkadot, there are essential steps to ensure a smooth transition while protecting your funds and account integrity. Whether you're taking a break for maintenance or unbonding entirely, you'll need to chill your validator, purge session keys, and unbond your tokens. This guide explains how to use Polkadot's tools and extrinsics to safely withdraw from validation activities, safeguarding your account's future usability.", "outline": [ { "depth": 2, - "title": "The Challenge of Blockchain Data Access", - "anchor": "the-challenge-of-blockchain-data-access" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "What is a Blockchain Indexer?", - "anchor": "what-is-a-blockchain-indexer" + "title": "Pause Versus Stop", + "anchor": "pause-versus-stop" }, { "depth": 2, - "title": "Indexer Implementations", - "anchor": "indexer-implementations" + "title": "Chill Validator", + "anchor": "chill-validator" + }, + { + "depth": 2, + "title": "Purge Validator Session Keys", + "anchor": "purge-validator-session-keys" + }, + { + "depth": 2, + "title": "Unbond Your Tokens", + "anchor": "unbond-your-tokens" } ], "stats": { - "chars": 2230, - "words": 302, - "headings": 3, - "estimated_token_count_total": 428 + "chars": 3230, + "words": 500, + "headings": 5, + "estimated_token_count_total": 629 }, - "hash": "sha256:cfcc76bb24779c9b613f2c046b6f99a0f2529c25fd82287d804f6b945b936227", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-integrations-oracles", - "title": "Oracles", - "slug": "develop-toolkit-integrations-oracles", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-integrations-oracles.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/integrations/oracles/", - "preview": "Oracles enable blockchains to access external data sources. Since blockchains operate as isolated networks, they cannot natively interact with external systems - this limitation is known as the \"blockchain oracle problem.\" Oracles solves this by extracting data from external sources (like APIs, IoT devices, or other blockchains), validating it, and submitting it on-chain.", - "outline": [ - { - "depth": 2, - "title": "What is a Blockchain Oracle?", - "anchor": "what-is-a-blockchain-oracle" - }, - { - "depth": 2, - "title": "Oracle Implementations", - "anchor": "oracle-implementations" - } - ], - "stats": { - "chars": 1343, - "words": 181, - "headings": 2, - "estimated_token_count_total": 187 - }, - "hash": "sha256:6d8e01281a5895fd2bc4438b24c170c72a496de0b838626a53e87685aea4aa25", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-integrations-storage", - "title": "Storage", - "slug": "develop-toolkit-integrations-storage", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-integrations-storage.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/integrations/storage/", - "preview": "Polkadot offers developers a range of decentralized storage solutions to manage dApp data, host front ends, and store large files in a censorship-resistant and resilient manner. These integrations are essential for building fully decentralized applications, ensuring that all components of your dApp, from the front end to the data, are not reliant on centralized servers.", - "outline": [ - { - "depth": 2, - "title": "Key Storage Solutions", - "anchor": "key-storage-solutions" - }, - { - "depth": 2, - "title": "Crust Network", - "anchor": "crust-network" - }, - { - "depth": 3, - "title": "Key Features of Crust", - "anchor": "key-features-of-crust" - }, - { - "depth": 3, - "title": "Use Cases", - "anchor": "use-cases" - }, - { - "depth": 2, - "title": "IPFS", - "anchor": "ipfs" - }, - { - "depth": 3, - "title": "Using IPFS with Polkadot", - "anchor": "using-ipfs-with-polkadot" - }, - { - "depth": 2, - "title": "Other Solutions", - "anchor": "other-solutions" - } - ], - "stats": { - "chars": 4369, - "words": 642, - "headings": 7, - "estimated_token_count_total": 847 - }, - "hash": "sha256:a206dd86fc3d80aed22384000839ca0c9c75c69ad461abd9810d96c03cf6a3bd", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-integrations-transaction-construction", - "title": "Transaction Construction", - "slug": "develop-toolkit-integrations-transaction-construction", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-integrations-transaction-construction.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/integrations/transaction-construction/", - "preview": "This page will discuss the transaction format in Polkadot and how to create, sign, and broadcast transactions, as well as highlight some of the commands and tools available for integrators.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Transaction Format", - "anchor": "transaction-format" - }, - { - "depth": 3, - "title": "Mode and Metadata Hash", - "anchor": "mode-and-metadata-hash" - }, - { - "depth": 3, - "title": "Serialized Transactions and Metadata", - "anchor": "serialized-transactions-and-metadata" - }, - { - "depth": 3, - "title": "Transaction Flow", - "anchor": "transaction-flow" - }, - { - "depth": 2, - "title": "Polkadot-JS Tools", - "anchor": "polkadot-js-tools" - }, - { - "depth": 3, - "title": "Creating a Transaction, Signing, and Submitting", - "anchor": "creating-a-transaction-signing-and-submitting" - }, - { - "depth": 2, - "title": "Txwrapper", - "anchor": "txwrapper" - }, - { - "depth": 3, - "title": "Creating a Transaction, Signing, and Submitting", - "anchor": "creating-a-transaction-signing-and-submitting-2" - }, - { - "depth": 2, - "title": "Additional Libraries for Submitting a Transaction", - "anchor": "additional-libraries-for-submitting-a-transaction" - } - ], - "stats": { - "chars": 27671, - "words": 2949, - "headings": 10, - "estimated_token_count_total": 6280 - }, - "hash": "sha256:9b03477d13a285fced6bf845c3827084f790a626989dc2c09ef9ff53643045f4", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-integrations", - "title": "Integrations", - "slug": "develop-toolkit-integrations", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-integrations.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/integrations/", - "preview": "Polkadot offers a wide range of integrations that allow developers to enhance their decentralized applications (dApps) and leverage the full capabilities of the ecosystem. Whether you’re looking to extend your application’s functionality, integrate with other chains, or access specialized services, these integrations provide the tools and resources you need to build efficiently and effectively. Explore the available options to find the solutions that best suit your development needs.", - "outline": [ - { - "depth": 2, - "title": "Key Integration Solutions", - "anchor": "key-integration-solutions" - }, - { - "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" - } - ], - "stats": { - "chars": 988, - "words": 135, - "headings": 2, - "estimated_token_count_total": 92 - }, - "hash": "sha256:62c5ad101282227f79eac0e30a3ba9ce3ae1bf9e358bd58c0b17ef45db29c2ff", - "last_modified": "2025-10-28T14:15:59+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-interoperability", - "title": "Interoperability", - "slug": "develop-toolkit-interoperability", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-interoperability.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/interoperability/", - "preview": "Polkadot's XCM tooling ecosystem redefines the boundaries of cross-chain communication and asset movement. With unparalleled flexibility and scalability, these advanced tools empower developers to build decentralized applications that connect parachains, relay chains, and external networks. By bridging siloed blockchains, Polkadot paves the way for a unified, interoperable ecosystem that accelerates innovation and collaboration.", - "outline": [ - { - "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" - } - ], - "stats": { - "chars": 1010, - "words": 128, - "headings": 1, - "estimated_token_count_total": 12 - }, - "hash": "sha256:966ec1bcc014a454f6b837b503025d9fb89c30f6a65d0aaec82ea5ff976e53a9", - "last_modified": "2025-10-28T14:15:59+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains-e2e-testing", - "title": "E2E Testing on Polkadot SDK Chains", - "slug": "develop-toolkit-parachains-e2e-testing", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-e2e-testing.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/e2e-testing/", - "preview": ":::INSERT_IN_THIS_SECTION:::", - "outline": [ - { - "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" - } - ], - "stats": { - "chars": 64, - "words": 6, - "headings": 1, - "estimated_token_count_total": 12 - }, - "hash": "sha256:47328231d6ff4dc52cd93aaf1baf5d0bc2d9fc372f3d79339d87aafa0dabd1b8", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains-fork-chains-chopsticks", - "title": "Chopsticks", - "slug": "develop-toolkit-parachains-fork-chains-chopsticks", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-fork-chains-chopsticks.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/fork-chains/chopsticks/", - "preview": "Chopsticks is a powerful tool that lets you create local copies of running Polkadot SDK-based networks. By forking live chains locally, you can safely test features, analyze network behavior, and simulate complex scenarios without affecting production networks.", - "outline": [ - { - "depth": 2, - "title": "What Can I Do with Chopsticks?", - "anchor": "what-can-i-do-with-chopsticks" - }, - { - "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" - }, - { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 1495, - "words": 201, - "headings": 3, - "estimated_token_count_total": 291 - }, - "hash": "sha256:2c77cfb38bb2e466a8f56dabbb706fcd2e90cf1634fc9beb7f0ee95a75735653", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains-fork-chains-chopsticks-get-started", - "title": "Get Started", - "slug": "develop-toolkit-parachains-fork-chains-chopsticks-get-started", - "categories": [ - "Parachains", - "Tooling" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-fork-chains-chopsticks-get-started.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/fork-chains/chopsticks/get-started/", - "preview": "[Chopsticks](https://github.com/AcalaNetwork/chopsticks/){target=\\_blank}, developed by the [Acala Foundation](https://github.com/AcalaNetwork){target=\\_blank}, is a versatile tool tailored for developers working on Polkadot SDK-based blockchains. With Chopsticks, you can fork live chains locally, replay blocks to analyze extrinsics, and simulate complex scenarios like XCM interactions all without deploying to a live network.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Install Chopsticks", - "anchor": "install-chopsticks" - }, - { - "depth": 3, - "title": "Global Installation", - "anchor": "global-installation" - }, - { - "depth": 3, - "title": "Local Installation", - "anchor": "local-installation" - }, - { - "depth": 2, - "title": "Configure Chopsticks", - "anchor": "configure-chopsticks" - }, - { - "depth": 3, - "title": "Configuration File", - "anchor": "configuration-file" - }, - { - "depth": 3, - "title": "CLI Flags", - "anchor": "cli-flags" - }, - { - "depth": 2, - "title": "WebSocket Commands", - "anchor": "websocket-commands" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 10894, - "words": 1330, - "headings": 10, - "estimated_token_count_total": 2614 - }, - "hash": "sha256:4325cdd697814b8043db808da3dee86d3d9c6fc7dd523aae7fe8914d59d1b39c", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains-light-clients", - "title": "develop-toolkit-parachains-light-clients", - "slug": "develop-toolkit-parachains-light-clients", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-fork-chains.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/fork-chains/", - "preview": "Explore tools for forking live blockchain networks. These tools enable you to replicate real-world conditions in a local environment for accurate testing and debugging. They also allow you to analyze network behavior, test new features, and simulate complex scenarios in a controlled environment without affecting production systems.", - "outline": [ - { - "depth": 2, - "title": "Why Fork a Live Chain?", - "anchor": "why-fork-a-live-chain" - }, - { - "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" - }, - { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 1269, - "words": 173, - "headings": 3, - "estimated_token_count_total": 183 - }, - "hash": "sha256:1284c42be692167e01bcc44e2e134ec20615402675fac26df246c00aa1588d80", - "last_modified": "2025-10-28T14:15:59+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains-polkadot-omni-node", - "title": "Polkadot Omni Node", - "slug": "develop-toolkit-parachains-polkadot-omni-node", - "categories": [ - "Parachains", - "Tooling" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-polkadot-omni-node.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/polkadot-omni-node/", - "preview": "The [`polkadot-omni-node`](https://crates.io/crates/polkadot-omni-node/0.7.0){target=\\_blank} crate is a versatile, pre-built binary designed to simplify running parachains in the Polkadot ecosystem. Unlike traditional node binaries that are tightly coupled to specific runtime code, the `polkadot-omni-node` operates using an external [chain specification](/polkadot-protocol/glossary#chain-specification){target=\\_blank} file, allowing it to adapt dynamically to different parachains.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Install Polkadot Omni Node", - "anchor": "install-polkadot-omni-node" - }, - { - "depth": 2, - "title": "Obtain Chain Specifications", - "anchor": "obtain-chain-specifications" - }, - { - "depth": 2, - "title": "Run a Parachain Full Node", - "anchor": "run-a-parachain-full-node" - }, - { - "depth": 2, - "title": "Interact with the Node", - "anchor": "interact-with-the-node" - }, - { - "depth": 2, - "title": "Parachain Compatibility", - "anchor": "parachain-compatibility" - }, - { - "depth": 3, - "title": "Required Runtime APIs", - "anchor": "required-runtime-apis" - }, - { - "depth": 3, - "title": "Required Pallets", - "anchor": "required-pallets" - } - ], - "stats": { - "chars": 8916, - "words": 1165, - "headings": 9, - "estimated_token_count_total": 2018 - }, - "hash": "sha256:49866761ef638dd0683bb5558f5319b9568ff136295b3359580a6f478172c73f", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains-quickstart-pop-cli", - "title": "Quickstart Parachain Development with Pop CLI", - "slug": "develop-toolkit-parachains-quickstart-pop-cli", - "categories": [ - "Parachains", - "Tooling" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-quickstart-pop-cli.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/quickstart/pop-cli/", - "preview": "[Pop CLI](https://onpop.io/cli/){target=\\_blank} is a powerful command-line tool designed explicitly for rapid parachain development within the Polkadot ecosystem. It addresses essential developer needs by providing streamlined commands to set up development environments, scaffold parachain templates, and manage local blockchain networks.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 3, - "title": "Install Pop CLI", - "anchor": "install-pop-cli" - }, - { - "depth": 3, - "title": "Set Up Your Development Environment", - "anchor": "set-up-your-development-environment" - }, - { - "depth": 3, - "title": "Initialize a Project", - "anchor": "initialize-a-project" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 4236, - "words": 610, - "headings": 5, - "estimated_token_count_total": 999 - }, - "hash": "sha256:6d6c66430a7302f29113924c5208e64d7c244497e50c61ab2f45c4b5141620e4", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains-remote-proxies", - "title": "Remote Proxies", - "slug": "develop-toolkit-parachains-remote-proxies", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-remote-proxies.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/remote-proxies/", - "preview": "!!!warning \"Kusama Implementation Only\" Remote proxies are currently only available on Kusama and its parachains (such as Kusama Asset Hub). This feature is not yet deployed on Polkadot MainNet. The examples and implementations described in this guide are specific to the Kusama ecosystem.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Remote Proxy Architecture", - "anchor": "remote-proxy-architecture" - }, - { - "depth": 2, - "title": "Implementation Workflow", - "anchor": "implementation-workflow" - }, - { - "depth": 2, - "title": "Practical Implementation", - "anchor": "practical-implementation" - }, - { - "depth": 3, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 3, - "title": "Installation and Setup", - "anchor": "installation-and-setup" - }, - { - "depth": 3, - "title": "Implementation Example", - "anchor": "implementation-example" - }, - { - "depth": 2, - "title": "Resources", - "anchor": "resources" - } - ], - "stats": { - "chars": 9063, - "words": 1113, - "headings": 8, - "estimated_token_count_total": 1863 - }, - "hash": "sha256:7086406b31e7aa9089b221ffaa548ee5540a3d147ec1e93136f481c883f2e434", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains-rpc-calls", - "title": "RPC Calls to Polkadot SDK chains.", - "slug": "develop-toolkit-parachains-rpc-calls", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-rpc-calls.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/rpc-calls/", - "preview": "[Remote Procedure Call](https://en.wikipedia.org/wiki/Remote_procedure_call){target=\\_blank} (RPC) interfaces are the primary way to interact programmatically with Polkadot SDK-based parachains and relay chains. RPC calls allow you to query chain state, submit transactions, and monitor network health from external applications or scripts.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "How Do RPC Calls Work?", - "anchor": "how-do-rpc-calls-work" - }, - { - "depth": 2, - "title": "Making RPC Calls with Curl", - "anchor": "making-rpc-calls-with-curl" - }, - { - "depth": 2, - "title": "Essential RPC Methods", - "anchor": "essential-rpc-methods" - }, - { - "depth": 3, - "title": "system_health", - "anchor": "system_health" - }, - { - "depth": 3, - "title": "chain_getBlock", - "anchor": "chain_getblock" - }, - { - "depth": 3, - "title": "state_getStorage", - "anchor": "state_getstorage" - }, - { - "depth": 3, - "title": "author_submitExtrinsic", - "anchor": "author_submitextrinsic" - }, - { - "depth": 3, - "title": "state_getMetadata", - "anchor": "state_getmetadata" - }, - { - "depth": 2, - "title": "Check Available RPC Calls", - "anchor": "check-available-rpc-calls" - }, - { - "depth": 3, - "title": "Using curl", - "anchor": "using-curl" - }, - { - "depth": 3, - "title": "Using Polkadot.js Apps", - "anchor": "using-polkadotjs-apps" - }, - { - "depth": 2, - "title": "Resources", - "anchor": "resources" - } - ], - "stats": { - "chars": 6496, - "words": 909, - "headings": 13, - "estimated_token_count_total": 1870 - }, - "hash": "sha256:3b766e00e55a224201bc6744386a6dabc7da54ed9199b16abab3b94cff449eca", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains-spawn-chains-zombienet-get-started", - "title": "Get Started", - "slug": "develop-toolkit-parachains-spawn-chains-zombienet-get-started", - "categories": [ - "Parachains", - "Tooling" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-spawn-chains-zombienet-get-started.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/spawn-chains/zombienet/get-started/", - "preview": "Zombienet is a robust testing framework designed for Polkadot SDK-based blockchain networks. It enables developers to efficiently deploy and test ephemeral blockchain environments on platforms like Kubernetes, Podman, and native setups. With its simple and versatile CLI, Zombienet provides an all-in-one solution for spawning networks, running tests, and validating performance.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Install Zombienet", - "anchor": "install-zombienet" - }, - { - "depth": 2, - "title": "Providers", - "anchor": "providers" - }, - { - "depth": 3, - "title": "Kubernetes", - "anchor": "kubernetes" - }, - { - "depth": 3, - "title": "Podman", - "anchor": "podman" - }, - { - "depth": 3, - "title": "Local Provider", - "anchor": "local-provider" - }, - { - "depth": 2, - "title": "Configure Zombienet", - "anchor": "configure-zombienet" - }, - { - "depth": 3, - "title": "Configuration Files", - "anchor": "configuration-files" - }, - { - "depth": 3, - "title": "CLI Usage", - "anchor": "cli-usage" - }, - { - "depth": 3, - "title": "Settings", - "anchor": "settings" - }, - { - "depth": 3, - "title": "Relay Chain Configuration", - "anchor": "relay-chain-configuration" - }, - { - "depth": 3, - "title": "Parachain Configuration", - "anchor": "parachain-configuration" - }, - { - "depth": 3, - "title": "XCM Configuration", - "anchor": "xcm-configuration" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 41636, - "words": 4599, - "headings": 14, - "estimated_token_count_total": 9871 - }, - "hash": "sha256:0d7e04fd952cc9d5bd8cdbfd87cc4004c5f95e896a16bc7f89dfc4caeac8f371", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains-spawn-chains-zombienet-write-tests", - "title": "Write Tests", - "slug": "develop-toolkit-parachains-spawn-chains-zombienet-write-tests", - "categories": [ - "Parachains", - "Tooling" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-spawn-chains-zombienet-write-tests.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/spawn-chains/zombienet/write-tests/", - "preview": "Testing is a critical step in blockchain development, ensuring reliability, performance, and security. Zombienet simplifies this process with its intuitive Domain Specific Language (DSL), enabling developers to write natural-language test scripts tailored to their network needs.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Testing DSL", - "anchor": "testing-dsl" - }, - { - "depth": 2, - "title": "The Test File", - "anchor": "the-test-file" - }, - { - "depth": 3, - "title": "Name", - "anchor": "name" - }, - { - "depth": 3, - "title": "Assertions", - "anchor": "assertions" - }, - { - "depth": 3, - "title": "Commands", - "anchor": "commands" - }, - { - "depth": 2, - "title": "Running a Test", - "anchor": "running-a-test" - }, - { - "depth": 2, - "title": "Example Test Files", - "anchor": "example-test-files" - } - ], - "stats": { - "chars": 11297, - "words": 1491, - "headings": 8, - "estimated_token_count_total": 2661 - }, - "hash": "sha256:04e85c4cddb58252f8253d78a3924bb56952dac2a3e9a057704a91a0d1f21d75", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains-spawn-chains-zombienet", - "title": "Zombienet", - "slug": "develop-toolkit-parachains-spawn-chains-zombienet", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-spawn-chains-zombienet.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/spawn-chains/zombienet/", - "preview": "Zombienet is a testing framework that lets you quickly spin up ephemeral blockchain networks for development and testing. With support for multiple deployment targets, such as Kubernetes, Podman, and native environments, Zombienet makes it easy to validate your blockchain implementation in a controlled environment.", - "outline": [ - { - "depth": 2, - "title": "What Can I Do with Zombienet?", - "anchor": "what-can-i-do-with-zombienet" - }, - { - "depth": 2, - "title": "Download LLM Files", - "anchor": "download-llm-files" - } - ], - "stats": { - "chars": 7659, - "words": 777, - "headings": 2, - "estimated_token_count_total": 2073 - }, - "hash": "sha256:9836ab7da420e9ca8196da77dc3ff8198cb3b622548842d0505c0aa043a5f02e", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "get-support-explore-resources", - "title": "Subscribe to Updates", - "slug": "get-support-explore-resources", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/get-support-explore-resources.md", - "html_url": "https://docs.polkadot.com/get-support/explore-resources/", - "preview": "Looking for answers beyond the documentation? These platforms are full of useful content and experienced developers sharing insights.", - "outline": [ - { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 1237, - "words": 164, - "headings": 3, - "estimated_token_count_total": 193 - }, - "hash": "sha256:4c33d0ec5026128b3bfdb1dfc1f4b29487404eaa8043071d536e8638356c6e1f", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains-spawn-chains", - "title": "Spawn Networks for Testing", - "slug": "develop-toolkit-parachains-spawn-chains", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-spawn-chains.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/spawn-chains/", - "preview": "Testing blockchain networks in a controlled environment is essential for development and validation. The Polkadot ecosystem provides specialized tools that enable you to spawn test networks, helping you verify functionality and catch issues before deploying to production.", - "outline": [ - { - "depth": 2, - "title": "Why Spawn a Network?", - "anchor": "why-spawn-a-network" - }, - { - "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" - }, - { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 1180, - "words": 155, - "headings": 3, - "estimated_token_count_total": 171 - }, - "hash": "sha256:993e93b05c8fbdfc2f7510c61ac86bc4c2ff0f03e573695b2f260933c8b62f78", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit-parachains", - "title": "Parachains", - "slug": "develop-toolkit-parachains", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/parachains/", - "preview": "Within the Polkadot ecosystem, you'll find a robust set of development tools that empower developers to build, test, and deploy blockchain applications efficiently. Whether you're designing a custom parachain, testing new features, or validating network configurations, these tools streamline the development process and ensure your blockchain setup is secure and optimized.", - "outline": [ - { - "depth": 2, - "title": "Quick Links", - "anchor": "quick-links" - }, - { - "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" - } - ], - "stats": { - "chars": 986, - "words": 136, - "headings": 2, - "estimated_token_count_total": 106 - }, - "hash": "sha256:d84a5af1a0237a911d25a68c077f508ebbce608f673ef4f9055e8e434daa96b9", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop-toolkit", - "title": "Toolkit", - "slug": "develop-toolkit", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit.md", - "html_url": "https://docs.polkadot.com/develop/toolkit/", - "preview": "Explore Polkadot's core development toolkit, designed to support a variety of developers and use cases within the ecosystem. Whether you're building blockchain infrastructure, developing cross-chain applications, or integrating with external services, this section offers essential tools and resources to help you succeed.", - "outline": [ - { - "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" - } - ], - "stats": { - "chars": 902, - "words": 113, - "headings": 1, - "estimated_token_count_total": 12 - }, - "hash": "sha256:abd9f939f68b068a18567b875c9f7e11d102c54fc02ca0e6ee8041c539061ed0", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "develop", - "title": "Develop", - "slug": "develop", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop.md", - "html_url": "https://docs.polkadot.com/develop/", - "preview": "This guide is a starting point for developers who wish to build in the Polkadot ecosystem. To get the most from this section:", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Development Pathways", - "anchor": "development-pathways" - }, - { - "depth": 3, - "title": "Parachain Developers", - "anchor": "parachain-developers" - }, - { - "depth": 3, - "title": "Smart Contract Developers", - "anchor": "smart-contract-developers" - }, - { - "depth": 3, - "title": "Application Developers", - "anchor": "application-developers" - }, - { - "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" - } - ], - "stats": { - "chars": 6923, - "words": 882, - "headings": 6, - "estimated_token_count_total": 1843 - }, - "hash": "sha256:0b43b452e9d709cb324bf51fd88c2fed8e6249534a7c2b852e1bd36bcb9b981a", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "get-support-ai-ready-docs", - "title": "AI Ready Docs", - "slug": "get-support-ai-ready-docs", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/get-support-ai-ready-docs.md", - "html_url": "https://docs.polkadot.com/get-support/ai-ready-docs/", - "preview": "Polkadot provides files to make documentation content available in a structure optimized for use with large language models (LLMs) and AI tools. These resources help build AI assistants, power code search, or enable custom tooling trained on Polkadot’s documentation.", - "outline": [ - { - "depth": 2, - "title": "How to Use These Files", - "anchor": "how-to-use-these-files" - }, - { - "depth": 2, - "title": "Download LLM Files", - "anchor": "download-llm-files" - } - ], - "stats": { - "chars": 7998, - "words": 825, - "headings": 2, - "estimated_token_count_total": 2232 - }, - "hash": "sha256:1090b02689df5f4c59bb83f9c81436718d06e46f3b615bc655fef3c7b6c9fb02", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "get-support-explore-resources", - "title": "Subscribe to Updates", - "slug": "get-support-explore-resources", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/get-support-explore-resources.md", - "html_url": "https://docs.polkadot.com/get-support/explore-resources/", - "preview": "Looking for answers beyond the documentation? These platforms are full of useful content and experienced developers sharing insights.", - "outline": [ - { - "depth": 2, - "title": "🧠 Stack Exchange", - "anchor": "stack-exchange" - }, - { - "depth": 2, - "title": "🧵 Reddit: r/Polkadot", - "anchor": "reddit-rpolkadot" - }, - { - "depth": 2, - "title": "💬 Discord (Community Threads Only)", - "anchor": "discord-community-threads-only" - }, - { - "depth": 2, - "title": "🎥 YouTube: @PolkadotNetwork", - "anchor": "youtube-polkadotnetwork" - }, - { - "depth": 2, - "title": "Verify Installation", - "anchor": "verify-installation" - } - ], - "stats": { - "chars": 11883, - "words": 1662, - "headings": 12, - "estimated_token_count_total": 2559 - }, - "hash": "sha256:0857a9e83aefc6d3f04e8cb320ab82d35211bbd73d2eb2614cf7b97f8e6d36b9", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "infrastructure-running-a-validator-onboarding-and-offboarding-start-validating", - "title": "Start Validating", - "slug": "infrastructure-running-a-validator-onboarding-and-offboarding-start-validating", - "categories": [ - "Infrastructure" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/infrastructure-running-a-validator-onboarding-and-offboarding-start-validating.md", - "html_url": "https://docs.polkadot.com/infrastructure/running-a-validator/onboarding-and-offboarding/start-validating/", - "preview": "After configuring your node keys as shown in the [Key Management](/infrastructure/running-a-validator/onboarding-and-offboarding/key-management){target=\\_blank} section and ensuring your system is set up, you're ready to begin the validator setup process. This guide will walk you through choosing a network, synchronizing your node with the blockchain, bonding your DOT tokens, and starting your validator.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Choose a Network", - "anchor": "choose-a-network" - }, - { - "depth": 2, - "title": "Synchronize Chain Data", - "anchor": "synchronize-chain-data" - }, - { - "depth": 3, - "title": "🔷 X (Twitter): Official Accounts", - "anchor": "x-twitter-official-accounts" - }, - { - "depth": 3, - "title": "🔁 X (Twitter): Community Accounts", - "anchor": "x-twitter-community-accounts" - }, - { - "depth": 3, - "title": "🗣️ Polkadot Forum", - "anchor": "polkadot-forum" - }, - { - "depth": 3, - "title": "🧑‍⚖️ Polkassembly: OpenGov", - "anchor": "polkassembly-opengov" - }, - { - "depth": 3, - "title": "📸 Instagram", - "anchor": "instagram" - } - ], - "stats": { - "chars": 2456, - "words": 295, - "headings": 10, - "estimated_token_count_total": 579 - }, - "hash": "sha256:e2567b7d5377c87984622cf93afe4bd8cedf46b80597736cf53f26b5f31c5065", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "get-support-get-in-touch", - "title": "Get in Touch", - "slug": "get-support-get-in-touch", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/get-support-get-in-touch.md", - "html_url": "https://docs.polkadot.com/get-support/get-in-touch/", - "preview": "Use one of the channels below to get live technical support or ask questions.", - "outline": [ - { - "depth": 2, - "title": "Need Help Fast?", - "anchor": "need-help-fast" - }, - { - "depth": 2, - "title": "📱 Telegram: Polkadot Developer Support", - "anchor": "telegram-polkadot-developer-support" - }, - { - "depth": 2, - "title": "🔌 Discord: Polkadot Official Server", - "anchor": "discord-polkadot-official-server" - }, - { - "depth": 2, - "title": "🧬 Matrix: Polkadot Developer Support", - "anchor": "matrix-polkadot-developer-support" - } - ], - "stats": { - "chars": 1949, - "words": 258, - "headings": 4, - "estimated_token_count_total": 557 - }, - "hash": "sha256:9ab570299106336e5d75923b876247e8eb4a71851a77e84d68e0335e9da5e0a8", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "get-support", - "title": "Support", - "slug": "get-support", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/get-support.md", - "html_url": "https://docs.polkadot.com/get-support/", - "preview": "Use one of the channels below to get live technical support or ask questions.", - "outline": [ - { - "depth": 2, - "title": "Need More than Just Documentation?", - "anchor": "need-more-than-just-documentation" - }, - { - "depth": 2, - "title": "What You Can Do Here", - "anchor": "what-you-can-do-here" - }, - { - "depth": 2, - "title": "Help Us Improve", - "anchor": "help-us-improve" - } - ], - "stats": { - "chars": 1658, - "words": 244, - "headings": 3, - "estimated_token_count_total": 280 - }, - "hash": "sha256:a7b5239c3be0341ced8f28146e240ff6061fded2e71094bd586beeb024684a50", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "index", - "title": "Polkadot Developer Docs", - "slug": "index", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/index.md", - "html_url": "https://docs.polkadot.com/index/", - "preview": "Explore everything you need to start building on top of Polkadot, a protocol that provides parachains with shared security and interoperability using XCM.", - "outline": [], - "stats": { - "chars": 0, - "words": 0, - "headings": 0, - "estimated_token_count_total": 0 - }, - "hash": "sha256:97655248c65e816fdf3d85dab4ace7ca0c145c50f671c25c24627cfd7660c7a6", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "infrastructure-running-a-validator-operational-tasks-upgrade-your-node", - "title": "Upgrade a Validator Node", - "slug": "infrastructure-running-a-validator-operational-tasks-upgrade-your-node", - "categories": [ - "Infrastructure" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/infrastructure-running-a-validator-operational-tasks-upgrade-your-node.md", - "html_url": "https://docs.polkadot.com/infrastructure/running-a-validator/operational-tasks/upgrade-your-node/", - "preview": "Upgrading a Polkadot validator node is essential for staying current with network updates and maintaining optimal performance. This guide covers routine and extended maintenance scenarios, including software upgrades and major server changes. Following these steps, you can manage session keys and transition smoothly between servers without risking downtime, slashing, or network disruptions. The process requires strategic planning, especially if you need to perform long-lead maintenance, ensuring", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Session Keys", - "anchor": "session-keys" - }, - { - "depth": 2, - "title": "Keystore", - "anchor": "keystore" - }, - { - "depth": 2, - "title": "Upgrade Using Backup Validator", - "anchor": "upgrade-using-backup-validator" - }, - { - "depth": 3, - "title": "Session `N`", - "anchor": "session-n" - }, - { - "depth": 3, - "title": "Session `N+3`", - "anchor": "session-n3" - } - ], - "stats": { - "chars": 5624, - "words": 842, - "headings": 7, - "estimated_token_count_total": 1167 - }, - "hash": "sha256:b2e8abce15fc9df106a5e972f28c64f606f9dd50ba3a256093eb53bdd5126224", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "infrastructure-running-a-validator-requirements", - "title": "Validator Requirements", - "slug": "infrastructure-running-a-validator-requirements", - "categories": [ - "Infrastructure" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/infrastructure-running-a-validator-requirements.md", - "html_url": "https://docs.polkadot.com/infrastructure/running-a-validator/requirements/", - "preview": "Running a validator in the Polkadot ecosystem is essential for maintaining network security and decentralization. Validators are responsible for validating transactions and adding new blocks to the chain, ensuring the system operates smoothly. In return for their services, validators earn rewards. However, the role comes with inherent risks, such as slashing penalties for misbehavior or technical failures. If you’re new to validation, starting on Kusama provides a lower-stakes environment to gai", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Minimum Hardware Requirements", - "anchor": "minimum-hardware-requirements" - }, - { - "depth": 2, - "title": "VPS Provider List", - "anchor": "vps-provider-list" - }, - { - "depth": 2, - "title": "Minimum Bond Requirement", - "anchor": "minimum-bond-requirement" - } - ], - "stats": { - "chars": 6838, - "words": 940, - "headings": 5, - "estimated_token_count_total": 1477 - }, - "hash": "sha256:76500d1d63f4205a84f0bc5b7f9aec945781127d41c32927280ac74bc14f0296", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "infrastructure-staking-mechanics-offenses-and-slashes", - "title": "Offenses and Slashes", - "slug": "infrastructure-staking-mechanics-offenses-and-slashes", - "categories": [ - "Infrastructure" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/infrastructure-staking-mechanics-offenses-and-slashes.md", - "html_url": "https://docs.polkadot.com/infrastructure/staking-mechanics/offenses-and-slashes/", - "preview": "In Polkadot's Nominated Proof of Stake (NPoS) system, validator misconduct is deterred through a combination of slashing, disabling, and reputation penalties. Validators and nominators who stake tokens face consequences for validator misbehavior, which range from token slashes to restrictions on network participation.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Offenses", - "anchor": "offenses" - }, - { - "depth": 3, - "title": "Invalid Votes", - "anchor": "invalid-votes" - }, - { - "depth": 3, - "title": "Equivocations", - "anchor": "equivocations" - }, - { - "depth": 2, - "title": "Penalties", - "anchor": "penalties" - }, - { - "depth": 3, - "title": "Slashing", - "anchor": "slashing" - }, - { - "depth": 3, - "title": "Disabling", - "anchor": "disabling" - }, - { - "depth": 3, - "title": "Reputation Changes", - "anchor": "reputation-changes" - }, - { - "depth": 3, - "title": "Penalties by Offense", - "anchor": "penalties-by-offense" - } - ], - "stats": { - "chars": 15427, - "words": 2103, - "headings": 9, - "estimated_token_count_total": 3409 - }, - "hash": "sha256:abe6bedab04f463ec07f554977b8d6355a5d2fad9bcda01cbe58568152295daa", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "infrastructure-staking-mechanics-rewards-payout", - "title": "Rewards Payout", - "slug": "infrastructure-staking-mechanics-rewards-payout", - "categories": [ - "Infrastructure" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/infrastructure-staking-mechanics-rewards-payout.md", - "html_url": "https://docs.polkadot.com/infrastructure/staking-mechanics/rewards-payout/", - "preview": "Understanding how rewards are distributed to validators and nominators is essential for network participants. In Polkadot and Kusama, validators earn rewards based on their era points, which are accrued through actions like block production and parachain validation.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Era Points", - "anchor": "era-points" - }, - { - "depth": 2, - "title": "Reward Variance", - "anchor": "reward-variance" - }, - { - "depth": 2, - "title": "Payout Scheme", - "anchor": "payout-scheme" - }, - { - "depth": 2, - "title": "Running Multiple Validators", - "anchor": "running-multiple-validators" - }, - { - "depth": 2, - "title": "Nominators and Validator Payments", - "anchor": "nominators-and-validator-payments" - } - ], - "stats": { - "chars": 11070, - "words": 1764, - "headings": 6, - "estimated_token_count_total": 2617 - }, - "hash": "sha256:7d43408276d811c96b7b081a7b9f4d884893282a230b564c9eb3be2fc7857565", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "nodes-and-validators-run-a-node-bootnode", - "title": "Set Up a Bootnode", - "slug": "nodes-and-validators-run-a-node-bootnode", - "categories": [ - "Infrastructure" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-node-bootnode.md", - "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-node/bootnode/", - "preview": "Bootnodes are essential for helping blockchain nodes discover peers and join the network. When a node starts, it needs to find other nodes, and bootnodes provide an initial point of contact. Once connected, a node can expand its peer connections and play its role in the network, like participating as a validator.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Accessing the Bootnode", - "anchor": "accessing-the-bootnode" - }, - { - "depth": 2, - "title": "Node Key", - "anchor": "node-key" - }, - { - "depth": 2, - "title": "Running the Bootnode", - "anchor": "running-the-bootnode" - }, - { - "depth": 2, - "title": "Testing Bootnode Connection", - "anchor": "testing-bootnode-connection" - }, - { - "depth": 3, - "title": "P2P", - "anchor": "p2p" - }, - { - "depth": 3, - "title": "P2P/WS", - "anchor": "p2pws" - }, - { - "depth": 3, - "title": "P2P/WSS", - "anchor": "p2pwss" - } - ], - "stats": { - "chars": 4538, - "words": 647, - "headings": 9, - "estimated_token_count_total": 1044 - }, - "hash": "sha256:d84a5af1a0237a911d25a68c077f508ebbce608f673ef4f9055e8e434daa96b9", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "nodes-and-validators-run-a-node-full-node", - "title": "Set Up a Node", - "slug": "nodes-and-validators-run-a-node-full-node", - "categories": [ - "Infrastructure" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-node-full-node.md", - "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-node/full-node/", - "preview": "Running a node on Polkadot provides direct interaction with the network, enhanced privacy, and full control over RPC requests, transactions, and data queries. As the backbone of the network, nodes ensure decentralized data propagation, transaction validation, and seamless communication across the ecosystem.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Set Up a Node", - "anchor": "set-up-a-node" - }, - { - "depth": 3, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 3, - "title": "Install and Build the Polkadot Binary", - "anchor": "install-and-build-the-polkadot-binary" - }, - { - "depth": 3, - "title": "Use Docker", - "anchor": "use-docker" - }, - { - "depth": 2, - "title": "Configure and Run Your Node", - "anchor": "configure-and-run-your-node" - }, - { - "depth": 3, - "title": "RPC Configurations", - "anchor": "rpc-configurations" - }, - { - "depth": 2, - "title": "Sync Your Node", - "anchor": "sync-your-node" - }, - { - "depth": 3, - "title": "Connect to Your Node", - "anchor": "connect-to-your-node" - } - ], - "stats": { - "chars": 15947, - "words": 2482, - "headings": 9, - "estimated_token_count_total": 4197 - }, - "hash": "sha256:b83e3f77bd30ac8c8fb00a193bbec33cd641d94f1a37ac611dea32326c3d77b0", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "nodes-and-validators-run-a-node-secure-wss", - "title": "Set Up Secure WebSocket", - "slug": "nodes-and-validators-run-a-node-secure-wss", - "categories": [ - "Infrastructure" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-node-secure-wss.md", - "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-node/secure-wss/", - "preview": "Ensuring secure WebSocket communication is crucial for maintaining the integrity and security of a Polkadot or Kusama node when interacting with remote clients. This guide walks you through setting up a secure WebSocket (WSS) connection for your node by leveraging SSL encryption with popular web server proxies like nginx or Apache.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Secure a WebSocket Port", - "anchor": "secure-a-websocket-port" - }, - { - "depth": 3, - "title": "Obtain an SSL Certificate", - "anchor": "obtain-an-ssl-certificate" - }, - { - "depth": 2, - "title": "Install a Proxy Server", - "anchor": "install-a-proxy-server" - }, - { - "depth": 3, - "title": "Use nginx", - "anchor": "use-nginx" - }, - { - "depth": 3, - "title": "Use Apache2", - "anchor": "use-apache2" - }, - { - "depth": 2, - "title": "Connect to the Node", - "anchor": "connect-to-the-node" - } - ], - "stats": { - "chars": 5568, - "words": 774, - "headings": 7, - "estimated_token_count_total": 1280 - }, - "hash": "sha256:992082e4ad87348b283f6c37ea886ae0e7bf016852b6470000876f3d169c65a4", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management", - "title": "Validator Key Management", - "slug": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management", - "categories": [ - "Infrastructure" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-key-management.md", - "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/", - "preview": "After setting up your node environment as shown in the [Setup](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/){target=\\_blank} section, you'll need to configure multiple keys for your validator to operate properly. This includes setting up session keys, which are essential for participating in the consensus process, and configuring a node key that maintains a stable network identity. This guide walks you through the key management process, showing you how to g", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Set Session Keys", - "anchor": "set-session-keys" - }, - { - "depth": 3, - "title": "Generate Session Keys", - "anchor": "generate-session-keys" - }, - { - "depth": 3, - "title": "Submit Transaction to Set Keys", - "anchor": "submit-transaction-to-set-keys" - }, - { - "depth": 3, - "title": "Verify Session Key Setup", - "anchor": "verify-session-key-setup" - }, - { - "depth": 2, - "title": "Set the Node Key", - "anchor": "set-the-node-key" - }, - { - "depth": 3, - "title": "Generate the Node Key", - "anchor": "generate-the-node-key" - }, - { - "depth": 3, - "title": "Set Node Key", - "anchor": "set-node-key" - } - ], - "stats": { - "chars": 8227, - "words": 1183, - "headings": 8, - "estimated_token_count_total": 1840 - }, - "hash": "sha256:0fb5a83835aab263c0b9aa886028c8aa8a2d6d0897d7b9fff4b5258835d30dfe", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", - "title": "Set Up a Validator", - "slug": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator", - "categories": [ - "Infrastructure" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-set-up-validator.md", - "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/set-up-validator/", - "preview": "Setting up a Polkadot validator node is essential for securing the network and earning staking rewards. This guide walks you through the technical steps to set up a validator, from installing the necessary software to managing keys and synchronizing your node with the chain.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Initial Setup", - "anchor": "initial-setup" - }, - { - "depth": 3, - "title": "Install Network Time Protocol Client", - "anchor": "install-network-time-protocol-client" - }, - { - "depth": 3, - "title": "Verify Landlock is Activated", - "anchor": "verify-landlock-is-activated" - }, - { - "depth": 2, - "title": "Install the Polkadot Binaries", - "anchor": "install-the-polkadot-binaries" - }, - { - "depth": 3, - "title": "Install from Official Releases", - "anchor": "install-from-official-releases" - }, - { - "depth": 3, - "title": "Install with Package Managers", - "anchor": "install-with-package-managers" - }, - { - "depth": 3, - "title": "Install with Ansible", - "anchor": "install-with-ansible" - }, - { - "depth": 3, - "title": "Install with Docker", - "anchor": "install-with-docker" - }, - { - "depth": 3, - "title": "Build from Sources", - "anchor": "build-from-sources" - }, - { - "depth": 2, - "title": "Verify Installation", - "anchor": "verify-installation" - } - ], - "stats": { - "chars": 11921, - "words": 1678, - "headings": 12, - "estimated_token_count_total": 2592 - }, - "hash": "sha256:d2c1c91734bc8185057d8eeec6829ea91e0316f7ba884c5dc3922a5e5778815e", - "last_modified": "2025-10-28T14:42:13+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", - "title": "Start Validating", - "slug": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating", - "categories": [ - "Infrastructure" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-start-validating.md", - "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/start-validating/", - "preview": "After configuring your node keys as shown in the [Key Management](/nodes-and-validators/run-a-validator/onboarding-and-offboarding/key-management/){target=\\_blank} section and ensuring your system is set up, you're ready to begin the validator setup process. This guide will walk you through choosing a network, synchronizing your node with the blockchain, bonding your DOT tokens, and starting your validator.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Choose a Network", - "anchor": "choose-a-network" - }, - { - "depth": 2, - "title": "Synchronize Chain Data", - "anchor": "synchronize-chain-data" - }, - { - "depth": 3, - "title": "Database Snapshot Services", - "anchor": "database-snapshot-services" - }, - { - "depth": 2, - "title": "Bond DOT", - "anchor": "bond-dot" - }, - { - "depth": 3, - "title": "Bonding DOT on Polkadot.js Apps", - "anchor": "bonding-dot-on-polkadotjs-apps" - }, - { - "depth": 2, - "title": "Validate", - "anchor": "validate" - }, - { - "depth": 3, - "title": "Verify Sync via Telemetry", - "anchor": "verify-sync-via-telemetry" - }, - { - "depth": 3, - "title": "Activate using Polkadot.js Apps", - "anchor": "activate-using-polkadotjs-apps" - }, - { - "depth": 3, - "title": "Monitor Validation Status and Slots", - "anchor": "monitor-validation-status-and-slots" - }, - { - "depth": 2, - "title": "Run a Validator Using Systemd", - "anchor": "run-a-validator-using-systemd" - }, - { - "depth": 3, - "title": "Create the Systemd Service File", - "anchor": "create-the-systemd-service-file" - }, - { - "depth": 3, - "title": "Run the Service", - "anchor": "run-the-service" - } - ], - "stats": { - "chars": 15821, - "words": 2446, - "headings": 13, - "estimated_token_count_total": 3861 - }, - "hash": "sha256:a4235e8d590033d5d54434143e0a5e23603c53ae70d4f0a9ebfe4ca9442baa8d", - "last_modified": "2025-10-28T14:42:14+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating", - "title": "Stop Validating", - "slug": "nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating", - "categories": [ - "Infrastructure" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/nodes-and-validators-run-a-validator-onboarding-and-offboarding-stop-validating.md", - "html_url": "https://docs.polkadot.com/nodes-and-validators/run-a-validator/onboarding-and-offboarding/stop-validating/", - "preview": "If you're ready to stop validating on Polkadot, there are essential steps to ensure a smooth transition while protecting your funds and account integrity. Whether you're taking a break for maintenance or unbonding entirely, you'll need to chill your validator, purge session keys, and unbond your tokens. This guide explains how to use Polkadot's tools and extrinsics to safely withdraw from validation activities, safeguarding your account's future usability.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Pause Versus Stop", - "anchor": "pause-versus-stop" - }, - { - "depth": 2, - "title": "Chill Validator", - "anchor": "chill-validator" - }, - { - "depth": 2, - "title": "Purge Validator Session Keys", - "anchor": "purge-validator-session-keys" - }, - { - "depth": 2, - "title": "Unbond Your Tokens", - "anchor": "unbond-your-tokens" - } - ], - "stats": { - "chars": 3230, - "words": 500, - "headings": 5, - "estimated_token_count_total": 629 - }, - "hash": "sha256:0d6db361bfa7a3022849bbe39989bfdac0429537498d7f534adadec131afca98", - "last_modified": "2025-10-28T14:42:14+00:00", + "hash": "sha256:0d6db361bfa7a3022849bbe39989bfdac0429537498d7f534adadec131afca98", "token_estimator": "heuristic-v1" }, { @@ -6419,7 +4233,6 @@ "estimated_token_count_total": 5866 }, "hash": "sha256:81eb0fe77f05155f1ec0511cd066120fc9994961e9d91e21b6666377e65b4586", - "last_modified": "2025-10-28T14:42:14+00:00", "token_estimator": "heuristic-v1" }, { @@ -6471,7 +4284,6 @@ "estimated_token_count_total": 861 }, "hash": "sha256:1af153570ce57bd5b52d08493a300996765686f2a6d04519a2e0aa91191612c1", - "last_modified": "2025-10-28T14:42:14+00:00", "token_estimator": "heuristic-v1" }, { @@ -6528,7 +4340,6 @@ "estimated_token_count_total": 1185 }, "hash": "sha256:888230b128d8c648c4f06a18d3b1d1b06dd1bf22a0de4add1f28210ffccb2549", - "last_modified": "2025-10-28T14:42:14+00:00", "token_estimator": "heuristic-v1" }, { @@ -6575,7 +4386,6 @@ "estimated_token_count_total": 1485 }, "hash": "sha256:46435b97c37ef6798d2c75c69df31c5e5f07e04b218c370ec5af6b1838d43aac", - "last_modified": "2025-10-28T14:42:14+00:00", "token_estimator": "heuristic-v1" }, { @@ -6642,7 +4452,6 @@ "estimated_token_count_total": 3409 }, "hash": "sha256:abe6bedab04f463ec07f554977b8d6355a5d2fad9bcda01cbe58568152295daa", - "last_modified": "2025-10-28T14:42:14+00:00", "token_estimator": "heuristic-v1" }, { @@ -6694,7 +4503,6 @@ "estimated_token_count_total": 2588 }, "hash": "sha256:d5d6d72eb2cf10f624d84c65f2274f7df90acb5d071bf170bc8eae8d98a810a5", - "last_modified": "2025-10-28T14:42:14+00:00", "token_estimator": "heuristic-v1" }, { @@ -6786,7 +4594,6 @@ "estimated_token_count_total": 2724 }, "hash": "sha256:93d123cbaaccc2515b4a70be8e1327b4f75b1051d16c5e3daf5a2035af7b7ca3", - "last_modified": "2025-10-28T14:42:14+00:00", "token_estimator": "heuristic-v1" }, { @@ -6913,7 +4720,6 @@ "estimated_token_count_total": 3811 }, "hash": "sha256:d83e574726c524fa017236eb5e3b8a0676d598be4da1ce4fe25a60141baeee49", - "last_modified": "2025-10-28T14:42:14+00:00", "token_estimator": "heuristic-v1" }, { @@ -6925,7 +4731,7 @@ ], "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-add-smart-contract-functionality.md", "html_url": "https://docs.polkadot.com/parachains/customize-runtime/add-smart-contract-functionality/", - "preview": "When building your custom blockchain with the Polkadot SDK, you have the flexibility to add smart contract capabilities through specialized pallets. These pallets allow blockchain users to deploy and execute smart contracts, enhancing your chain's functionality and programmability.", + "preview": "When building your custom blockchain with the Polkadot SDK, you can add smart contract capabilities through specialized pallets. These pallets enable users to deploy and execute smart contracts, enhancing your chain's programmability and allowing developers to build decentralized applications on your network.", "outline": [ { "depth": 2, @@ -6934,13 +4740,73 @@ }, { "depth": 2, - "title": "EVM Smart Contracts", - "anchor": "evm-smart-contracts" + "title": "pallet-revive", + "anchor": "pallet-revive" + }, + { + "depth": 3, + "title": "Core Components", + "anchor": "core-components" + }, + { + "depth": 3, + "title": "Supported Languages and Compilers", + "anchor": "supported-languages-and-compilers" + }, + { + "depth": 3, + "title": "How It Works", + "anchor": "how-it-works" + }, + { + "depth": 3, + "title": "Key Benefits", + "anchor": "key-benefits" + }, + { + "depth": 3, + "title": "Implementation Examples", + "anchor": "implementation-examples" + }, + { + "depth": 2, + "title": "Frontier", + "anchor": "frontier" + }, + { + "depth": 3, + "title": "Integration Options", + "anchor": "integration-options" + }, + { + "depth": 3, + "title": "EVM Execution Only", + "anchor": "evm-execution-only" + }, + { + "depth": 3, + "title": "Full Ethereum Compatibility", + "anchor": "full-ethereum-compatibility" + }, + { + "depth": 3, + "title": "Key Benefits", + "anchor": "key-benefits-2" + }, + { + "depth": 3, + "title": "Implementation Examples", + "anchor": "implementation-examples-2" }, { "depth": 2, - "title": "Wasm Smart Contracts", - "anchor": "wasm-smart-contracts" + "title": "pallet-contracts (Legacy)", + "anchor": "pallet-contracts-legacy" + }, + { + "depth": 3, + "title": "Implementation Example", + "anchor": "implementation-example" }, { "depth": 2, @@ -6949,13 +4815,12 @@ } ], "stats": { - "chars": 3865, - "words": 521, - "headings": 4, - "estimated_token_count_total": 901 + "chars": 6655, + "words": 833, + "headings": 16, + "estimated_token_count_total": 1631 }, - "hash": "sha256:f56a32d5323c371f084833b4e647f21e1d76ad242d8c4e4826bcaed467acc7cf", - "last_modified": "2025-10-28T14:42:14+00:00", + "hash": "sha256:6297bb5e0809fdd0585d6170054599f7ab4a3ce7c687ad03ae43092057c493b7", "token_estimator": "heuristic-v1" }, { @@ -7008,86 +4873,18 @@ "estimated_token_count_total": 3091 }, "hash": "sha256:87add0ae178e4970601a27efccadb58eff1375d19819201034ba2829914f1cd5", - "last_modified": "2025-10-28T14:42:14+00:00", "token_estimator": "heuristic-v1" }, { "id": "parachains-customize-runtime-pallet-development-benchmark-pallet", - "title": "Benchmarking FRAME Pallets", + "title": "Benchmark Your Pallet", "slug": "parachains-customize-runtime-pallet-development-benchmark-pallet", "categories": [ "Parachains" ], "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md", "html_url": "https://docs.polkadot.com/parachains/customize-runtime/pallet-development/benchmark-pallet/", - "preview": "Benchmarking is a critical component of developing efficient and secure blockchain runtimes. In the Polkadot ecosystem, accurately benchmarking your custom pallets ensures that each extrinsic has a precise [weight](/reference/glossary/#weight){target=\\_blank}, representing its computational and storage demands. This process is vital for maintaining the blockchain's performance and preventing potential vulnerabilities, such as Denial of Service (DoS) attacks.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "The Case for Benchmarking", - "anchor": "the-case-for-benchmarking" - }, - { - "depth": 3, - "title": "Benchmarking and Weight", - "anchor": "benchmarking-and-weight" - }, - { - "depth": 2, - "title": "Benchmarking Process", - "anchor": "benchmarking-process" - }, - { - "depth": 3, - "title": "Prepare Your Environment", - "anchor": "prepare-your-environment" - }, - { - "depth": 3, - "title": "Write Benchmark Tests", - "anchor": "write-benchmark-tests" - }, - { - "depth": 3, - "title": "Add Benchmarks to Runtime", - "anchor": "add-benchmarks-to-runtime" - }, - { - "depth": 3, - "title": "Run Benchmarks", - "anchor": "run-benchmarks" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 14715, - "words": 1879, - "headings": 9, - "estimated_token_count_total": 3338 - }, - "hash": "sha256:915bc91edd56cdedd516e871dbe450d70c9f99fb467cc00ff231ea3a74f61d96", - "last_modified": "2025-10-28T14:42:14+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "parachains-customize-runtime-pallet-development-create-a-pallet", - "title": "Create a Custom Pallet", - "slug": "parachains-customize-runtime-pallet-development-create-a-pallet", - "categories": [ - "Parachains" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-create-a-pallet.md", - "html_url": "https://docs.polkadot.com/parachains/customize-runtime/pallet-development/create-a-pallet/", - "preview": "[Framework for Runtime Aggregation of Modular Entities (FRAME)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\\_blank} provides a powerful set of tools for blockchain development through modular components called [pallets](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/pallet/index.html){target=\\_blank}. These Rust-based runtime modules allow you to build custom blockchain functional", + "preview": "Benchmarking is the process of measuring the computational resources (execution time and storage) required by your pallet's extrinsics. Accurate [weight](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/index.html){target=\\_blank} calculations are essential for ensuring your blockchain can process transactions efficiently while protecting against denial-of-service attacks.", "outline": [ { "depth": 2, @@ -7101,547 +4898,355 @@ }, { "depth": 2, - "title": "Core Pallet Components", - "anchor": "core-pallet-components" - }, - { - "depth": 2, - "title": "Create the Pallet Project", - "anchor": "create-the-pallet-project" - }, - { - "depth": 2, - "title": "Configure Dependencies", - "anchor": "configure-dependencies" + "title": "Why Benchmark?", + "anchor": "why-benchmark" }, { "depth": 2, - "title": "Initialize the Pallet Structure", - "anchor": "initialize-the-pallet-structure" + "title": "Understanding Weights", + "anchor": "understanding-weights" }, { "depth": 2, - "title": "Configure the Pallet", - "anchor": "configure-the-pallet" + "title": "Step 1: Create the Benchmarking Module", + "anchor": "step-1-create-the-benchmarking-module" }, { "depth": 2, - "title": "Define Events", - "anchor": "define-events" + "title": "Step 2: Define the Weight Trait", + "anchor": "step-2-define-the-weight-trait" }, { "depth": 2, - "title": "Define Errors", - "anchor": "define-errors" + "title": "Step 3: Add WeightInfo to Config", + "anchor": "step-3-add-weightinfo-to-config" }, { "depth": 2, - "title": "Add Storage Items", - "anchor": "add-storage-items" + "title": "Step 4: Update Extrinsic Weight Annotations", + "anchor": "step-4-update-extrinsic-weight-annotations" }, { "depth": 2, - "title": "Configure Genesis State", - "anchor": "configure-genesis-state" + "title": "Step 5: Include the Benchmarking Module", + "anchor": "step-5-include-the-benchmarking-module" }, { "depth": 2, - "title": "Implement Dispatchable Functions", - "anchor": "implement-dispatchable-functions" - }, - { - "depth": 3, - "title": "Dispatchable Function Details", - "anchor": "dispatchable-function-details" + "title": "Step 6: Configure Pallet Dependencies", + "anchor": "step-6-configure-pallet-dependencies" }, { "depth": 2, - "title": "Verify Pallet Compilation", - "anchor": "verify-pallet-compilation" + "title": "Step 7: Update Mock Runtime", + "anchor": "step-7-update-mock-runtime" }, { "depth": 2, - "title": "Add the Pallet to Your Runtime", - "anchor": "add-the-pallet-to-your-runtime" - }, - { - "depth": 3, - "title": "Add Runtime Dependency", - "anchor": "add-runtime-dependency" - }, - { - "depth": 3, - "title": "Implement the Config Trait", - "anchor": "implement-the-config-trait" + "title": "Step 8: Configure Runtime Benchmarking", + "anchor": "step-8-configure-runtime-benchmarking" }, { "depth": 3, - "title": "Add to Runtime Construct", - "anchor": "add-to-runtime-construct" + "title": "Update Runtime Cargo.toml", + "anchor": "update-runtime-cargotoml" }, { "depth": 3, - "title": "Configure Genesis for Your Runtime", - "anchor": "configure-genesis-for-your-runtime" + "title": "Update Runtime Configuration", + "anchor": "update-runtime-configuration" }, { "depth": 3, - "title": "Verify Runtime Compilation", - "anchor": "verify-runtime-compilation" + "title": "Register Benchmarks", + "anchor": "register-benchmarks" }, { "depth": 2, - "title": "Run Your Chain Locally", - "anchor": "run-your-chain-locally" - }, - { - "depth": 3, - "title": "Generate a Chain Specification", - "anchor": "generate-a-chain-specification" + "title": "Step 9: Run Benchmarks", + "anchor": "step-9-run-benchmarks" }, { "depth": 3, - "title": "Start the Parachain Node", - "anchor": "start-the-parachain-node" + "title": "Test Benchmark Compilation", + "anchor": "test-benchmark-compilation" }, { - "depth": 2, - "title": "Interact with Your Pallet", - "anchor": "interact-with-your-pallet" - }, - { - "depth": 2, - "title": "Key Takeaways", - "anchor": "key-takeaways" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 26671, - "words": 3041, - "headings": 26, - "estimated_token_count_total": 6113 - }, - "hash": "sha256:607e283aaa1295de0af191d97de7f6f87afb722c601a447821fde6a09b97f1af", - "token_estimator": "heuristic-v1" - }, - { - "id": "parachains-customize-runtime-pallet-development-mock-runtime", - "title": "Mock Your Runtime", - "slug": "parachains-customize-runtime-pallet-development-mock-runtime", - "categories": [ - "Parachains" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-mock-runtime.md", - "html_url": "https://docs.polkadot.com/parachains/customize-runtime/pallet-development/mock-runtime/", - "preview": "Testing is a critical part of pallet development. Before integrating your pallet into a full runtime, you need a way to test its functionality in isolation. A mock runtime provides a minimal, simulated blockchain environment where you can verify your pallet's logic without the overhead of running a full node.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "depth": 3, + "title": "Build the Runtime with Benchmarks", + "anchor": "build-the-runtime-with-benchmarks" }, { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" + "depth": 3, + "title": "Install the Benchmarking Tool", + "anchor": "install-the-benchmarking-tool" }, { - "depth": 2, - "title": "Understand Mock Runtimes", - "anchor": "understand-mock-runtimes" + "depth": 3, + "title": "Download the Weight Template", + "anchor": "download-the-weight-template" }, { - "depth": 2, - "title": "Create the Mock Runtime Module", - "anchor": "create-the-mock-runtime-module" + "depth": 3, + "title": "Hardware Requirements for Benchmarking", + "anchor": "hardware-requirements-for-benchmarking" }, { - "depth": 2, - "title": "Set Up Basic Mock", - "anchor": "set-up-basic-mock" + "depth": 3, + "title": "Execute Benchmarks", + "anchor": "execute-benchmarks" }, { - "depth": 2, - "title": "Implement Essential Configuration", - "anchor": "implement-essential-configuration" + "depth": 3, + "title": "Advanced Options", + "anchor": "advanced-options" }, { "depth": 2, - "title": "Implement Your Pallet's Configuration", - "anchor": "implement-your-pallets-configuration" + "title": "Step 10: Use Generated Weights", + "anchor": "step-10-use-generated-weights" }, { - "depth": 2, - "title": "Configure Genesis Storage", - "anchor": "configure-genesis-storage" + "depth": 3, + "title": "Integrate the Generated Weights", + "anchor": "integrate-the-generated-weights" }, { "depth": 3, - "title": "Basic Test Environment", - "anchor": "basic-test-environment" + "title": "Update Runtime Configuration", + "anchor": "update-runtime-configuration-2" }, { "depth": 3, - "title": "Custom Genesis Configurations", - "anchor": "custom-genesis-configurations" + "title": "Example Generated Weight File", + "anchor": "example-generated-weight-file" }, { "depth": 2, - "title": "Verify Mock Compilation", - "anchor": "verify-mock-compilation" + "title": "Benchmarking Best Practices", + "anchor": "benchmarking-best-practices" }, { - "depth": 2, - "title": "Key Takeaways", - "anchor": "key-takeaways" + "depth": 3, + "title": "1. Test Worst-Case Scenarios", + "anchor": "1-test-worst-case-scenarios" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 11766, - "words": 1369, - "headings": 13, - "estimated_token_count_total": 2514 - }, - "hash": "sha256:dd784a5d2daebb9a885fe09f6a967e6c84958d96ddb38d8366eabe9d860fa539", - "token_estimator": "heuristic-v1" - }, - { - "id": "parachains-customize-runtime-pallet-development-pallet-testing", - "title": "Pallet Testing", - "slug": "parachains-customize-runtime-pallet-development-pallet-testing", - "categories": [ - "Parachains" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-pallet-testing.md", - "html_url": "https://docs.polkadot.com/parachains/customize-runtime/pallet-development/pallet-testing/", - "preview": "Unit testing in the Polkadot SDK helps ensure that the functions provided by a pallet behave as expected. It also confirms that data and events associated with a pallet are processed correctly during interactions. The Polkadot SDK offers a set of APIs to create a test environment to simulate runtime and mock transaction execution for extrinsics and queries.", - "outline": [ + "depth": 3, + "title": "2. Use Linear Components for Variable Complexity", + "anchor": "2-use-linear-components-for-variable-complexity" + }, { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "depth": 3, + "title": "3. Verify Results", + "anchor": "3-verify-results" + }, + { + "depth": 3, + "title": "4. Minimize Setup Code", + "anchor": "4-minimize-setup-code" }, { "depth": 2, - "title": "Writing Unit Tests", - "anchor": "writing-unit-tests" + "title": "Run Your Chain Locally", + "anchor": "run-your-chain-locally" }, { "depth": 3, - "title": "Test Initialization", - "anchor": "test-initialization" + "title": "Build the Production Runtime", + "anchor": "build-the-production-runtime" }, { "depth": 3, - "title": "Function Call Testing", - "anchor": "function-call-testing" + "title": "Generate a Chain Specification", + "anchor": "generate-a-chain-specification" }, { "depth": 3, - "title": "Storage Testing", - "anchor": "storage-testing" + "title": "Start the Parachain Node", + "anchor": "start-the-parachain-node" }, { "depth": 3, - "title": "Event Testing", - "anchor": "event-testing" + "title": "Verify Block Production", + "anchor": "verify-block-production" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Related Resources", + "anchor": "related-resources" } ], "stats": { - "chars": 6892, - "words": 911, - "headings": 7, - "estimated_token_count_total": 1563 + "chars": 31318, + "words": 3912, + "headings": 38, + "estimated_token_count_total": 6933 }, - "hash": "sha256:8568dfa238b9a649a4e6e60510625c2e7879b76a93187b0b8b8dccf6bc467ae6", - "last_modified": "2025-10-28T14:42:14+00:00", + "hash": "sha256:14b1f18a3ed81ff2fa96ae45661122502d3edcda704796ed08a77604ca1f4993", "token_estimator": "heuristic-v1" }, { - "id": "parachains-get-started", - "title": "Get Started with Parachain Development", - "slug": "parachains-get-started", + "id": "parachains-customize-runtime-pallet-development-create-a-pallet", + "title": "Create a Custom Pallet", + "slug": "parachains-customize-runtime-pallet-development-create-a-pallet", "categories": [ - "Basics", "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-get-started.md", - "html_url": "https://docs.polkadot.com/parachains/get-started/", - "preview": "The following sections provide practical recipes for building parachains on Polkadot—each focused on specific development scenarios with step-by-step, hands-on examples.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-create-a-pallet.md", + "html_url": "https://docs.polkadot.com/parachains/customize-runtime/pallet-development/create-a-pallet/", + "preview": "[Framework for Runtime Aggregation of Modular Entities (FRAME)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\\_blank} provides a powerful set of tools for blockchain development through modular components called [pallets](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/pallet/index.html){target=\\_blank}. These Rust-based runtime modules allow you to build custom blockchain functional", "outline": [ { "depth": 2, - "title": "Quick Start Guides", - "anchor": "quick-start-guides" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Launch a Simple Parachain", - "anchor": "launch-a-simple-parachain" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Customize Your Runtime", - "anchor": "customize-your-runtime" - }, - { - "depth": 3, - "title": "Pallet Development", - "anchor": "pallet-development" + "title": "Core Pallet Components", + "anchor": "core-pallet-components" }, { "depth": 2, - "title": "Testing", - "anchor": "testing" + "title": "Create the Pallet Project", + "anchor": "create-the-pallet-project" }, { "depth": 2, - "title": "Runtime Upgrades and Maintenance", - "anchor": "runtime-upgrades-and-maintenance" + "title": "Configure Dependencies", + "anchor": "configure-dependencies" }, { "depth": 2, - "title": "Interoperability", - "anchor": "interoperability" + "title": "Initialize the Pallet Structure", + "anchor": "initialize-the-pallet-structure" }, { "depth": 2, - "title": "Integrations", - "anchor": "integrations" + "title": "Configure the Pallet", + "anchor": "configure-the-pallet" }, { "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 7941, - "words": 631, - "headings": 9, - "estimated_token_count_total": 2292 - }, - "hash": "sha256:759ed27cf3d473445e33141089b652082c42a2c59eb822d6b506146fd9555e13", - "last_modified": "2025-10-28T14:42:14+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "parachains-install-polkadot-sdk", - "title": "Install Polkadot SDK Dependencies", - "slug": "parachains-install-polkadot-sdk", - "categories": [ - "Basics", - "Tooling" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-install-polkadot-sdk.md", - "html_url": "https://docs.polkadot.com/parachains/install-polkadot-sdk/", - "preview": "This guide provides step-by-step instructions for installing the dependencies you need to work with the Polkadot SDK-based chains on macOS, Linux, and Windows. Follow the appropriate section for your operating system to ensure all necessary tools are installed and configured properly.", - "outline": [ + "title": "Define Events", + "anchor": "define-events" + }, { "depth": 2, - "title": "macOS", - "anchor": "macos" + "title": "Define Errors", + "anchor": "define-errors" }, { - "depth": 3, - "title": "Before You Begin", - "anchor": "before-you-begin" + "depth": 2, + "title": "Add Storage Items", + "anchor": "add-storage-items" }, { - "depth": 3, - "title": "Install Required Packages and Rust", - "anchor": "install-required-packages-and-rust" + "depth": 2, + "title": "Configure Genesis State", + "anchor": "configure-genesis-state" }, { "depth": 2, - "title": "Linux", - "anchor": "linux" + "title": "Implement Dispatchable Functions", + "anchor": "implement-dispatchable-functions" }, { "depth": 3, - "title": "Before You Begin {: #before-you-begin-linux }", - "anchor": "before-you-begin-before-you-begin-linux" + "title": "Dispatchable Function Details", + "anchor": "dispatchable-function-details" }, { - "depth": 3, - "title": "Install Required Packages and Rust {: #install-required-packages-and-rust-linux }", - "anchor": "install-required-packages-and-rust-install-required-packages-and-rust-linux" + "depth": 2, + "title": "Verify Pallet Compilation", + "anchor": "verify-pallet-compilation" }, { "depth": 2, - "title": "Windows (WSL)", - "anchor": "windows-wsl" + "title": "Add the Pallet to Your Runtime", + "anchor": "add-the-pallet-to-your-runtime" }, { "depth": 3, - "title": "Before You Begin {: #before-you-begin-windows }", - "anchor": "before-you-begin-before-you-begin-windows" + "title": "Add Runtime Dependency", + "anchor": "add-runtime-dependency" }, { "depth": 3, - "title": "Set Up Windows Subsystem for Linux", - "anchor": "set-up-windows-subsystem-for-linux" + "title": "Implement the Config Trait", + "anchor": "implement-the-config-trait" }, { "depth": 3, - "title": "Install Required Packages and Rust {: #install-required-packages-and-rust-windows }", - "anchor": "install-required-packages-and-rust-install-required-packages-and-rust-windows" - }, - { - "depth": 2, - "title": "Verifying Installation", - "anchor": "verifying-installation" + "title": "Add to Runtime Construct", + "anchor": "add-to-runtime-construct" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 12756, - "words": 1840, - "headings": 12, - "estimated_token_count_total": 2709 - }, - "hash": "sha256:2ee5656f749b4bca445172f2bc66c7fc39af40ff173626662ae4c399f49cf909", - "last_modified": "2025-10-28T14:42:14+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "parachains-integrations-indexers", - "title": "Indexers", - "slug": "parachains-integrations-indexers", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-indexers.md", - "html_url": "https://docs.polkadot.com/parachains/integrations/indexers/", - "preview": "Blockchain data is inherently sequential and distributed, with information stored chronologically across numerous blocks. While retrieving data from a single block through JSON-RPC API calls is straightforward, more complex queries that span multiple blocks present significant challenges:", - "outline": [ - { - "depth": 2, - "title": "The Challenge of Blockchain Data Access", - "anchor": "the-challenge-of-blockchain-data-access" + "depth": 3, + "title": "Configure Genesis for Your Runtime", + "anchor": "configure-genesis-for-your-runtime" }, { - "depth": 2, - "title": "What is a Blockchain Indexer?", - "anchor": "what-is-a-blockchain-indexer" + "depth": 3, + "title": "Verify Runtime Compilation", + "anchor": "verify-runtime-compilation" }, { "depth": 2, - "title": "Indexer Implementations", - "anchor": "indexer-implementations" - } - ], - "stats": { - "chars": 2230, - "words": 302, - "headings": 3, - "estimated_token_count_total": 428 - }, - "hash": "sha256:cfcc76bb24779c9b613f2c046b6f99a0f2529c25fd82287d804f6b945b936227", - "last_modified": "2025-10-28T14:42:14+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "parachains-integrations-oracles", - "title": "Oracles", - "slug": "parachains-integrations-oracles", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-oracles.md", - "html_url": "https://docs.polkadot.com/parachains/integrations/oracles/", - "preview": "Oracles enable blockchains to access external data sources. Since blockchains operate as isolated networks, they cannot natively interact with external systems - this limitation is known as the \"blockchain oracle problem.\" Oracles solves this by extracting data from external sources (like APIs, IoT devices, or other blockchains), validating it, and submitting it on-chain.", - "outline": [ + "title": "Run Your Chain Locally", + "anchor": "run-your-chain-locally" + }, { - "depth": 2, - "title": "What is a Blockchain Oracle?", - "anchor": "what-is-a-blockchain-oracle" + "depth": 3, + "title": "Generate a Chain Specification", + "anchor": "generate-a-chain-specification" }, { - "depth": 2, - "title": "Oracle Implementations", - "anchor": "oracle-implementations" - } - ], - "stats": { - "chars": 1343, - "words": 181, - "headings": 2, - "estimated_token_count_total": 245 - }, - "hash": "sha256:6d8e01281a5895fd2bc4438b24c170c72a496de0b838626a53e87685aea4aa25", - "last_modified": "2025-10-28T14:42:14+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "parachains-integrations-wallets", - "title": "Wallets", - "slug": "parachains-integrations-wallets", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-wallets.md", - "html_url": "https://docs.polkadot.com/parachains/integrations/wallets/", - "preview": "A wallet serves as your gateway to interacting with blockchain networks. Rather than storing funds, wallets secure your private keys, controlling access to your blockchain assets. Your private key provides complete control over all permitted transactions on your blockchain account, making it essential to keep it secure.", - "outline": [ + "depth": 3, + "title": "Start the Parachain Node", + "anchor": "start-the-parachain-node" + }, { "depth": 2, - "title": "What is a Blockchain Wallet?", - "anchor": "what-is-a-blockchain-wallet" + "title": "Interact with Your Pallet", + "anchor": "interact-with-your-pallet" }, { "depth": 2, - "title": "Hot Wallets", - "anchor": "hot-wallets" + "title": "Key Takeaways", + "anchor": "key-takeaways" }, { "depth": 2, - "title": "Cold Wallets", - "anchor": "cold-wallets" + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 2921, - "words": 401, - "headings": 3, - "estimated_token_count_total": 633 + "chars": 26958, + "words": 3085, + "headings": 26, + "estimated_token_count_total": 6194 }, - "hash": "sha256:62c5ad101282227f79eac0e30a3ba9ce3ae1bf9e358bd58c0b17ef45db29c2ff", - "last_modified": "2025-10-28T14:42:14+00:00", + "hash": "sha256:dad68ea59fd05fd60dc8890c4cf5615243c7ea879830b0dcf3a5e5e53c3ccec7", "token_estimator": "heuristic-v1" }, { - "id": "parachains-interoperability-channels-between-parachains", - "title": "Opening HRMP Channels Between Parachains", - "slug": "parachains-interoperability-channels-between-parachains", + "id": "parachains-customize-runtime-pallet-development-mock-runtime", + "title": "Mock Your Runtime", + "slug": "parachains-customize-runtime-pallet-development-mock-runtime", "categories": [ "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-interoperability-channels-between-parachains.md", - "html_url": "https://docs.polkadot.com/parachains/interoperability/channels-between-parachains/", - "preview": "For establishing communication channels between parachains on the Polkadot network using the Horizontal Relay-routed Message Passing (HRMP) protocol, the following steps are required:", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-mock-runtime.md", + "html_url": "https://docs.polkadot.com/parachains/customize-runtime/pallet-development/mock-runtime/", + "preview": "Testing is a critical part of pallet development. Before integrating your pallet into a full runtime, you need a way to test its functionality in isolation. A mock runtime provides a minimal, simulated blockchain environment where you can verify your pallet's logic without the overhead of running a full node.", "outline": [ { "depth": 2, @@ -7655,65 +5260,79 @@ }, { "depth": 2, - "title": "Procedure to Initiate an HRMP Channel", - "anchor": "procedure-to-initiate-an-hrmp-channel" + "title": "Understand Mock Runtimes", + "anchor": "understand-mock-runtimes" }, { - "depth": 3, - "title": "Fund Sender Sovereign Account", - "anchor": "fund-sender-sovereign-account" + "depth": 2, + "title": "Create the Mock Runtime Module", + "anchor": "create-the-mock-runtime-module" }, { - "depth": 3, - "title": "Create Channel Opening Extrinsic", - "anchor": "create-channel-opening-extrinsic" + "depth": 2, + "title": "Set Up Basic Mock", + "anchor": "set-up-basic-mock" }, { - "depth": 3, - "title": "Craft and Submit the XCM Message from the Sender", - "anchor": "craft-and-submit-the-xcm-message-from-the-sender" + "depth": 2, + "title": "Implement Essential Configuration", + "anchor": "implement-essential-configuration" }, { "depth": 2, - "title": "Procedure to Accept an HRMP Channel", - "anchor": "procedure-to-accept-an-hrmp-channel" + "title": "Implement Your Pallet's Configuration", + "anchor": "implement-your-pallets-configuration" }, { - "depth": 3, - "title": "Fund Receiver Sovereign Account", - "anchor": "fund-receiver-sovereign-account" + "depth": 2, + "title": "Configure Genesis Storage", + "anchor": "configure-genesis-storage" }, { "depth": 3, - "title": "Create Channel Accepting Extrinsic", - "anchor": "create-channel-accepting-extrinsic" + "title": "Basic Test Environment", + "anchor": "basic-test-environment" }, { "depth": 3, - "title": "Craft and Submit the XCM Message from the Receiver", - "anchor": "craft-and-submit-the-xcm-message-from-the-receiver" + "title": "Custom Genesis Configurations", + "anchor": "custom-genesis-configurations" + }, + { + "depth": 2, + "title": "Verify Mock Compilation", + "anchor": "verify-mock-compilation" + }, + { + "depth": 2, + "title": "Key Takeaways", + "anchor": "key-takeaways" + }, + { + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 10934, - "words": 1549, - "headings": 10, - "estimated_token_count_total": 2285 + "chars": 11766, + "words": 1369, + "headings": 13, + "estimated_token_count_total": 2514 }, - "hash": "sha256:b8de1228b9976765accd18ff724038bed6f2449367f500bc3177ab2a053abe63", - "last_modified": "2025-10-28T14:42:14+00:00", + "hash": "sha256:dd784a5d2daebb9a885fe09f6a967e6c84958d96ddb38d8366eabe9d860fa539", "token_estimator": "heuristic-v1" }, { - "id": "parachains-interoperability-channels-with-system-parachains", - "title": "Opening HRMP Channels with System Parachains", - "slug": "parachains-interoperability-channels-with-system-parachains", + "id": "parachains-customize-runtime-pallet-development-pallet-testing", + "title": "Pallet Testing", + "slug": "parachains-customize-runtime-pallet-development-pallet-testing", "categories": [ "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-interoperability-channels-with-system-parachains.md", - "html_url": "https://docs.polkadot.com/parachains/interoperability/channels-with-system-parachains/", - "preview": "While establishing Horizontal Relay-routed Message Passing (HRMP) channels between regular parachains involves a two-step request and acceptance procedure, opening channels with system parachains follows a more straightforward approach.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-pallet-testing.md", + "html_url": "https://docs.polkadot.com/parachains/customize-runtime/pallet-development/pallet-testing/", + "preview": "Unit testing in the Polkadot SDK helps ensure that the functions provided by a pallet behave as expected. It also confirms that data and events associated with a pallet are processed correctly during interactions. The Polkadot SDK offers a set of APIs to create a test environment to simulate runtime and mock transaction execution for extrinsics and queries.", "outline": [ { "depth": 2, @@ -7722,51 +5341,55 @@ }, { "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" + "title": "Writing Unit Tests", + "anchor": "writing-unit-tests" }, { - "depth": 2, - "title": "Procedure to Establish an HRMP Channel", - "anchor": "procedure-to-establish-an-hrmp-channel" + "depth": 3, + "title": "Test Initialization", + "anchor": "test-initialization" }, { "depth": 3, - "title": "Fund Parachain Sovereign Account", - "anchor": "fund-parachain-sovereign-account" + "title": "Function Call Testing", + "anchor": "function-call-testing" }, { "depth": 3, - "title": "Create Establish Channel with System Extrinsic", - "anchor": "create-establish-channel-with-system-extrinsic" + "title": "Storage Testing", + "anchor": "storage-testing" }, { "depth": 3, - "title": "Craft and Submit the XCM Message", - "anchor": "craft-and-submit-the-xcm-message" + "title": "Event Testing", + "anchor": "event-testing" + }, + { + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 7203, - "words": 889, - "headings": 6, - "estimated_token_count_total": 1427 + "chars": 6892, + "words": 911, + "headings": 7, + "estimated_token_count_total": 1563 }, - "hash": "sha256:b501d99c464fb049d46676827b6a325a195c90617becc4a7db305441c115350a", - "last_modified": "2025-10-28T14:42:14+00:00", + "hash": "sha256:8568dfa238b9a649a4e6e60510625c2e7879b76a93187b0b8b8dccf6bc467ae6", "token_estimator": "heuristic-v1" }, { - "id": "parachains-interoperability-get-started", - "title": "Introduction to XCM", - "slug": "parachains-interoperability-get-started", + "id": "parachains-customize-runtime", + "title": "Overview of FRAME", + "slug": "parachains-customize-runtime", "categories": [ "Basics", - "Polkadot Protocol" + "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-interoperability-get-started.md", - "html_url": "https://docs.polkadot.com/parachains/interoperability/get-started/", - "preview": "Polkadot’s unique value lies in its ability to enable interoperability between parachains and other blockchain systems. At the core of this capability is XCM (Cross-Consensus Messaging)—a flexible messaging format that facilitates communication and collaboration between independent consensus systems.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime.md", + "html_url": "https://docs.polkadot.com/parachains/customize-runtime/", + "preview": "A blockchain runtime is more than just a fixed set of rules—it's a dynamic foundation that you can shape to match your specific needs. With Polkadot SDK's [FRAME (Framework for Runtime Aggregation of Modularized Entities)](/reference/glossary/#frame-framework-for-runtime-aggregation-of-modularized-entities){target=\\_blank}, customizing your runtime is straightforward and modular. Instead of building everything from scratch, you combine pre-built pallets with your own custom logic to create a run", "outline": [ { "depth": 2, @@ -7775,304 +5398,319 @@ }, { "depth": 2, - "title": "Messaging Format", - "anchor": "messaging-format" + "title": "Understanding Your Runtime", + "anchor": "understanding-your-runtime" }, { "depth": 2, - "title": "The Four Principles of XCM", - "anchor": "the-four-principles-of-xcm" + "title": "Runtime Architecture", + "anchor": "runtime-architecture" }, { "depth": 2, - "title": "The XCM Tech Stack", - "anchor": "the-xcm-tech-stack" + "title": "Building Blocks: Pallets", + "anchor": "building-blocks-pallets" + }, + { + "depth": 3, + "title": "Pre-Built Pallets vs. Custom Pallets", + "anchor": "pre-built-pallets-vs-custom-pallets" + }, + { + "depth": 3, + "title": "Pallet Structure", + "anchor": "pallet-structure" }, { "depth": 2, - "title": "Core Functionalities of XCM", - "anchor": "core-functionalities-of-xcm" + "title": "How Runtime Customization Works", + "anchor": "how-runtime-customization-works" }, { "depth": 2, - "title": "XCM Example", - "anchor": "xcm-example" + "title": "Starting Templates", + "anchor": "starting-templates" }, { "depth": 2, - "title": "Overview", - "anchor": "overview" + "title": "Key Customization Scenarios", + "anchor": "key-customization-scenarios" } ], "stats": { - "chars": 7450, - "words": 974, - "headings": 7, - "estimated_token_count_total": 1501 - }, - "hash": "sha256:3b26606dd5310c4b8ade5d05270ebf1e06f59afcda4ca2b985e07948215a197e", - "last_modified": "2025-10-28T14:42:14+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "parachains-launch-a-parachain-choose-a-template", - "title": "parachains-launch-a-parachain-choose-a-template", - "slug": "parachains-launch-a-parachain-choose-a-template", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-choose-a-template.md", - "html_url": "https://docs.polkadot.com/parachains/launch-a-parachain/choose-a-template/", - "preview": "TODO", - "outline": [], - "stats": { - "chars": 5, - "words": 1, - "headings": 0, - "estimated_token_count_total": 0 + "chars": 8236, + "words": 1101, + "headings": 9, + "estimated_token_count_total": 1828 }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:15:59+00:00", + "hash": "sha256:ad58d1c942b567acc4519abc35c0a049ab3e04711c2a49089ceba6324a5aa7ea", "token_estimator": "heuristic-v1" }, { - "id": "parachains-launch-a-parachain-deploy-to-polkadot", - "title": "Deploy on Polkadot", - "slug": "parachains-launch-a-parachain-deploy-to-polkadot", + "id": "parachains-get-started", + "title": "Get Started with Parachain Development", + "slug": "parachains-get-started", "categories": [ + "Basics", "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-deploy-to-polkadot.md", - "html_url": "https://docs.polkadot.com/parachains/launch-a-parachain/deploy-to-polkadot/", - "preview": "Previously, you learned how to [choose and set up a parachain template](/parachains/launch-a-parachain/choose-a-template/){target=\\_blank}. Now, you'll take the next step towards a production-like environment by deploying your parachain to the Polkadot TestNet. Deploying to a TestNet is a crucial step for validating your parachain's functionality and preparing it for eventual MainNet deployment.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-get-started.md", + "html_url": "https://docs.polkadot.com/parachains/get-started/", + "preview": "The following sections provide practical recipes for building parachains on Polkadot—each focused on specific development scenarios with step-by-step, hands-on examples.", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Quick Start Guides", + "anchor": "quick-start-guides" }, { "depth": 2, - "title": "Get Started with an Account and Tokens", - "anchor": "get-started-with-an-account-and-tokens" + "title": "Launch a Simple Parachain", + "anchor": "launch-a-simple-parachain" }, { "depth": 2, - "title": "Reserve a Parachain Identifier", - "anchor": "reserve-a-parachain-identifier" + "title": "Customize Your Runtime", + "anchor": "customize-your-runtime" }, { - "depth": 2, - "title": "Generate Custom Keys for Your Collators", - "anchor": "generate-custom-keys-for-your-collators" + "depth": 3, + "title": "Pallet Development", + "anchor": "pallet-development" }, { "depth": 2, - "title": "Generate the Chain Specification", - "anchor": "generate-the-chain-specification" + "title": "Testing", + "anchor": "testing" }, { "depth": 2, - "title": "Export Required Files", - "anchor": "export-required-files" + "title": "Runtime Upgrades and Maintenance", + "anchor": "runtime-upgrades-and-maintenance" }, { "depth": 2, - "title": "Register a Parathread", - "anchor": "register-a-parathread" + "title": "Interoperability", + "anchor": "interoperability" }, { "depth": 2, - "title": "Start the Collator Node", - "anchor": "start-the-collator-node" + "title": "Integrations", + "anchor": "integrations" }, { "depth": 2, - "title": "Producing Blocks", - "anchor": "producing-blocks" + "title": "Additional Resources", + "anchor": "additional-resources" } ], "stats": { - "chars": 14404, - "words": 2116, + "chars": 7941, + "words": 631, "headings": 9, - "estimated_token_count_total": 3296 + "estimated_token_count_total": 2292 }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:14+00:00", + "hash": "sha256:759ed27cf3d473445e33141089b652082c42a2c59eb822d6b506146fd9555e13", "token_estimator": "heuristic-v1" }, { - "id": "parachains-launch-a-parachain-obtain-coretime", - "title": "Obtain Coretime", - "slug": "parachains-launch-a-parachain-obtain-coretime", + "id": "parachains-install-polkadot-sdk", + "title": "Install Polkadot SDK Dependencies", + "slug": "parachains-install-polkadot-sdk", "categories": [ - "Parachains" + "Basics", + "Tooling" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-obtain-coretime.md", - "html_url": "https://docs.polkadot.com/parachains/launch-a-parachain/obtain-coretime/", - "preview": "After deploying a parachain to Paseo in the [Deploy on Polkadot](/parachains/launch-a-parachain/deploy-to-polkadot/){target=\\_blank} tutorial, the next critical step is obtaining coretime. Coretime is the mechanism through which validation resources are allocated from the relay chain to your parachain. Your parachain can only produce and finalize blocks on the relay chain by obtaining coretime.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-install-polkadot-sdk.md", + "html_url": "https://docs.polkadot.com/parachains/install-polkadot-sdk/", + "preview": "This guide provides step-by-step instructions for installing the dependencies you need to work with the Polkadot SDK-based chains on macOS, Linux, and Windows. Follow the appropriate section for your operating system to ensure all necessary tools are installed and configured properly.", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "macOS", + "anchor": "macos" }, { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" + "depth": 3, + "title": "Before You Begin", + "anchor": "before-you-begin" + }, + { + "depth": 3, + "title": "Install Required Packages and Rust", + "anchor": "install-required-packages-and-rust" }, { "depth": 2, - "title": "Order On-Demand Coretime", - "anchor": "order-on-demand-coretime" + "title": "Linux", + "anchor": "linux" }, { "depth": 3, - "title": "On-Demand Extrinsics", - "anchor": "on-demand-extrinsics" + "title": "Before You Begin {: #before-you-begin-linux }", + "anchor": "before-you-begin-before-you-begin-linux" }, { "depth": 3, - "title": "Place an On-Demand Order", - "anchor": "place-an-on-demand-order" + "title": "Install Required Packages and Rust {: #install-required-packages-and-rust-linux }", + "anchor": "install-required-packages-and-rust-install-required-packages-and-rust-linux" }, { "depth": 2, - "title": "Purchase Bulk Coretime", - "anchor": "purchase-bulk-coretime" - }, - { - "depth": 3, - "title": "Connect Your Wallet to RegionX", - "anchor": "connect-your-wallet-to-regionx" + "title": "Windows (WSL)", + "anchor": "windows-wsl" }, { "depth": 3, - "title": "Obtain Coretime Chain Funds", - "anchor": "obtain-coretime-chain-funds" + "title": "Before You Begin {: #before-you-begin-windows }", + "anchor": "before-you-begin-before-you-begin-windows" }, { "depth": 3, - "title": "Purchase a Core", - "anchor": "purchase-a-core" + "title": "Set Up Windows Subsystem for Linux", + "anchor": "set-up-windows-subsystem-for-linux" }, { "depth": 3, - "title": "Verify Your Purchase", - "anchor": "verify-your-purchase" + "title": "Install Required Packages and Rust {: #install-required-packages-and-rust-windows }", + "anchor": "install-required-packages-and-rust-install-required-packages-and-rust-windows" }, { - "depth": 3, - "title": "Assign Your Parachain to the Core", - "anchor": "assign-your-parachain-to-the-core" + "depth": 2, + "title": "Verifying Installation", + "anchor": "verifying-installation" }, { "depth": 2, - "title": "Next Steps", - "anchor": "next-steps" + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 9049, - "words": 1345, + "chars": 12756, + "words": 1840, "headings": 12, - "estimated_token_count_total": 2103 + "estimated_token_count_total": 2709 }, - "hash": "sha256:15154f211753665d9af70dc81d15ceb3f0954e3febf9282c68c0074881d620c6", - "last_modified": "2025-10-28T14:42:14+00:00", + "hash": "sha256:2ee5656f749b4bca445172f2bc66c7fc39af40ff173626662ae4c399f49cf909", "token_estimator": "heuristic-v1" }, { - "id": "parachains-launch-a-parachain-set-up-the-parachain-template", - "title": "Set Up the Polkadot SDK Parachain Template", - "slug": "parachains-launch-a-parachain-set-up-the-parachain-template", + "id": "parachains-integrations-indexers", + "title": "Indexers", + "slug": "parachains-integrations-indexers", "categories": [ - "Basics", - "Parachains" + "Tooling", + "Dapps" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-set-up-the-parachain-template.md", - "html_url": "https://docs.polkadot.com/parachains/launch-a-parachain/set-up-the-parachain-template/", - "preview": "The [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\\_blank} includes several [templates](/parachains/customize-runtime/#starting-templates){target=\\_blank} designed to help you quickly start building your own blockchain. Each template offers a different level of configuration, from minimal setups to feature-rich environments, allowing you to choose the foundation that best fits your project's needs.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-indexers.md", + "html_url": "https://docs.polkadot.com/parachains/integrations/indexers/", + "preview": "Blockchain data is inherently sequential and distributed, with information stored chronologically across numerous blocks. While retrieving data from a single block through JSON-RPC API calls is straightforward, more complex queries that span multiple blocks present significant challenges:", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Polkadot SDK Utility Tools", - "anchor": "polkadot-sdk-utility-tools" - }, - { - "depth": 2, - "title": "Clone the Template", - "anchor": "clone-the-template" + "title": "The Challenge of Blockchain Data Access", + "anchor": "the-challenge-of-blockchain-data-access" }, { "depth": 2, - "title": "Explore the Project Structure", - "anchor": "explore-the-project-structure" + "title": "What is a Blockchain Indexer?", + "anchor": "what-is-a-blockchain-indexer" }, { "depth": 2, - "title": "Compile the Runtime", - "anchor": "compile-the-runtime" - }, + "title": "Indexer Implementations", + "anchor": "indexer-implementations" + } + ], + "stats": { + "chars": 2230, + "words": 302, + "headings": 3, + "estimated_token_count_total": 428 + }, + "hash": "sha256:cfcc76bb24779c9b613f2c046b6f99a0f2529c25fd82287d804f6b945b936227", + "token_estimator": "heuristic-v1" + }, + { + "id": "parachains-integrations-oracles", + "title": "Oracles", + "slug": "parachains-integrations-oracles", + "categories": [ + "Tooling", + "Dapps" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-oracles.md", + "html_url": "https://docs.polkadot.com/parachains/integrations/oracles/", + "preview": "Oracles enable blockchains to access external data sources. Since blockchains operate as isolated networks, they cannot natively interact with external systems - this limitation is known as the \"blockchain oracle problem.\" Oracles solves this by extracting data from external sources (like APIs, IoT devices, or other blockchains), validating it, and submitting it on-chain.", + "outline": [ { "depth": 2, - "title": "Verify the Build", - "anchor": "verify-the-build" + "title": "What is a Blockchain Oracle?", + "anchor": "what-is-a-blockchain-oracle" }, { "depth": 2, - "title": "Run the Node Locally", - "anchor": "run-the-node-locally" - }, + "title": "Oracle Implementations", + "anchor": "oracle-implementations" + } + ], + "stats": { + "chars": 1343, + "words": 181, + "headings": 2, + "estimated_token_count_total": 245 + }, + "hash": "sha256:6d8e01281a5895fd2bc4438b24c170c72a496de0b838626a53e87685aea4aa25", + "token_estimator": "heuristic-v1" + }, + { + "id": "parachains-integrations-wallets", + "title": "Wallets", + "slug": "parachains-integrations-wallets", + "categories": [ + "Tooling", + "Dapps" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-integrations-wallets.md", + "html_url": "https://docs.polkadot.com/parachains/integrations/wallets/", + "preview": "A wallet serves as your gateway to interacting with blockchain networks. Rather than storing funds, wallets secure your private keys, controlling access to your blockchain assets. Your private key provides complete control over all permitted transactions on your blockchain account, making it essential to keep it secure.", + "outline": [ { "depth": 2, - "title": "Interact with the Node", - "anchor": "interact-with-the-node" + "title": "What is a Blockchain Wallet?", + "anchor": "what-is-a-blockchain-wallet" }, { "depth": 2, - "title": "Stop the Node", - "anchor": "stop-the-node" + "title": "Hot Wallets", + "anchor": "hot-wallets" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "depth": 2, + "title": "Cold Wallets", + "anchor": "cold-wallets" } ], "stats": { - "chars": 10608, - "words": 1512, - "headings": 11, - "estimated_token_count_total": 2379 + "chars": 2921, + "words": 401, + "headings": 3, + "estimated_token_count_total": 633 }, - "hash": "sha256:637b9460bb65621cbc7c1bff272ea287d5181a983bc61418167959e108e21791", - "last_modified": "2025-10-28T14:42:14+00:00", + "hash": "sha256:62c5ad101282227f79eac0e30a3ba9ce3ae1bf9e358bd58c0b17ef45db29c2ff", "token_estimator": "heuristic-v1" }, { - "id": "parachains-overview", - "title": "Parachains Overview", - "slug": "parachains-overview", + "id": "parachains-interoperability-channels-between-parachains", + "title": "Opening HRMP Channels Between Parachains", + "slug": "parachains-interoperability-channels-between-parachains", "categories": [ - "Basics", "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-overview.md", - "html_url": "https://docs.polkadot.com/parachains/overview/", - "preview": "A parachain is a specialized blockchain that connects to the Polkadot relay chain, benefiting from shared security, interoperability, and scalability. Parachains are built using the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\\_blank}, a powerful toolkit written in Rust that provides everything needed to create custom blockchain logic while integrating seamlessly with the Polkadot network.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-interoperability-channels-between-parachains.md", + "html_url": "https://docs.polkadot.com/parachains/interoperability/channels-between-parachains/", + "preview": "For establishing communication channels between parachains on the Polkadot network using the Horizontal Relay-routed Message Passing (HRMP) protocol, the following steps are required:", "outline": [ { "depth": 2, @@ -8081,97 +5719,69 @@ }, { "depth": 2, - "title": "Polkadot SDK: Parachain Architecture", - "anchor": "polkadot-sdk-parachain-architecture" + "title": "Prerequisites", + "anchor": "prerequisites" }, { - "depth": 3, - "title": "Substrate: The Foundation", - "anchor": "substrate-the-foundation" + "depth": 2, + "title": "Procedure to Initiate an HRMP Channel", + "anchor": "procedure-to-initiate-an-hrmp-channel" }, { "depth": 3, - "title": "FRAME: Building Blocks for Your Runtime", - "anchor": "frame-building-blocks-for-your-runtime" + "title": "Fund Sender Sovereign Account", + "anchor": "fund-sender-sovereign-account" }, { "depth": 3, - "title": "Cumulus: Parachain-Specific Functionality", - "anchor": "cumulus-parachain-specific-functionality" + "title": "Create Channel Opening Extrinsic", + "anchor": "create-channel-opening-extrinsic" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 8461, - "words": 1024, - "headings": 6, - "estimated_token_count_total": 1751 - }, - "hash": "sha256:bbef601f2645c23200a3b16bc1b8e5bcad2aafdee6d60ae860ce8b5a53122c14", - "last_modified": "2025-10-28T14:15:59+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "parachains-runtime-maintenance-runtime-upgrades", - "title": "Runtime Upgrades", - "slug": "parachains-runtime-maintenance-runtime-upgrades", - "categories": [ - "Parachains" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-runtime-maintenance-runtime-upgrades.md", - "html_url": "https://docs.polkadot.com/parachains/runtime-maintenance/runtime-upgrades/", - "preview": "One of the defining features of Polkadot SDK-based blockchains is the ability to perform forkless runtime upgrades. Unlike traditional blockchains, which require hard forks and node coordination for upgrades, Polkadot networks enable seamless updates without network disruption.", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "depth": 3, + "title": "Craft and Submit the XCM Message from the Sender", + "anchor": "craft-and-submit-the-xcm-message-from-the-sender" }, { "depth": 2, - "title": "How Runtime Upgrades Work", - "anchor": "how-runtime-upgrades-work" + "title": "Procedure to Accept an HRMP Channel", + "anchor": "procedure-to-accept-an-hrmp-channel" }, { "depth": 3, - "title": "Runtime Versioning", - "anchor": "runtime-versioning" + "title": "Fund Receiver Sovereign Account", + "anchor": "fund-receiver-sovereign-account" }, { "depth": 3, - "title": "Accessing the Runtime Version", - "anchor": "accessing-the-runtime-version" + "title": "Create Channel Accepting Extrinsic", + "anchor": "create-channel-accepting-extrinsic" }, { - "depth": 2, - "title": "Storage Migrations", - "anchor": "storage-migrations" + "depth": 3, + "title": "Craft and Submit the XCM Message from the Receiver", + "anchor": "craft-and-submit-the-xcm-message-from-the-receiver" } ], "stats": { - "chars": 5837, - "words": 811, - "headings": 5, - "estimated_token_count_total": 1161 + "chars": 10934, + "words": 1549, + "headings": 10, + "estimated_token_count_total": 2285 }, - "hash": "sha256:ec31270001a6cd9d0a8ecb7974ad161d5c1ef4d3023d5a6af9fbc5a6ca46cbca", - "last_modified": "2025-10-28T14:42:14+00:00", + "hash": "sha256:b8de1228b9976765accd18ff724038bed6f2449367f500bc3177ab2a053abe63", "token_estimator": "heuristic-v1" }, { - "id": "parachains-runtime-maintenance-storage-migrations", - "title": "Storage Migrations", - "slug": "parachains-runtime-maintenance-storage-migrations", + "id": "parachains-interoperability-channels-with-system-parachains", + "title": "Opening HRMP Channels with System Parachains", + "slug": "parachains-interoperability-channels-with-system-parachains", "categories": [ "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-runtime-maintenance-storage-migrations.md", - "html_url": "https://docs.polkadot.com/parachains/runtime-maintenance/storage-migrations/", - "preview": "Storage migrations are a crucial part of the runtime upgrade process. They allow you to update the [storage items](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/attr.storage.html){target=\\_blank} of your blockchain, adapting to changes in the runtime. Whenever you change the encoding or data types used to represent data in storage, you'll need to provide a storage migration to ensure the runtime can correctly interpret the existing stored values in the new runtime", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-interoperability-channels-with-system-parachains.md", + "html_url": "https://docs.polkadot.com/parachains/interoperability/channels-with-system-parachains/", + "preview": "While establishing Horizontal Relay-routed Message Passing (HRMP) channels between regular parachains involves a two-step request and acceptance procedure, opening channels with system parachains follows a more straightforward approach.", "outline": [ { "depth": 2, @@ -8180,70 +5790,50 @@ }, { "depth": 2, - "title": "Storage Migration Scenarios", - "anchor": "storage-migration-scenarios" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Implement Storage Migrations", - "anchor": "implement-storage-migrations" - }, - { - "depth": 3, - "title": "Core Migration Function", - "anchor": "core-migration-function" - }, - { - "depth": 3, - "title": "Migration Testing Hooks", - "anchor": "migration-testing-hooks" + "title": "Procedure to Establish an HRMP Channel", + "anchor": "procedure-to-establish-an-hrmp-channel" }, { "depth": 3, - "title": "Migration Structure", - "anchor": "migration-structure" + "title": "Fund Parachain Sovereign Account", + "anchor": "fund-parachain-sovereign-account" }, { "depth": 3, - "title": "Migration Organization", - "anchor": "migration-organization" + "title": "Create Establish Channel with System Extrinsic", + "anchor": "create-establish-channel-with-system-extrinsic" }, { "depth": 3, - "title": "Scheduling Migrations", - "anchor": "scheduling-migrations" - }, - { - "depth": 2, - "title": "Single-Block Migrations", - "anchor": "single-block-migrations" - }, - { - "depth": 2, - "title": "Multi Block Migrations", - "anchor": "multi-block-migrations" + "title": "Craft and Submit the XCM Message", + "anchor": "craft-and-submit-the-xcm-message" } ], "stats": { - "chars": 18500, - "words": 2363, - "headings": 10, - "estimated_token_count_total": 4014 + "chars": 7203, + "words": 889, + "headings": 6, + "estimated_token_count_total": 1427 }, - "hash": "sha256:55dc252fdecf1590048ce8d009b822e90231442abe81e9593cf1635944a31336", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:b501d99c464fb049d46676827b6a325a195c90617becc4a7db305441c115350a", "token_estimator": "heuristic-v1" }, { - "id": "parachains-runtime-maintenance-unlock-parachains", - "title": "Unlock a Parachain", - "slug": "parachains-runtime-maintenance-unlock-parachains", + "id": "parachains-interoperability-get-started", + "title": "Introduction to XCM", + "slug": "parachains-interoperability-get-started", "categories": [ - "Parachains" + "Basics", + "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-runtime-maintenance-unlock-parachains.md", - "html_url": "https://docs.polkadot.com/parachains/runtime-maintenance/unlock-parachains/", - "preview": "Parachain locks are a critical security mechanism in the Polkadot ecosystem designed to maintain decentralization during the parachain lifecycle. These locks prevent potential centralization risks that could emerge during the early stages of parachain operation.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-interoperability-get-started.md", + "html_url": "https://docs.polkadot.com/parachains/interoperability/get-started/", + "preview": "Polkadot’s unique value lies in its ability to enable interoperability between parachains and other blockchain systems. At the core of this capability is XCM (Cross-Consensus Messaging)—a flexible messaging format that facilitates communication and collaboration between independent consensus systems.", "outline": [ { "depth": 2, @@ -8252,51 +5842,54 @@ }, { "depth": 2, - "title": "Check If the Parachain Is Locked", - "anchor": "check-if-the-parachain-is-locked" + "title": "Messaging Format", + "anchor": "messaging-format" }, { "depth": 2, - "title": "How to Unlock a Parachain", - "anchor": "how-to-unlock-a-parachain" + "title": "The Four Principles of XCM", + "anchor": "the-four-principles-of-xcm" }, { - "depth": 3, - "title": "Prepare the Unlock Call", - "anchor": "prepare-the-unlock-call" + "depth": 2, + "title": "The XCM Tech Stack", + "anchor": "the-xcm-tech-stack" }, { - "depth": 3, - "title": "Fund the Sovereign Account", - "anchor": "fund-the-sovereign-account" + "depth": 2, + "title": "Core Functionalities of XCM", + "anchor": "core-functionalities-of-xcm" }, { - "depth": 3, - "title": "Craft and Submit the XCM", - "anchor": "craft-and-submit-the-xcm" + "depth": 2, + "title": "XCM Example", + "anchor": "xcm-example" + }, + { + "depth": 2, + "title": "Overview", + "anchor": "overview" } ], "stats": { - "chars": 9232, - "words": 1276, - "headings": 6, - "estimated_token_count_total": 2028 + "chars": 7450, + "words": 974, + "headings": 7, + "estimated_token_count_total": 1501 }, - "hash": "sha256:e408d05199cc184fc6fe8bb212efb3c9aa6cb79258977e07566692176c912def", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:3b26606dd5310c4b8ade5d05270ebf1e06f59afcda4ca2b985e07948215a197e", "token_estimator": "heuristic-v1" }, { - "id": "parachains-testing-fork-a-parachain", - "title": "Get Started", - "slug": "parachains-testing-fork-a-parachain", + "id": "parachains-launch-a-parachain-deploy-to-polkadot", + "title": "Deploy on Polkadot", + "slug": "parachains-launch-a-parachain-deploy-to-polkadot", "categories": [ - "Parachains", - "Tooling" + "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-fork-a-parachain.md", - "html_url": "https://docs.polkadot.com/parachains/testing/fork-a-parachain/", - "preview": "[Chopsticks](https://github.com/AcalaNetwork/chopsticks/){target=\\_blank}, developed by the [Acala Foundation](https://github.com/AcalaNetwork){target=\\_blank}, is a versatile tool tailored for developers working on Polkadot SDK-based blockchains. With Chopsticks, you can fork live chains locally, replay blocks to analyze extrinsics, and simulate complex scenarios like XCM interactions all without deploying to a live network.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-deploy-to-polkadot.md", + "html_url": "https://docs.polkadot.com/parachains/launch-a-parachain/deploy-to-polkadot/", + "preview": "Previously, you learned how to [choose and set up a parachain template](/parachains/launch-a-parachain/choose-a-template/){target=\\_blank}. Now, you'll take the next step towards a production-like environment by deploying your parachain to the Polkadot TestNet. Deploying to a TestNet is a crucial step for validating your parachain's functionality and preparing it for eventual MainNet deployment.", "outline": [ { "depth": 2, @@ -8305,71 +5898,64 @@ }, { "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" + "title": "Get Started with an Account and Tokens", + "anchor": "get-started-with-an-account-and-tokens" }, { "depth": 2, - "title": "Install Chopsticks", - "anchor": "install-chopsticks" - }, - { - "depth": 3, - "title": "Global Installation", - "anchor": "global-installation" + "title": "Reserve a Parachain Identifier", + "anchor": "reserve-a-parachain-identifier" }, { - "depth": 3, - "title": "Local Installation", - "anchor": "local-installation" + "depth": 2, + "title": "Generate Custom Keys for Your Collators", + "anchor": "generate-custom-keys-for-your-collators" }, { "depth": 2, - "title": "Configure Chopsticks", - "anchor": "configure-chopsticks" + "title": "Generate the Chain Specification", + "anchor": "generate-the-chain-specification" }, { - "depth": 3, - "title": "Configuration File", - "anchor": "configuration-file" + "depth": 2, + "title": "Export Required Files", + "anchor": "export-required-files" }, { - "depth": 3, - "title": "CLI Flags", - "anchor": "cli-flags" + "depth": 2, + "title": "Register a Parathread", + "anchor": "register-a-parathread" }, { "depth": 2, - "title": "WebSocket Commands", - "anchor": "websocket-commands" + "title": "Start the Collator Node", + "anchor": "start-the-collator-node" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Producing Blocks", + "anchor": "producing-blocks" } ], "stats": { - "chars": 10894, - "words": 1330, - "headings": 10, - "estimated_token_count_total": 2614 + "chars": 14404, + "words": 2116, + "headings": 9, + "estimated_token_count_total": 3296 }, - "hash": "sha256:4325cdd697814b8043db808da3dee86d3d9c6fc7dd523aae7fe8914d59d1b39c", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:fde940bced4380fc01b1840907059d03f6d47b6cb54bf78c95269ac57adbc99e", "token_estimator": "heuristic-v1" }, { - "id": "parachains-testing-run-a-parachain-network", - "title": "Get Started", - "slug": "parachains-testing-run-a-parachain-network", + "id": "parachains-launch-a-parachain-obtain-coretime", + "title": "Obtain Coretime", + "slug": "parachains-launch-a-parachain-obtain-coretime", "categories": [ - "Parachains", - "Tooling" + "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-run-a-parachain-network.md", - "html_url": "https://docs.polkadot.com/parachains/testing/run-a-parachain-network/", - "preview": "Zombienet is a robust testing framework designed for Polkadot SDK-based blockchain networks. It enables developers to efficiently deploy and test ephemeral blockchain environments on platforms like Kubernetes, Podman, and native setups. With its simple and versatile CLI, Zombienet provides an all-in-one solution for spawning networks, running tests, and validating performance.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-obtain-coretime.md", + "html_url": "https://docs.polkadot.com/parachains/launch-a-parachain/obtain-coretime/", + "preview": "After deploying a parachain to Paseo in the [Deploy on Polkadot](/parachains/launch-a-parachain/deploy-to-polkadot/){target=\\_blank} tutorial, the next critical step is obtaining coretime. Coretime is the mechanism through which validation resources are allocated from the relay chain to your parachain. Your parachain can only produce and finalize blocks on the relay chain by obtaining coretime.", "outline": [ { "depth": 2, @@ -8378,91 +5964,80 @@ }, { "depth": 2, - "title": "Install Zombienet", - "anchor": "install-zombienet" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Providers", - "anchor": "providers" - }, - { - "depth": 3, - "title": "Kubernetes", - "anchor": "kubernetes" + "title": "Order On-Demand Coretime", + "anchor": "order-on-demand-coretime" }, { "depth": 3, - "title": "Podman", - "anchor": "podman" + "title": "On-Demand Extrinsics", + "anchor": "on-demand-extrinsics" }, { "depth": 3, - "title": "Local Provider", - "anchor": "local-provider" + "title": "Place an On-Demand Order", + "anchor": "place-an-on-demand-order" }, { "depth": 2, - "title": "Configure Zombienet", - "anchor": "configure-zombienet" - }, - { - "depth": 3, - "title": "Configuration Files", - "anchor": "configuration-files" + "title": "Purchase Bulk Coretime", + "anchor": "purchase-bulk-coretime" }, { "depth": 3, - "title": "CLI Usage", - "anchor": "cli-usage" + "title": "Connect Your Wallet to RegionX", + "anchor": "connect-your-wallet-to-regionx" }, { "depth": 3, - "title": "Settings", - "anchor": "settings" + "title": "Obtain Coretime Chain Funds", + "anchor": "obtain-coretime-chain-funds" }, { "depth": 3, - "title": "Relay Chain Configuration", - "anchor": "relay-chain-configuration" + "title": "Purchase a Core", + "anchor": "purchase-a-core" }, { "depth": 3, - "title": "Parachain Configuration", - "anchor": "parachain-configuration" + "title": "Verify Your Purchase", + "anchor": "verify-your-purchase" }, { "depth": 3, - "title": "XCM Configuration", - "anchor": "xcm-configuration" + "title": "Assign Your Parachain to the Core", + "anchor": "assign-your-parachain-to-the-core" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Next Steps", + "anchor": "next-steps" } ], "stats": { - "chars": 41636, - "words": 4599, - "headings": 14, - "estimated_token_count_total": 9871 + "chars": 9049, + "words": 1345, + "headings": 12, + "estimated_token_count_total": 2103 }, - "hash": "sha256:0d7e04fd952cc9d5bd8cdbfd87cc4004c5f95e896a16bc7f89dfc4caeac8f371", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:15154f211753665d9af70dc81d15ceb3f0954e3febf9282c68c0074881d620c6", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-architecture-parachains-consensus", - "title": "Parachain Consensus", - "slug": "polkadot-protocol-architecture-parachains-consensus", + "id": "parachains-launch-a-parachain-set-up-the-parachain-template", + "title": "Set Up the Polkadot SDK Parachain Template", + "slug": "parachains-launch-a-parachain-set-up-the-parachain-template", "categories": [ - "Polkadot Protocol", + "Basics", "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-parachains-consensus.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/parachains/consensus/", - "preview": "Parachains are independent blockchains built with the Polkadot SDK, designed to leverage Polkadot’s relay chain for shared security and transaction finality. These specialized chains operate as part of Polkadot’s execution sharding model, where each parachain manages its own state and transactions while relying on the relay chain for validation and consensus.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-launch-a-parachain-set-up-the-parachain-template.md", + "html_url": "https://docs.polkadot.com/parachains/launch-a-parachain/set-up-the-parachain-template/", + "preview": "The [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\\_blank} includes several [templates](/parachains/customize-runtime/#starting-templates){target=\\_blank} designed to help you quickly start building your own blockchain. Each template offers a different level of configuration, from minimal setups to feature-rich environments, allowing you to choose the foundation that best fits your project's needs.", "outline": [ { "depth": 2, @@ -8471,82 +6046,48 @@ }, { "depth": 2, - "title": "The Role of Collators", - "anchor": "the-role-of-collators" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Consensus and Validation", - "anchor": "consensus-and-validation" - }, - { - "depth": 3, - "title": "Path of a Parachain Block", - "anchor": "path-of-a-parachain-block" + "title": "Polkadot SDK Utility Tools", + "anchor": "polkadot-sdk-utility-tools" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 6150, - "words": 790, - "headings": 5, - "estimated_token_count_total": 1125 - }, - "hash": "sha256:9875239c6071033a37a0f67fabca5a6e840c4a287620309f47b4f29c5a95a1cb", - "last_modified": "2025-10-28T14:42:15+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "polkadot-protocol-architecture-parachains-overview", - "title": "Overview", - "slug": "polkadot-protocol-architecture-parachains-overview", - "categories": [ - "Basics", - "Polkadot Protocol", - "Parachains" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-parachains-overview.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/parachains/overview/", - "preview": "A [_parachain_](/polkadot-protocol/glossary#parachain){target=\\_blank} is a coherent, application-specific blockchain that derives security from its respective relay chain. Parachains on Polkadot are each their own separate, fully functioning blockchain. The primary difference between a parachain and a regular, \"solo\" blockchain is that the relay chain verifies the state of all parachains that are connected to it. In many ways, parachains can be thought of as a [\"cynical\" rollup](#cryptoeconomic", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Clone the Template", + "anchor": "clone-the-template" }, { "depth": 2, - "title": "Coherent Systems", - "anchor": "coherent-systems" + "title": "Explore the Project Structure", + "anchor": "explore-the-project-structure" }, { "depth": 2, - "title": "Flexible Ecosystem", - "anchor": "flexible-ecosystem" + "title": "Compile the Runtime", + "anchor": "compile-the-runtime" }, { "depth": 2, - "title": "State Transition Functions (Runtimes)", - "anchor": "state-transition-functions-runtimes" + "title": "Verify the Build", + "anchor": "verify-the-build" }, { "depth": 2, - "title": "Shared Security: Validated by the Relay Chain", - "anchor": "shared-security-validated-by-the-relay-chain" + "title": "Run the Node Locally", + "anchor": "run-the-node-locally" }, { - "depth": 3, - "title": "Cryptoeconomic Security: ELVES Protocol", - "anchor": "cryptoeconomic-security-elves-protocol" + "depth": 2, + "title": "Interact with the Node", + "anchor": "interact-with-the-node" }, { "depth": 2, - "title": "Interoperability", - "anchor": "interoperability" + "title": "Stop the Node", + "anchor": "stop-the-node" }, { "depth": 2, @@ -8555,83 +6096,70 @@ } ], "stats": { - "chars": 9561, - "words": 1321, - "headings": 8, - "estimated_token_count_total": 1861 + "chars": 10608, + "words": 1512, + "headings": 11, + "estimated_token_count_total": 2379 }, - "hash": "sha256:932c12e1af939698279ede2eacb2190e1f56119582adf2064d6cf86f7a4f3e3c", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:637b9460bb65621cbc7c1bff272ea287d5181a983bc61418167959e108e21791", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-architecture-parachains", - "title": "Parachains", - "slug": "polkadot-protocol-architecture-parachains", + "id": "parachains-runtime-maintenance-runtime-upgrades", + "title": "Runtime Upgrades", + "slug": "parachains-runtime-maintenance-runtime-upgrades", "categories": [ - "Uncategorized" + "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-parachains.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/parachains/", - "preview": "Discover how parachains secure their networks and reach consensus by harnessing Polkadot’s relay chain and its robust validator framework. This integrated architecture ensures shared security and seamless coordination across the entire ecosystem.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-runtime-maintenance-runtime-upgrades.md", + "html_url": "https://docs.polkadot.com/parachains/runtime-maintenance/runtime-upgrades/", + "preview": "One of the defining features of Polkadot SDK-based blockchains is the ability to perform forkless runtime upgrades. Unlike traditional blockchains, which require hard forks and node coordination for upgrades, Polkadot networks enable seamless updates without network disruption.", "outline": [ { "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" - } - ], - "stats": { - "chars": 725, - "words": 93, - "headings": 1, - "estimated_token_count_total": 12 - }, - "hash": "sha256:00be43ac8d666bbe15c5c2fa5a5085697d0bb5a6f341ebbb943a209f0be355df", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "polkadot-protocol-architecture-polkadot-chain", - "title": "The Polkadot Relay Chain", - "slug": "polkadot-protocol-architecture-polkadot-chain", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-polkadot-chain.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/polkadot-chain/", - "preview": "Discover the central role of the Polkadot relay chain in securing the network and fostering interoperability. As the backbone of Polkadot, the relay chain provides shared security and ensures consensus across the ecosystem. It empowers parachains with flexible coretime allocation, enabling them to purchase blockspace on demand, ensuring efficiency and scalability for diverse blockchain applications.", - "outline": [ + "title": "Introduction", + "anchor": "introduction" + }, { "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" + "title": "How Runtime Upgrades Work", + "anchor": "how-runtime-upgrades-work" + }, + { + "depth": 3, + "title": "Runtime Versioning", + "anchor": "runtime-versioning" + }, + { + "depth": 3, + "title": "Accessing the Runtime Version", + "anchor": "accessing-the-runtime-version" + }, + { + "depth": 2, + "title": "Storage Migrations", + "anchor": "storage-migrations" } ], "stats": { - "chars": 481, - "words": 63, - "headings": 1, - "estimated_token_count_total": 12 + "chars": 5837, + "words": 811, + "headings": 5, + "estimated_token_count_total": 1161 }, - "hash": "sha256:2d228c52844df8952520fafdd3e6f0e26bfd2f32b5ee60c6241cf7d38603643c", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:ec31270001a6cd9d0a8ecb7974ad161d5c1ef4d3023d5a6af9fbc5a6ca46cbca", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-architecture-polkadot-chain-overview", - "title": "Overview of the Polkadot Relay Chain", - "slug": "polkadot-protocol-architecture-polkadot-chain-overview", + "id": "parachains-runtime-maintenance-storage-migrations", + "title": "Storage Migrations", + "slug": "parachains-runtime-maintenance-storage-migrations", "categories": [ - "Basics", - "Polkadot Protocol", "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-polkadot-chain-overview.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/polkadot-chain/overview/", - "preview": "Polkadot is a next-generation blockchain protocol designed to support a multi-chain future by enabling secure communication and interoperability between different blockchains. Built as a Layer-0 protocol, Polkadot introduces innovations like application-specific Layer-1 chains ([parachains](/polkadot-protocol/architecture/parachains/){targe=\\_blank}), shared security through [Nominated Proof of Stake (NPoS)](/polkadot-protocol/glossary/#nominated-proof-of-stake-npos){target=\\_blank}, and cross-c", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-runtime-maintenance-storage-migrations.md", + "html_url": "https://docs.polkadot.com/parachains/runtime-maintenance/storage-migrations/", + "preview": "Storage migrations are a crucial part of the runtime upgrade process. They allow you to update the [storage items](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/attr.storage.html){target=\\_blank} of your blockchain, adapting to changes in the runtime. Whenever you change the encoding or data types used to represent data in storage, you'll need to provide a storage migration to ensure the runtime can correctly interpret the existing stored values in the new runtime", "outline": [ { "depth": 2, @@ -8640,75 +6168,69 @@ }, { "depth": 2, - "title": "Polkadot 1.0", - "anchor": "polkadot-10" + "title": "Storage Migration Scenarios", + "anchor": "storage-migration-scenarios" }, { - "depth": 3, - "title": "High-Level Architecture", - "anchor": "high-level-architecture" + "depth": 2, + "title": "Implement Storage Migrations", + "anchor": "implement-storage-migrations" }, { "depth": 3, - "title": "Polkadot's Additional Functionalities", - "anchor": "polkadots-additional-functionalities" + "title": "Core Migration Function", + "anchor": "core-migration-function" }, { "depth": 3, - "title": "Polkadot's Resilience", - "anchor": "polkadots-resilience" + "title": "Migration Testing Hooks", + "anchor": "migration-testing-hooks" }, { "depth": 3, - "title": "Polkadot's Blockspace", - "anchor": "polkadots-blockspace" - }, - { - "depth": 2, - "title": "DOT Token", - "anchor": "dot-token" + "title": "Migration Structure", + "anchor": "migration-structure" }, { "depth": 3, - "title": "Redenomination of DOT", - "anchor": "redenomination-of-dot" + "title": "Migration Organization", + "anchor": "migration-organization" }, { "depth": 3, - "title": "The Planck Unit", - "anchor": "the-planck-unit" + "title": "Scheduling Migrations", + "anchor": "scheduling-migrations" }, { - "depth": 3, - "title": "Uses for DOT", - "anchor": "uses-for-dot" + "depth": 2, + "title": "Single-Block Migrations", + "anchor": "single-block-migrations" }, { "depth": 2, - "title": "JAM and the Road Ahead", - "anchor": "jam-and-the-road-ahead" + "title": "Multi Block Migrations", + "anchor": "multi-block-migrations" } ], "stats": { - "chars": 12513, - "words": 1781, - "headings": 11, - "estimated_token_count_total": 2591 + "chars": 18500, + "words": 2363, + "headings": 10, + "estimated_token_count_total": 4014 }, - "hash": "sha256:201e7efa0ad6b24890dd06f69714e19d9700ab7f7a51a33fe6d6e0664b7170b2", - "last_modified": "2025-10-28T14:15:59+00:00", + "hash": "sha256:55dc252fdecf1590048ce8d009b822e90231442abe81e9593cf1635944a31336", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-architecture-polkadot-chain-pos-consensus", - "title": "Proof of Stake Consensus", - "slug": "polkadot-protocol-architecture-polkadot-chain-pos-consensus", + "id": "parachains-runtime-maintenance-unlock-parachains", + "title": "Unlock a Parachain", + "slug": "parachains-runtime-maintenance-unlock-parachains", "categories": [ - "Polkadot Protocol" + "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-polkadot-chain-pos-consensus.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/polkadot-chain/pos-consensus/", - "preview": "Polkadot's Proof of Stake consensus model leverages a unique hybrid approach by design to promote decentralized and secure network operations. In traditional Proof of Stake (PoS) systems, a node's ability to validate transactions is tied to its token holdings, which can lead to centralization risks and limited validator participation. Polkadot addresses these concerns through its [Nominated Proof of Stake (NPoS)](/polkadot-protocol/glossary/#nominated-proof-of-stake-npos){target=\\_blank} model a", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-runtime-maintenance-unlock-parachains.md", + "html_url": "https://docs.polkadot.com/parachains/runtime-maintenance/unlock-parachains/", + "preview": "Parachain locks are a critical security mechanism in the Polkadot ecosystem designed to maintain decentralization during the parachain lifecycle. These locks prevent potential centralization risks that could emerge during the early stages of parachain operation.", "outline": [ { "depth": 2, @@ -8717,86 +6239,122 @@ }, { "depth": 2, - "title": "Nominated Proof of Stake", - "anchor": "nominated-proof-of-stake" + "title": "Check If the Parachain Is Locked", + "anchor": "check-if-the-parachain-is-locked" }, { "depth": 2, - "title": "Hybrid Consensus", - "anchor": "hybrid-consensus" + "title": "How to Unlock a Parachain", + "anchor": "how-to-unlock-a-parachain" }, { - "depth": 2, - "title": "Block Production - BABE", - "anchor": "block-production-babe" + "depth": 3, + "title": "Prepare the Unlock Call", + "anchor": "prepare-the-unlock-call" }, { "depth": 3, - "title": "Validator Participation", - "anchor": "validator-participation" + "title": "Fund the Sovereign Account", + "anchor": "fund-the-sovereign-account" }, { "depth": 3, - "title": "Additional Resources", - "anchor": "additional-resources" + "title": "Craft and Submit the XCM", + "anchor": "craft-and-submit-the-xcm" + } + ], + "stats": { + "chars": 9232, + "words": 1276, + "headings": 6, + "estimated_token_count_total": 2028 + }, + "hash": "sha256:e408d05199cc184fc6fe8bb212efb3c9aa6cb79258977e07566692176c912def", + "token_estimator": "heuristic-v1" + }, + { + "id": "parachains-testing-fork-a-parachain", + "title": "Get Started", + "slug": "parachains-testing-fork-a-parachain", + "categories": [ + "Parachains", + "Tooling" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-fork-a-parachain.md", + "html_url": "https://docs.polkadot.com/parachains/testing/fork-a-parachain/", + "preview": "[Chopsticks](https://github.com/AcalaNetwork/chopsticks/){target=\\_blank}, developed by the [Acala Foundation](https://github.com/AcalaNetwork){target=\\_blank}, is a versatile tool tailored for developers working on Polkadot SDK-based blockchains. With Chopsticks, you can fork live chains locally, replay blocks to analyze extrinsics, and simulate complex scenarios like XCM interactions all without deploying to a live network.", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Finality Gadget - GRANDPA", - "anchor": "finality-gadget-grandpa" + "title": "Prerequisites", + "anchor": "prerequisites" + }, + { + "depth": 2, + "title": "Install Chopsticks", + "anchor": "install-chopsticks" }, { "depth": 3, - "title": "Probabilistic vs. Provable Finality", - "anchor": "probabilistic-vs-provable-finality" + "title": "Global Installation", + "anchor": "global-installation" }, { "depth": 3, - "title": "Additional Resources", - "anchor": "additional-resources-2" + "title": "Local Installation", + "anchor": "local-installation" }, { "depth": 2, - "title": "Fork Choice", - "anchor": "fork-choice" + "title": "Configure Chopsticks", + "anchor": "configure-chopsticks" }, { "depth": 3, - "title": "Additional Resources", - "anchor": "additional-resources-3" + "title": "Configuration File", + "anchor": "configuration-file" + }, + { + "depth": 3, + "title": "CLI Flags", + "anchor": "cli-flags" }, { "depth": 2, - "title": "Bridging - BEEFY", - "anchor": "bridging-beefy" + "title": "WebSocket Commands", + "anchor": "websocket-commands" }, { - "depth": 3, - "title": "Additional Resources", - "anchor": "additional-resources-4" + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 12788, - "words": 1838, - "headings": 13, - "estimated_token_count_total": 2534 + "chars": 10894, + "words": 1330, + "headings": 10, + "estimated_token_count_total": 2614 }, - "hash": "sha256:191df9b098e17e9de4597c9f8ced8abbafdfabc7e0f5c0a94d767fc2c9d7742b", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:4325cdd697814b8043db808da3dee86d3d9c6fc7dd523aae7fe8914d59d1b39c", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-architecture-system-chains-asset-hub", - "title": "Asset Hub", - "slug": "polkadot-protocol-architecture-system-chains-asset-hub", + "id": "parachains-testing-run-a-parachain-network", + "title": "Get Started", + "slug": "parachains-testing-run-a-parachain-network", "categories": [ - "Polkadot Protocol" + "Parachains", + "Tooling" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-system-chains-asset-hub.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/system-chains/asset-hub/", - "preview": "The Asset Hub is a critical component in the Polkadot ecosystem, enabling the management of fungible and non-fungible assets across the network. Since the relay chain focuses on maintaining security and consensus without direct asset management, Asset Hub provides a streamlined platform for creating, managing, and using on-chain assets in a fee-efficient manner. This guide outlines the core features of Asset Hub, including how it handles asset operations, cross-chain transfers, and asset integra", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-testing-run-a-parachain-network.md", + "html_url": "https://docs.polkadot.com/parachains/testing/run-a-parachain-network/", + "preview": "Zombienet is a robust testing framework designed for Polkadot SDK-based blockchain networks. It enables developers to efficiently deploy and test ephemeral blockchain environments on platforms like Kubernetes, Podman, and native setups. With its simple and versatile CLI, Zombienet provides an all-in-one solution for spawning networks, running tests, and validating performance.", "outline": [ { "depth": 2, @@ -8805,103 +6363,110 @@ }, { "depth": 2, - "title": "Assets Basics", - "anchor": "assets-basics" + "title": "Install Zombienet", + "anchor": "install-zombienet" }, { "depth": 2, - "title": "Assets Pallet", - "anchor": "assets-pallet" + "title": "Providers", + "anchor": "providers" }, { "depth": 3, - "title": "Key Features", - "anchor": "key-features" + "title": "Kubernetes", + "anchor": "kubernetes" }, { "depth": 3, - "title": "Main Functions", - "anchor": "main-functions" + "title": "Podman", + "anchor": "podman" }, { "depth": 3, - "title": "Querying Functions", - "anchor": "querying-functions" + "title": "Local Provider", + "anchor": "local-provider" }, { - "depth": 3, - "title": "Permission Models and Roles", - "anchor": "permission-models-and-roles" + "depth": 2, + "title": "Configure Zombienet", + "anchor": "configure-zombienet" }, { "depth": 3, - "title": "Asset Freezing", - "anchor": "asset-freezing" + "title": "Configuration Files", + "anchor": "configuration-files" }, { "depth": 3, - "title": "Non-Custodial Transfers (Approval API)", - "anchor": "non-custodial-transfers-approval-api" - }, - { - "depth": 2, - "title": "Foreign Assets", - "anchor": "foreign-assets" + "title": "CLI Usage", + "anchor": "cli-usage" }, { "depth": 3, - "title": "Handling Foreign Assets", - "anchor": "handling-foreign-assets" - }, - { - "depth": 2, - "title": "Integration", - "anchor": "integration" + "title": "Settings", + "anchor": "settings" }, { "depth": 3, - "title": "API Sidecar", - "anchor": "api-sidecar" + "title": "Relay Chain Configuration", + "anchor": "relay-chain-configuration" }, { "depth": 3, - "title": "TxWrapper", - "anchor": "txwrapper" + "title": "Parachain Configuration", + "anchor": "parachain-configuration" }, { "depth": 3, - "title": "ParaSpell", - "anchor": "paraspell" + "title": "XCM Configuration", + "anchor": "xcm-configuration" }, { - "depth": 3, - "title": "Parachain Node", - "anchor": "parachain-node" - }, + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" + } + ], + "stats": { + "chars": 41636, + "words": 4599, + "headings": 14, + "estimated_token_count_total": 9871 + }, + "hash": "sha256:0d7e04fd952cc9d5bd8cdbfd87cc4004c5f95e896a16bc7f89dfc4caeac8f371", + "token_estimator": "heuristic-v1" + }, + { + "id": "polkadot-protocol-architecture-parachains-consensus", + "title": "Parachain Consensus", + "slug": "polkadot-protocol-architecture-parachains-consensus", + "categories": [ + "Polkadot Protocol", + "Parachains" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-parachains-consensus.md", + "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/parachains/consensus/", + "preview": "Parachains are independent blockchains built with the Polkadot SDK, designed to leverage Polkadot’s relay chain for shared security and transaction finality. These specialized chains operate as part of Polkadot’s execution sharding model, where each parachain manages its own state and transactions while relying on the relay chain for validation and consensus.", + "outline": [ { "depth": 2, - "title": "XCM Transfer Monitoring", - "anchor": "xcm-transfer-monitoring" - }, - { - "depth": 3, - "title": "Monitor XCM Deposits", - "anchor": "monitor-xcm-deposits" + "title": "Introduction", + "anchor": "introduction" }, { - "depth": 3, - "title": "Track XCM Information Back to the Source", - "anchor": "track-xcm-information-back-to-the-source" + "depth": 2, + "title": "The Role of Collators", + "anchor": "the-role-of-collators" }, { - "depth": 3, - "title": "Practical Monitoring Examples", - "anchor": "practical-monitoring-examples" + "depth": 2, + "title": "Consensus and Validation", + "anchor": "consensus-and-validation" }, { "depth": 3, - "title": "Monitor for Failed XCM Transfers", - "anchor": "monitor-for-failed-xcm-transfers" + "title": "Path of a Parachain Block", + "anchor": "path-of-a-parachain-block" }, { "depth": 2, @@ -8910,26 +6475,26 @@ } ], "stats": { - "chars": 20100, - "words": 2910, - "headings": 22, - "estimated_token_count_total": 4105 + "chars": 6150, + "words": 790, + "headings": 5, + "estimated_token_count_total": 1125 }, - "hash": "sha256:759ab6dea0ad03c3f627558ea186d9f32351fa559acde82931684efc2da59d46", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:9875239c6071033a37a0f67fabca5a6e840c4a287620309f47b4f29c5a95a1cb", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-architecture-system-chains-bridge-hub", - "title": "Bridge Hub", - "slug": "polkadot-protocol-architecture-system-chains-bridge-hub", + "id": "polkadot-protocol-architecture-parachains-overview", + "title": "Overview", + "slug": "polkadot-protocol-architecture-parachains-overview", "categories": [ - "Polkadot Protocol" + "Basics", + "Polkadot Protocol", + "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-system-chains-bridge-hub.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/system-chains/bridge-hub/", - "preview": "The Bridge Hub system parachain plays a crucial role in facilitating trustless interactions between Polkadot, Kusama, Ethereum, and other blockchain ecosystems. By implementing on-chain light clients and supporting protocols like BEEFY and GRANDPA, Bridge Hub ensures seamless message transmission and state verification across chains. It also provides essential [pallets](/polkadot-protocol/glossary/#pallet){target=\\_blank} for sending and receiving messages, making it a cornerstone of Polkadot’s", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-parachains-overview.md", + "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/parachains/overview/", + "preview": "A [_parachain_](/polkadot-protocol/glossary#parachain){target=\\_blank} is a coherent, application-specific blockchain that derives security from its respective relay chain. Parachains on Polkadot are each their own separate, fully functioning blockchain. The primary difference between a parachain and a regular, \"solo\" blockchain is that the relay chain verifies the state of all parachains that are connected to it. In many ways, parachains can be thought of as a [\"cynical\" rollup](#cryptoeconomic", "outline": [ { "depth": 2, @@ -8938,23 +6503,33 @@ }, { "depth": 2, - "title": "Trustless Bridging", - "anchor": "trustless-bridging" + "title": "Coherent Systems", + "anchor": "coherent-systems" }, { "depth": 2, - "title": "Bridging Components", - "anchor": "bridging-components" + "title": "Flexible Ecosystem", + "anchor": "flexible-ecosystem" + }, + { + "depth": 2, + "title": "State Transition Functions (Runtimes)", + "anchor": "state-transition-functions-runtimes" + }, + { + "depth": 2, + "title": "Shared Security: Validated by the Relay Chain", + "anchor": "shared-security-validated-by-the-relay-chain" }, { "depth": 3, - "title": "Ethereum-Specific Support", - "anchor": "ethereum-specific-support" + "title": "Cryptoeconomic Security: ELVES Protocol", + "anchor": "cryptoeconomic-security-elves-protocol" }, { "depth": 2, - "title": "Deployed Bridges", - "anchor": "deployed-bridges" + "title": "Interoperability", + "anchor": "interoperability" }, { "depth": 2, @@ -8963,47 +6538,64 @@ } ], "stats": { - "chars": 5475, - "words": 775, - "headings": 6, - "estimated_token_count_total": 1218 + "chars": 9561, + "words": 1321, + "headings": 8, + "estimated_token_count_total": 1861 }, - "hash": "sha256:26c156146ef9743fc26c6499294ff14186f97edbc2a34f445d3366b72f7148ae", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:932c12e1af939698279ede2eacb2190e1f56119582adf2064d6cf86f7a4f3e3c", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-architecture-system-chains-collectives", - "title": "Collectives Chain", - "slug": "polkadot-protocol-architecture-system-chains-collectives", + "id": "polkadot-protocol-architecture-parachains", + "title": "Parachains", + "slug": "polkadot-protocol-architecture-parachains", "categories": [ - "Polkadot Protocol" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-system-chains-collectives.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/system-chains/collectives/", - "preview": "Established through [Referendum 81](https://polkadot-old.polkassembly.io/referendum/81){target=\\_blank}, the Collectives chain operates as a dedicated parachain exclusive to the Polkadot network with no counterpart on Kusama. This specialized infrastructure provides a foundation for various on-chain governance groups essential to Polkadot's ecosystem.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-parachains.md", + "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/parachains/", + "preview": "Discover how parachains secure their networks and reach consensus by harnessing Polkadot’s relay chain and its robust validator framework. This integrated architecture ensures shared security and seamless coordination across the entire ecosystem.", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 725, + "words": 93, + "headings": 1, + "estimated_token_count_total": 12 + }, + "hash": "sha256:3b9160b166d9b42b124f3b07eb26bdc5499fbbace6f951095009a5eee7fccbb6", + "token_estimator": "heuristic-v1" + }, + { + "id": "polkadot-protocol-architecture-polkadot-chain", + "title": "The Polkadot Relay Chain", + "slug": "polkadot-protocol-architecture-polkadot-chain", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-architecture-polkadot-chain.md", + "html_url": "https://docs.polkadot.com/polkadot-protocol/architecture/polkadot-chain/", + "preview": "Discover the central role of the Polkadot relay chain in securing the network and fostering interoperability. As the backbone of Polkadot, the relay chain provides shared security and ensures consensus across the ecosystem. It empowers parachains with flexible coretime allocation, enabling them to purchase blockspace on demand, ensuring efficiency and scalability for diverse blockchain applications.", + "outline": [ { "depth": 2, - "title": "Key Collectives", - "anchor": "key-collectives" + "title": "In This Section", + "anchor": "in-this-section" } ], "stats": { - "chars": 2288, - "words": 293, - "headings": 2, - "estimated_token_count_total": 424 + "chars": 481, + "words": 63, + "headings": 1, + "estimated_token_count_total": 12 }, - "hash": "sha256:59ec351fbb8d3a392e90f4f5bf6b62f58b21d6d7a900c5e367e5d2e09ecb3aca", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:c29356358f095b0d413e4c6525146b3f1b0b900853aada2168e7e55cd8dd6641", "token_estimator": "heuristic-v1" }, { @@ -9045,7 +6637,6 @@ "estimated_token_count_total": 1230 }, "hash": "sha256:8d186fa56ccbbf4b6c85cffc5521b9a99a20e9517f3b4a435730745803cbf2e8", - "last_modified": "2025-10-28T14:42:15+00:00", "token_estimator": "heuristic-v1" }, { @@ -9113,7 +6704,6 @@ "estimated_token_count_total": 1643 }, "hash": "sha256:100377787627052a29bd1173270b5ad307639b828c331e71c85d4c00bc5692d8", - "last_modified": "2025-10-28T14:42:15+00:00", "token_estimator": "heuristic-v1" }, { @@ -9139,9 +6729,7 @@ "headings": 1, "estimated_token_count_total": 12 }, - "hash": "sha256:8239d1e8d8642cb7c10e9e5f971c99b999e9e4a87373b50bf4a691225c1e4702", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:6ef13c197dd1865fcc1a405d67486f1d053534d576bb32fe47a442fd2c11b6cd", "token_estimator": "heuristic-v1" }, { @@ -9172,9 +6760,7 @@ "headings": 2, "estimated_token_count_total": 177 }, - "hash": "sha256:f0e04286eacf23b182186f23e9854c0cd251545b8a8d561d2503f962dbfe32c0", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:ffda04c93c70ec7204be28b642fa6e51f6bf9436d4792ecd25136696683f0902", "token_estimator": "heuristic-v1" }, { @@ -9205,9 +6791,7 @@ "headings": 2, "estimated_token_count_total": 233 }, - "hash": "sha256:baba9dd41091b792d09005d55d3df0bf65b35f42b40ebe63caf425a0978a22b0", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:58fd5c8c092ee748c2979164f985a67071a6ccb88492e79cdad536363364c858", "token_estimator": "heuristic-v1" }, { @@ -9233,9 +6817,7 @@ "headings": 1, "estimated_token_count_total": 12 }, - "hash": "sha256:62beec261e72529f70e07a641177d489d2c8872f9c9d618cbadf1ac0fd881986", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:235f33cdb64494815dbb3eb58ea98c69935098684e1b34b6d15356bc54b082ea", "token_estimator": "heuristic-v1" }, { @@ -9250,33 +6832,143 @@ "preview": "This section equips developers with the essential knowledge to create, deploy, and enhance applications and blockchains within the Polkadot ecosystem. Gain a comprehensive understanding of Polkadot’s foundational components, including accounts, balances, and transactions, as well as advanced topics like data encoding and cryptographic methods. Mastering these concepts is vital for building robust and secure applications on Polkadot.", "outline": [ { - "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" + "depth": 2, + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 998, + "words": 130, + "headings": 1, + "estimated_token_count_total": 12 + }, + "hash": "sha256:1514316acba1e9bba82ae1c82b09481e9d03d286e6f5d93b66e5a85fd4be7bca", + "token_estimator": "heuristic-v1" + }, + { + "id": "polkadot-protocol-smart-contract-basics-evm-vs-polkavm", + "title": "EVM vs PolkaVM", + "slug": "polkadot-protocol-smart-contract-basics-evm-vs-polkavm", + "categories": [ + "Basics", + "Polkadot Protocol" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-smart-contract-basics-evm-vs-polkavm.md", + "html_url": "https://docs.polkadot.com/polkadot-protocol/smart-contract-basics/evm-vs-polkavm/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" + }, + { + "depth": 2, + "title": "Core Virtual Machine Architecture", + "anchor": "core-virtual-machine-architecture" + }, + { + "depth": 3, + "title": "High-Level Architecture Comparison", + "anchor": "high-level-architecture-comparison" + }, + { + "depth": 2, + "title": "Gas Model", + "anchor": "gas-model" + }, + { + "depth": 3, + "title": "Dynamic Gas Value Scaling", + "anchor": "dynamic-gas-value-scaling" + }, + { + "depth": 3, + "title": "Multi-Dimensional Resource Metering", + "anchor": "multi-dimensional-resource-metering" + }, + { + "depth": 2, + "title": "Memory Management", + "anchor": "memory-management" + }, + { + "depth": 3, + "title": "Current Memory Limits", + "anchor": "current-memory-limits" + }, + { + "depth": 2, + "title": "Account Management - Existential Deposit", + "anchor": "account-management-existential-deposit" + }, + { + "depth": 3, + "title": "Account Management Comparison", + "anchor": "account-management-comparison" + }, + { + "depth": 2, + "title": "Contract Deployment", + "anchor": "contract-deployment" + }, + { + "depth": 2, + "title": "Solidity and YUL IR Translation Incompatibilities", + "anchor": "solidity-and-yul-ir-translation-incompatibilities" + }, + { + "depth": 3, + "title": "Contract Code Structure", + "anchor": "contract-code-structure" + }, + { + "depth": 3, + "title": "Solidity-Specific Differences", + "anchor": "solidity-specific-differences" + }, + { + "depth": 3, + "title": "YUL Function Translation Differences", + "anchor": "yul-function-translation-differences" + }, + { + "depth": 3, + "title": "Unsupported Operations", + "anchor": "unsupported-operations" + }, + { + "depth": 3, + "title": "Compilation Pipeline Considerations", + "anchor": "compilation-pipeline-considerations" + }, + { + "depth": 3, + "title": "Memory Pointer Limitations", + "anchor": "memory-pointer-limitations" } ], "stats": { - "chars": 29648, - "words": 4201, - "headings": 15, - "estimated_token_count_total": 6521 + "chars": 27673, + "words": 3392, + "headings": 18, + "estimated_token_count_total": 5305 }, - "hash": "sha256:1f9ce923b3ce296571fe63837c0d3c3c791a339ef02db09ead6b2b92e9d1bfd5", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:fe651be49fe0a9ae899b2cbf9c663325f407718dc63f1d2c6a2dc4931be751fa", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-parachain-basics-blocks-transactions-fees-blocks", - "title": "Blocks", - "slug": "polkadot-protocol-parachain-basics-blocks-transactions-fees-blocks", + "id": "polkadot-protocol-smart-contract-basics-networks", + "title": "Networks for Polkadot Hub Smart Contracts", + "slug": "polkadot-protocol-smart-contract-basics-networks", "categories": [ "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-parachain-basics-blocks-transactions-fees-blocks.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/parachain-basics/blocks-transactions-fees/blocks/", - "preview": "In the Polkadot SDK, blocks are fundamental to the functioning of the blockchain, serving as containers for [transactions](/polkadot-protocol/parachain-basics/blocks-transactions-fees/transactions/){target=\\_blank} and changes to the chain's state. Blocks consist of headers and an array of transactions, ensuring the integrity and validity of operations on the network. This guide explores the essential components of a block, the process of block production, and how blocks are validated and import", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-smart-contract-basics-networks.md", + "html_url": "https://docs.polkadot.com/polkadot-protocol/smart-contract-basics/networks/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", "outline": [ { "depth": 2, @@ -9285,551 +6977,509 @@ }, { "depth": 2, - "title": "What is a Block?", - "anchor": "what-is-a-block" + "title": "Network Overview", + "anchor": "network-overview" }, { "depth": 2, - "title": "Block Production", - "anchor": "block-production" + "title": "Local Development", + "anchor": "local-development" + }, + { + "depth": 2, + "title": "Test Networks", + "anchor": "test-networks" }, { "depth": 3, - "title": "Initialize Block", - "anchor": "initialize-block" + "title": "Passet Hub", + "anchor": "passet-hub" }, { "depth": 3, - "title": "Finalize Block", - "anchor": "finalize-block" + "title": "Westend Hub", + "anchor": "westend-hub" }, { "depth": 2, - "title": "Block Authoring and Import", - "anchor": "block-authoring-and-import" + "title": "Production Networks", + "anchor": "production-networks" }, { "depth": 3, - "title": "Block Import Queue", - "anchor": "block-import-queue" + "title": "Polkadot Hub", + "anchor": "polkadot-hub" }, { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" + "depth": 3, + "title": "Kusama Hub", + "anchor": "kusama-hub" } ], "stats": { - "chars": 6266, - "words": 912, - "headings": 8, - "estimated_token_count_total": 1399 + "chars": 5108, + "words": 696, + "headings": 9, + "estimated_token_count_total": 891 }, - "hash": "sha256:bcad23a74d962cab72b54cdc090bf9ee0cd5ecf79f70fb642f154668c2743983", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:b5acdc9acf0e44836b8a4518155eba7d16cc3b103c557a00970ffb1c44c3e9f6", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-parachain-basics-blocks-transactions-fees-fees", - "title": "Transactions Weights and Fees", - "slug": "polkadot-protocol-parachain-basics-blocks-transactions-fees-fees", + "id": "polkadot-protocol-smart-contract-basics-overview", + "title": "Smart Contracts Basics Overview", + "slug": "polkadot-protocol-smart-contract-basics-overview", "categories": [ "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-parachain-basics-blocks-transactions-fees-fees.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/parachain-basics/blocks-transactions-fees/fees/", - "preview": "When transactions are executed, or data is stored on-chain, the activity changes the chain's state and consumes blockchain resources. Because the resources available to a blockchain are limited, managing how operations on-chain consume them is important. In addition to being limited in practical terms, such as storage capacity, blockchain resources represent a potential attack vector for malicious users. For example, a malicious user might attempt to overload the network with messages to stop th", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-smart-contract-basics-overview.md", + "html_url": "https://docs.polkadot.com/polkadot-protocol/smart-contract-basics/overview/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", "outline": [ { "depth": 2, - "title": "Introductions", - "anchor": "introductions" - }, - { - "depth": 2, - "title": "How Fees are Calculated", - "anchor": "how-fees-are-calculated" - }, - { - "depth": 2, - "title": "Using the Transaction Payment Pallet", - "anchor": "using-the-transaction-payment-pallet" - }, - { - "depth": 3, - "title": "Understanding the Inclusion Fee", - "anchor": "understanding-the-inclusion-fee" - }, - { - "depth": 3, - "title": "Accounts with an Insufficient Balance", - "anchor": "accounts-with-an-insufficient-balance" - }, - { - "depth": 3, - "title": "Fee Multipliers", - "anchor": "fee-multipliers" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Transactions with Special Requirements", - "anchor": "transactions-with-special-requirements" + "title": "Smart Contracts Versus Parachains", + "anchor": "smart-contracts-versus-parachains" }, { "depth": 2, - "title": "Default Weight Annotations", - "anchor": "default-weight-annotations" + "title": "Building a Smart Contract", + "anchor": "building-a-smart-contract" }, { "depth": 3, - "title": "Weights and Database Read/Write Operations", - "anchor": "weights-and-database-readwrite-operations" + "title": "PolkaVM Contracts", + "anchor": "polkavm-contracts" }, { "depth": 3, - "title": "Dispatch Classes", - "anchor": "dispatch-classes" + "title": "EVM Contracts", + "anchor": "evm-contracts" }, { "depth": 3, - "title": "Dynamic Weights", - "anchor": "dynamic-weights" - }, + "title": "Wasm Contracts", + "anchor": "wasm-contracts" + } + ], + "stats": { + "chars": 10854, + "words": 1559, + "headings": 6, + "estimated_token_count_total": 2550 + }, + "hash": "sha256:5d293525ce81d27e32c26938a029a6a82b137221a0630d084f528853ffaf798e", + "token_estimator": "heuristic-v1" + }, + { + "id": "polkadot-protocol-smart-contract-basics", + "title": "Smart Contract Basics", + "slug": "polkadot-protocol-smart-contract-basics", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-smart-contract-basics.md", + "html_url": "https://docs.polkadot.com/polkadot-protocol/smart-contract-basics/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. Gain a deep understanding of smart contracts on Polkadot, from execution environments to transaction mechanics.", + "outline": [ { "depth": 2, - "title": "Post Dispatch Weight Correction", - "anchor": "post-dispatch-weight-correction" + "title": "Key Topics", + "anchor": "key-topics" }, { "depth": 2, - "title": "Custom Fees", - "anchor": "custom-fees" - }, - { - "depth": 3, - "title": "Custom Weights", - "anchor": "custom-weights" - }, + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 1110, + "words": 136, + "headings": 2, + "estimated_token_count_total": 148 + }, + "hash": "sha256:e8dac01e89b7aac4b887e962e91084c253f5ea25c1abc3a56355390d0c3201c8", + "token_estimator": "heuristic-v1" + }, + { + "id": "polkadot-protocol", + "title": "Learn About the Polkadot Protocol", + "slug": "polkadot-protocol", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol.md", + "html_url": "https://docs.polkadot.com/polkadot-protocol/", + "preview": "The Polkadot protocol is designed to enable scalable, secure, and interoperable networks. It introduces a unique multichain architecture that allows independent blockchains, known as parachains, to operate seamlessly while benefiting from the shared security of the relay chain. Polkadot’s decentralized governance ensures that network upgrades and decisions are community-driven, while its cross-chain messaging and interoperability features make it a hub for multichain applications.", + "outline": [ { "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" + "title": "In This Section", + "anchor": "in-this-section" } ], "stats": { - "chars": 20797, - "words": 2917, - "headings": 15, - "estimated_token_count_total": 4464 + "chars": 1170, + "words": 150, + "headings": 1, + "estimated_token_count_total": 12 }, - "hash": "sha256:299597c39d0e4e4902be8e45b354fff78a862aa5799e4f16d16787a97a1e3da8", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:49be4b4b5289572086eaaaf9ccff3bee7879b534188331c9a8052b3fe5aa4933", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-parachain-basics-blocks-transactions-fees-transactions", - "title": "Transactions", - "slug": "polkadot-protocol-parachain-basics-blocks-transactions-fees-transactions", + "id": "reference-glossary", + "title": "Glossary", + "slug": "reference-glossary", "categories": [ - "Basics", - "Polkadot Protocol" + "Reference" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-parachain-basics-blocks-transactions-fees-transactions.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/parachain-basics/blocks-transactions-fees/transactions/", - "preview": "Transactions are essential components of blockchain networks, enabling state changes and the execution of key operations. In the Polkadot SDK, transactions, often called extrinsics, come in multiple forms, including signed, unsigned, and inherent transactions.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-glossary.md", + "html_url": "https://docs.polkadot.com/reference/glossary/", + "preview": "Key definitions, concepts, and terminology specific to the Polkadot ecosystem are included here.", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Authority", + "anchor": "authority" }, { "depth": 2, - "title": "What Is a Transaction?", - "anchor": "what-is-a-transaction" + "title": "Authority Round (Aura)", + "anchor": "authority-round-aura" + }, + { + "depth": 2, + "title": "Blind Assignment of Blockchain Extension (BABE)", + "anchor": "blind-assignment-of-blockchain-extension-babe" + }, + { + "depth": 2, + "title": "Block Author", + "anchor": "block-author" + }, + { + "depth": 2, + "title": "Byzantine Fault Tolerance (BFT)", + "anchor": "byzantine-fault-tolerance-bft" }, { "depth": 3, - "title": "Signed Transactions", - "anchor": "signed-transactions" + "title": "Byzantine Failure", + "anchor": "byzantine-failure" }, { "depth": 3, - "title": "Unsigned Transactions", - "anchor": "unsigned-transactions" + "title": "Practical Byzantine Fault Tolerance (pBFT)", + "anchor": "practical-byzantine-fault-tolerance-pbft" }, { "depth": 3, - "title": "Inherent Transactions", - "anchor": "inherent-transactions" + "title": "Preimage", + "anchor": "preimage" }, { "depth": 2, - "title": "Transaction Formats", - "anchor": "transaction-formats" + "title": "Call", + "anchor": "call" }, { - "depth": 3, - "title": "Types of Transaction Formats", - "anchor": "types-of-transaction-formats" + "depth": 2, + "title": "Chain Specification", + "anchor": "chain-specification" }, { - "depth": 3, - "title": "Signed Transaction Data Structure", - "anchor": "signed-transaction-data-structure" + "depth": 2, + "title": "Collator", + "anchor": "collator" }, { - "depth": 3, - "title": "Signed Extensions", - "anchor": "signed-extensions" + "depth": 2, + "title": "Collective", + "anchor": "collective" }, { "depth": 2, - "title": "Transaction Construction", - "anchor": "transaction-construction" + "title": "Consensus", + "anchor": "consensus" }, { - "depth": 3, - "title": "Construct a Signed Transaction", - "anchor": "construct-a-signed-transaction" + "depth": 2, + "title": "Consensus Algorithm", + "anchor": "consensus-algorithm" }, { - "depth": 3, - "title": "Transaction Encoding", - "anchor": "transaction-encoding" + "depth": 2, + "title": "Consensus Engine", + "anchor": "consensus-engine" }, { - "depth": 3, - "title": "Customize Transaction Construction", - "anchor": "customize-transaction-construction" + "depth": 2, + "title": "Coretime", + "anchor": "coretime" }, { "depth": 2, - "title": "Lifecycle of a Transaction", - "anchor": "lifecycle-of-a-transaction" + "title": "Development Phrase", + "anchor": "development-phrase" }, { - "depth": 3, - "title": "Define Transaction Properties", - "anchor": "define-transaction-properties" + "depth": 2, + "title": "Digest", + "anchor": "digest" }, { - "depth": 3, - "title": "Process on a Block Authoring Node", - "anchor": "process-on-a-block-authoring-node" + "depth": 2, + "title": "Dispatchable", + "anchor": "dispatchable" }, { - "depth": 3, - "title": "Validate and Queue", - "anchor": "validate-and-queue" + "depth": 2, + "title": "Events", + "anchor": "events" }, { - "depth": 3, - "title": "Transaction Ordering and Priority", - "anchor": "transaction-ordering-and-priority" + "depth": 2, + "title": "Executor", + "anchor": "executor" }, { - "depth": 3, - "title": "Transaction Execution", - "anchor": "transaction-execution" + "depth": 2, + "title": "Existential Deposit", + "anchor": "existential-deposit" }, { "depth": 2, - "title": "Transaction Mortality", - "anchor": "transaction-mortality" + "title": "Extrinsic", + "anchor": "extrinsic" }, { "depth": 2, - "title": "Unique Identifiers for Extrinsics", - "anchor": "unique-identifiers-for-extrinsics" + "title": "Fork Choice Rule/Strategy", + "anchor": "fork-choice-rulestrategy" }, { "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 23604, - "words": 3333, - "headings": 22, - "estimated_token_count_total": 4705 - }, - "hash": "sha256:6675634d4c5f274a7cc69802ee0a2d259e38efd5afd1c9dacc2d0fecfb370e4c", - "last_modified": "2025-10-28T14:15:59+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "polkadot-protocol-parachain-basics-chain-data", - "title": "Chain Data", - "slug": "polkadot-protocol-parachain-basics-chain-data", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-parachain-basics-chain-data.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/parachain-basics/chain-data/", - "preview": "Understanding and leveraging on-chain data is a fundamental aspect of blockchain development. Whether you're building frontend applications or backend systems, accessing and decoding runtime metadata is vital to interacting with the blockchain. This guide introduces you to the tools and processes for generating and retrieving metadata, explains its role in application development, and outlines the additional APIs available for interacting with a Polkadot node. By mastering these components, you", - "outline": [ + "title": "FRAME (Framework for Runtime Aggregation of Modularized Entities)", + "anchor": "frame-framework-for-runtime-aggregation-of-modularized-entities" + }, { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Full Node", + "anchor": "full-node" }, { "depth": 2, - "title": "Application Development", - "anchor": "application-development" + "title": "Genesis Configuration", + "anchor": "genesis-configuration" }, { "depth": 2, - "title": "Understand Metadata", - "anchor": "understand-metadata" + "title": "GRANDPA", + "anchor": "grandpa" }, { "depth": 2, - "title": "Expose Runtime Information as Metadata", - "anchor": "expose-runtime-information-as-metadata" + "title": "Header", + "anchor": "header" }, { "depth": 2, - "title": "Generate Metadata", - "anchor": "generate-metadata" + "title": "Hybrid Consensus", + "anchor": "hybrid-consensus" }, { "depth": 2, - "title": "Retrieve Runtime Metadata", - "anchor": "retrieve-runtime-metadata" + "title": "Inherent Transactions", + "anchor": "inherent-transactions" }, { - "depth": 3, - "title": "Use Polkadot.js", - "anchor": "use-polkadotjs" + "depth": 2, + "title": "JSON-RPC", + "anchor": "json-rpc" }, { - "depth": 3, - "title": "Use Curl", - "anchor": "use-curl" + "depth": 2, + "title": "Keystore", + "anchor": "keystore" }, { - "depth": 3, - "title": "Use Subxt", - "anchor": "use-subxt" + "depth": 2, + "title": "Kusama", + "anchor": "kusama" }, { "depth": 2, - "title": "Client Applications and Metadata", - "anchor": "client-applications-and-metadata" + "title": "libp2p", + "anchor": "libp2p" }, { "depth": 2, - "title": "Metadata Format", - "anchor": "metadata-format" + "title": "Light Client", + "anchor": "light-client" }, { - "depth": 3, - "title": "Pallets", - "anchor": "pallets" + "depth": 2, + "title": "Metadata", + "anchor": "metadata" }, { - "depth": 3, - "title": "Extrinsic", - "anchor": "extrinsic" + "depth": 2, + "title": "Nominated Proof of Stake (NPoS)", + "anchor": "nominated-proof-of-stake-npos" }, { "depth": 2, - "title": "Included RPC APIs", - "anchor": "included-rpc-apis" + "title": "Oracle", + "anchor": "oracle" }, { "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 18678, - "words": 2220, - "headings": 15, - "estimated_token_count_total": 3782 - }, - "hash": "sha256:eb4da21d561e9fd9333d97805318f0e263f54570120d3852ce7eba64da604cc2", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "polkadot-protocol-parachain-basics-cryptography", - "title": "Cryptography", - "slug": "polkadot-protocol-parachain-basics-cryptography", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-parachain-basics-cryptography.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/parachain-basics/cryptography/", - "preview": "Cryptography forms the backbone of blockchain technology, providing the mathematical verifiability crucial for consensus systems, data integrity, and user security. While a deep understanding of the underlying mathematical processes isn't necessary for most blockchain developers, grasping the fundamental applications of cryptography is essential. This page comprehensively overviews cryptographic implementations used across Polkadot SDK-based chains and the broader blockchain ecosystem.", - "outline": [ + "title": "Origin", + "anchor": "origin" + }, { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Pallet", + "anchor": "pallet" }, { "depth": 2, - "title": "Hash Functions", - "anchor": "hash-functions" + "title": "Parachain", + "anchor": "parachain" }, { - "depth": 3, - "title": "Key Properties of Hash Functions", - "anchor": "key-properties-of-hash-functions" + "depth": 2, + "title": "Paseo", + "anchor": "paseo" }, { - "depth": 3, - "title": "Blake2", - "anchor": "blake2" + "depth": 2, + "title": "Polkadot", + "anchor": "polkadot" }, { "depth": 2, - "title": "Types of Cryptography", - "anchor": "types-of-cryptography" + "title": "Polkadot Cloud", + "anchor": "polkadot-cloud" }, { - "depth": 3, - "title": "Symmetric Cryptography", - "anchor": "symmetric-cryptography" + "depth": 2, + "title": "Polkadot Hub", + "anchor": "polkadot-hub" }, { - "depth": 3, - "title": "Asymmetric Cryptography", - "anchor": "asymmetric-cryptography" + "depth": 2, + "title": "PolkaVM", + "anchor": "polkavm" }, { - "depth": 3, - "title": "Trade-offs and Compromises", - "anchor": "trade-offs-and-compromises" + "depth": 2, + "title": "Relay Chain", + "anchor": "relay-chain" }, { "depth": 2, - "title": "Digital Signatures", - "anchor": "digital-signatures" + "title": "Rococo", + "anchor": "rococo" }, { - "depth": 3, - "title": "Example of Creating a Digital Signature", - "anchor": "example-of-creating-a-digital-signature" + "depth": 2, + "title": "Runtime", + "anchor": "runtime" }, { "depth": 2, - "title": "Elliptic Curve", - "anchor": "elliptic-curve" + "title": "Slot", + "anchor": "slot" }, { - "depth": 3, - "title": "Various Implementations", - "anchor": "various-implementations" - } - ], - "stats": { - "chars": 8860, - "words": 1293, - "headings": 12, - "estimated_token_count_total": 1797 - }, - "hash": "sha256:259dcef86aadc513675258b665cc3940db65af6eb32a5db85da6ac339966fa60", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "polkadot-protocol-parachain-basics-data-encoding", - "title": "Data Encoding", - "slug": "polkadot-protocol-parachain-basics-data-encoding", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-parachain-basics-data-encoding.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/parachain-basics/data-encoding/", - "preview": "The Polkadot SDK uses a lightweight and efficient encoding/decoding mechanism to optimize data transmission across the network. This mechanism, known as the _SCALE_ codec, is used for serializing and deserializing data.", - "outline": [ + "depth": 2, + "title": "Sovereign Account", + "anchor": "sovereign-account" + }, + { + "depth": 2, + "title": "SS58 Address Format", + "anchor": "ss58-address-format" + }, { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "State Transition Function (STF)", + "anchor": "state-transition-function-stf" }, { "depth": 2, - "title": "SCALE Codec", - "anchor": "scale-codec" + "title": "Storage Item", + "anchor": "storage-item" }, { - "depth": 3, - "title": "Encode", - "anchor": "encode" + "depth": 2, + "title": "Substrate", + "anchor": "substrate" }, { - "depth": 3, - "title": "Decode", - "anchor": "decode" + "depth": 2, + "title": "Transaction", + "anchor": "transaction" }, { - "depth": 3, - "title": "CompactAs", - "anchor": "compactas" + "depth": 2, + "title": "Transaction Era", + "anchor": "transaction-era" }, { - "depth": 3, - "title": "HasCompact", - "anchor": "hascompact" + "depth": 2, + "title": "Trie (Patricia Merkle Tree)", + "anchor": "trie-patricia-merkle-tree" }, { - "depth": 3, - "title": "EncodeLike", - "anchor": "encodelike" + "depth": 2, + "title": "Validator", + "anchor": "validator" }, { - "depth": 3, - "title": "Data Types", - "anchor": "data-types" + "depth": 2, + "title": "WebAssembly (Wasm)", + "anchor": "webassembly-wasm" }, { "depth": 2, - "title": "Encode and Decode Rust Trait Implementations", - "anchor": "encode-and-decode-rust-trait-implementations" + "title": "Weight", + "anchor": "weight" }, { "depth": 2, - "title": "SCALE Codec Libraries", - "anchor": "scale-codec-libraries" + "title": "Westend", + "anchor": "westend" } ], "stats": { - "chars": 13629, - "words": 1314, - "headings": 10, - "estimated_token_count_total": 3213 + "chars": 24739, + "words": 3626, + "headings": 63, + "estimated_token_count_total": 5273 }, - "hash": "sha256:e448294b6e52291ac0add5fa6533572814e6cd27af42bdaccc2000b86f52d775", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:40bd67811e7eabc79ca5d105eae388b19380d9f035022da17fc0d6bb173c817c", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-parachain-basics-interoperability", - "title": "Interoperability", - "slug": "polkadot-protocol-parachain-basics-interoperability", + "id": "reference-governance-origins-tracks", + "title": "Origins and Tracks", + "slug": "reference-governance-origins-tracks", "categories": [ - "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-parachain-basics-interoperability.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/parachain-basics/interoperability/", - "preview": "Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance-origins-tracks.md", + "html_url": "https://docs.polkadot.com/reference/governance/origins-tracks/", + "preview": "Polkadot's OpenGov system empowers decentralized decision-making and active community participation by tailoring the governance process to the impact of proposed changes. Through a system of origins and tracks, OpenGov ensures that every referendum receives the appropriate scrutiny, balancing security, inclusivity, and efficiency.", "outline": [ { "depth": 2, @@ -9838,58 +7488,40 @@ }, { "depth": 2, - "title": "Why Interoperability Matters", - "anchor": "why-interoperability-matters" - }, - { - "depth": 2, - "title": "Key Mechanisms for Interoperability", - "anchor": "key-mechanisms-for-interoperability" - }, - { - "depth": 3, - "title": "Cross-Consensus Messaging (XCM): The Backbone of Communication", - "anchor": "cross-consensus-messaging-xcm-the-backbone-of-communication" - }, - { - "depth": 3, - "title": "Bridges: Connecting External Networks", - "anchor": "bridges-connecting-external-networks" + "title": "Origins", + "anchor": "origins" }, { "depth": 2, - "title": "The Polkadot Advantage", - "anchor": "the-polkadot-advantage" + "title": "Tracks", + "anchor": "tracks" }, { "depth": 2, - "title": "Looking Ahead", - "anchor": "looking-ahead" + "title": "Additional Resources", + "anchor": "additional-resources" } ], "stats": { - "chars": 4657, - "words": 588, - "headings": 7, - "estimated_token_count_total": 780 + "chars": 3333, + "words": 469, + "headings": 4, + "estimated_token_count_total": 631 }, - "hash": "sha256:077e7e5bfc9509cf09f455959a5da7a74b7af69836b3c4b334692f32e306ddf1", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:baba9dd41091b792d09005d55d3df0bf65b35f42b40ebe63caf425a0978a22b0", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-parachain-basics-networks", - "title": "Networks", - "slug": "polkadot-protocol-parachain-basics-networks", + "id": "reference-governance", + "title": "On-Chain Governance Overview", + "slug": "reference-governance", "categories": [ "Basics", - "Polkadot Protocol", - "Networks" + "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-parachain-basics-networks.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/parachain-basics/networks/", - "preview": "The Polkadot ecosystem is built on a robust set of networks designed to enable secure and scalable development. Whether you are testing new features or deploying to live production, Polkadot offers several layers of networks tailored for each stage of the development process. From local environments to experimental networks like Kusama and community-run TestNets such as Paseo, developers can thoroughly test, iterate, and validate their applications. This guide will introduce you to Polkadot's va", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance.md", + "html_url": "https://docs.polkadot.com/reference/governance/", + "preview": "Polkadot’s governance system exemplifies decentralized decision-making, empowering its community of stakeholders to shape the network’s future through active participation. The latest evolution, OpenGov, builds on Polkadot’s foundation by providing a more inclusive and efficient governance model.", "outline": [ { "depth": 2, @@ -9898,72 +7530,65 @@ }, { "depth": 2, - "title": "Network Overview", - "anchor": "network-overview" + "title": "Governance Evolution", + "anchor": "governance-evolution" }, { "depth": 2, - "title": "Polkadot Development Networks", - "anchor": "polkadot-development-networks" + "title": "OpenGov Key Features", + "anchor": "opengov-key-features" }, { "depth": 2, - "title": "Kusama Network", - "anchor": "kusama-network" + "title": "Origins and Tracks", + "anchor": "origins-and-tracks" }, { "depth": 2, - "title": "Test Networks", - "anchor": "test-networks" + "title": "Referendums", + "anchor": "referendums" }, { "depth": 3, - "title": "Westend", - "anchor": "westend" + "title": "Vote on Referendums", + "anchor": "vote-on-referendums" }, { "depth": 3, - "title": "Paseo", - "anchor": "paseo" - }, - { - "depth": 2, - "title": "Local Test Networks", - "anchor": "local-test-networks" + "title": "Delegate Voting Power", + "anchor": "delegate-voting-power" }, { "depth": 3, - "title": "Zombienet", - "anchor": "zombienet" + "title": "Cancel a Referendum", + "anchor": "cancel-a-referendum" }, { - "depth": 3, - "title": "Chopsticks", - "anchor": "chopsticks" + "depth": 2, + "title": "Additional Resources", + "anchor": "additional-resources" } ], "stats": { - "chars": 7834, - "words": 1111, - "headings": 10, - "estimated_token_count_total": 1473 + "chars": 7493, + "words": 1019, + "headings": 9, + "estimated_token_count_total": 1611 }, - "hash": "sha256:695c624a1d7a3ed6fea0f4f5c19bb2100be986cec29ba58edb4598b9e9b98494", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:62beec261e72529f70e07a641177d489d2c8872f9c9d618cbadf1ac0fd881986", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-parachain-basics-node-and-runtime", - "title": "Node and Runtime", - "slug": "polkadot-protocol-parachain-basics-node-and-runtime", + "id": "reference-parachains-accounts", + "title": "Polkadot SDK Accounts", + "slug": "reference-parachains-accounts", "categories": [ "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-parachain-basics-node-and-runtime.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/parachain-basics/node-and-runtime/", - "preview": "Every blockchain platform relies on a decentralized network of computers, called nodes, that communicate with each other about transactions and blocks. In this context, a node refers to the software running on the connected devices rather than the physical or virtual machines in the network.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-accounts.md", + "html_url": "https://docs.polkadot.com/reference/parachains/accounts/", + "preview": "Accounts are essential for managing identity, transactions, and governance on the network in the Polkadot SDK. Understanding these components is critical for seamless development and operation on the network, whether you're building or interacting with Polkadot-based chains.", "outline": [ { "depth": 2, @@ -9972,72 +7597,95 @@ }, { "depth": 2, - "title": "Architectural Principles", - "anchor": "architectural-principles" + "title": "Account Data Structure", + "anchor": "account-data-structure" }, { "depth": 3, - "title": "Advantages of this Architecture", - "anchor": "advantages-of-this-architecture" + "title": "Account", + "anchor": "account" }, { - "depth": 2, - "title": "Node (Client)", - "anchor": "node-client" + "depth": 3, + "title": "Account Info", + "anchor": "account-info" + }, + { + "depth": 3, + "title": "Account Reference Counters", + "anchor": "account-reference-counters" }, { "depth": 2, - "title": "Runtime", - "anchor": "runtime" + "title": "Account Balance Types", + "anchor": "account-balance-types" }, { "depth": 3, - "title": "Characteristics", - "anchor": "characteristics" + "title": "Balance Types", + "anchor": "balance-types" }, { "depth": 3, - "title": "Key Functions", - "anchor": "key-functions" + "title": "Locks", + "anchor": "locks" + }, + { + "depth": 3, + "title": "Balance Types on Polkadot.js", + "anchor": "balance-types-on-polkadotjs" }, { "depth": 2, - "title": "Communication Between Node and Runtime", - "anchor": "communication-between-node-and-runtime" + "title": "Address Formats", + "anchor": "address-formats" }, { "depth": 3, - "title": "Runtime APIs", - "anchor": "runtime-apis" + "title": "Basic Format", + "anchor": "basic-format" }, { "depth": 3, - "title": "Host Functions", - "anchor": "host-functions" + "title": "Address Type", + "anchor": "address-type" + }, + { + "depth": 3, + "title": "Address Length", + "anchor": "address-length" + }, + { + "depth": 3, + "title": "Checksum Types", + "anchor": "checksum-types" + }, + { + "depth": 3, + "title": "Validating Addresses", + "anchor": "validating-addresses" } ], "stats": { - "chars": 4937, - "words": 628, - "headings": 10, - "estimated_token_count_total": 914 + "chars": 29604, + "words": 4194, + "headings": 15, + "estimated_token_count_total": 6507 }, - "hash": "sha256:8122e21c149d0863cfe3b37fc5606bcdb91668e9d265f0f05451a61ff70e4e93", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:0104a9132a69345a2faac37fca0e2853a2ded1efb009511a83a98d44509ab887", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-parachain-basics-randomness", - "title": "Randomness", - "slug": "polkadot-protocol-parachain-basics-randomness", + "id": "reference-parachains-blocks-transactions-fees-blocks", + "title": "Blocks", + "slug": "reference-parachains-blocks-transactions-fees-blocks", "categories": [ "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-parachain-basics-randomness.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/parachain-basics/randomness/", - "preview": "Randomness is crucial in Proof of Stake (PoS) blockchains to ensure a fair and unpredictable distribution of validator duties. However, computers are inherently deterministic, meaning the same input always produces the same output. What we typically refer to as \"random\" numbers on a computer are actually pseudo-random. These numbers rely on an initial \"seed,\" which can come from external sources like [atmospheric noise](https://www.random.org/randomness/){target=\\_blank}, [heart rates](https://m", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-blocks.md", + "html_url": "https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/blocks/", + "preview": "In the Polkadot SDK, blocks are fundamental to the functioning of the blockchain, serving as containers for [transactions](/reference/parachains/blocks-transactions-fees/transactions/){target=\\_blank} and changes to the chain's state. Blocks consist of headers and an array of transactions, ensuring the integrity and validity of operations on the network. This guide explores the essential components of a block, the process of block production, and how blocks are validated and imported across the", "outline": [ { "depth": 2, @@ -10046,23 +7694,33 @@ }, { "depth": 2, - "title": "VRF", - "anchor": "vrf" + "title": "What is a Block?", + "anchor": "what-is-a-block" + }, + { + "depth": 2, + "title": "Block Production", + "anchor": "block-production" }, { "depth": 3, - "title": "How VRF Works", - "anchor": "how-vrf-works" + "title": "Initialize Block", + "anchor": "initialize-block" }, { - "depth": 2, - "title": "RANDAO", - "anchor": "randao" + "depth": 3, + "title": "Finalize Block", + "anchor": "finalize-block" }, { "depth": 2, - "title": "VDFs", - "anchor": "vdfs" + "title": "Block Authoring and Import", + "anchor": "block-authoring-and-import" + }, + { + "depth": 3, + "title": "Block Import Queue", + "anchor": "block-import-queue" }, { "depth": 2, @@ -10071,160 +7729,122 @@ } ], "stats": { - "chars": 6541, - "words": 1008, - "headings": 6, - "estimated_token_count_total": 1394 + "chars": 6252, + "words": 910, + "headings": 8, + "estimated_token_count_total": 1395 }, - "hash": "sha256:217a79109aff1607594a0238fd91bfa812827620887c4f063c7e0a7a37f967d6", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:424783c102bea5dae5b8749635858c6c59055563442a98f57521f0027dafa8d3", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-smart-contract-basics-accounts", - "title": "Accounts in Asset Hub Smart Contracts", - "slug": "polkadot-protocol-smart-contract-basics-accounts", + "id": "reference-parachains-blocks-transactions-fees-fees", + "title": "Transactions Weights and Fees", + "slug": "reference-parachains-blocks-transactions-fees-fees", "categories": [ "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-smart-contract-basics-accounts.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/smart-contract-basics/accounts/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-fees.md", + "html_url": "https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/fees/", + "preview": "When transactions are executed, or data is stored on-chain, the activity changes the chain's state and consumes blockchain resources. Because the resources available to a blockchain are limited, managing how operations on-chain consume them is important. In addition to being limited in practical terms, such as storage capacity, blockchain resources represent a potential attack vector for malicious users. For example, a malicious user might attempt to overload the network with messages to stop th", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Introductions", + "anchor": "introductions" }, { "depth": 2, - "title": "Address Types and Mappings", - "anchor": "address-types-and-mappings" + "title": "How Fees are Calculated", + "anchor": "how-fees-are-calculated" }, { - "depth": 3, - "title": "Ethereum to Polkadot Mapping", - "anchor": "ethereum-to-polkadot-mapping" + "depth": 2, + "title": "Using the Transaction Payment Pallet", + "anchor": "using-the-transaction-payment-pallet" }, { "depth": 3, - "title": "Polkadot to Ethereum Mapping", - "anchor": "polkadot-to-ethereum-mapping" + "title": "Understanding the Inclusion Fee", + "anchor": "understanding-the-inclusion-fee" }, { "depth": 3, - "title": "Account Mapping for Native Polkadot Accounts", - "anchor": "account-mapping-for-native-polkadot-accounts" - }, - { - "depth": 2, - "title": "Account Registration", - "anchor": "account-registration" + "title": "Accounts with an Insufficient Balance", + "anchor": "accounts-with-an-insufficient-balance" }, { - "depth": 2, - "title": "Fallback Accounts", - "anchor": "fallback-accounts" + "depth": 3, + "title": "Fee Multipliers", + "anchor": "fee-multipliers" }, { "depth": 2, - "title": "Contract Address Generation", - "anchor": "contract-address-generation" + "title": "Transactions with Special Requirements", + "anchor": "transactions-with-special-requirements" }, { "depth": 2, - "title": "Security Considerations", - "anchor": "security-considerations" - } - ], - "stats": { - "chars": 8538, - "words": 1141, - "headings": 9, - "estimated_token_count_total": 1822 - }, - "hash": "sha256:db2b1806153242680043ced536f64fc8a2ed3c09adc1bec5aa287168b48e0994", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "polkadot-protocol-smart-contract-basics-blocks-transactions-fees", - "title": "Transactions and Fees on Asset Hub", - "slug": "polkadot-protocol-smart-contract-basics-blocks-transactions-fees", - "categories": [ - "Basics", - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-smart-contract-basics-blocks-transactions-fees.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/smart-contract-basics/blocks-transactions-fees/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", - "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Default Weight Annotations", + "anchor": "default-weight-annotations" }, { - "depth": 2, - "title": "Smart Contract Blocks", - "anchor": "smart-contract-blocks" + "depth": 3, + "title": "Weights and Database Read/Write Operations", + "anchor": "weights-and-database-readwrite-operations" }, { - "depth": 2, - "title": "Smart Contract Transactions", - "anchor": "smart-contract-transactions" + "depth": 3, + "title": "Dispatch Classes", + "anchor": "dispatch-classes" }, { "depth": 3, - "title": "EVM Transaction Types", - "anchor": "evm-transaction-types" + "title": "Dynamic Weights", + "anchor": "dynamic-weights" }, { "depth": 2, - "title": "Fees and Gas", - "anchor": "fees-and-gas" + "title": "Post Dispatch Weight Correction", + "anchor": "post-dispatch-weight-correction" }, { - "depth": 3, - "title": "Gas Model Overview", - "anchor": "gas-model-overview" + "depth": 2, + "title": "Custom Fees", + "anchor": "custom-fees" }, { "depth": 3, - "title": "Fee Components", - "anchor": "fee-components" + "title": "Custom Weights", + "anchor": "custom-weights" }, { - "depth": 3, - "title": "Gas Calculation and Conversion", - "anchor": "gas-calculation-and-conversion" + "depth": 2, + "title": "Additional Resources", + "anchor": "additional-resources" } ], "stats": { - "chars": 6361, - "words": 789, - "headings": 8, - "estimated_token_count_total": 1178 + "chars": 20800, + "words": 2917, + "headings": 15, + "estimated_token_count_total": 4464 }, - "hash": "sha256:9a6b3fa6c005d75c25f0f683b7d8c3b65891454743b794c12b005f910b81609c", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:7d0c3fa7982b3e1843adb8f27422456397580b3a3eba5047b381da8517742536", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-smart-contract-basics-evm-vs-polkavm", - "title": "EVM vs PolkaVM", - "slug": "polkadot-protocol-smart-contract-basics-evm-vs-polkavm", + "id": "reference-parachains-blocks-transactions-fees-transactions", + "title": "Transactions", + "slug": "reference-parachains-blocks-transactions-fees-transactions", "categories": [ "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-smart-contract-basics-evm-vs-polkavm.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/smart-contract-basics/evm-vs-polkavm/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-transactions.md", + "html_url": "https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/transactions/", + "preview": "Transactions are essential components of blockchain networks, enabling state changes and the execution of key operations. In the Polkadot SDK, transactions, often called extrinsics, come in multiple forms, including signed, unsigned, and inherent transactions.", "outline": [ { "depth": 2, @@ -10233,179 +7853,246 @@ }, { "depth": 2, - "title": "Core Virtual Machine Architecture", - "anchor": "core-virtual-machine-architecture" + "title": "What Is a Transaction?", + "anchor": "what-is-a-transaction" }, { "depth": 3, - "title": "High-Level Architecture Comparison", - "anchor": "high-level-architecture-comparison" + "title": "Signed Transactions", + "anchor": "signed-transactions" }, { - "depth": 2, - "title": "Gas Model", - "anchor": "gas-model" + "depth": 3, + "title": "Unsigned Transactions", + "anchor": "unsigned-transactions" }, { "depth": 3, - "title": "Dynamic Gas Value Scaling", - "anchor": "dynamic-gas-value-scaling" + "title": "Inherent Transactions", + "anchor": "inherent-transactions" + }, + { + "depth": 2, + "title": "Transaction Formats", + "anchor": "transaction-formats" }, { "depth": 3, - "title": "Multi-Dimensional Resource Metering", - "anchor": "multi-dimensional-resource-metering" + "title": "Types of Transaction Formats", + "anchor": "types-of-transaction-formats" }, { - "depth": 2, - "title": "Memory Management", - "anchor": "memory-management" + "depth": 3, + "title": "Signed Transaction Data Structure", + "anchor": "signed-transaction-data-structure" }, { "depth": 3, - "title": "Current Memory Limits", - "anchor": "current-memory-limits" + "title": "Signed Extensions", + "anchor": "signed-extensions" }, { "depth": 2, - "title": "Account Management - Existential Deposit", - "anchor": "account-management-existential-deposit" + "title": "Transaction Construction", + "anchor": "transaction-construction" }, { "depth": 3, - "title": "Account Management Comparison", - "anchor": "account-management-comparison" + "title": "Construct a Signed Transaction", + "anchor": "construct-a-signed-transaction" }, { - "depth": 2, - "title": "Contract Deployment", - "anchor": "contract-deployment" + "depth": 3, + "title": "Transaction Encoding", + "anchor": "transaction-encoding" + }, + { + "depth": 3, + "title": "Customize Transaction Construction", + "anchor": "customize-transaction-construction" }, { "depth": 2, - "title": "Solidity and YUL IR Translation Incompatibilities", - "anchor": "solidity-and-yul-ir-translation-incompatibilities" + "title": "Lifecycle of a Transaction", + "anchor": "lifecycle-of-a-transaction" }, { "depth": 3, - "title": "Contract Code Structure", - "anchor": "contract-code-structure" + "title": "Define Transaction Properties", + "anchor": "define-transaction-properties" }, { "depth": 3, - "title": "Solidity-Specific Differences", - "anchor": "solidity-specific-differences" + "title": "Process on a Block Authoring Node", + "anchor": "process-on-a-block-authoring-node" }, { "depth": 3, - "title": "YUL Function Translation Differences", - "anchor": "yul-function-translation-differences" + "title": "Validate and Queue", + "anchor": "validate-and-queue" }, { "depth": 3, - "title": "Unsupported Operations", - "anchor": "unsupported-operations" + "title": "Transaction Ordering and Priority", + "anchor": "transaction-ordering-and-priority" }, { "depth": 3, - "title": "Compilation Pipeline Considerations", - "anchor": "compilation-pipeline-considerations" + "title": "Transaction Execution", + "anchor": "transaction-execution" }, { - "depth": 3, - "title": "Memory Pointer Limitations", - "anchor": "memory-pointer-limitations" + "depth": 2, + "title": "Transaction Mortality", + "anchor": "transaction-mortality" + }, + { + "depth": 2, + "title": "Unique Identifiers for Extrinsics", + "anchor": "unique-identifiers-for-extrinsics" + }, + { + "depth": 2, + "title": "Additional Resources", + "anchor": "additional-resources" } ], "stats": { - "chars": 27673, - "words": 3392, - "headings": 18, - "estimated_token_count_total": 5305 + "chars": 23610, + "words": 3333, + "headings": 22, + "estimated_token_count_total": 4708 }, - "hash": "sha256:fe651be49fe0a9ae899b2cbf9c663325f407718dc63f1d2c6a2dc4931be751fa", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:66726634d3a51cd9c471621054a6e5f09c8061dca6144b64c8bcf45626359617", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-smart-contract-basics-networks", - "title": "Networks for Polkadot Hub Smart Contracts", - "slug": "polkadot-protocol-smart-contract-basics-networks", + "id": "reference-parachains-chain-data", + "title": "Chain Data", + "slug": "reference-parachains-chain-data", "categories": [ "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-smart-contract-basics-networks.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/smart-contract-basics/networks/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-chain-data.md", + "html_url": "https://docs.polkadot.com/reference/parachains/chain-data/", + "preview": "Understanding and leveraging on-chain data is a fundamental aspect of blockchain development. Whether you're building frontend applications or backend systems, accessing and decoding runtime metadata is vital to interacting with the blockchain. This guide introduces you to the tools and processes for generating and retrieving metadata, explains its role in application development, and outlines the additional APIs available for interacting with a Polkadot node. By mastering these components, you", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Introduction", + "anchor": "introduction" + }, + { + "depth": 2, + "title": "Application Development", + "anchor": "application-development" + }, + { + "depth": 2, + "title": "Understand Metadata", + "anchor": "understand-metadata" }, { "depth": 2, - "title": "Network Overview", - "anchor": "network-overview" + "title": "Expose Runtime Information as Metadata", + "anchor": "expose-runtime-information-as-metadata" }, { "depth": 2, - "title": "Local Development", - "anchor": "local-development" + "title": "Generate Metadata", + "anchor": "generate-metadata" }, { "depth": 2, - "title": "Test Networks", - "anchor": "test-networks" + "title": "Retrieve Runtime Metadata", + "anchor": "retrieve-runtime-metadata" }, { "depth": 3, - "title": "Passet Hub", - "anchor": "passet-hub" + "title": "Use Polkadot.js", + "anchor": "use-polkadotjs" }, { "depth": 3, - "title": "Westend Hub", - "anchor": "westend-hub" + "title": "Use Curl", + "anchor": "use-curl" + }, + { + "depth": 3, + "title": "Use Subxt", + "anchor": "use-subxt" }, { "depth": 2, - "title": "Production Networks", - "anchor": "production-networks" + "title": "Client Applications and Metadata", + "anchor": "client-applications-and-metadata" + }, + { + "depth": 2, + "title": "Metadata Format", + "anchor": "metadata-format" }, { "depth": 3, - "title": "Polkadot Hub", - "anchor": "polkadot-hub" + "title": "Pallets", + "anchor": "pallets" }, { "depth": 3, - "title": "Kusama Hub", - "anchor": "kusama-hub" + "title": "Extrinsic", + "anchor": "extrinsic" + }, + { + "depth": 2, + "title": "Included RPC APIs", + "anchor": "included-rpc-apis" + }, + { + "depth": 2, + "title": "Additional Resources", + "anchor": "additional-resources" } ], "stats": { - "chars": 5108, - "words": 696, - "headings": 9, - "estimated_token_count_total": 891 + "chars": 18650, + "words": 2216, + "headings": 15, + "estimated_token_count_total": 3774 }, - "hash": "sha256:b5acdc9acf0e44836b8a4518155eba7d16cc3b103c557a00970ffb1c44c3e9f6", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:49238d1e9e2c33e0fcd3a84b5e30f0d3840d7d23a783b538875e0a23f38efc1d", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol-smart-contract-basics-overview", - "title": "Smart Contracts Basics Overview", - "slug": "polkadot-protocol-smart-contract-basics-overview", + "id": "reference-parachains-consensus-async-backing", + "title": "reference-parachains-consensus-async-backing", + "slug": "reference-parachains-consensus-async-backing", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus-async-backing.md", + "html_url": "https://docs.polkadot.com/reference/parachains/consensus/async-backing/", + "preview": "TODO", + "outline": [], + "stats": { + "chars": 5, + "words": 1, + "headings": 0, + "estimated_token_count_total": 0 + }, + "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-parachains-consensus-elastic-scaling", + "title": "Elastic Scaling", + "slug": "reference-parachains-consensus-elastic-scaling", "categories": [ - "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-smart-contract-basics-overview.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/smart-contract-basics/overview/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus-elastic-scaling.md", + "html_url": "https://docs.polkadot.com/reference/parachains/consensus/elastic-scaling/", + "preview": "Polkadot's architecture delivers scalability and security through its shared security model, where the relay chain coordinates and validates multiple parallel chains.", "outline": [ { "depth": 2, @@ -10414,354 +8101,384 @@ }, { "depth": 2, - "title": "Smart Contracts Versus Parachains", - "anchor": "smart-contracts-versus-parachains" + "title": "How Elastic Scaling Works", + "anchor": "how-elastic-scaling-works" }, { "depth": 2, - "title": "Building a Smart Contract", - "anchor": "building-a-smart-contract" + "title": "Benefits of Elastic Scaling", + "anchor": "benefits-of-elastic-scaling" }, { - "depth": 3, - "title": "PolkaVM Contracts", - "anchor": "polkavm-contracts" + "depth": 2, + "title": "Use Cases", + "anchor": "use-cases" }, { "depth": 3, - "title": "EVM Contracts", - "anchor": "evm-contracts" + "title": "Handling Sudden Traffic Spikes", + "anchor": "handling-sudden-traffic-spikes" }, { "depth": 3, - "title": "Wasm Contracts", - "anchor": "wasm-contracts" - } - ], - "stats": { - "chars": 10854, - "words": 1559, - "headings": 6, - "estimated_token_count_total": 2550 - }, - "hash": "sha256:e2cf14bcb483308f73a80c8e8871ce1a86fa694576d2e6e51beafc24488f4d58", - "last_modified": "2025-10-28T14:42:15+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "polkadot-protocol-smart-contract-basics", - "title": "Smart Contract Basics", - "slug": "polkadot-protocol-smart-contract-basics", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol-smart-contract-basics.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/smart-contract-basics/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. Gain a deep understanding of smart contracts on Polkadot, from execution environments to transaction mechanics.", - "outline": [ + "title": "Supporting Early-Stage Growth", + "anchor": "supporting-early-stage-growth" + }, { - "depth": 2, - "title": "Key Topics", - "anchor": "key-topics" + "depth": 3, + "title": "Scaling Massive IoT Networks", + "anchor": "scaling-massive-iot-networks" }, { - "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" + "depth": 3, + "title": "Powering Real-Time, Low-Latency Systems", + "anchor": "powering-real-time-low-latency-systems" } ], "stats": { - "chars": 1110, - "words": 136, - "headings": 2, - "estimated_token_count_total": 148 + "chars": 7871, + "words": 1047, + "headings": 8, + "estimated_token_count_total": 1440 }, - "hash": "sha256:e8dac01e89b7aac4b887e962e91084c253f5ea25c1abc3a56355390d0c3201c8", + "hash": "sha256:2d228c52844df8952520fafdd3e6f0e26bfd2f32b5ee60c6241cf7d38603643c", "token_estimator": "heuristic-v1" }, { - "id": "polkadot-protocol", - "title": "Learn About the Polkadot Protocol", - "slug": "polkadot-protocol", + "id": "reference-parachains-consensus", + "title": "reference-parachains-consensus", + "slug": "reference-parachains-consensus", "categories": [ "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/polkadot-protocol.md", - "html_url": "https://docs.polkadot.com/polkadot-protocol/", - "preview": "The Polkadot protocol is designed to enable scalable, secure, and interoperable networks. It introduces a unique multichain architecture that allows independent blockchains, known as parachains, to operate seamlessly while benefiting from the shared security of the relay chain. Polkadot’s decentralized governance ensures that network upgrades and decisions are community-driven, while its cross-chain messaging and interoperability features make it a hub for multichain applications.", - "outline": [ - { - "depth": 2, - "title": "In This Section", - "anchor": "in-this-section" - } - ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus.md", + "html_url": "https://docs.polkadot.com/reference/parachains/consensus/", + "preview": "TODO", + "outline": [], "stats": { - "chars": 1170, - "words": 150, - "headings": 1, - "estimated_token_count_total": 12 + "chars": 5, + "words": 1, + "headings": 0, + "estimated_token_count_total": 0 }, - "hash": "sha256:6992c9a2d1b315b64d9782880105cf2d436750249a84577aceb95cc213863009", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", "token_estimator": "heuristic-v1" }, { - "id": "reference-glossary", - "title": "Glossary", - "slug": "reference-glossary", + "id": "reference-parachains-cryptography", + "title": "Cryptography", + "slug": "reference-parachains-cryptography", "categories": [ - "Reference" + "Basics", + "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-glossary.md", - "html_url": "https://docs.polkadot.com/reference/glossary/", - "preview": "Key definitions, concepts, and terminology specific to the Polkadot ecosystem are included here.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-cryptography.md", + "html_url": "https://docs.polkadot.com/reference/parachains/cryptography/", + "preview": "Cryptography forms the backbone of blockchain technology, providing the mathematical verifiability crucial for consensus systems, data integrity, and user security. While a deep understanding of the underlying mathematical processes isn't necessary for most blockchain developers, grasping the fundamental applications of cryptography is essential. This page comprehensively overviews cryptographic implementations used across Polkadot SDK-based chains and the broader blockchain ecosystem.", "outline": [ { "depth": 2, - "title": "Authority", - "anchor": "authority" - }, - { - "depth": 2, - "title": "Authority Round (Aura)", - "anchor": "authority-round-aura" - }, - { - "depth": 2, - "title": "Blind Assignment of Blockchain Extension (BABE)", - "anchor": "blind-assignment-of-blockchain-extension-babe" - }, - { - "depth": 2, - "title": "Block Author", - "anchor": "block-author" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Byzantine Fault Tolerance (BFT)", - "anchor": "byzantine-fault-tolerance-bft" - }, - { - "depth": 3, - "title": "Byzantine Failure", - "anchor": "byzantine-failure" + "title": "Hash Functions", + "anchor": "hash-functions" }, { "depth": 3, - "title": "Practical Byzantine Fault Tolerance (pBFT)", - "anchor": "practical-byzantine-fault-tolerance-pbft" + "title": "Key Properties of Hash Functions", + "anchor": "key-properties-of-hash-functions" }, { "depth": 3, - "title": "Preimage", - "anchor": "preimage" - }, - { - "depth": 2, - "title": "Call", - "anchor": "call" - }, - { - "depth": 2, - "title": "Chain Specification", - "anchor": "chain-specification" - }, - { - "depth": 2, - "title": "Collator", - "anchor": "collator" + "title": "Blake2", + "anchor": "blake2" }, { "depth": 2, - "title": "Collective", - "anchor": "collective" + "title": "Types of Cryptography", + "anchor": "types-of-cryptography" }, { - "depth": 2, - "title": "Consensus", - "anchor": "consensus" + "depth": 3, + "title": "Symmetric Cryptography", + "anchor": "symmetric-cryptography" }, { - "depth": 2, - "title": "Consensus Algorithm", - "anchor": "consensus-algorithm" + "depth": 3, + "title": "Asymmetric Cryptography", + "anchor": "asymmetric-cryptography" }, { - "depth": 2, - "title": "Consensus Engine", - "anchor": "consensus-engine" + "depth": 3, + "title": "Trade-offs and Compromises", + "anchor": "trade-offs-and-compromises" }, { "depth": 2, - "title": "Coretime", - "anchor": "coretime" + "title": "Digital Signatures", + "anchor": "digital-signatures" }, { - "depth": 2, - "title": "Development Phrase", - "anchor": "development-phrase" + "depth": 3, + "title": "Example of Creating a Digital Signature", + "anchor": "example-of-creating-a-digital-signature" }, { "depth": 2, - "title": "Digest", - "anchor": "digest" + "title": "Elliptic Curve", + "anchor": "elliptic-curve" }, { - "depth": 2, - "title": "Dispatchable", - "anchor": "dispatchable" - }, + "depth": 3, + "title": "Various Implementations", + "anchor": "various-implementations" + } + ], + "stats": { + "chars": 8860, + "words": 1293, + "headings": 12, + "estimated_token_count_total": 1797 + }, + "hash": "sha256:259dcef86aadc513675258b665cc3940db65af6eb32a5db85da6ac339966fa60", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-parachains-data-encoding", + "title": "Data Encoding", + "slug": "reference-parachains-data-encoding", + "categories": [ + "Basics", + "Polkadot Protocol" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-data-encoding.md", + "html_url": "https://docs.polkadot.com/reference/parachains/data-encoding/", + "preview": "The Polkadot SDK uses a lightweight and efficient encoding/decoding mechanism to optimize data transmission across the network. This mechanism, known as the _SCALE_ codec, is used for serializing and deserializing data.", + "outline": [ { "depth": 2, - "title": "Events", - "anchor": "events" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Executor", - "anchor": "executor" + "title": "SCALE Codec", + "anchor": "scale-codec" }, { - "depth": 2, - "title": "Existential Deposit", - "anchor": "existential-deposit" + "depth": 3, + "title": "Encode", + "anchor": "encode" }, { - "depth": 2, - "title": "Extrinsic", - "anchor": "extrinsic" + "depth": 3, + "title": "Decode", + "anchor": "decode" }, { - "depth": 2, - "title": "Fork Choice Rule/Strategy", - "anchor": "fork-choice-rulestrategy" + "depth": 3, + "title": "CompactAs", + "anchor": "compactas" }, { - "depth": 2, - "title": "FRAME (Framework for Runtime Aggregation of Modularized Entities)", - "anchor": "frame-framework-for-runtime-aggregation-of-modularized-entities" + "depth": 3, + "title": "HasCompact", + "anchor": "hascompact" }, { - "depth": 2, - "title": "Full Node", - "anchor": "full-node" + "depth": 3, + "title": "EncodeLike", + "anchor": "encodelike" }, { - "depth": 2, - "title": "Genesis Configuration", - "anchor": "genesis-configuration" + "depth": 3, + "title": "Data Types", + "anchor": "data-types" }, { "depth": 2, - "title": "GRANDPA", - "anchor": "grandpa" + "title": "Encode and Decode Rust Trait Implementations", + "anchor": "encode-and-decode-rust-trait-implementations" }, { "depth": 2, - "title": "Header", - "anchor": "header" - }, + "title": "SCALE Codec Libraries", + "anchor": "scale-codec-libraries" + } + ], + "stats": { + "chars": 13629, + "words": 1314, + "headings": 10, + "estimated_token_count_total": 3213 + }, + "hash": "sha256:e448294b6e52291ac0add5fa6533572814e6cd27af42bdaccc2000b86f52d775", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-parachains-interoperability", + "title": "Interoperability", + "slug": "reference-parachains-interoperability", + "categories": [ + "Basics", + "Polkadot Protocol" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md", + "html_url": "https://docs.polkadot.com/reference/parachains/interoperability/", + "preview": "Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions.", + "outline": [ { "depth": 2, - "title": "Hybrid Consensus", - "anchor": "hybrid-consensus" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Inherent Transactions", - "anchor": "inherent-transactions" + "title": "Why Interoperability Matters", + "anchor": "why-interoperability-matters" }, { "depth": 2, - "title": "JSON-RPC", - "anchor": "json-rpc" + "title": "Key Mechanisms for Interoperability", + "anchor": "key-mechanisms-for-interoperability" }, { - "depth": 2, - "title": "Keystore", - "anchor": "keystore" + "depth": 3, + "title": "Cross-Consensus Messaging (XCM): The Backbone of Communication", + "anchor": "cross-consensus-messaging-xcm-the-backbone-of-communication" }, { - "depth": 2, - "title": "Kusama", - "anchor": "kusama" + "depth": 3, + "title": "Bridges: Connecting External Networks", + "anchor": "bridges-connecting-external-networks" }, { "depth": 2, - "title": "libp2p", - "anchor": "libp2p" + "title": "The Polkadot Advantage", + "anchor": "the-polkadot-advantage" }, { "depth": 2, - "title": "Light Client", - "anchor": "light-client" - }, + "title": "Looking Ahead", + "anchor": "looking-ahead" + } + ], + "stats": { + "chars": 4635, + "words": 584, + "headings": 7, + "estimated_token_count_total": 772 + }, + "hash": "sha256:11bb4f113bdda5852a3115e64d5ba47f8eccd4e3619a05ad960ab3a541f31346", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-parachains-networks", + "title": "Networks", + "slug": "reference-parachains-networks", + "categories": [ + "Basics", + "Polkadot Protocol", + "Networks" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md", + "html_url": "https://docs.polkadot.com/reference/parachains/networks/", + "preview": "The Polkadot ecosystem is built on a robust set of networks designed to enable secure and scalable development. Whether you are testing new features or deploying to live production, Polkadot offers several layers of networks tailored for each stage of the development process. From local environments to experimental networks like Kusama and community-run TestNets such as Paseo, developers can thoroughly test, iterate, and validate their applications. This guide will introduce you to Polkadot's va", + "outline": [ { "depth": 2, - "title": "Metadata", - "anchor": "metadata" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Nominated Proof of Stake (NPoS)", - "anchor": "nominated-proof-of-stake-npos" + "title": "Network Overview", + "anchor": "network-overview" }, { "depth": 2, - "title": "Oracle", - "anchor": "oracle" + "title": "Polkadot Development Networks", + "anchor": "polkadot-development-networks" }, { "depth": 2, - "title": "Origin", - "anchor": "origin" + "title": "Kusama Network", + "anchor": "kusama-network" }, { "depth": 2, - "title": "Pallet", - "anchor": "pallet" + "title": "Test Networks", + "anchor": "test-networks" }, { - "depth": 2, - "title": "Parachain", - "anchor": "parachain" + "depth": 3, + "title": "Westend", + "anchor": "westend" }, { - "depth": 2, + "depth": 3, "title": "Paseo", "anchor": "paseo" }, { "depth": 2, - "title": "Polkadot", - "anchor": "polkadot" + "title": "Local Test Networks", + "anchor": "local-test-networks" }, { - "depth": 2, - "title": "Polkadot Cloud", - "anchor": "polkadot-cloud" + "depth": 3, + "title": "Zombienet", + "anchor": "zombienet" }, + { + "depth": 3, + "title": "Chopsticks", + "anchor": "chopsticks" + } + ], + "stats": { + "chars": 7834, + "words": 1111, + "headings": 10, + "estimated_token_count_total": 1473 + }, + "hash": "sha256:e49e063a2cc0fb5a48c6cdc3de266bb6e025a006940fea8e90cc4d5f9884900f", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-parachains-node-and-runtime", + "title": "Node and Runtime", + "slug": "reference-parachains-node-and-runtime", + "categories": [ + "Basics", + "Polkadot Protocol" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-node-and-runtime.md", + "html_url": "https://docs.polkadot.com/reference/parachains/node-and-runtime/", + "preview": "Every blockchain platform relies on a decentralized network of computers, called nodes, that communicate with each other about transactions and blocks. In this context, a node refers to the software running on the connected devices rather than the physical or virtual machines in the network.", + "outline": [ { "depth": 2, - "title": "Polkadot Hub", - "anchor": "polkadot-hub" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "PolkaVM", - "anchor": "polkavm" + "title": "Architectural Principles", + "anchor": "architectural-principles" }, { - "depth": 2, - "title": "Relay Chain", - "anchor": "relay-chain" + "depth": 3, + "title": "Advantages of this Architecture", + "anchor": "advantages-of-this-architecture" }, { "depth": 2, - "title": "Rococo", - "anchor": "rococo" + "title": "Node (Client)", + "anchor": "node-client" }, { "depth": 2, @@ -10769,91 +8486,103 @@ "anchor": "runtime" }, { - "depth": 2, - "title": "Slot", - "anchor": "slot" - }, - { - "depth": 2, - "title": "Sovereign Account", - "anchor": "sovereign-account" - }, - { - "depth": 2, - "title": "SS58 Address Format", - "anchor": "ss58-address-format" + "depth": 3, + "title": "Characteristics", + "anchor": "characteristics" }, { - "depth": 2, - "title": "State Transition Function (STF)", - "anchor": "state-transition-function-stf" + "depth": 3, + "title": "Key Functions", + "anchor": "key-functions" }, { "depth": 2, - "title": "Storage Item", - "anchor": "storage-item" + "title": "Communication Between Node and Runtime", + "anchor": "communication-between-node-and-runtime" }, { - "depth": 2, - "title": "Substrate", - "anchor": "substrate" + "depth": 3, + "title": "Runtime APIs", + "anchor": "runtime-apis" }, { - "depth": 2, - "title": "Transaction", - "anchor": "transaction" - }, + "depth": 3, + "title": "Host Functions", + "anchor": "host-functions" + } + ], + "stats": { + "chars": 4937, + "words": 628, + "headings": 10, + "estimated_token_count_total": 914 + }, + "hash": "sha256:8122e21c149d0863cfe3b37fc5606bcdb91668e9d265f0f05451a61ff70e4e93", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-parachains-randomness", + "title": "Randomness", + "slug": "reference-parachains-randomness", + "categories": [ + "Basics", + "Polkadot Protocol" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-randomness.md", + "html_url": "https://docs.polkadot.com/reference/parachains/randomness/", + "preview": "Randomness is crucial in Proof of Stake (PoS) blockchains to ensure a fair and unpredictable distribution of validator duties. However, computers are inherently deterministic, meaning the same input always produces the same output. What we typically refer to as \"random\" numbers on a computer are actually pseudo-random. These numbers rely on an initial \"seed,\" which can come from external sources like [atmospheric noise](https://www.random.org/randomness/){target=\\_blank}, [heart rates](https://m", + "outline": [ { "depth": 2, - "title": "Transaction Era", - "anchor": "transaction-era" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Trie (Patricia Merkle Tree)", - "anchor": "trie-patricia-merkle-tree" + "title": "VRF", + "anchor": "vrf" }, { - "depth": 2, - "title": "Validator", - "anchor": "validator" + "depth": 3, + "title": "How VRF Works", + "anchor": "how-vrf-works" }, { "depth": 2, - "title": "WebAssembly (Wasm)", - "anchor": "webassembly-wasm" + "title": "RANDAO", + "anchor": "randao" }, { "depth": 2, - "title": "Weight", - "anchor": "weight" + "title": "VDFs", + "anchor": "vdfs" }, { "depth": 2, - "title": "Westend", - "anchor": "westend" + "title": "Additional Resources", + "anchor": "additional-resources" } ], "stats": { - "chars": 24739, - "words": 3626, - "headings": 63, - "estimated_token_count_total": 5273 + "chars": 6503, + "words": 1005, + "headings": 6, + "estimated_token_count_total": 1388 }, - "hash": "sha256:40bd67811e7eabc79ca5d105eae388b19380d9f035022da17fc0d6bb173c817c", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:c7d8a5a4263fd21af458ab0bd102377104affdf2431b4fe74eeff4ebe62a4a81", "token_estimator": "heuristic-v1" }, { - "id": "reference-governance-origins-tracks", - "title": "Origins and Tracks", - "slug": "reference-governance-origins-tracks", + "id": "reference-parachains", + "title": "Parachains Overview", + "slug": "reference-parachains", "categories": [ - "Polkadot Protocol" + "Basics", + "Parachains" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-governance-origins-tracks.md", - "html_url": "https://docs.polkadot.com/reference/governance/origins-tracks/", - "preview": "Polkadot's OpenGov system empowers decentralized decision-making and active community participation by tailoring the governance process to the impact of proposed changes. Through a system of origins and tracks, OpenGov ensures that every referendum receives the appropriate scrutiny, balancing security, inclusivity, and efficiency.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains.md", + "html_url": "https://docs.polkadot.com/reference/parachains/", + "preview": "A parachain is a specialized blockchain that connects to the Polkadot relay chain, benefiting from shared security, interoperability, and scalability. Parachains are built using the [Polkadot SDK](https://github.com/paritytech/polkadot-sdk){target=\\_blank}, a powerful toolkit written in Rust that provides everything needed to create custom blockchain logic while integrating seamlessly with the Polkadot network.", "outline": [ { "depth": 2, @@ -10862,41 +8591,49 @@ }, { "depth": 2, - "title": "Origins", - "anchor": "origins" + "title": "Polkadot SDK: Parachain Architecture", + "anchor": "polkadot-sdk-parachain-architecture" }, { - "depth": 2, - "title": "Tracks", - "anchor": "tracks" + "depth": 3, + "title": "Substrate: The Foundation", + "anchor": "substrate-the-foundation" + }, + { + "depth": 3, + "title": "FRAME: Building Blocks for Your Runtime", + "anchor": "frame-building-blocks-for-your-runtime" + }, + { + "depth": 3, + "title": "Cumulus: Parachain-Specific Functionality", + "anchor": "cumulus-parachain-specific-functionality" }, { "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 3333, - "words": 469, - "headings": 4, - "estimated_token_count_total": 631 + "chars": 8495, + "words": 1029, + "headings": 6, + "estimated_token_count_total": 1759 }, - "hash": "sha256:baba9dd41091b792d09005d55d3df0bf65b35f42b40ebe63caf425a0978a22b0", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:ecb0d9459e08920db7d2d59dc7c01aba7a91ce8c9e39256bd0c3efa473dbaa17", "token_estimator": "heuristic-v1" }, { - "id": "reference-parachains-accounts", - "title": "Polkadot SDK Accounts", - "slug": "reference-parachains-accounts", + "id": "reference-polkadot-hub-assets-and-smart-contracts", + "title": "Asset Hub", + "slug": "reference-polkadot-hub-assets-and-smart-contracts", "categories": [ - "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-accounts.md", - "html_url": "https://docs.polkadot.com/reference/parachains/accounts/", - "preview": "Accounts are essential for managing identity, transactions, and governance on the network in the Polkadot SDK. Understanding these components is critical for seamless development and operation on the network, whether you're building or interacting with Polkadot-based chains.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-assets-and-smart-contracts.md", + "html_url": "https://docs.polkadot.com/reference/polkadot-hub/assets-and-smart-contracts/", + "preview": "The Asset Hub is a critical component in the Polkadot ecosystem, enabling the management of fungible and non-fungible assets across the network. Since the relay chain focuses on maintaining security and consensus without direct asset management, Asset Hub provides a streamlined platform for creating, managing, and using on-chain assets in a fee-efficient manner. This guide outlines the core features of Asset Hub, including how it handles asset operations, cross-chain transfers, and asset integra", "outline": [ { "depth": 2, @@ -10905,96 +8642,129 @@ }, { "depth": 2, - "title": "Account Data Structure", - "anchor": "account-data-structure" + "title": "Assets Basics", + "anchor": "assets-basics" + }, + { + "depth": 2, + "title": "Assets Pallet", + "anchor": "assets-pallet" }, { "depth": 3, - "title": "Account", - "anchor": "account" + "title": "Key Features", + "anchor": "key-features" }, { "depth": 3, - "title": "Account Info", - "anchor": "account-info" + "title": "Main Functions", + "anchor": "main-functions" }, { "depth": 3, - "title": "Account Reference Counters", - "anchor": "account-reference-counters" + "title": "Querying Functions", + "anchor": "querying-functions" }, { - "depth": 2, - "title": "Account Balance Types", - "anchor": "account-balance-types" + "depth": 3, + "title": "Permission Models and Roles", + "anchor": "permission-models-and-roles" }, { "depth": 3, - "title": "Balance Types", - "anchor": "balance-types" + "title": "Asset Freezing", + "anchor": "asset-freezing" }, { "depth": 3, - "title": "Locks", - "anchor": "locks" + "title": "Non-Custodial Transfers (Approval API)", + "anchor": "non-custodial-transfers-approval-api" + }, + { + "depth": 2, + "title": "Foreign Assets", + "anchor": "foreign-assets" }, { "depth": 3, - "title": "Balance Types on Polkadot.js", - "anchor": "balance-types-on-polkadotjs" + "title": "Handling Foreign Assets", + "anchor": "handling-foreign-assets" }, { "depth": 2, - "title": "Address Formats", - "anchor": "address-formats" + "title": "Integration", + "anchor": "integration" }, { "depth": 3, - "title": "Basic Format", - "anchor": "basic-format" + "title": "API Sidecar", + "anchor": "api-sidecar" }, { "depth": 3, - "title": "Address Type", - "anchor": "address-type" + "title": "TxWrapper", + "anchor": "txwrapper" + }, + { + "depth": 3, + "title": "ParaSpell", + "anchor": "paraspell" + }, + { + "depth": 3, + "title": "Parachain Node", + "anchor": "parachain-node" + }, + { + "depth": 2, + "title": "XCM Transfer Monitoring", + "anchor": "xcm-transfer-monitoring" + }, + { + "depth": 3, + "title": "Monitor XCM Deposits", + "anchor": "monitor-xcm-deposits" }, { "depth": 3, - "title": "Address Length", - "anchor": "address-length" + "title": "Track XCM Information Back to the Source", + "anchor": "track-xcm-information-back-to-the-source" }, { "depth": 3, - "title": "Checksum Types", - "anchor": "checksum-types" + "title": "Practical Monitoring Examples", + "anchor": "practical-monitoring-examples" }, { "depth": 3, - "title": "Validating Addresses", - "anchor": "validating-addresses" + "title": "Monitor for Failed XCM Transfers", + "anchor": "monitor-for-failed-xcm-transfers" + }, + { + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 29604, - "words": 4194, - "headings": 15, - "estimated_token_count_total": 6507 + "chars": 20065, + "words": 2901, + "headings": 22, + "estimated_token_count_total": 4087 }, - "hash": "sha256:0104a9132a69345a2faac37fca0e2853a2ded1efb009511a83a98d44509ab887", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:73c34bb1dc80d04f765812c3ed2f247aeda6ce55598b0680d0bd157f25456b99", "token_estimator": "heuristic-v1" }, { - "id": "reference-parachains-blocks-transactions-fees-blocks", - "title": "Blocks", - "slug": "reference-parachains-blocks-transactions-fees-blocks", + "id": "reference-polkadot-hub-bridging", + "title": "Bridge Hub", + "slug": "reference-polkadot-hub-bridging", "categories": [ - "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-blocks.md", - "html_url": "https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/blocks/", - "preview": "In the Polkadot SDK, blocks are fundamental to the functioning of the blockchain, serving as containers for [transactions](/reference/parachains/blocks-transactions-fees/transactions/){target=\\_blank} and changes to the chain's state. Blocks consist of headers and an array of transactions, ensuring the integrity and validity of operations on the network. This guide explores the essential components of a block, the process of block production, and how blocks are validated and imported across the", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-bridging.md", + "html_url": "https://docs.polkadot.com/reference/polkadot-hub/bridging/", + "preview": "The Bridge Hub system parachain plays a crucial role in facilitating trustless interactions between Polkadot, Kusama, Ethereum, and other blockchain ecosystems. By implementing on-chain light clients and supporting protocols like BEEFY and GRANDPA, Bridge Hub ensures seamless message transmission and state verification across chains. It also provides essential [pallets](/reference/glossary/#pallet){target=\\_blank} for sending and receiving messages, making it a cornerstone of Polkadot’s interope", "outline": [ { "depth": 2, @@ -11003,159 +8773,126 @@ }, { "depth": 2, - "title": "What is a Block?", - "anchor": "what-is-a-block" + "title": "Trustless Bridging", + "anchor": "trustless-bridging" }, { "depth": 2, - "title": "Block Production", - "anchor": "block-production" - }, - { - "depth": 3, - "title": "Initialize Block", - "anchor": "initialize-block" + "title": "Bridging Components", + "anchor": "bridging-components" }, { "depth": 3, - "title": "Finalize Block", - "anchor": "finalize-block" + "title": "Ethereum-Specific Support", + "anchor": "ethereum-specific-support" }, { "depth": 2, - "title": "Block Authoring and Import", - "anchor": "block-authoring-and-import" - }, - { - "depth": 3, - "title": "Block Import Queue", - "anchor": "block-import-queue" + "title": "Deployed Bridges", + "anchor": "deployed-bridges" }, { "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 6252, - "words": 910, - "headings": 8, - "estimated_token_count_total": 1395 + "chars": 5467, + "words": 776, + "headings": 6, + "estimated_token_count_total": 1220 }, - "hash": "sha256:424783c102bea5dae5b8749635858c6c59055563442a98f57521f0027dafa8d3", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:86734ba8bcdea7913f488edf666a6104bed0a18649d57abde82c149c41c2b871", "token_estimator": "heuristic-v1" }, { - "id": "reference-parachains-blocks-transactions-fees-fees", - "title": "Transactions Weights and Fees", - "slug": "reference-parachains-blocks-transactions-fees-fees", + "id": "reference-polkadot-hub-collectives-and-daos", + "title": "Collectives Chain", + "slug": "reference-polkadot-hub-collectives-and-daos", "categories": [ - "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-fees.md", - "html_url": "https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/fees/", - "preview": "When transactions are executed, or data is stored on-chain, the activity changes the chain's state and consumes blockchain resources. Because the resources available to a blockchain are limited, managing how operations on-chain consume them is important. In addition to being limited in practical terms, such as storage capacity, blockchain resources represent a potential attack vector for malicious users. For example, a malicious user might attempt to overload the network with messages to stop th", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-collectives-and-daos.md", + "html_url": "https://docs.polkadot.com/reference/polkadot-hub/collectives-and-daos/", + "preview": "Established through [Referendum 81](https://polkadot-old.polkassembly.io/referendum/81){target=\\_blank}, the Collectives chain operates as a dedicated parachain exclusive to the Polkadot network with no counterpart on Kusama. This specialized infrastructure provides a foundation for various on-chain governance groups essential to Polkadot's ecosystem.", "outline": [ { "depth": 2, - "title": "Introductions", - "anchor": "introductions" - }, - { - "depth": 2, - "title": "How Fees are Calculated", - "anchor": "how-fees-are-calculated" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Using the Transaction Payment Pallet", - "anchor": "using-the-transaction-payment-pallet" - }, - { - "depth": 3, - "title": "Understanding the Inclusion Fee", - "anchor": "understanding-the-inclusion-fee" - }, - { - "depth": 3, - "title": "Accounts with an Insufficient Balance", - "anchor": "accounts-with-an-insufficient-balance" - }, - { - "depth": 3, - "title": "Fee Multipliers", - "anchor": "fee-multipliers" - }, + "title": "Key Collectives", + "anchor": "key-collectives" + } + ], + "stats": { + "chars": 2288, + "words": 293, + "headings": 2, + "estimated_token_count_total": 424 + }, + "hash": "sha256:59ec351fbb8d3a392e90f4f5bf6b62f58b21d6d7a900c5e367e5d2e09ecb3aca", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-polkadot-hub-consensus-and-security-agile-coretime", + "title": "Agile Coretime", + "slug": "reference-polkadot-hub-consensus-and-security-agile-coretime", + "categories": [ + "Polkadot Protocol" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-agile-coretime.md", + "html_url": "https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/agile-coretime/", + "preview": "Agile Coretime is the [scheduling](https://en.wikipedia.org/wiki/Scheduling_(computing)){target=\\_blank} framework on Polkadot that lets parachains efficiently access cores, which comprise an active validator set tasked with parablock validation. As the first blockchain to enable a flexible scheduling system for blockspace production, Polkadot offers unparalleled adaptability for parachains.", + "outline": [ { "depth": 2, - "title": "Transactions with Special Requirements", - "anchor": "transactions-with-special-requirements" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Default Weight Annotations", - "anchor": "default-weight-annotations" - }, - { - "depth": 3, - "title": "Weights and Database Read/Write Operations", - "anchor": "weights-and-database-readwrite-operations" - }, - { - "depth": 3, - "title": "Dispatch Classes", - "anchor": "dispatch-classes" + "title": "Bulk Coretime", + "anchor": "bulk-coretime" }, { "depth": 3, - "title": "Dynamic Weights", - "anchor": "dynamic-weights" - }, - { - "depth": 2, - "title": "Post Dispatch Weight Correction", - "anchor": "post-dispatch-weight-correction" - }, - { - "depth": 2, - "title": "Custom Fees", - "anchor": "custom-fees" + "title": "Coretime Interlacing", + "anchor": "coretime-interlacing" }, { "depth": 3, - "title": "Custom Weights", - "anchor": "custom-weights" + "title": "Coretime Splitting", + "anchor": "coretime-splitting" }, { "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" + "title": "On-Demand Coretime", + "anchor": "on-demand-coretime" } ], "stats": { - "chars": 20800, - "words": 2917, - "headings": 15, - "estimated_token_count_total": 4464 + "chars": 3028, + "words": 452, + "headings": 5, + "estimated_token_count_total": 619 }, - "hash": "sha256:7d0c3fa7982b3e1843adb8f27422456397580b3a3eba5047b381da8517742536", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:00be43ac8d666bbe15c5c2fa5a5085697d0bb5a6f341ebbb943a209f0be355df", "token_estimator": "heuristic-v1" }, { - "id": "reference-parachains-blocks-transactions-fees-transactions", - "title": "Transactions", - "slug": "reference-parachains-blocks-transactions-fees-transactions", + "id": "reference-polkadot-hub-consensus-and-security-pos-consensus", + "title": "Proof of Stake Consensus", + "slug": "reference-polkadot-hub-consensus-and-security-pos-consensus", "categories": [ - "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-blocks-transactions-fees-transactions.md", - "html_url": "https://docs.polkadot.com/reference/parachains/blocks-transactions-fees/transactions/", - "preview": "Transactions are essential components of blockchain networks, enabling state changes and the execution of key operations. In the Polkadot SDK, transactions, often called extrinsics, come in multiple forms, including signed, unsigned, and inherent transactions.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-pos-consensus.md", + "html_url": "https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/pos-consensus/", + "preview": "Polkadot's Proof of Stake consensus model leverages a unique hybrid approach by design to promote decentralized and secure network operations. In traditional Proof of Stake (PoS) systems, a node's ability to validate transactions is tied to its token holdings, which can lead to centralization risks and limited validator participation. Polkadot addresses these concerns through its [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\\_blank} model and a com", "outline": [ { "depth": 2, @@ -11164,131 +8901,162 @@ }, { "depth": 2, - "title": "What Is a Transaction?", - "anchor": "what-is-a-transaction" + "title": "Nominated Proof of Stake", + "anchor": "nominated-proof-of-stake" }, { - "depth": 3, - "title": "Signed Transactions", - "anchor": "signed-transactions" + "depth": 2, + "title": "Hybrid Consensus", + "anchor": "hybrid-consensus" }, { - "depth": 3, - "title": "Unsigned Transactions", - "anchor": "unsigned-transactions" + "depth": 2, + "title": "Block Production - BABE", + "anchor": "block-production-babe" }, { "depth": 3, - "title": "Inherent Transactions", - "anchor": "inherent-transactions" + "title": "Validator Participation", + "anchor": "validator-participation" }, { - "depth": 2, - "title": "Transaction Formats", - "anchor": "transaction-formats" + "depth": 3, + "title": "Additional Resources", + "anchor": "additional-resources" }, { - "depth": 3, - "title": "Types of Transaction Formats", - "anchor": "types-of-transaction-formats" + "depth": 2, + "title": "Finality Gadget - GRANDPA", + "anchor": "finality-gadget-grandpa" }, { "depth": 3, - "title": "Signed Transaction Data Structure", - "anchor": "signed-transaction-data-structure" + "title": "Probabilistic vs. Provable Finality", + "anchor": "probabilistic-vs-provable-finality" }, { "depth": 3, - "title": "Signed Extensions", - "anchor": "signed-extensions" + "title": "Additional Resources", + "anchor": "additional-resources-2" }, { "depth": 2, - "title": "Transaction Construction", - "anchor": "transaction-construction" - }, - { - "depth": 3, - "title": "Construct a Signed Transaction", - "anchor": "construct-a-signed-transaction" + "title": "Fork Choice", + "anchor": "fork-choice" }, { "depth": 3, - "title": "Transaction Encoding", - "anchor": "transaction-encoding" + "title": "Additional Resources", + "anchor": "additional-resources-3" + }, + { + "depth": 2, + "title": "Bridging - BEEFY", + "anchor": "bridging-beefy" }, { "depth": 3, - "title": "Customize Transaction Construction", - "anchor": "customize-transaction-construction" + "title": "Additional Resources", + "anchor": "additional-resources-4" + } + ], + "stats": { + "chars": 12753, + "words": 1834, + "headings": 13, + "estimated_token_count_total": 2526 + }, + "hash": "sha256:231fc555eefe5f910fb36e0c03945147d0fb235272850797391751f4444b0a9c", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-polkadot-hub-consensus-and-security-relay-chain", + "title": "Overview of the Polkadot Relay Chain", + "slug": "reference-polkadot-hub-consensus-and-security-relay-chain", + "categories": [ + "Basics", + "Polkadot Protocol", + "Parachains" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-relay-chain.md", + "html_url": "https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/relay-chain/", + "preview": "Polkadot is a next-generation blockchain protocol designed to support a multi-chain future by enabling secure communication and interoperability between different blockchains. Built as a Layer-0 protocol, Polkadot introduces innovations like application-specific Layer-1 chains ([parachains](/polkadot-protocol/architecture/parachains/){targe=\\_blank}), shared security through [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\\_blank}, and cross-chain int", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Lifecycle of a Transaction", - "anchor": "lifecycle-of-a-transaction" + "title": "Polkadot 1.0", + "anchor": "polkadot-10" }, { "depth": 3, - "title": "Define Transaction Properties", - "anchor": "define-transaction-properties" + "title": "High-Level Architecture", + "anchor": "high-level-architecture" }, { "depth": 3, - "title": "Process on a Block Authoring Node", - "anchor": "process-on-a-block-authoring-node" + "title": "Polkadot's Additional Functionalities", + "anchor": "polkadots-additional-functionalities" }, { "depth": 3, - "title": "Validate and Queue", - "anchor": "validate-and-queue" + "title": "Polkadot's Resilience", + "anchor": "polkadots-resilience" }, { "depth": 3, - "title": "Transaction Ordering and Priority", - "anchor": "transaction-ordering-and-priority" + "title": "Polkadot's Blockspace", + "anchor": "polkadots-blockspace" + }, + { + "depth": 2, + "title": "DOT Token", + "anchor": "dot-token" }, { "depth": 3, - "title": "Transaction Execution", - "anchor": "transaction-execution" + "title": "Redenomination of DOT", + "anchor": "redenomination-of-dot" }, { - "depth": 2, - "title": "Transaction Mortality", - "anchor": "transaction-mortality" + "depth": 3, + "title": "The Planck Unit", + "anchor": "the-planck-unit" }, { - "depth": 2, - "title": "Unique Identifiers for Extrinsics", - "anchor": "unique-identifiers-for-extrinsics" + "depth": 3, + "title": "Uses for DOT", + "anchor": "uses-for-dot" }, { "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" + "title": "JAM and the Road Ahead", + "anchor": "jam-and-the-road-ahead" } ], "stats": { - "chars": 23610, - "words": 3333, - "headings": 22, - "estimated_token_count_total": 4708 + "chars": 12430, + "words": 1771, + "headings": 11, + "estimated_token_count_total": 2571 }, - "hash": "sha256:547f062b248779f0b3e823778120c4f32e449937b6f270ddf97378bc6d795c62", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:8a914e4309d4fe7070e62d7abe4665b6c76c8dc5ec3219332eccb16b77b0dd95", "token_estimator": "heuristic-v1" }, { - "id": "reference-parachains-chain-data", - "title": "Chain Data", - "slug": "reference-parachains-chain-data", + "id": "reference-polkadot-hub-people-and-identity", + "title": "People Chain", + "slug": "reference-polkadot-hub-people-and-identity", "categories": [ - "Basics", "Polkadot Protocol" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-chain-data.md", - "html_url": "https://docs.polkadot.com/reference/parachains/chain-data/", - "preview": "Understanding and leveraging on-chain data is a fundamental aspect of blockchain development. Whether you're building frontend applications or backend systems, accessing and decoding runtime metadata is vital to interacting with the blockchain. This guide introduces you to the tools and processes for generating and retrieving metadata, explains its role in application development, and outlines the additional APIs available for interacting with a Polkadot node. By mastering these components, you", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-people-and-identity.md", + "html_url": "https://docs.polkadot.com/reference/polkadot-hub/people-and-identity/", + "preview": "People chain is a specialized parachain within the Polkadot ecosystem dedicated to secure, decentralized identity management.", "outline": [ { "depth": 2, @@ -11297,116 +9065,167 @@ }, { "depth": 2, - "title": "Application Development", - "anchor": "application-development" + "title": "Identity Management System", + "anchor": "identity-management-system" }, { - "depth": 2, - "title": "Understand Metadata", - "anchor": "understand-metadata" + "depth": 3, + "title": "Sub-Identities", + "anchor": "sub-identities" }, { "depth": 2, - "title": "Expose Runtime Information as Metadata", - "anchor": "expose-runtime-information-as-metadata" + "title": "Verification Process", + "anchor": "verification-process" }, { - "depth": 2, - "title": "Generate Metadata", - "anchor": "generate-metadata" + "depth": 3, + "title": "Judgment Requests", + "anchor": "judgment-requests" }, { - "depth": 2, - "title": "Retrieve Runtime Metadata", - "anchor": "retrieve-runtime-metadata" + "depth": 3, + "title": "Judgment Classifications", + "anchor": "judgment-classifications" }, { "depth": 3, - "title": "Use Polkadot.js", - "anchor": "use-polkadotjs" + "title": "Registrars", + "anchor": "registrars" }, { - "depth": 3, - "title": "Use Curl", - "anchor": "use-curl" + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" + } + ], + "stats": { + "chars": 4750, + "words": 606, + "headings": 8, + "estimated_token_count_total": 876 + }, + "hash": "sha256:8239d1e8d8642cb7c10e9e5f971c99b999e9e4a87373b50bf4a691225c1e4702", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-polkadot-hub", + "title": "reference-polkadot-hub", + "slug": "reference-polkadot-hub", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub.md", + "html_url": "https://docs.polkadot.com/reference/polkadot-hub/", + "preview": "TODO", + "outline": [], + "stats": { + "chars": 5, + "words": 1, + "headings": 0, + "estimated_token_count_total": 0 + }, + "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-tools-chopsticks", + "title": "reference-tools-chopsticks", + "slug": "reference-tools-chopsticks", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-chopsticks.md", + "html_url": "https://docs.polkadot.com/reference/tools/chopsticks/", + "preview": "TODO", + "outline": [], + "stats": { + "chars": 5, + "words": 1, + "headings": 0, + "estimated_token_count_total": 0 + }, + "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-tools-dedot", + "title": "Dedot", + "slug": "reference-tools-dedot", + "categories": [ + "Tooling", + "Dapps" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-dedot.md", + "html_url": "https://docs.polkadot.com/reference/tools/dedot/", + "preview": "[Dedot](https://github.com/dedotdev/dedot){target=\\_blank} is a next-generation JavaScript client for Polkadot and Polkadot SDK-based blockchains. Designed to elevate the dApp development experience, Dedot is built and optimized to be lightweight and tree-shakable, offering precise types and APIs suggestions for individual Polkadot SDK-based blockchains and [ink! smart contracts](https://use.ink/){target=\\_blank}.", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" }, { "depth": 3, - "title": "Use Subxt", - "anchor": "use-subxt" + "title": "Key Features", + "anchor": "key-features" }, { "depth": 2, - "title": "Client Applications and Metadata", - "anchor": "client-applications-and-metadata" + "title": "Installation", + "anchor": "installation" }, { "depth": 2, - "title": "Metadata Format", - "anchor": "metadata-format" + "title": "Get Started", + "anchor": "get-started" }, { "depth": 3, - "title": "Pallets", - "anchor": "pallets" + "title": "Initialize a Client Instance", + "anchor": "initialize-a-client-instance" }, { "depth": 3, - "title": "Extrinsic", - "anchor": "extrinsic" + "title": "Enable Type and API Suggestions", + "anchor": "enable-type-and-api-suggestions" }, { - "depth": 2, - "title": "Included RPC APIs", - "anchor": "included-rpc-apis" + "depth": 3, + "title": "Read On-Chain Data", + "anchor": "read-on-chain-data" }, { - "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" - } - ], - "stats": { - "chars": 18650, - "words": 2216, - "headings": 15, - "estimated_token_count_total": 3774 - }, - "hash": "sha256:49238d1e9e2c33e0fcd3a84b5e30f0d3840d7d23a783b538875e0a23f38efc1d", - "last_modified": "2025-10-28T14:42:15+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-parachains-consensus-async-backing", - "title": "reference-parachains-consensus-async-backing", - "slug": "reference-parachains-consensus-async-backing", - "categories": [ - "Uncategorized" + "depth": 3, + "title": "Sign and Send Transactions", + "anchor": "sign-and-send-transactions" + }, + { + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" + } ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus-async-backing.md", - "html_url": "https://docs.polkadot.com/reference/parachains/consensus/async-backing/", - "preview": "TODO", - "outline": [], "stats": { - "chars": 5, - "words": 1, - "headings": 0, - "estimated_token_count_total": 0 + "chars": 8855, + "words": 1100, + "headings": 9, + "estimated_token_count_total": 2300 }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:ba24e31e2ad94fbf1d73f1878da92dd2e1476db00170780bbdf0e65ab18bc961", "token_estimator": "heuristic-v1" }, { - "id": "reference-parachains-consensus-elastic-scaling", - "title": "Elastic Scaling", - "slug": "reference-parachains-consensus-elastic-scaling", + "id": "reference-tools-light-clients", + "title": "Light Clients", + "slug": "reference-tools-light-clients", "categories": [ - "Polkadot Protocol" + "Parachains", + "Tooling" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-consensus-elastic-scaling.md", - "html_url": "https://docs.polkadot.com/reference/parachains/consensus/elastic-scaling/", - "preview": "Polkadot's architecture delivers scalability and security through its shared security model, where the relay chain coordinates and validates multiple parallel chains.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-light-clients.md", + "html_url": "https://docs.polkadot.com/reference/tools/light-clients/", + "preview": "Light clients enable secure and efficient blockchain interaction without running a full node. They provide a trust-minimized alternative to JSON-RPC by verifying data through cryptographic proofs rather than blindly trusting remote nodes.", "outline": [ { "depth": 2, @@ -11415,61 +9234,55 @@ }, { "depth": 2, - "title": "How Elastic Scaling Works", - "anchor": "how-elastic-scaling-works" + "title": "Light Clients Workflow", + "anchor": "light-clients-workflow" }, { "depth": 2, - "title": "Benefits of Elastic Scaling", - "anchor": "benefits-of-elastic-scaling" + "title": "JSON-RPC and Light Client Comparison", + "anchor": "json-rpc-and-light-client-comparison" }, { "depth": 2, - "title": "Use Cases", - "anchor": "use-cases" - }, - { - "depth": 3, - "title": "Handling Sudden Traffic Spikes", - "anchor": "handling-sudden-traffic-spikes" + "title": "Using Light Clients", + "anchor": "using-light-clients" }, { "depth": 3, - "title": "Supporting Early-Stage Growth", - "anchor": "supporting-early-stage-growth" + "title": "PAPI Light Client Support", + "anchor": "papi-light-client-support" }, { "depth": 3, - "title": "Scaling Massive IoT Networks", - "anchor": "scaling-massive-iot-networks" + "title": "Substrate Connect - Browser Extension", + "anchor": "substrate-connect-browser-extension" }, { - "depth": 3, - "title": "Powering Real-Time, Low-Latency Systems", - "anchor": "powering-real-time-low-latency-systems" + "depth": 2, + "title": "Resources", + "anchor": "resources" } ], "stats": { - "chars": 7871, - "words": 1047, - "headings": 8, - "estimated_token_count_total": 1440 + "chars": 6490, + "words": 870, + "headings": 7, + "estimated_token_count_total": 1430 }, - "hash": "sha256:2d228c52844df8952520fafdd3e6f0e26bfd2f32b5ee60c6241cf7d38603643c", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:1284c42be692167e01bcc44e2e134ec20615402675fac26df246c00aa1588d80", "token_estimator": "heuristic-v1" }, { - "id": "reference-parachains-cryptography", - "title": "Cryptography", - "slug": "reference-parachains-cryptography", + "id": "reference-tools-moonwall", + "title": "E2E Testing with Moonwall", + "slug": "reference-tools-moonwall", "categories": [ - "Basics", - "Polkadot Protocol" + "Parachains", + "Tooling" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-cryptography.md", - "html_url": "https://docs.polkadot.com/reference/parachains/cryptography/", - "preview": "Cryptography forms the backbone of blockchain technology, providing the mathematical verifiability crucial for consensus systems, data integrity, and user security. While a deep understanding of the underlying mathematical processes isn't necessary for most blockchain developers, grasping the fundamental applications of cryptography is essential. This page comprehensively overviews cryptographic implementations used across Polkadot SDK-based chains and the broader blockchain ecosystem.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-moonwall.md", + "html_url": "https://docs.polkadot.com/reference/tools/moonwall/", + "preview": "Moonwall is an end-to-end testing framework designed explicitly for Polkadot SDK-based blockchain networks. It addresses one of the most significant challenges in blockchain development: managing complex test environments and network configurations.", "outline": [ { "depth": 2, @@ -11478,81 +9291,65 @@ }, { "depth": 2, - "title": "Hash Functions", - "anchor": "hash-functions" - }, - { - "depth": 3, - "title": "Key Properties of Hash Functions", - "anchor": "key-properties-of-hash-functions" - }, - { - "depth": 3, - "title": "Blake2", - "anchor": "blake2" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Types of Cryptography", - "anchor": "types-of-cryptography" - }, - { - "depth": 3, - "title": "Symmetric Cryptography", - "anchor": "symmetric-cryptography" + "title": "Install Moonwall", + "anchor": "install-moonwall" }, { "depth": 3, - "title": "Asymmetric Cryptography", - "anchor": "asymmetric-cryptography" + "title": "Global Installation", + "anchor": "global-installation" }, { "depth": 3, - "title": "Trade-offs and Compromises", - "anchor": "trade-offs-and-compromises" + "title": "Local Installation", + "anchor": "local-installation" }, { "depth": 2, - "title": "Digital Signatures", - "anchor": "digital-signatures" + "title": "Initialize Moonwall", + "anchor": "initialize-moonwall" }, { - "depth": 3, - "title": "Example of Creating a Digital Signature", - "anchor": "example-of-creating-a-digital-signature" + "depth": 2, + "title": "Writing Tests", + "anchor": "writing-tests" }, { "depth": 2, - "title": "Elliptic Curve", - "anchor": "elliptic-curve" + "title": "Running the Tests", + "anchor": "running-the-tests" }, { - "depth": 3, - "title": "Various Implementations", - "anchor": "various-implementations" + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 8860, - "words": 1293, - "headings": 12, - "estimated_token_count_total": 1797 + "chars": 10240, + "words": 1295, + "headings": 9, + "estimated_token_count_total": 2453 }, - "hash": "sha256:259dcef86aadc513675258b665cc3940db65af6eb32a5db85da6ac339966fa60", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:2c77cfb38bb2e466a8f56dabbb706fcd2e90cf1634fc9beb7f0ee95a75735653", "token_estimator": "heuristic-v1" }, { - "id": "reference-parachains-data-encoding", - "title": "Data Encoding", - "slug": "reference-parachains-data-encoding", + "id": "reference-tools-omninode", + "title": "Polkadot Omni Node", + "slug": "reference-tools-omninode", "categories": [ - "Basics", - "Polkadot Protocol" + "Parachains", + "Tooling" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-data-encoding.md", - "html_url": "https://docs.polkadot.com/reference/parachains/data-encoding/", - "preview": "The Polkadot SDK uses a lightweight and efficient encoding/decoding mechanism to optimize data transmission across the network. This mechanism, known as the _SCALE_ codec, is used for serializing and deserializing data.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-omninode.md", + "html_url": "https://docs.polkadot.com/reference/tools/omninode/", + "preview": "The [`polkadot-omni-node`](https://crates.io/crates/polkadot-omni-node/0.7.0){target=\\_blank} crate is a versatile, pre-built binary designed to simplify running parachains in the Polkadot ecosystem. Unlike traditional node binaries that are tightly coupled to specific runtime code, the `polkadot-omni-node` operates using an external [chain specification](/polkadot-protocol/glossary#chain-specification){target=\\_blank} file, allowing it to adapt dynamically to different parachains.", "outline": [ { "depth": 2, @@ -11561,71 +9358,65 @@ }, { "depth": 2, - "title": "SCALE Codec", - "anchor": "scale-codec" + "title": "Prerequisites", + "anchor": "prerequisites" }, { - "depth": 3, - "title": "Encode", - "anchor": "encode" + "depth": 2, + "title": "Install Polkadot Omni Node", + "anchor": "install-polkadot-omni-node" }, { - "depth": 3, - "title": "Decode", - "anchor": "decode" + "depth": 2, + "title": "Obtain Chain Specifications", + "anchor": "obtain-chain-specifications" }, { - "depth": 3, - "title": "CompactAs", - "anchor": "compactas" + "depth": 2, + "title": "Run a Parachain Full Node", + "anchor": "run-a-parachain-full-node" }, { - "depth": 3, - "title": "HasCompact", - "anchor": "hascompact" + "depth": 2, + "title": "Interact with the Node", + "anchor": "interact-with-the-node" }, { - "depth": 3, - "title": "EncodeLike", - "anchor": "encodelike" + "depth": 2, + "title": "Parachain Compatibility", + "anchor": "parachain-compatibility" }, { "depth": 3, - "title": "Data Types", - "anchor": "data-types" - }, - { - "depth": 2, - "title": "Encode and Decode Rust Trait Implementations", - "anchor": "encode-and-decode-rust-trait-implementations" + "title": "Required Runtime APIs", + "anchor": "required-runtime-apis" }, { - "depth": 2, - "title": "SCALE Codec Libraries", - "anchor": "scale-codec-libraries" + "depth": 3, + "title": "Required Pallets", + "anchor": "required-pallets" } ], "stats": { - "chars": 13629, - "words": 1314, - "headings": 10, - "estimated_token_count_total": 3213 + "chars": 8916, + "words": 1165, + "headings": 9, + "estimated_token_count_total": 2018 }, - "hash": "sha256:e448294b6e52291ac0add5fa6533572814e6cd27af42bdaccc2000b86f52d775", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:a87815deff81936d7f50842f8600004990076c1a33e7e6b408ab954b6ce47259", "token_estimator": "heuristic-v1" }, { - "id": "reference-parachains-interoperability", - "title": "Interoperability", - "slug": "reference-parachains-interoperability", + "id": "reference-tools-papi", + "title": "Polkadot-API", + "slug": "reference-tools-papi", "categories": [ - "Basics", - "Polkadot Protocol" + "Tooling", + "Dapps" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md", - "html_url": "https://docs.polkadot.com/reference/parachains/interoperability/", - "preview": "Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-papi.md", + "html_url": "https://docs.polkadot.com/reference/tools/papi/", + "preview": "[Polkadot-API](https://github.com/polkadot-api/polkadot-api){target=\\_blank} (PAPI) is a set of libraries built to be modular, composable, and grounded in a “light-client first” approach. Its primary aim is to equip dApp developers with an extensive toolkit for building fully decentralized applications.", "outline": [ { "depth": 2, @@ -11634,130 +9425,153 @@ }, { "depth": 2, - "title": "Why Interoperability Matters", - "anchor": "why-interoperability-matters" - }, - { - "depth": 2, - "title": "Key Mechanisms for Interoperability", - "anchor": "key-mechanisms-for-interoperability" + "title": "Get Started", + "anchor": "get-started" }, { "depth": 3, - "title": "Cross-Consensus Messaging (XCM): The Backbone of Communication", - "anchor": "cross-consensus-messaging-xcm-the-backbone-of-communication" + "title": "API Instantiation", + "anchor": "api-instantiation" }, { "depth": 3, - "title": "Bridges: Connecting External Networks", - "anchor": "bridges-connecting-external-networks" + "title": "Reading Chain Data", + "anchor": "reading-chain-data" }, { - "depth": 2, - "title": "The Polkadot Advantage", - "anchor": "the-polkadot-advantage" + "depth": 3, + "title": "Sending Transactions", + "anchor": "sending-transactions" }, { "depth": 2, - "title": "Looking Ahead", - "anchor": "looking-ahead" + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 4635, - "words": 584, - "headings": 7, - "estimated_token_count_total": 772 + "chars": 8957, + "words": 1156, + "headings": 6, + "estimated_token_count_total": 1987 }, - "hash": "sha256:11bb4f113bdda5852a3115e64d5ba47f8eccd4e3619a05ad960ab3a541f31346", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:2ca93b09d3bb9159bbf53816886a9b242bb3c13b996c51fd52962e049e2d5477", "token_estimator": "heuristic-v1" }, { - "id": "reference-parachains-networks", - "title": "Networks", - "slug": "reference-parachains-networks", + "id": "reference-tools-paraspell", + "title": "ParaSpell XCM SDK", + "slug": "reference-tools-paraspell", "categories": [ - "Basics", - "Polkadot Protocol", - "Networks" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-networks.md", - "html_url": "https://docs.polkadot.com/reference/parachains/networks/", - "preview": "The Polkadot ecosystem is built on a robust set of networks designed to enable secure and scalable development. Whether you are testing new features or deploying to live production, Polkadot offers several layers of networks tailored for each stage of the development process. From local environments to experimental networks like Kusama and community-run TestNets such as Paseo, developers can thoroughly test, iterate, and validate their applications. This guide will introduce you to Polkadot's va", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-paraspell.md", + "html_url": "https://docs.polkadot.com/reference/tools/paraspell/", + "preview": "[ParaSpell](https://paraspell.github.io/docs/){target=\\_blank} is a comprehensive suite of open-source tools designed to simplify cross-chain interactions within the Polkadot ecosystem. At its core, ParaSpell is dedicated to enhancing the functionality of the [XCM (Cross-Consensus Messaging)](/parachains/interoperability/get-started/){target=\\_blank} protocol by providing developers with a unified and streamlined experience for building interoperable decentralized applications (dApps).", "outline": [ { "depth": 2, "title": "Introduction", "anchor": "introduction" }, + { + "depth": 3, + "title": "ParaSpell XCM SDK", + "anchor": "paraspell-xcm-sdk" + } + ], + "stats": { + "chars": 3005, + "words": 433, + "headings": 2, + "estimated_token_count_total": 669 + }, + "hash": "sha256:a7f9c4a03153ee637a0557d2cea0b622c849667ce793b1294bb3299cf036197d", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-tools-polkadart", + "title": "Polkadart", + "slug": "reference-tools-polkadart", + "categories": [ + "Tooling", + "Dapps" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadart.md", + "html_url": "https://docs.polkadot.com/reference/tools/polkadart/", + "preview": "Polkadart is the most comprehensive Dart/Flutter SDK for interacting with Polkadot, Substrate, and other compatible blockchain networks. Designed with a Dart-first approach and type-safe APIs, it provides everything developers need to build powerful decentralized applications.", + "outline": [ { "depth": 2, - "title": "Network Overview", - "anchor": "network-overview" + "title": "Installation", + "anchor": "installation" }, { "depth": 2, - "title": "Polkadot Development Networks", - "anchor": "polkadot-development-networks" + "title": "Get Started", + "anchor": "get-started" }, { - "depth": 2, - "title": "Kusama Network", - "anchor": "kusama-network" + "depth": 3, + "title": "Type Generation", + "anchor": "type-generation" }, { - "depth": 2, - "title": "Test Networks", - "anchor": "test-networks" + "depth": 3, + "title": "Run Generator", + "anchor": "run-generator" }, { "depth": 3, - "title": "Westend", - "anchor": "westend" + "title": "Use Generated Types", + "anchor": "use-generated-types" }, { "depth": 3, - "title": "Paseo", - "anchor": "paseo" + "title": "Creating an API Instance", + "anchor": "creating-an-api-instance" }, { - "depth": 2, - "title": "Local Test Networks", - "anchor": "local-test-networks" + "depth": 3, + "title": "Reading Chain Data", + "anchor": "reading-chain-data" }, { "depth": 3, - "title": "Zombienet", - "anchor": "zombienet" + "title": "Subscribe to New Blocks", + "anchor": "subscribe-to-new-blocks" }, { "depth": 3, - "title": "Chopsticks", - "anchor": "chopsticks" + "title": "Send a Transaction", + "anchor": "send-a-transaction" + }, + { + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 7834, - "words": 1111, + "chars": 5178, + "words": 624, "headings": 10, - "estimated_token_count_total": 1473 + "estimated_token_count_total": 1084 }, - "hash": "sha256:e49e063a2cc0fb5a48c6cdc3de266bb6e025a006940fea8e90cc4d5f9884900f", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:7f533abe61586af8438e350c41b741d74a8edb839f9dc4139bc4619ba3748258", "token_estimator": "heuristic-v1" }, { - "id": "reference-parachains-node-and-runtime", - "title": "Node and Runtime", - "slug": "reference-parachains-node-and-runtime", + "id": "reference-tools-polkadot-js-api", + "title": "Polkadot.js API", + "slug": "reference-tools-polkadot-js-api", "categories": [ - "Basics", - "Polkadot Protocol" + "Tooling", + "Dapps" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-node-and-runtime.md", - "html_url": "https://docs.polkadot.com/reference/parachains/node-and-runtime/", - "preview": "Every blockchain platform relies on a decentralized network of computers, called nodes, that communicate with each other about transactions and blocks. In this context, a node refers to the software running on the connected devices rather than the physical or virtual machines in the network.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadot-js-api.md", + "html_url": "https://docs.polkadot.com/reference/tools/polkadot-js-api/", + "preview": "!!! warning \"Maintenance Mode Only\" The Polkadot.js API is now in maintenance mode and is no longer actively developed. New projects should use [Dedot](/develop/toolkit/api-libraries/dedot){target=\\_blank} (TypeScript-first API) or [Polkadot API](/develop/toolkit/api-libraries/papi){target=\\_blank} (modern, type-safe API) as actively maintained alternatives.", "outline": [ { "depth": 2, @@ -11765,72 +9579,66 @@ "anchor": "introduction" }, { - "depth": 2, - "title": "Architectural Principles", - "anchor": "architectural-principles" + "depth": 3, + "title": "Dynamic API Generation", + "anchor": "dynamic-api-generation" }, { "depth": 3, - "title": "Advantages of this Architecture", - "anchor": "advantages-of-this-architecture" + "title": "Available API Categories", + "anchor": "available-api-categories" }, { "depth": 2, - "title": "Node (Client)", - "anchor": "node-client" + "title": "Installation", + "anchor": "installation" }, { "depth": 2, - "title": "Runtime", - "anchor": "runtime" + "title": "Get Started", + "anchor": "get-started" }, { "depth": 3, - "title": "Characteristics", - "anchor": "characteristics" + "title": "Creating an API Instance", + "anchor": "creating-an-api-instance" }, { "depth": 3, - "title": "Key Functions", - "anchor": "key-functions" - }, - { - "depth": 2, - "title": "Communication Between Node and Runtime", - "anchor": "communication-between-node-and-runtime" + "title": "Reading Chain Data", + "anchor": "reading-chain-data" }, { "depth": 3, - "title": "Runtime APIs", - "anchor": "runtime-apis" + "title": "Sending Transactions", + "anchor": "sending-transactions" }, { - "depth": 3, - "title": "Host Functions", - "anchor": "host-functions" + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 4937, - "words": 628, - "headings": 10, - "estimated_token_count_total": 914 + "chars": 5042, + "words": 684, + "headings": 9, + "estimated_token_count_total": 1166 }, - "hash": "sha256:8122e21c149d0863cfe3b37fc5606bcdb91668e9d265f0f05451a61ff70e4e93", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:ed3986f30880fefca5975fcdc847c68b4aca65862c63e3002b25391b0521781d", "token_estimator": "heuristic-v1" }, { - "id": "reference-parachains-randomness", - "title": "Randomness", - "slug": "reference-parachains-randomness", + "id": "reference-tools-py-substrate-interface", + "title": "Python Substrate Interface", + "slug": "reference-tools-py-substrate-interface", "categories": [ - "Basics", - "Polkadot Protocol" + "Tooling", + "Dapps" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-randomness.md", - "html_url": "https://docs.polkadot.com/reference/parachains/randomness/", - "preview": "Randomness is crucial in Proof of Stake (PoS) blockchains to ensure a fair and unpredictable distribution of validator duties. However, computers are inherently deterministic, meaning the same input always produces the same output. What we typically refer to as \"random\" numbers on a computer are actually pseudo-random. These numbers rely on an initial \"seed,\" which can come from external sources like [atmospheric noise](https://www.random.org/randomness/){target=\\_blank}, [heart rates](https://m", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-py-substrate-interface.md", + "html_url": "https://docs.polkadot.com/reference/tools/py-substrate-interface/", + "preview": "The [Python Substrate Interface](https://github.com/polkascan/py-substrate-interface){target=\\_blank} is a powerful library that enables interaction with Polkadot SDK-based chains. It provides essential functionality for:", "outline": [ { "depth": 2, @@ -11839,50 +9647,55 @@ }, { "depth": 2, - "title": "VRF", - "anchor": "vrf" + "title": "Installation", + "anchor": "installation" + }, + { + "depth": 2, + "title": "Get Started", + "anchor": "get-started" }, { "depth": 3, - "title": "How VRF Works", - "anchor": "how-vrf-works" + "title": "Establishing Connection", + "anchor": "establishing-connection" }, { - "depth": 2, - "title": "RANDAO", - "anchor": "randao" + "depth": 3, + "title": "Reading Chain State", + "anchor": "reading-chain-state" }, { - "depth": 2, - "title": "VDFs", - "anchor": "vdfs" + "depth": 3, + "title": "Submitting Transactions", + "anchor": "submitting-transactions" }, { "depth": 2, - "title": "Additional Resources", - "anchor": "additional-resources" + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 6503, - "words": 1005, - "headings": 6, - "estimated_token_count_total": 1388 + "chars": 4302, + "words": 541, + "headings": 7, + "estimated_token_count_total": 942 }, - "hash": "sha256:c7d8a5a4263fd21af458ab0bd102377104affdf2431b4fe74eeff4ebe62a4a81", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:8987fc35cd28602054ee018031f773e2e3837425107c51d0e2ac68a94b86e9c0", "token_estimator": "heuristic-v1" }, { - "id": "reference-polkadot-hub-assets-and-smart-contracts", - "title": "Asset Hub", - "slug": "reference-polkadot-hub-assets-and-smart-contracts", + "id": "reference-tools-sidecar", + "title": "Sidecar REST API", + "slug": "reference-tools-sidecar", "categories": [ - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-assets-and-smart-contracts.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/assets-and-smart-contracts/", - "preview": "The Asset Hub is a critical component in the Polkadot ecosystem, enabling the management of fungible and non-fungible assets across the network. Since the relay chain focuses on maintaining security and consensus without direct asset management, Asset Hub provides a streamlined platform for creating, managing, and using on-chain assets in a fee-efficient manner. This guide outlines the core features of Asset Hub, including how it handles asset operations, cross-chain transfers, and asset integra", + "Tooling", + "Dapps" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-sidecar.md", + "html_url": "https://docs.polkadot.com/reference/tools/sidecar/", + "preview": "The [Sidecar REST API](https://github.com/paritytech/substrate-api-sidecar){target=\\_blank} is a service that provides a REST interface for interacting with Polkadot SDK-based blockchains. With this API, developers can easily access a broad range of endpoints for nodes, accounts, transactions, parachains, and more.", "outline": [ { "depth": 2, @@ -11891,103 +9704,95 @@ }, { "depth": 2, - "title": "Assets Basics", - "anchor": "assets-basics" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Assets Pallet", - "anchor": "assets-pallet" - }, - { - "depth": 3, - "title": "Key Features", - "anchor": "key-features" - }, - { - "depth": 3, - "title": "Main Functions", - "anchor": "main-functions" - }, - { - "depth": 3, - "title": "Querying Functions", - "anchor": "querying-functions" - }, - { - "depth": 3, - "title": "Permission Models and Roles", - "anchor": "permission-models-and-roles" + "title": "Installation", + "anchor": "installation" }, { - "depth": 3, - "title": "Asset Freezing", - "anchor": "asset-freezing" + "depth": 2, + "title": "Usage", + "anchor": "usage" }, { "depth": 3, - "title": "Non-Custodial Transfers (Approval API)", - "anchor": "non-custodial-transfers-approval-api" + "title": "Endpoints", + "anchor": "endpoints" }, { "depth": 2, - "title": "Foreign Assets", - "anchor": "foreign-assets" - }, - { - "depth": 3, - "title": "Handling Foreign Assets", - "anchor": "handling-foreign-assets" - }, + "title": "Where to Go Next", + "anchor": "where-to-go-next" + } + ], + "stats": { + "chars": 7309, + "words": 1033, + "headings": 6, + "estimated_token_count_total": 1945 + }, + "hash": "sha256:0795462182cb97256bb5c2acb035855fe0d6557185de8ac99482725ecb4f94c1", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference-tools-subxt", + "title": "Subxt Rust API", + "slug": "reference-tools-subxt", + "categories": [ + "Tooling", + "Dapps" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-subxt.md", + "html_url": "https://docs.polkadot.com/reference/tools/subxt/", + "preview": "Subxt is a Rust library designed to interact with Polkadot SDK-based blockchains. It provides a type-safe interface for submitting transactions, querying on-chain state, and performing other blockchain interactions. By leveraging Rust's strong type system, subxt ensures that your code is validated at compile time, reducing runtime errors and improving reliability.", + "outline": [ { "depth": 2, - "title": "Integration", - "anchor": "integration" + "title": "Introduction", + "anchor": "introduction" }, { - "depth": 3, - "title": "API Sidecar", - "anchor": "api-sidecar" + "depth": 2, + "title": "Prerequisites", + "anchor": "prerequisites" }, { - "depth": 3, - "title": "TxWrapper", - "anchor": "txwrapper" + "depth": 2, + "title": "Installation", + "anchor": "installation" }, { - "depth": 3, - "title": "ParaSpell", - "anchor": "paraspell" + "depth": 2, + "title": "Get Started", + "anchor": "get-started" }, { "depth": 3, - "title": "Parachain Node", - "anchor": "parachain-node" - }, - { - "depth": 2, - "title": "XCM Transfer Monitoring", - "anchor": "xcm-transfer-monitoring" + "title": "Download Chain Metadata", + "anchor": "download-chain-metadata" }, { "depth": 3, - "title": "Monitor XCM Deposits", - "anchor": "monitor-xcm-deposits" + "title": "Generate Type-Safe Interfaces", + "anchor": "generate-type-safe-interfaces" }, { "depth": 3, - "title": "Track XCM Information Back to the Source", - "anchor": "track-xcm-information-back-to-the-source" + "title": "Initialize the Subxt Client", + "anchor": "initialize-the-subxt-client" }, { "depth": 3, - "title": "Practical Monitoring Examples", - "anchor": "practical-monitoring-examples" + "title": "Read Chain Data", + "anchor": "read-chain-data" }, { "depth": 3, - "title": "Monitor for Failed XCM Transfers", - "anchor": "monitor-for-failed-xcm-transfers" + "title": "Submit Transactions", + "anchor": "submit-transactions" }, { "depth": 2, @@ -11996,25 +9801,26 @@ } ], "stats": { - "chars": 20065, - "words": 2901, - "headings": 22, - "estimated_token_count_total": 4087 + "chars": 9174, + "words": 1175, + "headings": 10, + "estimated_token_count_total": 2187 }, - "hash": "sha256:73c34bb1dc80d04f765812c3ed2f247aeda6ce55598b0680d0bd157f25456b99", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:56269d9ea47f5b4e92cd7d5a1e65ab06d181a9c380f90bb3ef285529b12299f7", "token_estimator": "heuristic-v1" }, { - "id": "reference-polkadot-hub-bridging", - "title": "Bridge Hub", - "slug": "reference-polkadot-hub-bridging", + "id": "reference-tools-xcm-tools", + "title": "XCM Tools", + "slug": "reference-tools-xcm-tools", "categories": [ - "Polkadot Protocol" + "Basics", + "Tooling", + "Dapps" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-bridging.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/bridging/", - "preview": "The Bridge Hub system parachain plays a crucial role in facilitating trustless interactions between Polkadot, Kusama, Ethereum, and other blockchain ecosystems. By implementing on-chain light clients and supporting protocols like BEEFY and GRANDPA, Bridge Hub ensures seamless message transmission and state verification across chains. It also provides essential [pallets](/reference/glossary/#pallet){target=\\_blank} for sending and receiving messages, making it a cornerstone of Polkadot’s interope", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md", + "html_url": "https://docs.polkadot.com/reference/tools/xcm-tools/", + "preview": "As described in the [Interoperability](/develop/interoperability){target=\\_blank} section, XCM (Cross-Consensus Messaging) is a protocol used in the Polkadot and Kusama ecosystems to enable communication and interaction between chains. It facilitates cross-chain communication, allowing assets, data, and messages to flow seamlessly across the ecosystem.", "outline": [ { "depth": 2, @@ -12023,218 +9829,263 @@ }, { "depth": 2, - "title": "Trustless Bridging", - "anchor": "trustless-bridging" + "title": "Popular XCM Tools", + "anchor": "popular-xcm-tools" }, { - "depth": 2, - "title": "Bridging Components", - "anchor": "bridging-components" + "depth": 3, + "title": "Moonsong Labs XCM Tools", + "anchor": "moonsong-labs-xcm-tools" }, { "depth": 3, - "title": "Ethereum-Specific Support", - "anchor": "ethereum-specific-support" + "title": "ParaSpell", + "anchor": "paraspell" }, { - "depth": 2, - "title": "Deployed Bridges", - "anchor": "deployed-bridges" + "depth": 3, + "title": "Astar XCM Tools", + "anchor": "astar-xcm-tools" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "depth": 3, + "title": "Chopsticks", + "anchor": "chopsticks" + }, + { + "depth": 3, + "title": "Moonbeam XCM SDK", + "anchor": "moonbeam-xcm-sdk" } ], "stats": { - "chars": 5467, - "words": 776, - "headings": 6, - "estimated_token_count_total": 1220 + "chars": 7524, + "words": 1043, + "headings": 7, + "estimated_token_count_total": 1700 }, - "hash": "sha256:86734ba8bcdea7913f488edf666a6104bed0a18649d57abde82c149c41c2b871", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:47328231d6ff4dc52cd93aaf1baf5d0bc2d9fc372f3d79339d87aafa0dabd1b8", "token_estimator": "heuristic-v1" }, { - "id": "reference-polkadot-hub-collectives-and-daos", - "title": "Collectives Chain", - "slug": "reference-polkadot-hub-collectives-and-daos", + "id": "reference-tools-zombienet", + "title": "reference-tools-zombienet", + "slug": "reference-tools-zombienet", "categories": [ - "Polkadot Protocol" + "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-collectives-and-daos.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/collectives-and-daos/", - "preview": "Established through [Referendum 81](https://polkadot-old.polkassembly.io/referendum/81){target=\\_blank}, the Collectives chain operates as a dedicated parachain exclusive to the Polkadot network with no counterpart on Kusama. This specialized infrastructure provides a foundation for various on-chain governance groups essential to Polkadot's ecosystem.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-zombienet.md", + "html_url": "https://docs.polkadot.com/reference/tools/zombienet/", + "preview": "TODO", + "outline": [], + "stats": { + "chars": 5, + "words": 1, + "headings": 0, + "estimated_token_count_total": 0 + }, + "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", + "token_estimator": "heuristic-v1" + }, + { + "id": "reference", + "title": "reference", + "slug": "reference", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md", + "html_url": "https://docs.polkadot.com/reference/", + "preview": "TODO", + "outline": [], + "stats": { + "chars": 5, + "words": 1, + "headings": 0, + "estimated_token_count_total": 0 + }, + "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-connect", + "title": "Connect to Polkadot", + "slug": "smart-contracts-connect", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-connect.md", + "html_url": "https://docs.polkadot.com/smart-contracts/connect/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Networks Details", + "anchor": "networks-details" }, { "depth": 2, - "title": "Key Collectives", - "anchor": "key-collectives" + "title": "Test Tokens", + "anchor": "test-tokens" + }, + { + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 2288, - "words": 293, - "headings": 2, - "estimated_token_count_total": 424 + "chars": 3459, + "words": 476, + "headings": 3, + "estimated_token_count_total": 558 }, - "hash": "sha256:59ec351fbb8d3a392e90f4f5bf6b62f58b21d6d7a900c5e367e5d2e09ecb3aca", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:a2490223926957381913ae0ed22e2df3611a6713ec9d77a3015d1cd6a578b3f6", "token_estimator": "heuristic-v1" }, { - "id": "reference-polkadot-hub-consensus-and-security-agile-coretime", - "title": "Agile Coretime", - "slug": "reference-polkadot-hub-consensus-and-security-agile-coretime", + "id": "smart-contracts-cookbook-dapps-zero-to-hero", + "title": "Zero to Hero Smart Contract DApp", + "slug": "smart-contracts-cookbook-dapps-zero-to-hero", "categories": [ - "Polkadot Protocol" + "dApp", + "Tooling" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-agile-coretime.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/agile-coretime/", - "preview": "Agile Coretime is the [scheduling](https://en.wikipedia.org/wiki/Scheduling_(computing)){target=\\_blank} framework on Polkadot that lets parachains efficiently access cores, which comprise an active validator set tasked with parablock validation. As the first blockchain to enable a flexible scheduling system for blockspace production, Polkadot offers unparalleled adaptability for parachains.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-dapps-zero-to-hero.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/dapps/zero-to-hero/", + "preview": "Decentralized applications (dApps) are a key component of the Web3 ecosystem, enabling developers to build applications that communicate directly with blockchain networks. Polkadot Hub, a blockchain with smart contract support, serves as a robust platform for deploying and interacting with dApps.", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Bulk Coretime", - "anchor": "bulk-coretime" + "title": "Project Overview", + "anchor": "project-overview" + }, + { + "depth": 2, + "title": "Create and Deploy the Storage Contract", + "anchor": "create-and-deploy-the-storage-contract" }, { "depth": 3, - "title": "Coretime Interlacing", - "anchor": "coretime-interlacing" + "title": "Set Up Hardhat Project", + "anchor": "set-up-hardhat-project" }, { "depth": 3, - "title": "Coretime Splitting", - "anchor": "coretime-splitting" + "title": "Create the Storage Contract", + "anchor": "create-the-storage-contract" }, { - "depth": 2, - "title": "On-Demand Coretime", - "anchor": "on-demand-coretime" - } - ], - "stats": { - "chars": 3028, - "words": 452, - "headings": 5, - "estimated_token_count_total": 619 - }, - "hash": "sha256:00be43ac8d666bbe15c5c2fa5a5085697d0bb5a6f341ebbb943a209f0be355df", - "last_modified": "2025-10-28T14:42:15+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-polkadot-hub-consensus-and-security-pos-consensus", - "title": "Proof of Stake Consensus", - "slug": "reference-polkadot-hub-consensus-and-security-pos-consensus", - "categories": [ - "Polkadot Protocol" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-pos-consensus.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/pos-consensus/", - "preview": "Polkadot's Proof of Stake consensus model leverages a unique hybrid approach by design to promote decentralized and secure network operations. In traditional Proof of Stake (PoS) systems, a node's ability to validate transactions is tied to its token holdings, which can lead to centralization risks and limited validator participation. Polkadot addresses these concerns through its [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\\_blank} model and a com", - "outline": [ + "depth": 3, + "title": "Configure Hardhat for Polkadot Hub", + "anchor": "configure-hardhat-for-polkadot-hub" + }, + { + "depth": 3, + "title": "Compile the Contract", + "anchor": "compile-the-contract" + }, + { + "depth": 3, + "title": "Deploy the Contract", + "anchor": "deploy-the-contract" + }, + { + "depth": 3, + "title": "Export the Contract ABI", + "anchor": "export-the-contract-abi" + }, { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Set Up the dApp Project", + "anchor": "set-up-the-dapp-project" }, { "depth": 2, - "title": "Nominated Proof of Stake", - "anchor": "nominated-proof-of-stake" + "title": "Install Dependencies", + "anchor": "install-dependencies" }, { "depth": 2, - "title": "Hybrid Consensus", - "anchor": "hybrid-consensus" + "title": "Connect to Polkadot Hub", + "anchor": "connect-to-polkadot-hub" }, { "depth": 2, - "title": "Block Production - BABE", - "anchor": "block-production-babe" + "title": "Set Up the Smart Contract Interface", + "anchor": "set-up-the-smart-contract-interface" }, { - "depth": 3, - "title": "Validator Participation", - "anchor": "validator-participation" + "depth": 2, + "title": "Create the Wallet Connection Component", + "anchor": "create-the-wallet-connection-component" }, { - "depth": 3, - "title": "Additional Resources", - "anchor": "additional-resources" + "depth": 2, + "title": "Create the Read Contract Component", + "anchor": "create-the-read-contract-component" }, { "depth": 2, - "title": "Finality Gadget - GRANDPA", - "anchor": "finality-gadget-grandpa" + "title": "Create the Write Contract Component", + "anchor": "create-the-write-contract-component" }, { - "depth": 3, - "title": "Probabilistic vs. Provable Finality", - "anchor": "probabilistic-vs-provable-finality" + "depth": 2, + "title": "How It Works", + "anchor": "how-it-works" }, { "depth": 3, - "title": "Additional Resources", - "anchor": "additional-resources-2" + "title": "Wallet Connection", + "anchor": "wallet-connection" }, { - "depth": 2, - "title": "Fork Choice", - "anchor": "fork-choice" + "depth": 3, + "title": "Data Reads", + "anchor": "data-reads" }, { "depth": 3, - "title": "Additional Resources", - "anchor": "additional-resources-3" + "title": "Data Writes", + "anchor": "data-writes" }, { "depth": 2, - "title": "Bridging - BEEFY", - "anchor": "bridging-beefy" + "title": "Conclusion", + "anchor": "conclusion" }, { - "depth": 3, - "title": "Additional Resources", - "anchor": "additional-resources-4" + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 12753, - "words": 1834, - "headings": 13, - "estimated_token_count_total": 2526 + "chars": 31207, + "words": 3688, + "headings": 22, + "estimated_token_count_total": 6967 }, - "hash": "sha256:231fc555eefe5f910fb36e0c03945147d0fb235272850797391751f4444b0a9c", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:b200f93a9179f0b2588ba722dd4c118536136faf3c39eabccf4abf5c346f78a8", "token_estimator": "heuristic-v1" }, { - "id": "reference-polkadot-hub-consensus-and-security-relay-chain", - "title": "Overview of the Polkadot Relay Chain", - "slug": "reference-polkadot-hub-consensus-and-security-relay-chain", + "id": "smart-contracts-cookbook-eth-dapps-uniswap-v2", + "title": "Deploying Uniswap V2 on Polkadot", + "slug": "smart-contracts-cookbook-eth-dapps-uniswap-v2", "categories": [ - "Basics", - "Polkadot Protocol", - "Parachains" + "dApps", + "Tooling" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-consensus-and-security-relay-chain.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/consensus-and-security/relay-chain/", - "preview": "Polkadot is a next-generation blockchain protocol designed to support a multi-chain future by enabling secure communication and interoperability between different blockchains. Built as a Layer-0 protocol, Polkadot introduces innovations like application-specific Layer-1 chains ([parachains](/polkadot-protocol/architecture/parachains/){targe=\\_blank}), shared security through [Nominated Proof of Stake (NPoS)](/reference/glossary/#nominated-proof-of-stake-npos){target=\\_blank}, and cross-chain int", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-eth-dapps-uniswap-v2.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/eth-dapps/uniswap-v2/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", "outline": [ { "depth": 2, @@ -12243,579 +10094,573 @@ }, { "depth": 2, - "title": "Polkadot 1.0", - "anchor": "polkadot-10" - }, - { - "depth": 3, - "title": "High-Level Architecture", - "anchor": "high-level-architecture" - }, - { - "depth": 3, - "title": "Polkadot's Additional Functionalities", - "anchor": "polkadots-additional-functionalities" - }, - { - "depth": 3, - "title": "Polkadot's Resilience", - "anchor": "polkadots-resilience" - }, - { - "depth": 3, - "title": "Polkadot's Blockspace", - "anchor": "polkadots-blockspace" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "DOT Token", - "anchor": "dot-token" + "title": "Set Up the Project", + "anchor": "set-up-the-project" }, { - "depth": 3, - "title": "Redenomination of DOT", - "anchor": "redenomination-of-dot" + "depth": 2, + "title": "Understanding Uniswap V2 Architecture", + "anchor": "understanding-uniswap-v2-architecture" }, { - "depth": 3, - "title": "The Planck Unit", - "anchor": "the-planck-unit" + "depth": 2, + "title": "Test the Contracts", + "anchor": "test-the-contracts" }, { - "depth": 3, - "title": "Uses for DOT", - "anchor": "uses-for-dot" + "depth": 2, + "title": "Deploy the Contracts", + "anchor": "deploy-the-contracts" }, { "depth": 2, - "title": "JAM and the Road Ahead", - "anchor": "jam-and-the-road-ahead" + "title": "Conclusion", + "anchor": "conclusion" } ], "stats": { - "chars": 12430, - "words": 1771, - "headings": 11, - "estimated_token_count_total": 2571 + "chars": 11280, + "words": 1560, + "headings": 7, + "estimated_token_count_total": 2671 }, - "hash": "sha256:8a914e4309d4fe7070e62d7abe4665b6c76c8dc5ec3219332eccb16b77b0dd95", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:2a42198668c759f63aa602115bf2d290ec7d03bbc3a3df20e30e85027e1b1cc3", "token_estimator": "heuristic-v1" }, { - "id": "reference-polkadot-hub-people-and-identity", - "title": "People Chain", - "slug": "reference-polkadot-hub-people-and-identity", + "id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", + "title": "Deploy a Basic Contract to Polkadot Hub", + "slug": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "categories": [ - "Polkadot Protocol" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-polkadot-hub-people-and-identity.md", - "html_url": "https://docs.polkadot.com/reference/polkadot-hub/people-and-identity/", - "preview": "People chain is a specialized parachain within the Polkadot ecosystem dedicated to secure, decentralized identity management.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/.deploy-basic-pvm/", + "preview": "Deploying smart contracts to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\\_blank} can be accomplished through various tools and environments, each suited to different development workflows. This guide demonstrates how to deploy a basic PolkaVM (PVM) smart contract using four popular approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\\_blank}, [Remix IDE](https://remix.live/){target=\\_blank}, [Hardhat](https://hardhat.org/){target=\\_blank}", "outline": [ { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "depth": 2, + "title": "Introduction", + "anchor": "introduction" + }, + { + "depth": 2, + "title": "JavaScript with Ethers.js", + "anchor": "javascript-with-ethersjs" + }, + { + "depth": 3, + "title": "Setup", + "anchor": "setup" + }, + { + "depth": 3, + "title": "Create and Compile Your Contract", + "anchor": "create-and-compile-your-contract" + }, + { + "depth": 3, + "title": "Deploy the Contract", + "anchor": "deploy-the-contract" }, { "depth": 2, - "title": "Identity Management System", - "anchor": "identity-management-system" + "title": "Remix IDE", + "anchor": "remix-ide" }, { "depth": 3, - "title": "Sub-Identities", - "anchor": "sub-identities" + "title": "Access Remix", + "anchor": "access-remix" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy" }, { "depth": 2, - "title": "Verification Process", - "anchor": "verification-process" + "title": "Hardhat", + "anchor": "hardhat" }, { "depth": 3, - "title": "Judgment Requests", - "anchor": "judgment-requests" + "title": "Setup", + "anchor": "setup-2" }, { "depth": 3, - "title": "Judgment Classifications", - "anchor": "judgment-classifications" + "title": "Configure Hardhat", + "anchor": "configure-hardhat" }, { "depth": 3, - "title": "Registrars", - "anchor": "registrars" + "title": "Create Your Contract", + "anchor": "create-your-contract" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" - } - ], - "stats": { - "chars": 4750, - "words": 606, - "headings": 8, - "estimated_token_count_total": 876 - }, - "hash": "sha256:8239d1e8d8642cb7c10e9e5f971c99b999e9e4a87373b50bf4a691225c1e4702", - "last_modified": "2025-10-28T14:42:15+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-chopsticks", - "title": "reference-tools-chopsticks", - "slug": "reference-tools-chopsticks", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-chopsticks.md", - "html_url": "https://docs.polkadot.com/reference/tools/chopsticks/", - "preview": "TODO", - "outline": [], - "stats": { - "chars": 5, - "words": 1, - "headings": 0, - "estimated_token_count_total": 0 - }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:15+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "reference-tools-dedot", - "title": "Dedot", - "slug": "reference-tools-dedot", - "categories": [ - "Tooling", - "Dapps" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-dedot.md", - "html_url": "https://docs.polkadot.com/reference/tools/dedot/", - "preview": "[Dedot](https://github.com/dedotdev/dedot){target=\\_blank} is a next-generation JavaScript client for Polkadot and Polkadot SDK-based blockchains. Designed to elevate the dApp development experience, Dedot is built and optimized to be lightweight and tree-shakable, offering precise types and APIs suggestions for individual Polkadot SDK-based blockchains and [ink! smart contracts](https://use.ink/){target=\\_blank}.", - "outline": [ + "depth": 3, + "title": "Compile", + "anchor": "compile-2" + }, { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "depth": 3, + "title": "Set Up Deployment", + "anchor": "set-up-deployment" }, { "depth": 3, - "title": "Key Features", - "anchor": "key-features" + "title": "Deploy", + "anchor": "deploy-2" }, { "depth": 2, - "title": "Installation", - "anchor": "installation" + "title": "Foundry", + "anchor": "foundry" }, { - "depth": 2, - "title": "Get Started", - "anchor": "get-started" + "depth": 3, + "title": "Setup", + "anchor": "setup-3" }, { "depth": 3, - "title": "Initialize a Client Instance", - "anchor": "initialize-a-client-instance" + "title": "Configure Foundry", + "anchor": "configure-foundry" }, { "depth": 3, - "title": "Enable Type and API Suggestions", - "anchor": "enable-type-and-api-suggestions" + "title": "Create Your Contract", + "anchor": "create-your-contract-2" }, { "depth": 3, - "title": "Read On-Chain Data", - "anchor": "read-on-chain-data" + "title": "Compile", + "anchor": "compile-3" }, { "depth": 3, - "title": "Sign and Send Transactions", - "anchor": "sign-and-send-transactions" + "title": "Deploy", + "anchor": "deploy-3" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Conclusion", + "anchor": "conclusion" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" } ], "stats": { - "chars": 8855, - "words": 1100, - "headings": 9, - "estimated_token_count_total": 2300 + "chars": 13872, + "words": 1640, + "headings": 24, + "estimated_token_count_total": 3228 }, - "hash": "sha256:ba24e31e2ad94fbf1d73f1878da92dd2e1476db00170780bbdf0e65ab18bc961", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:8f29b0f0b56f8c136206211a858cdc5bc27bcd9119eab179a6cd306182d910cb", "token_estimator": "heuristic-v1" }, { - "id": "reference-tools-light-clients", - "title": "Light Clients", - "slug": "reference-tools-light-clients", + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js", + "title": "JavaScript with Ethers.js", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js", "categories": [ - "Parachains", - "Tooling" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-light-clients.md", - "html_url": "https://docs.polkadot.com/reference/tools/light-clients/", - "preview": "Light clients enable secure and efficient blockchain interaction without running a full node. They provide a trust-minimized alternative to JSON-RPC by verifying data through cryptographic proofs rather than blindly trusting remote nodes.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-ethers-js/", + "preview": "[Ethers.js](https://docs.ethers.org/v6/){target=\\_blank} provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications.", "outline": [ { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Light Clients Workflow", - "anchor": "light-clients-workflow" - }, - { - "depth": 2, - "title": "JSON-RPC and Light Client Comparison", - "anchor": "json-rpc-and-light-client-comparison" - }, - { - "depth": 2, - "title": "Using Light Clients", - "anchor": "using-light-clients" + "depth": 3, + "title": "Setup", + "anchor": "setup" }, { "depth": 3, - "title": "PAPI Light Client Support", - "anchor": "papi-light-client-support" + "title": "Create and Compile Your Contract", + "anchor": "create-and-compile-your-contract" }, { "depth": 3, - "title": "Substrate Connect - Browser Extension", - "anchor": "substrate-connect-browser-extension" + "title": "Deploy the Contract", + "anchor": "deploy-the-contract" }, { - "depth": 2, - "title": "Resources", - "anchor": "resources" + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" } ], "stats": { - "chars": 6490, - "words": 870, - "headings": 7, - "estimated_token_count_total": 1430 + "chars": 6935, + "words": 767, + "headings": 4, + "estimated_token_count_total": 1490 }, - "hash": "sha256:1284c42be692167e01bcc44e2e134ec20615402675fac26df246c00aa1588d80", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:b0af34b460192f665ca70e7d7985e87b9f59a1a359888f6d14d651daedbcd711", "token_estimator": "heuristic-v1" }, { - "id": "reference-tools-moonwall", - "title": "E2E Testing with Moonwall", - "slug": "reference-tools-moonwall", + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry", + "title": "Foundry", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry", "categories": [ - "Parachains", - "Tooling" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-moonwall.md", - "html_url": "https://docs.polkadot.com/reference/tools/moonwall/", - "preview": "Moonwall is an end-to-end testing framework designed explicitly for Polkadot SDK-based blockchain networks. It addresses one of the most significant challenges in blockchain development: managing complex test environments and network configurations.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-foundry/", + "preview": "[Foundry](https://getfoundry.sh/){target=\\_blank} offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment.", "outline": [ - { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Install Moonwall", - "anchor": "install-moonwall" - }, { "depth": 3, - "title": "Global Installation", - "anchor": "global-installation" + "title": "Setup", + "anchor": "setup" }, { "depth": 3, - "title": "Local Installation", - "anchor": "local-installation" + "title": "Configure Foundry", + "anchor": "configure-foundry" }, { - "depth": 2, - "title": "Initialize Moonwall", - "anchor": "initialize-moonwall" + "depth": 3, + "title": "Create Your Contract", + "anchor": "create-your-contract" }, { - "depth": 2, - "title": "Writing Tests", - "anchor": "writing-tests" + "depth": 3, + "title": "Compile", + "anchor": "compile" }, { - "depth": 2, - "title": "Running the Tests", - "anchor": "running-the-tests" + "depth": 3, + "title": "Deploy", + "anchor": "deploy" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" } ], "stats": { - "chars": 10240, - "words": 1295, - "headings": 9, - "estimated_token_count_total": 2453 + "chars": 2125, + "words": 276, + "headings": 6, + "estimated_token_count_total": 429 }, - "hash": "sha256:2c77cfb38bb2e466a8f56dabbb706fcd2e90cf1634fc9beb7f0ee95a75735653", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:f7687b9a1e80ab381cf4fb24f37cccfb98ddf139bf687e8832af99364ef0a8a9", "token_estimator": "heuristic-v1" }, { - "id": "reference-tools-omninode", - "title": "Polkadot Omni Node", - "slug": "reference-tools-omninode", + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat", + "title": "hardhat", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat", "categories": [ - "Parachains", - "Tooling" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-omninode.md", - "html_url": "https://docs.polkadot.com/reference/tools/omninode/", - "preview": "The [`polkadot-omni-node`](https://crates.io/crates/polkadot-omni-node/0.7.0){target=\\_blank} crate is a versatile, pre-built binary designed to simplify running parachains in the Polkadot ecosystem. Unlike traditional node binaries that are tightly coupled to specific runtime code, the `polkadot-omni-node` operates using an external [chain specification](/polkadot-protocol/glossary#chain-specification){target=\\_blank} file, allowing it to adapt dynamically to different parachains.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-hardhat/", + "preview": "[Hardhat](https://hardhat.org/){target=\\_blank} provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects.", "outline": [ { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" - }, - { - "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" - }, - { - "depth": 2, - "title": "Install Polkadot Omni Node", - "anchor": "install-polkadot-omni-node" + "depth": 3, + "title": "Setup", + "anchor": "setup" }, { - "depth": 2, - "title": "Obtain Chain Specifications", - "anchor": "obtain-chain-specifications" + "depth": 3, + "title": "Configure Hardhat", + "anchor": "configure-hardhat" }, { - "depth": 2, - "title": "Run a Parachain Full Node", - "anchor": "run-a-parachain-full-node" + "depth": 3, + "title": "Create Your Contract", + "anchor": "create-your-contract" }, { - "depth": 2, - "title": "Interact with the Node", - "anchor": "interact-with-the-node" + "depth": 3, + "title": "Compile", + "anchor": "compile" }, { - "depth": 2, - "title": "Parachain Compatibility", - "anchor": "parachain-compatibility" + "depth": 3, + "title": "Set Up Deployment", + "anchor": "set-up-deployment" }, { "depth": 3, - "title": "Required Runtime APIs", - "anchor": "required-runtime-apis" + "title": "Deploy", + "anchor": "deploy" }, { "depth": 3, - "title": "Required Pallets", - "anchor": "required-pallets" + "title": "Next Steps", + "anchor": "next-steps" } ], "stats": { - "chars": 8916, - "words": 1165, - "headings": 9, - "estimated_token_count_total": 2018 + "chars": 3336, + "words": 375, + "headings": 7, + "estimated_token_count_total": 672 }, - "hash": "sha256:a87815deff81936d7f50842f8600004990076c1a33e7e6b408ab954b6ce47259", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:93ca24da15095dd0bb03657f53d27771934aee055c11af529445a50e161f79a3", "token_estimator": "heuristic-v1" }, { - "id": "reference-tools-papi", - "title": "Polkadot-API", - "slug": "reference-tools-papi", + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix", + "title": "Remix IDE", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix", "categories": [ - "Tooling", - "Dapps" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-papi.md", - "html_url": "https://docs.polkadot.com/reference/tools/papi/", - "preview": "[Polkadot-API](https://github.com/polkadot-api/polkadot-api){target=\\_blank} (PAPI) is a set of libraries built to be modular, composable, and grounded in a “light-client first” approach. Its primary aim is to equip dApp developers with an extensive toolkit for building fully decentralized applications.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-remix/", + "preview": "[Remix IDE](https://remix.live/){target=\\_blank} offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development.", "outline": [ { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "depth": 3, + "title": "Access Remix", + "anchor": "access-remix" }, { - "depth": 2, - "title": "Get Started", - "anchor": "get-started" + "depth": 3, + "title": "Compile", + "anchor": "compile" }, { "depth": 3, - "title": "API Instantiation", - "anchor": "api-instantiation" + "title": "Deploy", + "anchor": "deploy" }, { "depth": 3, - "title": "Reading Chain Data", - "anchor": "reading-chain-data" + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 2473, + "words": 363, + "headings": 4, + "estimated_token_count_total": 527 + }, + "hash": "sha256:56d730c8a6d2ccf0324caf1c3f30929a93904f80e482cfcb457541e04482dbad", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js", + "title": "JavaScript with Ethers.js", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-ethers-js/", + "preview": "[Ethers.js](https://docs.ethers.org/v6/){target=\\_blank} provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications.", + "outline": [ + { + "depth": 3, + "title": "Setup", + "anchor": "setup" }, { "depth": 3, - "title": "Sending Transactions", - "anchor": "sending-transactions" + "title": "Create and Compile Your Contract", + "anchor": "create-and-compile-your-contract" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "depth": 3, + "title": "Deploy the Contract", + "anchor": "deploy-the-contract" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" } ], "stats": { - "chars": 8957, - "words": 1156, - "headings": 6, - "estimated_token_count_total": 1987 + "chars": 6935, + "words": 767, + "headings": 4, + "estimated_token_count_total": 1490 }, - "hash": "sha256:2ca93b09d3bb9159bbf53816886a9b242bb3c13b996c51fd52962e049e2d5477", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:b0af34b460192f665ca70e7d7985e87b9f59a1a359888f6d14d651daedbcd711", "token_estimator": "heuristic-v1" }, { - "id": "reference-tools-paraspell", - "title": "ParaSpell XCM SDK", - "slug": "reference-tools-paraspell", + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry", + "title": "Foundry", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry", "categories": [ - "Uncategorized" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-paraspell.md", - "html_url": "https://docs.polkadot.com/reference/tools/paraspell/", - "preview": "[ParaSpell](https://paraspell.github.io/docs/){target=\\_blank} is a comprehensive suite of open-source tools designed to simplify cross-chain interactions within the Polkadot ecosystem. At its core, ParaSpell is dedicated to enhancing the functionality of the [XCM (Cross-Consensus Messaging)](/parachains/interoperability/get-started/){target=\\_blank} protocol by providing developers with a unified and streamlined experience for building interoperable decentralized applications (dApps).", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-foundry/", + "preview": "[Foundry](https://getfoundry.sh/){target=\\_blank} offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment.", "outline": [ { - "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "depth": 3, + "title": "Setup", + "anchor": "setup" }, { "depth": 3, - "title": "ParaSpell XCM SDK", - "anchor": "paraspell-xcm-sdk" + "title": "Configure Foundry", + "anchor": "configure-foundry" + }, + { + "depth": 3, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" } ], "stats": { - "chars": 3005, - "words": 433, - "headings": 2, - "estimated_token_count_total": 669 + "chars": 2125, + "words": 276, + "headings": 6, + "estimated_token_count_total": 429 }, - "hash": "sha256:a7f9c4a03153ee637a0557d2cea0b622c849667ce793b1294bb3299cf036197d", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:f7687b9a1e80ab381cf4fb24f37cccfb98ddf139bf687e8832af99364ef0a8a9", "token_estimator": "heuristic-v1" }, { - "id": "reference-tools-polkadart", - "title": "Polkadart", - "slug": "reference-tools-polkadart", + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat", + "title": "hardhat", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat", "categories": [ - "Tooling", - "Dapps" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadart.md", - "html_url": "https://docs.polkadot.com/reference/tools/polkadart/", - "preview": "Polkadart is the most comprehensive Dart/Flutter SDK for interacting with Polkadot, Substrate, and other compatible blockchain networks. Designed with a Dart-first approach and type-safe APIs, it provides everything developers need to build powerful decentralized applications.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-hardhat/", + "preview": "[Hardhat](https://hardhat.org/){target=\\_blank} provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects.", "outline": [ { - "depth": 2, - "title": "Installation", - "anchor": "installation" + "depth": 3, + "title": "Setup", + "anchor": "setup" }, { - "depth": 2, - "title": "Get Started", - "anchor": "get-started" + "depth": 3, + "title": "Configure Hardhat", + "anchor": "configure-hardhat" }, { "depth": 3, - "title": "Type Generation", - "anchor": "type-generation" + "title": "Create Your Contract", + "anchor": "create-your-contract" }, { "depth": 3, - "title": "Run Generator", - "anchor": "run-generator" + "title": "Compile", + "anchor": "compile" }, { "depth": 3, - "title": "Use Generated Types", - "anchor": "use-generated-types" + "title": "Set Up Deployment", + "anchor": "set-up-deployment" }, { "depth": 3, - "title": "Creating an API Instance", - "anchor": "creating-an-api-instance" + "title": "Deploy", + "anchor": "deploy" }, { "depth": 3, - "title": "Reading Chain Data", - "anchor": "reading-chain-data" + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 3336, + "words": 375, + "headings": 7, + "estimated_token_count_total": 672 + }, + "hash": "sha256:93ca24da15095dd0bb03657f53d27771934aee055c11af529445a50e161f79a3", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix", + "title": "Remix IDE", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-remix/", + "preview": "[Remix IDE](https://remix.live/){target=\\_blank} offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development.", + "outline": [ + { + "depth": 3, + "title": "Access Remix", + "anchor": "access-remix" }, { "depth": 3, - "title": "Subscribe to New Blocks", - "anchor": "subscribe-to-new-blocks" + "title": "Compile", + "anchor": "compile" }, { "depth": 3, - "title": "Send a Transaction", - "anchor": "send-a-transaction" + "title": "Deploy", + "anchor": "deploy" }, { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" } ], "stats": { - "chars": 5178, - "words": 624, - "headings": 10, - "estimated_token_count_total": 1084 + "chars": 2473, + "words": 363, + "headings": 4, + "estimated_token_count_total": 527 }, - "hash": "sha256:7f533abe61586af8438e350c41b741d74a8edb839f9dc4139bc4619ba3748258", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:56d730c8a6d2ccf0324caf1c3f30929a93904f80e482cfcb457541e04482dbad", "token_estimator": "heuristic-v1" }, { - "id": "reference-tools-polkadot-js-api", - "title": "Polkadot.js API", - "slug": "reference-tools-polkadot-js-api", + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-ethers", + "title": "Deploy a Basic Contract with Ethers.js", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-ethers", "categories": [ - "Tooling", - "Dapps" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-polkadot-js-api.md", - "html_url": "https://docs.polkadot.com/reference/tools/polkadot-js-api/", - "preview": "!!! warning \"Maintenance Mode Only\" The Polkadot.js API is now in maintenance mode and is no longer actively developed. New projects should use [Dedot](/develop/toolkit/api-libraries/dedot){target=\\_blank} (TypeScript-first API) or [Polkadot API](/develop/toolkit/api-libraries/papi){target=\\_blank} (modern, type-safe API) as actively maintained alternatives.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-ethers.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/ethers/", + "preview": "This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Ethers.js](https://docs.ethers.org/v6/){target=\\_blank}, which provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications.", "outline": [ { "depth": 2, @@ -12823,97 +10668,126 @@ "anchor": "introduction" }, { - "depth": 3, - "title": "Dynamic API Generation", - "anchor": "dynamic-api-generation" + "depth": 2, + "title": "Prerequisites", + "anchor": "prerequisites" }, { - "depth": 3, - "title": "Available API Categories", - "anchor": "available-api-categories" + "depth": 2, + "title": "Set Up Your Project", + "anchor": "set-up-your-project" + }, + { + "depth": 2, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 2, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 2, + "title": "Deploy", + "anchor": "deploy" }, { "depth": 2, - "title": "Installation", - "anchor": "installation" + "title": "Where to Go Next", + "anchor": "where-to-go-next" + } + ], + "stats": { + "chars": 7370, + "words": 823, + "headings": 7, + "estimated_token_count_total": 1729 + }, + "hash": "sha256:ff8975b44870613c3aef0907df365f1ac981de74ec83019df232fe4bda6d9dbe", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-evm", + "title": "Deploy a Basic Contract to EVM", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-evm", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-evm.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-evm/", + "preview": "Deploying smart contracts to the [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\\_blank} can be accomplished using standard EVM development tools and workflows. This guide demonstrates how to deploy a basic smart contract using four popular EVM approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\\_blank}, [Remix IDE](https://remix.live/){target=\\_blank}, [Hardhat](https://hardhat.org/){target=\\_blank}, and [Foundry](https://getfoundry.sh/){ta", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Get Started", - "anchor": "get-started" + "title": "Deployment options", + "anchor": "deployment-options" }, { - "depth": 3, - "title": "Creating an API Instance", - "anchor": "creating-an-api-instance" - }, - { - "depth": 3, - "title": "Reading Chain Data", - "anchor": "reading-chain-data" + "depth": 2, + "title": "Conclusion", + "anchor": "conclusion" }, { "depth": 3, - "title": "Sending Transactions", - "anchor": "sending-transactions" - }, - { - "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Next Steps", + "anchor": "next-steps" } ], "stats": { - "chars": 5042, - "words": 684, - "headings": 9, - "estimated_token_count_total": 1166 + "chars": 15629, + "words": 1659, + "headings": 4, + "estimated_token_count_total": 3341 }, - "hash": "sha256:ed3986f30880fefca5975fcdc847c68b4aca65862c63e3002b25391b0521781d", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:a4fd853afb897985602e0356551edacbce77db60bbc6556de3b6ae5af3fbc9e5", "token_estimator": "heuristic-v1" }, { - "id": "reference-tools-py-substrate-interface", - "title": "Python Substrate Interface", - "slug": "reference-tools-py-substrate-interface", + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-foundry", + "title": "Deploy a Basic Contract with Foundry", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-foundry", "categories": [ - "Tooling", - "Dapps" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-py-substrate-interface.md", - "html_url": "https://docs.polkadot.com/reference/tools/py-substrate-interface/", - "preview": "The [Python Substrate Interface](https://github.com/polkascan/py-substrate-interface){target=\\_blank} is a powerful library that enables interaction with Polkadot SDK-based chains. It provides essential functionality for:", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-foundry.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/foundry/", + "preview": "This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Foundry](https://getfoundry.sh/){target=\\_blank}, which offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment.", "outline": [ { "depth": 2, - "title": "Introduction", - "anchor": "introduction" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Installation", - "anchor": "installation" + "title": "Set Up Your Project", + "anchor": "set-up-your-project" }, { "depth": 2, - "title": "Get Started", - "anchor": "get-started" + "title": "Configure Foundry", + "anchor": "configure-foundry" }, { - "depth": 3, - "title": "Establishing Connection", - "anchor": "establishing-connection" + "depth": 2, + "title": "Create Your Contract", + "anchor": "create-your-contract" }, { - "depth": 3, - "title": "Reading Chain State", - "anchor": "reading-chain-state" + "depth": 2, + "title": "Compile", + "anchor": "compile" }, { - "depth": 3, - "title": "Submitting Transactions", - "anchor": "submitting-transactions" + "depth": 2, + "title": "Deploy", + "anchor": "deploy" }, { "depth": 2, @@ -12922,26 +10796,24 @@ } ], "stats": { - "chars": 4302, - "words": 541, + "chars": 2731, + "words": 355, "headings": 7, - "estimated_token_count_total": 942 + "estimated_token_count_total": 598 }, - "hash": "sha256:8987fc35cd28602054ee018031f773e2e3837425107c51d0e2ac68a94b86e9c0", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:63defd84f302f0778c90129abbe69ecd2a5d9d83c622f2b7e5c2ffc9bcb3312f", "token_estimator": "heuristic-v1" }, { - "id": "reference-tools-sidecar", - "title": "Sidecar REST API", - "slug": "reference-tools-sidecar", + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", + "title": "Deploy a Basic Contract with Hardhat", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", "categories": [ - "Tooling", - "Dapps" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-sidecar.md", - "html_url": "https://docs.polkadot.com/reference/tools/sidecar/", - "preview": "The [Sidecar REST API](https://github.com/paritytech/substrate-api-sidecar){target=\\_blank} is a service that provides a REST interface for interacting with Polkadot SDK-based blockchains. With this API, developers can easily access a broad range of endpoints for nodes, accounts, transactions, parachains, and more.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/hardhat/", + "preview": "This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Hardhat](https://hardhat.org/){target=\\_blank}, which provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects.", "outline": [ { "depth": 2, @@ -12955,18 +10827,33 @@ }, { "depth": 2, - "title": "Installation", - "anchor": "installation" + "title": "Set Up Your Project", + "anchor": "set-up-your-project" }, { "depth": 2, - "title": "Usage", - "anchor": "usage" + "title": "Configure Hardhat", + "anchor": "configure-hardhat" }, { - "depth": 3, - "title": "Endpoints", - "anchor": "endpoints" + "depth": 2, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 2, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 2, + "title": "Set Up Deployment", + "anchor": "set-up-deployment" + }, + { + "depth": 2, + "title": "Deploy the Contract", + "anchor": "deploy-the-contract" }, { "depth": 2, @@ -12975,26 +10862,24 @@ } ], "stats": { - "chars": 7309, - "words": 1033, - "headings": 6, - "estimated_token_count_total": 1945 + "chars": 4051, + "words": 475, + "headings": 9, + "estimated_token_count_total": 981 }, - "hash": "sha256:0795462182cb97256bb5c2acb035855fe0d6557185de8ac99482725ecb4f94c1", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:98f5c5c1a26db913e1c4c435062d214ca8c4b5f2dbed5b64d2e54c3435f06452", "token_estimator": "heuristic-v1" }, { - "id": "reference-tools-subxt", - "title": "Subxt Rust API", - "slug": "reference-tools-subxt", + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", + "title": "Deploy a Basic Contract to Polkadot Hub", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "categories": [ - "Tooling", - "Dapps" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-subxt.md", - "html_url": "https://docs.polkadot.com/reference/tools/subxt/", - "preview": "Subxt is a Rust library designed to interact with Polkadot SDK-based blockchains. It provides a type-safe interface for submitting transactions, querying on-chain state, and performing other blockchain interactions. By leveraging Rust's strong type system, subxt ensures that your code is validated at compile time, reducing runtime errors and improving reliability.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-pvm.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-pvm/", + "preview": "Deploying smart contracts to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\\_blank} can be accomplished through various tools and environments, each suited to different development workflows. This guide demonstrates how to deploy a basic PolkaVM (PVM) smart contract using four popular approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\\_blank}, [Remix IDE](https://remix.live/){target=\\_blank}, [Hardhat](https://hardhat.org/){target=\\_blank}", "outline": [ { "depth": 2, @@ -13003,72 +10888,139 @@ }, { "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" + "title": "JavaScript with Ethers.js", + "anchor": "javascript-with-ethersjs" + }, + { + "depth": 3, + "title": "Setup", + "anchor": "setup" + }, + { + "depth": 3, + "title": "Create and Compile Your Contract", + "anchor": "create-and-compile-your-contract" + }, + { + "depth": 3, + "title": "Deploy the Contract", + "anchor": "deploy-the-contract" }, { "depth": 2, - "title": "Installation", - "anchor": "installation" + "title": "Remix IDE", + "anchor": "remix-ide" + }, + { + "depth": 3, + "title": "Access Remix", + "anchor": "access-remix" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy" }, { "depth": 2, - "title": "Get Started", - "anchor": "get-started" + "title": "Hardhat", + "anchor": "hardhat" }, { "depth": 3, - "title": "Download Chain Metadata", - "anchor": "download-chain-metadata" + "title": "Setup", + "anchor": "setup-2" }, { "depth": 3, - "title": "Generate Type-Safe Interfaces", - "anchor": "generate-type-safe-interfaces" + "title": "Configure Hardhat", + "anchor": "configure-hardhat" }, { "depth": 3, - "title": "Initialize the Subxt Client", - "anchor": "initialize-the-subxt-client" + "title": "Create Your Contract", + "anchor": "create-your-contract" }, { "depth": 3, - "title": "Read Chain Data", - "anchor": "read-chain-data" + "title": "Compile", + "anchor": "compile-2" }, { "depth": 3, - "title": "Submit Transactions", - "anchor": "submit-transactions" + "title": "Set Up Deployment", + "anchor": "set-up-deployment" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy-2" }, { "depth": 2, - "title": "Where to Go Next", - "anchor": "where-to-go-next" + "title": "Foundry", + "anchor": "foundry" + }, + { + "depth": 3, + "title": "Setup", + "anchor": "setup-3" + }, + { + "depth": 3, + "title": "Configure Foundry", + "anchor": "configure-foundry" + }, + { + "depth": 3, + "title": "Create Your Contract", + "anchor": "create-your-contract-2" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile-3" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy-3" + }, + { + "depth": 2, + "title": "Conclusion", + "anchor": "conclusion" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" } ], "stats": { - "chars": 9174, - "words": 1175, - "headings": 10, - "estimated_token_count_total": 2187 + "chars": 13872, + "words": 1640, + "headings": 24, + "estimated_token_count_total": 3228 }, - "hash": "sha256:56269d9ea47f5b4e92cd7d5a1e65ab06d181a9c380f90bb3ef285529b12299f7", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:8f29b0f0b56f8c136206211a858cdc5bc27bcd9119eab179a6cd306182d910cb", "token_estimator": "heuristic-v1" }, { - "id": "reference-tools-xcm-tools", - "title": "XCM Tools", - "slug": "reference-tools-xcm-tools", + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-remix", + "title": "Deploy a Basic Contract with Remix IDE", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-remix", "categories": [ - "Basics", - "Tooling", - "Dapps" + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-xcm-tools.md", - "html_url": "https://docs.polkadot.com/reference/tools/xcm-tools/", - "preview": "As described in the [Interoperability](/develop/interoperability){target=\\_blank} section, XCM (Cross-Consensus Messaging) is a protocol used in the Polkadot and Kusama ecosystems to enable communication and interaction between chains. It facilitates cross-chain communication, allowing assets, data, and messages to flow seamlessly across the ecosystem.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-remix.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/remix/", + "preview": "This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Remix IDE](https://remix.ethereum.org/){target=\\_blank}, which offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development.", "outline": [ { "depth": 2, @@ -13077,54 +11029,48 @@ }, { "depth": 2, - "title": "Popular XCM Tools", - "anchor": "popular-xcm-tools" - }, - { - "depth": 3, - "title": "Moonsong Labs XCM Tools", - "anchor": "moonsong-labs-xcm-tools" + "title": "Prerequisites", + "anchor": "prerequisites" }, { - "depth": 3, - "title": "ParaSpell", - "anchor": "paraspell" + "depth": 2, + "title": "Access Remix", + "anchor": "access-remix" }, { - "depth": 3, - "title": "Astar XCM Tools", - "anchor": "astar-xcm-tools" + "depth": 2, + "title": "Compile", + "anchor": "compile" }, { - "depth": 3, - "title": "Chopsticks", - "anchor": "chopsticks" + "depth": 2, + "title": "Deploy", + "anchor": "deploy" }, { - "depth": 3, - "title": "Moonbeam XCM SDK", - "anchor": "moonbeam-xcm-sdk" + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], - "stats": { - "chars": 7524, - "words": 1043, - "headings": 7, - "estimated_token_count_total": 1700 + "stats": { + "chars": 2978, + "words": 430, + "headings": 6, + "estimated_token_count_total": 738 }, - "hash": "sha256:47328231d6ff4dc52cd93aaf1baf5d0bc2d9fc372f3d79339d87aafa0dabd1b8", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:0c00544ba0be9c0a6fa0c54bdb38045d64e95af714785b86e57f885a03b4b17a", "token_estimator": "heuristic-v1" }, { - "id": "reference-tools-zombienet", - "title": "reference-tools-zombienet", - "slug": "reference-tools-zombienet", + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic", + "title": "smart-contracts-cookbook-smart-contracts-deploy-basic", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic", "categories": [ "Uncategorized" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-zombienet.md", - "html_url": "https://docs.polkadot.com/reference/tools/zombienet/", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/", "preview": "TODO", "outline": [], "stats": { @@ -13134,29 +11080,49 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:15+00:00", "token_estimator": "heuristic-v1" }, { - "id": "smart-contracts-connect", - "title": "Connect to Polkadot", - "slug": "smart-contracts-connect", + "id": "smart-contracts-cookbook-smart-contracts-deploy-erc20-erc20-remix", + "title": "Deploy an ERC-20 to Polkadot Hub", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-erc20-erc20-remix", "categories": [ + "Basics", "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-connect.md", - "html_url": "https://docs.polkadot.com/smart-contracts/connect/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-erc20-erc20-remix.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-erc20/erc20-remix/", + "preview": "[ERC-20](https://eips.ethereum.org/EIPS/eip-20){target=\\_blank} tokens are fungible tokens commonly used for creating cryptocurrencies, governance tokens, and staking mechanisms. Polkadot Hub enables easy token deployment with Ethereum-compatible smart contracts and tools via the EVM backend.", "outline": [ { "depth": 2, - "title": "Networks Details", - "anchor": "networks-details" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Test Tokens", - "anchor": "test-tokens" + "title": "Prerequisites", + "anchor": "prerequisites" + }, + { + "depth": 2, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 2, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 2, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 2, + "title": "Interact with Your Contract", + "anchor": "interact-with-your-contract" }, { "depth": 2, @@ -13165,131 +11131,108 @@ } ], "stats": { - "chars": 3459, - "words": 476, - "headings": 3, - "estimated_token_count_total": 558 + "chars": 9109, + "words": 1260, + "headings": 7, + "estimated_token_count_total": 2182 }, - "hash": "sha256:a2490223926957381913ae0ed22e2df3611a6713ec9d77a3015d1cd6a578b3f6", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:0cb418d465a51230ece5d3a56d64754f979bc6c4ad78f2cc3df537b99739e627", "token_estimator": "heuristic-v1" }, { - "id": "smart-contracts-cookbook-dapps-zero-to-hero", - "title": "Zero to Hero Smart Contract DApp", - "slug": "smart-contracts-cookbook-dapps-zero-to-hero", + "id": "smart-contracts-cookbook-smart-contracts-deploy-erc20", + "title": "Deploy an ERC-20 to Polkadot Hub", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-erc20", "categories": [ - "dApp", - "Tooling" + "Basics", + "dApps", + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-dapps-zero-to-hero.md", - "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/dapps/zero-to-hero/", - "preview": "Decentralized applications (dApps) are a key component of the Web3 ecosystem, enabling developers to build applications that communicate directly with blockchain networks. Polkadot Hub, a blockchain with smart contract support, serves as a robust platform for deploying and interacting with dApps.", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-erc20.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-erc20/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", "outline": [ { "depth": 2, - "title": "Prerequisites", - "anchor": "prerequisites" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Project Overview", - "anchor": "project-overview" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Create and Deploy the Storage Contract", - "anchor": "create-and-deploy-the-storage-contract" - }, - { - "depth": 3, - "title": "Set Up Hardhat Project", - "anchor": "set-up-hardhat-project" - }, - { - "depth": 3, - "title": "Create the Storage Contract", - "anchor": "create-the-storage-contract" - }, - { - "depth": 3, - "title": "Configure Hardhat for Polkadot Hub", - "anchor": "configure-hardhat-for-polkadot-hub" + "title": "Create the ERC-20 Contract", + "anchor": "create-the-erc-20-contract" }, { - "depth": 3, + "depth": 2, "title": "Compile the Contract", "anchor": "compile-the-contract" }, { - "depth": 3, + "depth": 2, "title": "Deploy the Contract", "anchor": "deploy-the-contract" }, - { - "depth": 3, - "title": "Export the Contract ABI", - "anchor": "export-the-contract-abi" - }, - { - "depth": 2, - "title": "Set Up the dApp Project", - "anchor": "set-up-the-dapp-project" - }, - { - "depth": 2, - "title": "Install Dependencies", - "anchor": "install-dependencies" - }, { "depth": 2, - "title": "Connect to Polkadot Hub", - "anchor": "connect-to-polkadot-hub" - }, + "title": "Interact with Your ERC-20 Contract", + "anchor": "interact-with-your-erc-20-contract" + } + ], + "stats": { + "chars": 8926, + "words": 1207, + "headings": 6, + "estimated_token_count_total": 2107 + }, + "hash": "sha256:296cba75b1d49aefa1b8636ba95ca20c3431b7eb0e93b0658add671ef5801732", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-nft-ethers", + "title": "Deploy an NFT to Polkadot Hub with Ethers.js", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-nft-ethers", + "categories": [ + "Basics", + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-nft-ethers.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-nft/ethers/", + "preview": "Non-Fungible Tokens (NFTs) represent unique digital assets commonly used for digital art, collectibles, gaming, and identity verification.", + "outline": [ { "depth": 2, - "title": "Set Up the Smart Contract Interface", - "anchor": "set-up-the-smart-contract-interface" + "title": "Introduction", + "anchor": "introduction" }, { "depth": 2, - "title": "Create the Wallet Connection Component", - "anchor": "create-the-wallet-connection-component" + "title": "Prerequisites", + "anchor": "prerequisites" }, { "depth": 2, - "title": "Create the Read Contract Component", - "anchor": "create-the-read-contract-component" + "title": "Set Up Your Project", + "anchor": "set-up-your-project" }, { "depth": 2, - "title": "Create the Write Contract Component", - "anchor": "create-the-write-contract-component" + "title": "Create Your Contract", + "anchor": "create-your-contract" }, { "depth": 2, - "title": "How It Works", - "anchor": "how-it-works" - }, - { - "depth": 3, - "title": "Wallet Connection", - "anchor": "wallet-connection" - }, - { - "depth": 3, - "title": "Data Reads", - "anchor": "data-reads" - }, - { - "depth": 3, - "title": "Data Writes", - "anchor": "data-writes" + "title": "Compile", + "anchor": "compile" }, { "depth": 2, - "title": "Conclusion", - "anchor": "conclusion" + "title": "Deploy", + "anchor": "deploy" }, { "depth": 2, @@ -13298,26 +11241,25 @@ } ], "stats": { - "chars": 31203, - "words": 3688, - "headings": 22, - "estimated_token_count_total": 6967 + "chars": 8114, + "words": 912, + "headings": 7, + "estimated_token_count_total": 2015 }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:fdd65f6fe6d109043f11a26f1477e2bbbce1a440dbcb2b191eacfa79a28766e9", "token_estimator": "heuristic-v1" }, { - "id": "smart-contracts-cookbook-eth-dapps-uniswap-v2", - "title": "Deploying Uniswap V2 on Polkadot", - "slug": "smart-contracts-cookbook-eth-dapps-uniswap-v2", + "id": "smart-contracts-cookbook-smart-contracts-deploy-nft-foundry", + "title": "Deploy an NFT to Polkadot Hub with Foundry", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-nft-foundry", "categories": [ - "dApps", - "Tooling" + "Basics", + "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-eth-dapps-uniswap-v2.md", - "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/eth-dapps/uniswap-v2/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-nft-foundry.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-nft/foundry/", + "preview": "Non-Fungible Tokens (NFTs) represent unique digital assets commonly used for digital art, collectibles, gaming, and identity verification.", "outline": [ { "depth": 2, @@ -13331,73 +11273,55 @@ }, { "depth": 2, - "title": "Set Up the Project", - "anchor": "set-up-the-project" + "title": "Set Up Your Project", + "anchor": "set-up-your-project" }, { "depth": 2, - "title": "Understanding Uniswap V2 Architecture", - "anchor": "understanding-uniswap-v2-architecture" + "title": "Configure Foundry", + "anchor": "configure-foundry" }, { "depth": 2, - "title": "Test the Contracts", - "anchor": "test-the-contracts" + "title": "Create Your Contract", + "anchor": "create-your-contract" }, { "depth": 2, - "title": "Deploy the Contracts", - "anchor": "deploy-the-contracts" + "title": "Compile", + "anchor": "compile" }, { "depth": 2, - "title": "Conclusion", - "anchor": "conclusion" + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 11280, - "words": 1560, - "headings": 7, - "estimated_token_count_total": 2671 - }, - "hash": "sha256:2a42198668c759f63aa602115bf2d290ec7d03bbc3a3df20e30e85027e1b1cc3", - "last_modified": "2025-10-28T14:42:15+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "smart-contracts-cookbook-smart-contracts-deploy-basic", - "title": "smart-contracts-cookbook-smart-contracts-deploy-basic", - "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic", - "categories": [ - "Uncategorized" - ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic.md", - "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/", - "preview": "TODO", - "outline": [], - "stats": { - "chars": 5, - "words": 1, - "headings": 0, - "estimated_token_count_total": 0 + "chars": 3489, + "words": 438, + "headings": 8, + "estimated_token_count_total": 847 }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:c4b410125946db479b9c262a5132a31bb7730a778501c3a95910ad9d38007cf4", "token_estimator": "heuristic-v1" }, { - "id": "smart-contracts-cookbook-smart-contracts-deploy-erc20", - "title": "Deploy an ERC-20 to Polkadot Hub", - "slug": "smart-contracts-cookbook-smart-contracts-deploy-erc20", + "id": "smart-contracts-cookbook-smart-contracts-deploy-nft-hardhat", + "title": "Deploy an NFT to Polkadot Hub with Hardhat", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-nft-hardhat", "categories": [ "Basics", - "dApps", "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-erc20.md", - "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-erc20/", - "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-nft-hardhat.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-nft/hardhat/", + "preview": "Non-Fungible Tokens (NFTs) represent unique digital assets commonly used for digital art, collectibles, gaming, and identity verification.", "outline": [ { "depth": 2, @@ -13411,45 +11335,59 @@ }, { "depth": 2, - "title": "Create the ERC-20 Contract", - "anchor": "create-the-erc-20-contract" + "title": "Set Up Your Project", + "anchor": "set-up-your-project" }, { "depth": 2, - "title": "Compile the Contract", - "anchor": "compile-the-contract" + "title": "Configure Hardhat", + "anchor": "configure-hardhat" }, { "depth": 2, - "title": "Deploy the Contract", - "anchor": "deploy-the-contract" + "title": "Create Your Contract", + "anchor": "create-your-contract" }, { "depth": 2, - "title": "Interact with Your ERC-20 Contract", - "anchor": "interact-with-your-erc-20-contract" + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 2, + "title": "Set Up Deployment", + "anchor": "set-up-deployment" + }, + { + "depth": 2, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" } ], "stats": { - "chars": 8926, - "words": 1207, - "headings": 6, - "estimated_token_count_total": 2107 + "chars": 4745, + "words": 550, + "headings": 9, + "estimated_token_count_total": 1137 }, - "hash": "sha256:296cba75b1d49aefa1b8636ba95ca20c3431b7eb0e93b0658add671ef5801732", - "last_modified": "2025-10-28T14:42:15+00:00", + "hash": "sha256:f787f9c66787c53aa5c6fccf30d622b2b617794d1292641ea256e0896d418b28", "token_estimator": "heuristic-v1" }, { - "id": "smart-contracts-cookbook-smart-contracts-deploy-nft-ethers", - "title": "Deploy an NFT to Polkadot Hub with Ethers.js", - "slug": "smart-contracts-cookbook-smart-contracts-deploy-nft-ethers", + "id": "smart-contracts-cookbook-smart-contracts-deploy-nft-remix", + "title": "Deploy an NFT to Polkadot Hub with Remix", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-nft-remix", "categories": [ "Basics", "Smart Contracts" ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-nft-ethers.md", - "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-nft/ethers/", + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-nft-remix.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-nft/remix/", "preview": "Non-Fungible Tokens (NFTs) represent unique digital assets commonly used for digital art, collectibles, gaming, and identity verification.", "outline": [ { @@ -13464,8 +11402,8 @@ }, { "depth": 2, - "title": "Set Up Your Project", - "anchor": "set-up-your-project" + "title": "Access Remix", + "anchor": "access-remix" }, { "depth": 2, @@ -13489,13 +11427,50 @@ } ], "stats": { - "chars": 8114, - "words": 912, + "chars": 3754, + "words": 505, "headings": 7, - "estimated_token_count_total": 2015 + "estimated_token_count_total": 928 + }, + "hash": "sha256:12a8debfbc05c5ac0e2c94daa40167adab837dc4e1b2731f5b48ae8bc9bc2c93", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook", + "title": "Smart Contracts Cookbook Index", + "slug": "smart-contracts-cookbook", + "categories": [ + "Basics", + "dApps", + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/", + "preview": "Welcome to the Polkadot smart contracts cookbook index.", + "outline": [ + { + "depth": 2, + "title": "Get Tokens from the Faucet", + "anchor": "get-tokens-from-the-faucet" + }, + { + "depth": 2, + "title": "EVM/PVM Smart Contracts", + "anchor": "evmpvm-smart-contracts" + }, + { + "depth": 2, + "title": "Port Ethereum DApps", + "anchor": "port-ethereum-dapps" + } + ], + "stats": { + "chars": 1586, + "words": 204, + "headings": 3, + "estimated_token_count_total": 406 }, - "hash": "sha256:4e3ac6affdbe93ce9d132cbb838be1dfaf7a629b0e1f10ce4d90cc3899d656cb", - "last_modified": "2025-10-28T14:42:16+00:00", + "hash": "sha256:ea0d085c376117436a9cf68e786da942cf88993651d4e06550f9ee03d2e810f4", "token_estimator": "heuristic-v1" }, { @@ -13516,7 +11491,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13537,7 +11511,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13614,7 +11587,6 @@ "estimated_token_count_total": 6228 }, "hash": "sha256:72e41f816f07026d96c803f399c71852aa1151c464e79cec3e1746b282d5eaae", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13635,7 +11607,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13656,7 +11627,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13677,7 +11647,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13698,7 +11667,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13719,7 +11687,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13797,7 +11764,6 @@ "estimated_token_count_total": 4190 }, "hash": "sha256:1729ad83ad381a90752540644d400c60add3555e5da296ab455442be81d32f8c", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13818,7 +11784,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13839,7 +11804,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13860,7 +11824,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13902,7 +11865,6 @@ "estimated_token_count_total": 2430 }, "hash": "sha256:e3d8b84cb2cee7010978582998b2269296a042aec53fb016388690ab6adf355e", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13923,7 +11885,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -13986,7 +11947,6 @@ "estimated_token_count_total": 1347 }, "hash": "sha256:7589fa1dbdbf5748892ab6d42fc784d833f33e254bd3f95ee58424effcd38323", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14007,7 +11967,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14028,7 +11987,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14071,7 +12029,6 @@ "estimated_token_count_total": 309 }, "hash": "sha256:93e8a3043d65583e3d66f8f5f0ed6f4ef89a908ef85da2b6ca906a1100b7dded", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14108,7 +12065,6 @@ "estimated_token_count_total": 313 }, "hash": "sha256:c609bc98cba5efa2d2a808548cf93ad9d0a06455b35a8fd9f534daf52824f506", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14176,7 +12132,6 @@ "estimated_token_count_total": 1818 }, "hash": "sha256:f50cd1177dd4aff8eb031d6f21cb640f8187a7f2dd0edcaef5c73354a378e44d", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14239,7 +12194,6 @@ "estimated_token_count_total": 1182 }, "hash": "sha256:9542f40acae725e628f4c3155ad1e7e0e18b2eb518484856ad439a1d9f86d1f3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14322,7 +12276,6 @@ "estimated_token_count_total": 1133 }, "hash": "sha256:0792e3956242eb8e08ab82e2d73964c381074cc8b1ea46f396d136856fa6cc07", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14436,7 +12389,6 @@ "estimated_token_count_total": 1046 }, "hash": "sha256:dd29fab6e3c00d720b10effa4e50373a6fe9ab4b7bfd3aea892c7fa9c84318a2", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14633,28 +12585,87 @@ "estimated_token_count_total": 9750 }, "hash": "sha256:1fb7a20bc4a799a771954720428029419ec73afa640e589590c43dd041a7e307", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { "id": "smart-contracts-for-eth-devs-migration", - "title": "smart-contracts-for-eth-devs-migration", + "title": "Migration FAQs and Considerations", "slug": "smart-contracts-for-eth-devs-migration", "categories": [ - "Uncategorized" + "Smart Contracts" ], "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-migration.md", "html_url": "https://docs.polkadot.com/smart-contracts/for-eth-devs/migration/", - "preview": "TODO", - "outline": [], + "preview": "This guide helps Ethereum developers migrate their smart contracts to Polkadot Hub. Most contracts work without modifications on the REVM backend, while the PolkaVM backend offers enhanced performance with minimal adaptation for standard patterns.", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" + }, + { + "depth": 2, + "title": "Migration Considerations", + "anchor": "migration-considerations" + }, + { + "depth": 2, + "title": "Migration Checklist", + "anchor": "migration-checklist" + }, + { + "depth": 2, + "title": "Migration FAQs", + "anchor": "migration-faqs" + }, + { + "depth": 3, + "title": "Which backend should I choose?", + "anchor": "which-backend-should-i-choose" + }, + { + "depth": 3, + "title": "Do I need to rewrite my Solidity code?", + "anchor": "do-i-need-to-rewrite-my-solidity-code" + }, + { + "depth": 3, + "title": "What about factory contracts?", + "anchor": "what-about-factory-contracts" + }, + { + "depth": 3, + "title": "How do gas costs compare?", + "anchor": "how-do-gas-costs-compare" + }, + { + "depth": 3, + "title": "Which Solidity features are not supported?", + "anchor": "which-solidity-features-are-not-supported" + }, + { + "depth": 3, + "title": "How do I handle the existential deposit?", + "anchor": "how-do-i-handle-the-existential-deposit" + }, + { + "depth": 3, + "title": "Can I use my existing development tools?", + "anchor": "can-i-use-my-existing-development-tools" + }, + { + "depth": 2, + "title": "Conclusion", + "anchor": "conclusion" + } + ], "stats": { - "chars": 5, - "words": 1, - "headings": 0, - "estimated_token_count_total": 0 + "chars": 6247, + "words": 803, + "headings": 12, + "estimated_token_count_total": 1322 }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", + "hash": "sha256:bf9b21750158389c387b92f2165947e5f5cff752f5d163680ee37493710e81d7", "token_estimator": "heuristic-v1" }, { @@ -14712,7 +12723,6 @@ "estimated_token_count_total": 2840 }, "hash": "sha256:224a9f69d4613a5f1afdbc1f05379add8321fe159e32c71db003bbe08ff8e976", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14733,7 +12743,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14754,7 +12763,6 @@ "estimated_token_count_total": 0 }, "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14807,7 +12815,6 @@ "estimated_token_count_total": 1627 }, "hash": "sha256:65809486f62f60c6a6ac8109f9f027361683c23f639991a045ec5c057b665026", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14895,7 +12902,6 @@ "estimated_token_count_total": 4474 }, "hash": "sha256:c74a28d8d62369591c5734535136508db3d1f7380e486fd214f98d433cafd6e7", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -14988,7 +12994,6 @@ "estimated_token_count_total": 3891 }, "hash": "sha256:e27657e4e4a14fe86f424b96631946ec36fb90d277e6010b6cbd64c4769aba8a", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -15061,7 +13066,6 @@ "estimated_token_count_total": 3250 }, "hash": "sha256:bc771f912627fa09cad64adab1bc81c052f650d6c5a3b4f0c91883a98f6628da", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -15134,7 +13138,6 @@ "estimated_token_count_total": 3035 }, "hash": "sha256:f0d36333d0d3afff7f6374a61d0f6d1fb878c9ef4c4e4c24447745661dbe59d0", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -15187,7 +13190,6 @@ "estimated_token_count_total": 2509 }, "hash": "sha256:205892e350168b3d0da7ccc280c67c3217ad1e45e87a53d124fa1dd69661aa5e", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -15260,7 +13262,6 @@ "estimated_token_count_total": 1122 }, "hash": "sha256:ee87115c828928c82937de26f5f938cecd4c3bb1225fdb61627e8092e6ea5951", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -15272,37 +13273,36 @@ ], "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-precompiles-eth-native.md", "html_url": "https://docs.polkadot.com/smart-contracts/precompiles/eth-native/", - "preview": "TODO", - "outline": [], - "stats": { - "chars": 5, - "words": 1, - "headings": 0, - "estimated_token_count_total": 0 - }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", - "token_estimator": "heuristic-v1" - }, - { - "id": "smart-contracts-precompiles-staking", - "title": "smart-contracts-precompiles-staking", - "slug": "smart-contracts-precompiles-staking", - "categories": [ - "Uncategorized" + "preview": "Ethereum-native precompiles are special contract implementations that provide essential cryptographic and utility functions at the runtime level. These precompiles are available at predefined addresses and offer optimized, native implementations of commonly used operations that would be computationally expensive or impractical to implement in pure contract code.", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" + }, + { + "depth": 2, + "title": "How to Use Precompiles", + "anchor": "how-to-use-precompiles" + }, + { + "depth": 2, + "title": "Standard Precompiles in Polkadot Hub", + "anchor": "standard-precompiles-in-polkadot-hub" + }, + { + "depth": 2, + "title": "Conclusion", + "anchor": "conclusion" + } ], - "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-precompiles-staking.md", - "html_url": "https://docs.polkadot.com/smart-contracts/precompiles/staking/", - "preview": "TODO", - "outline": [], "stats": { "chars": 5232, "words": 532, "headings": 4, "estimated_token_count_total": 1192 }, - "hash": "sha256:56ba36249ea8216ad513b13df3de6c0e490ba214897674d30331f1c7e7edbef3", - "last_modified": "2025-10-28T14:42:16+00:00", + "hash": "sha256:f17db5daca8feae70ce428e03a5a4870ef87dfc8571b07376327cd80d057b759", "token_estimator": "heuristic-v1" }, { @@ -15368,8 +13368,43 @@ "headings": 9, "estimated_token_count_total": 2325 }, - "hash": "sha256:4856172c6356357818234a3b7f0828716bd32e6192f3609c51de0cafcc5a75e7", - "last_modified": "2025-10-28T14:42:16+00:00", + "hash": "sha256:c084190ea7d676128e7e399e8fe88598ca150f88d684db279a687ee1c3956120", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-precompiles", + "title": "Advanced Functionalities via Precompiles", + "slug": "smart-contracts-precompiles", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-precompiles.md", + "html_url": "https://docs.polkadot.com/smart-contracts/precompiles/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" + }, + { + "depth": 2, + "title": "What are Precompiles?", + "anchor": "what-are-precompiles" + }, + { + "depth": 2, + "title": "Conclusion", + "anchor": "conclusion" + } + ], + "stats": { + "chars": 2525, + "words": 328, + "headings": 3, + "estimated_token_count_total": 412 + }, + "hash": "sha256:a40e3f34f70db22bfe39e40d68dc5a53a726ce47cb73b602d8605355c61ffd22", "token_estimator": "heuristic-v1" }, { @@ -15436,7 +13471,6 @@ "estimated_token_count_total": 2249 }, "hash": "sha256:1368f6d49bccb7ba0e642cc58ea2c97ca95ae45e390cb9fa2ab11b0b41de52f4", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -15467,9 +13501,7 @@ "headings": 2, "estimated_token_count_total": 198 }, - "hash": "sha256:96acff10be56dea76acdb5c915c1dde0eb15eb12eb95e7871eef56bab6cda273", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:467765777cace42ab4e3f1bb36c94f97e655c5d2cd570e00dd747c6a3db043f7", "token_estimator": "heuristic-v1" }, { @@ -15505,9 +13537,7 @@ "headings": 3, "estimated_token_count_total": 208 }, - "hash": "sha256:61bc251929352f2299ca1d413d05aa9c3672b914575a285d73c7ba53dbd75bff", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:3a6704a6330c6e35aa98fe8d615e2e27beb870a48c68bda02c217e6ae77274d2", "token_estimator": "heuristic-v1" }, { @@ -15568,9 +13598,7 @@ "headings": 8, "estimated_token_count_total": 2764 }, - "hash": "sha256:370ed10155cee84889a6d230d0bc3476597448f88a2a271ab87ef893a3268c18", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:a2bba0ba575bd7e3f7199282ea5994087acf2c62e828f316e6eb62c9a43449e1", "token_estimator": "heuristic-v1" }, { @@ -15596,9 +13624,7 @@ "headings": 1, "estimated_token_count_total": 12 }, - "hash": "sha256:086a87823ab67ceac102358030e316583cd733c0ec326316e7f29061fe7f6934", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:917ce0777f8ac5a4288e54ce4086432d320b127a7fc753ade5392d766a1f3c33", "token_estimator": "heuristic-v1" }, { @@ -15639,8 +13665,7 @@ "headings": 4, "estimated_token_count_total": 339 }, - "hash": "sha256:a2bba0ba575bd7e3f7199282ea5994087acf2c62e828f316e6eb62c9a43449e1", - "last_modified": "2025-10-28T14:42:16+00:00", + "hash": "sha256:9559f240b9433b496bfea92b57394a75c28bc743bb756c231f0137dfdf077e4a", "token_estimator": "heuristic-v1" }, { @@ -15722,7 +13747,6 @@ "estimated_token_count_total": 34492 }, "hash": "sha256:bef820acfe429d4a847a8de82de6c70155ac6b3ad5ebdd574a2157923b45f688", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -15753,9 +13777,7 @@ "headings": 2, "estimated_token_count_total": 125 }, - "hash": "sha256:d2f3ab658ab29514ac161b17df23e0e7c1f63a7fa4fefcef451ef80b413ab757", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:c675e4231537732f24d1dd93f2b248398248a77c9877860fe53926e255ed0710", "token_estimator": "heuristic-v1" }, { @@ -15848,7 +13870,6 @@ "estimated_token_count_total": 5338 }, "hash": "sha256:b3530f5fc5c9e916181dbc259a7fbae9c60100cb0450fc6d47bbb0d140afa075", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -15920,7 +13941,6 @@ "estimated_token_count_total": 4358 }, "hash": "sha256:87b19f6e881611329b7015e8d8187d7d85b2b2ef14b01e832c8b8e20897e3b40", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -15977,7 +13997,6 @@ "estimated_token_count_total": 2138 }, "hash": "sha256:ff2c267284959711782c0d6ecb4b439c3a6cc31f763d5e1ff2cc3b1f6efb62b2", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -16029,7 +14048,6 @@ "estimated_token_count_total": 2929 }, "hash": "sha256:df60044893f48dd7f37a11de275a16bf32adb31317ed70a789fd7fac64150e1a", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -16121,7 +14139,6 @@ "estimated_token_count_total": 4789 }, "hash": "sha256:81750202081ff24447f4e129c49230eedb315d1b44c740b677c3495a8f7adb9a", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -16203,7 +14220,6 @@ "estimated_token_count_total": 2452 }, "hash": "sha256:1eb463c6b2732ebed0d16165425cde438688d21cc302f759b40250850c2a5e83", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -16266,7 +14282,6 @@ "estimated_token_count_total": 3255 }, "hash": "sha256:fe94de6f97fb588552f6cbc6b1a4c7399e91f5f31585f61a0dee66f5f50ff8a0", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -16292,9 +14307,7 @@ "headings": 1, "estimated_token_count_total": 42 }, - "hash": "sha256:2f11054e0d31c003ebae5d990b559bd56741d190ca409f6ad060216245fa2d17", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:06acc146698c1d3224544987d7ee52da498e3179228f98a494e385c5786a3a2c", "token_estimator": "heuristic-v1" }, { @@ -16330,9 +14343,7 @@ "headings": 3, "estimated_token_count_total": 107 }, - "hash": "sha256:a6a535f4f5e145d3e2a7518739f752ee3ed37b7745483f414e21c97792331d18", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:fdd391227992c966de25b9240f5492135a9993859ec42b77952c1aa3d2e39ed9", "token_estimator": "heuristic-v1" }, { @@ -16373,9 +14384,7 @@ "headings": 4, "estimated_token_count_total": 400 }, - "hash": "sha256:3ad540d8ad636304705cccb08bc1fdf21fe2fc7dc0f99bd509b23ae96d20e0ba", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:2fc6f513fd8b269e586b754b2bdbd2af9df5178624a028fab940a385f3fee577", "token_estimator": "heuristic-v1" }, { @@ -16411,8 +14420,7 @@ "headings": 3, "estimated_token_count_total": 211 }, - "hash": "sha256:388c988338ed84589c546bb1606d08641fb931dae307d3df92aeccd2e4986080", - "last_modified": "2025-10-28T14:15:59+00:00", + "hash": "sha256:5d45ec9f8efda8c4bc2d0c21399a036d017a03540e7efab60d4710cb7eb33eb3", "token_estimator": "heuristic-v1" }, { @@ -16481,7 +14489,6 @@ "estimated_token_count_total": 2702 }, "hash": "sha256:1f8ab387f721d865a7ca75eaa2528f1f2ebd4528a7d65ffeb27c68953100a3cb", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -16550,7 +14557,6 @@ "estimated_token_count_total": 2564 }, "hash": "sha256:97dadddf4c27f469f552875461fc54d331fa151e4656401e15d6d4173115eecf", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -16581,9 +14587,7 @@ "headings": 2, "estimated_token_count_total": 80 }, - "hash": "sha256:07629376480e74afc7fe4d91df539b6ab22453df0f8143df11cc51ef9a78f736", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:1dfbb8c3cfa27f92e982b4ce705415e117c50eb38f641691129863b474741da7", "token_estimator": "heuristic-v1" }, { @@ -16619,9 +14623,7 @@ "headings": 3, "estimated_token_count_total": 256 }, - "hash": "sha256:cf9197d6909dd8865e8838cad95e3692fefaecc3d2f4773b26809a02051d620f", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:d63121126e51c785f0dfd4ae4ecd49cb71640515d39df69a0689f30a7ab8122f", "token_estimator": "heuristic-v1" }, { @@ -16647,9 +14649,7 @@ "headings": 1, "estimated_token_count_total": 12 }, - "hash": "sha256:aa6371024bb78c3eeedb6820a37859670046fd0e4f756ad417b20c39fb2983b9", - "last_modified": "2025-10-27T18:04:05+00:00", - "last_modified": "2025-10-27T18:04:05+00:00", + "hash": "sha256:94dbafb2d78b87d5f0f0c75de002501b8210ac8d66072bc07989f685837cbac5", "token_estimator": "heuristic-v1" }, { @@ -16702,7 +14702,6 @@ "estimated_token_count_total": 1760 }, "hash": "sha256:9cf70459e921b8b231a3f2e7a7c1d47a4917e45f0c4d0fe873ad4062fd540a9a", - "last_modified": "2025-10-28T14:42:16+00:00", "token_estimator": "heuristic-v1" }, { @@ -16775,7 +14774,6 @@ "estimated_token_count_total": 5118 }, "hash": "sha256:de7fde61d4cac9c28634ee496dcabe116fe44b1b87408f202103290d78247c05", - "last_modified": "2025-10-28T14:42:18+00:00", "token_estimator": "heuristic-v1" }, { @@ -16858,7 +14856,6 @@ "estimated_token_count_total": 6206 }, "hash": "sha256:cb8ddb4a61f6a62182420b69382f1c7ab2adc2f4ae643f7f68c6867680afe81f", - "last_modified": "2025-10-28T14:42:19+00:00", "token_estimator": "heuristic-v1" }, { @@ -16921,7 +14918,114 @@ "estimated_token_count_total": 4135 }, "hash": "sha256:ca1d65d450f086a0eb7b81e9589e9894e04b217fe9709a1b464f09beb3ca9dc2", - "last_modified": "2025-10-28T14:42:20+00:00", + "token_estimator": "heuristic-v1" + }, + { + "id": "tutorials-smart-contracts-launch-your-first-project", + "title": "Launch Your First Project", + "slug": "tutorials-smart-contracts-launch-your-first-project", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/tutorials-smart-contracts-launch-your-first-project.md", + "html_url": "https://docs.polkadot.com/tutorials/smart-contracts/launch-your-first-project/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. Kickstart your journey into smart contract development with this comprehensive guide. Learn how to create, deploy, and interact with contracts on Polkadot. Whether you're new to smart contracts or refining your skills, these guides provide a structured approach to launching your project.", + "outline": [ + { + "depth": 2, + "title": "Development Pathway", + "anchor": "development-pathway" + }, + { + "depth": 2, + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 1211, + "words": 161, + "headings": 2, + "estimated_token_count_total": 77 + }, + "hash": "sha256:8d8fc5f794d4c793586cd3d412627f5e2fe76f182c75c3687abcf33deed5d65e", + "token_estimator": "heuristic-v1" + }, + { + "id": "tutorials-smart-contracts", + "title": "Smart Contracts", + "slug": "tutorials-smart-contracts", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/tutorials-smart-contracts.md", + "html_url": "https://docs.polkadot.com/tutorials/smart-contracts/", + "preview": "!!! smartcontract \"PolkaVM Preview Release\" PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. Get started with deploying and interacting with smart contracts on Polkadot through practical, hands-on tutorials. Whether you're a beginner or an experienced developer, these guides will help you navigate the entire development lifecycle.", + "outline": [ + { + "depth": 2, + "title": "What to Expect from These Tutorials", + "anchor": "what-to-expect-from-these-tutorials" + }, + { + "depth": 2, + "title": "Start Building", + "anchor": "start-building" + }, + { + "depth": 2, + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 1057, + "words": 145, + "headings": 3, + "estimated_token_count_total": 130 + }, + "hash": "sha256:66bc34a12c50539dde2ffc69fe66891f73d3e1a2da5833ada15e26744ff32209", + "token_estimator": "heuristic-v1" + }, + { + "id": "tutorials", + "title": "Tutorials", + "slug": "tutorials", + "categories": [ + "Uncategorized" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/tutorials.md", + "html_url": "https://docs.polkadot.com/tutorials/", + "preview": "Welcome to the Polkadot Tutorials hub! Whether you’re building parachains, integrating system chains, or developing decentralized applications, these step-by-step guides are designed to help you achieve your goals efficiently and effectively.", + "outline": [ + { + "depth": 2, + "title": "Polkadot Zero to Hero", + "anchor": "polkadot-zero-to-hero" + }, + { + "depth": 3, + "title": "Parachain Developers", + "anchor": "parachain-developers" + }, + { + "depth": 2, + "title": "Featured Tutorials", + "anchor": "featured-tutorials" + }, + { + "depth": 2, + "title": "In This Section", + "anchor": "in-this-section" + } + ], + "stats": { + "chars": 2501, + "words": 355, + "headings": 4, + "estimated_token_count_total": 590 + }, + "hash": "sha256:a1d7789d44e4653e98ed41b8a13ea69e7733803c598ca850c9e2fc8f27a2b410", "token_estimator": "heuristic-v1" } ] \ No newline at end of file diff --git a/llms-full.jsonl b/llms-full.jsonl index e7b3d0dd6..d53094e48 100644 --- a/llms-full.jsonl +++ b/llms-full.jsonl @@ -552,25 +552,66 @@ {"page_id": "parachains-customize-runtime-add-pallet-instances", "page_title": "Add Multiple Pallet Instances", "index": 18, "depth": 3, "title": "Interact with Both Pallet Instances", "anchor": "interact-with-both-pallet-instances", "start_char": 15206, "end_char": 16561, "estimated_token_count": 358, "token_estimator": "heuristic-v1", "text": "### Interact with Both Pallet Instances\n\nUse the Polkadot.js Apps interface to verify you can interact with both pallet instances independently.\n\nTo interact with the pallet instances:\n\n1. Navigate to [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/extrinsics){target=\\_blank}.\n2. Ensure you're connected to your local node at `ws://127.0.0.1:9944`.\n3. Go to the **Developer** > **Extrinsics** tab.\n4. In the **submit the following extrinsic** section, open the pallet dropdown. Verify that both pallet instances appear and contain the expected extrinsics.\n\n === \"Technical Committee\"\n\n Select **`technicalCommittee`** and open the extrinsics dropdown.\n\n ![](/images/parachains/customize-runtime/add-pallet-instances/add-pallet-instances-01.webp)\n\n === \"Council\"\n\n Select **`council`** and open the extrinsics dropdown.\n\n ![](/images/parachains/customize-runtime/add-pallet-instances/add-pallet-instances-02.webp)\n\nEach instance should display the following extrinsics (this is not an exhaustive list):\n\n- **`close(proposalHash, index, proposalWeightBound, lengthBound)`**: Close voting.\n- **`propose(threshold, proposal, lengthBound)`**: Submit a proposal.\n- **`setMembers(newMembers, prime, oldCount)`**: Update membership.\n- **`vote(proposal, index, approve)`**: Vote on a proposal."} {"page_id": "parachains-customize-runtime-add-pallet-instances", "page_title": "Add Multiple Pallet Instances", "index": 19, "depth": 3, "title": "Test Instance Independence", "anchor": "test-instance-independence", "start_char": 16561, "end_char": 17619, "estimated_token_count": 227, "token_estimator": "heuristic-v1", "text": "### Test Instance Independence\n\nVerify that both instances operate independently by testing their separate functionality.\n\nTo test instance independence:\n\n1. In Polkadot.js Apps, go to **Developer** > **Chain state**.\n2. Query storage for each instance:\n\n === \"Technical Committee\"\n\n Select **`technicalCommittee` > `members()`** to view technical committee members.\n\n ![](/images/parachains/customize-runtime/add-pallet-instances/add-pallet-instances-03.webp)\n\n === \"Council\"\n\n Select **`council` > `members()`** to view council members.\n\n ![](/images/parachains/customize-runtime/add-pallet-instances/add-pallet-instances-04.webp)\n\n3. Verify that:\n - Each instance maintains separate storage.\n - Changes to one instance don't affect the other.\n - Both instances can process proposals simultaneously.\n\nYou can now use both collective instances for different governance purposes in your parachain, such as technical decisions that require expertise and general governance decisions that require broader consensus."} {"page_id": "parachains-customize-runtime-add-pallet-instances", "page_title": "Add Multiple Pallet Instances", "index": 20, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 17619, "end_char": 17923, "estimated_token_count": 82, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Guide __Make a Custom Pallet__\n\n ---\n\n Learn how to create custom pallets using FRAME.\n\n [:octicons-arrow-right-24: Reference](/parachains/customize-runtime/pallet-development/create-a-pallet/)\n\n
"} -{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 36, "end_char": 704, "estimated_token_count": 118, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nWhen building your custom blockchain with the Polkadot SDK, you have the flexibility to add smart contract capabilities through specialized pallets. These pallets allow blockchain users to deploy and execute smart contracts, enhancing your chain's functionality and programmability.\n\nPolkadot SDK-based blockchains support two distinct smart contract execution environments: [EVM (Ethereum Virtual Machine)](#evm-smart-contracts) and [Wasm (WebAssembly)](#wasm-smart-contracts). Each environment allows developers to deploy and execute different types of smart contracts, providing flexibility in choosing the most suitable solution for their needs."} -{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 1, "depth": 2, "title": "EVM Smart Contracts", "anchor": "evm-smart-contracts", "start_char": 704, "end_char": 1957, "estimated_token_count": 327, "token_estimator": "heuristic-v1", "text": "## EVM Smart Contracts\n\nTo enable Ethereum-compatible smart contracts in your blockchain, you'll need to integrate [Frontier](https://github.com/polkadot-evm/frontier){target=\\_blank}, the Ethereum compatibility layer for Polkadot SDK-based chains. This requires adding two essential pallets to your runtime:\n\n- **[`pallet-evm`](https://github.com/polkadot-evm/frontier/tree/master/frame/evm){target=\\_blank}**: Provides the EVM execution environment.\n- **[`pallet-ethereum`](https://github.com/polkadot-evm/frontier/tree/master/frame/ethereum){target=\\_blank}**: Handles Ethereum-formatted transactions and RPC capabilities.\n\nFor step-by-step guidance on adding these pallets to your runtime, refer to [Add a Pallet to the Runtime](/parachains/customize-runtime/add-existing-pallets/){target=\\_blank}.\n\nFor a real-world example of how these pallets are implemented in production, you can check Moonbeam's implementation of [`pallet-evm`](https://github.com/moonbeam-foundation/moonbeam/blob/9e2ddbc9ae8bf65f11701e7ccde50075e5fe2790/runtime/moonbeam/src/lib.rs#L532){target=\\_blank} and [`pallet-ethereum`](https://github.com/moonbeam-foundation/moonbeam/blob/9e2ddbc9ae8bf65f11701e7ccde50075e5fe2790/runtime/moonbeam/src/lib.rs#L698){target=\\_blank}."} -{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 2, "depth": 2, "title": "Wasm Smart Contracts", "anchor": "wasm-smart-contracts", "start_char": 1957, "end_char": 2772, "estimated_token_count": 197, "token_estimator": "heuristic-v1", "text": "## Wasm Smart Contracts\n\nTo support Wasm-based smart contracts, you'll need to integrate:\n\n- **[`pallet-contracts`](https://docs.rs/pallet-contracts/latest/pallet_contracts/index.html#contracts-pallet){target=\\_blank}**: Provides the Wasm smart contract execution environment.\n\nThis pallet enables the deployment and execution of Wasm-based smart contracts on your blockchain. For detailed instructions on adding this pallet to your runtime, see [Add a Pallet to the Runtime](/parachains/customize-runtime/add-existing-pallets/){target=\\_blank}.\n\nFor a real-world example of how this pallet is implemented in production, you can check Astar's implementation of [`pallet-contracts`](https://github.com/AstarNetwork/Astar/blob/b6f7a408d31377130c3713ed52941a06b5436402/runtime/astar/src/lib.rs#L693){target=\\_blank}."} -{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 3, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 2772, "end_char": 3865, "estimated_token_count": 259, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\nNow that you understand how to enable smart contract functionality in your blockchain, you might want to:\n\n
\n\n- Guide __Get Started with Smart Contracts__\n\n ---\n\n Learn how developers can build smart contracts on Polkadot by leveraging the PolkaVM, Wasm/ink! or EVM contracts across many parachains.\n\n [:octicons-arrow-right-24: Reference](/smart-contracts/get-started/)\n\n- Guide __Wasm (ink!) Contracts__\n\n ---\n\n Learn to build Wasm smart contracts with ink!, a Rust-based eDSL. Explore installation, contract structure, and key features.\n\n [:octicons-arrow-right-24: Reference](/smart-contracts/overview/#wasm-ink)\n \n- Guide __EVM Contracts__\n\n ---\n\n Learn how Polkadot parachains such as Moonbeam, Astar, Acala, and Manta leverage the Ethereum Virtual Machine (EVM) and integrate it into their parachains.\n\n [:octicons-arrow-right-24: Reference](/smart-contracts/overview/#parachain-contracts)\n\n
"} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 36, "end_char": 724, "estimated_token_count": 139, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nWhen building your custom blockchain with the Polkadot SDK, you can add smart contract capabilities through specialized pallets. These pallets enable users to deploy and execute smart contracts, enhancing your chain's programmability and allowing developers to build decentralized applications on your network.\n\nThis guide covers three approaches to adding smart contracts to your blockchain:\n\n- **[`pallet-revive`](#pallet-revive)**: Modern unified solution supporting both PolkaVM and EVM bytecode\n- **[Frontier](#frontier)**: Ethereum compatibility layer for Polkadot SDK-based chains\n- **[`pallet-contracts`](#pallet-contracts-legacy)**: Wasm smart contract support"} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 1, "depth": 2, "title": "pallet-revive", "anchor": "pallet-revive", "start_char": 724, "end_char": 1046, "estimated_token_count": 74, "token_estimator": "heuristic-v1", "text": "## pallet-revive\n\n[`pallet-revive`](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame/revive){target=\\_blank} is the modern smart contract solution for Polkadot SDK-based chains. It provides a unified execution environment that supports both PolkaVM and EVM bytecode through dual execution backends."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 2, "depth": 3, "title": "Core Components", "anchor": "core-components", "start_char": 1046, "end_char": 1841, "estimated_token_count": 230, "token_estimator": "heuristic-v1", "text": "### Core Components\n\n**Essential Pallet:**\n**[`pallet-revive`](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame/revive){target=\\_blank}** provides the core smart contract execution environment with [PolkaVM](https://github.com/polkadot-developers/polkadot-docs/blob/71e1b51bb42ef55e20c2f3b953db86e8c26cd591/smart-contracts/for-eth-devs/dual-vm-stack.md#upgrade-to-polkavm){target=\\_blank} and [REVM](https://github.com/polkadot-developers/polkadot-docs/blob/71e1b51bb42ef55e20c2f3b953db86e8c26cd591/smart-contracts/for-eth-devs/dual-vm-stack.md#migrate-from-evm){target=\\_blank} backends.\n\n**RPC Adapter:**\n**[`pallet-revive-eth-rpc`](https://crates.io/crates/pallet-revive-eth-rpc){target=\\_blank}** adds full Ethereum RPC compatibility for Ethereum tooling integration."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 3, "depth": 3, "title": "Supported Languages and Compilers", "anchor": "supported-languages-and-compilers", "start_char": 1841, "end_char": 2463, "estimated_token_count": 196, "token_estimator": "heuristic-v1", "text": "### Supported Languages and Compilers\n\n`pallet-revive` accepts smart contracts from multiple languages and compilation paths:\n\n| Language | Compiler | Output Bytecode | Execution Backend |\n|----------|----------|-----------------|-------------------|\n| Solidity | `resolc` | PolkaVM | PolkaVM |\n| Solidity | `solc` | EVM | REVM |\n| Rust (ink!) | `cargo-contract` | PolkaVM | PolkaVM | \n\nAny language that can compile to PolkaVM bytecode and utilize `pallet-revive`'s host functions (via [`pallet-revive-uapi`](https://paritytech.github.io/polkadot-sdk/master/pallet_revive_uapi/index.html){target=\\_blank}) is supported."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 4, "depth": 3, "title": "How It Works", "anchor": "how-it-works", "start_char": 2463, "end_char": 2723, "estimated_token_count": 54, "token_estimator": "heuristic-v1", "text": "### How It Works\n\n**Dual Execution Model:**\n\n1. **PolkaVM Backend**: Executes PolkaVM bytecode with native performance optimization.\n2. **REVM Backend**: Implements EVM bytecode for compatibility with existing Ethereum contracts, ensuring seamless migration."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 5, "depth": 3, "title": "Key Benefits", "anchor": "key-benefits", "start_char": 2723, "end_char": 3199, "estimated_token_count": 106, "token_estimator": "heuristic-v1", "text": "### Key Benefits\n\n- **Unified platform**: Deploys both PolkaVM-optimized and EVM-compatible contracts using a single pallet.\n- **Performance**: PolkaVM execution provides improved performance compared to the traditional EVM, leveraging the [RISC-V](https://en.wikipedia.org/wiki/RISC-V){target=\\_blank} architecture to map instructions to the CPU and requires little transpiling.\n- **Ethereum compatibility**: Supports full integration with Ethereum tooling via RPC adapter."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 6, "depth": 3, "title": "Implementation Examples", "anchor": "implementation-examples", "start_char": 3199, "end_char": 3489, "estimated_token_count": 69, "token_estimator": "heuristic-v1", "text": "### Implementation Examples\n\nSee a real-world implementation in the [Polkadot Hub TestNet](https://github.com/paseo-network/runtimes/blob/c965c42a4e0bc9d1e9cc0a340322bc3b8e347bcf/system-parachains/asset-hub-paseo/src/lib.rs#L1122-L1157){target=\\_blank} in the Polkadot Fellows repository."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 7, "depth": 2, "title": "Frontier", "anchor": "frontier", "start_char": 3489, "end_char": 3786, "estimated_token_count": 62, "token_estimator": "heuristic-v1", "text": "## Frontier\n\n[Frontier](https://github.com/polkadot-evm/frontier){target=\\_blank} is the Ethereum compatibility layer designed for maximum compatibility with the Ethereum ecosystem. It's the ideal choice when you need seamless integration with existing Ethereum tools, dApps, and infrastructure."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 8, "depth": 3, "title": "Integration Options", "anchor": "integration-options", "start_char": 3786, "end_char": 3888, "estimated_token_count": 15, "token_estimator": "heuristic-v1", "text": "### Integration Options\n\nFrontier offers flexible integration depending on your compatibility needs:"} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 9, "depth": 3, "title": "EVM Execution Only", "anchor": "evm-execution-only", "start_char": 3888, "end_char": 4228, "estimated_token_count": 82, "token_estimator": "heuristic-v1", "text": "### EVM Execution Only\n\nFor basic EVM support using Polkadot SDK native APIs:\n\n- **[`pallet-evm`](https://github.com/polkadot-evm/frontier/tree/master/frame/evm){target=\\_blank}**: Provides the core EVM execution environment.\n\nThis configuration allows EVM contract execution but requires using Polkadot SDK-specific APIs for interaction."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 10, "depth": 3, "title": "Full Ethereum Compatibility", "anchor": "full-ethereum-compatibility", "start_char": 4228, "end_char": 4798, "estimated_token_count": 165, "token_estimator": "heuristic-v1", "text": "### Full Ethereum Compatibility\n\nFor complete Ethereum ecosystem integration with Ethereum RPC support:\n\n- **[`pallet-evm`](https://github.com/polkadot-evm/frontier/tree/master/frame/evm){target=\\_blank}**: Integrates core EVM execution environment.\n- **[`pallet-ethereum`](https://github.com/polkadot-evm/frontier/tree/master/frame/ethereum){target=\\_blank}**: Emulates Ethereum blocks and handles Ethereum-formatted transactions.\n- **[`fc-rpc`](https://github.com/polkadot-evm/frontier/tree/master/client/rpc){target=\\_blank}**: Provides Ethereum JSON-RPC endpoints."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 11, "depth": 3, "title": "Key Benefits", "anchor": "key-benefits-2", "start_char": 4798, "end_char": 5253, "estimated_token_count": 93, "token_estimator": "heuristic-v1", "text": "### Key Benefits\n\n- **Ethereum tooling compatibility**: Full compatibility with MetaMask, Hardhat, Remix, Foundry, and other Ethereum development tools.\n- **Minimal-friction migration**: Deployment of existing Ethereum dApps with minimal or no modifications.\n- **Native Ethereum formats**: Support for Ethereum transaction formats, signatures, and gas mechanics.\n- **Block emulation**: Ethereum-style block structure within Substrate's block production."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 12, "depth": 3, "title": "Implementation Examples", "anchor": "implementation-examples-2", "start_char": 5253, "end_char": 5720, "estimated_token_count": 114, "token_estimator": "heuristic-v1", "text": "### Implementation Examples\n\nProduction implementations demonstrate Frontier's capabilities:\n\n- **Moonbeam**: See their implementation of [`pallet-evm`](https://github.com/moonbeam-foundation/moonbeam/blob/9e2ddbc9ae8bf65f11701e7ccde50075e5fe2790/runtime/moonbeam/src/lib.rs#L532){target=\\_blank} and [`pallet-ethereum`](https://github.com/moonbeam-foundation/moonbeam/blob/9e2ddbc9ae8bf65f11701e7ccde50075e5fe2790/runtime/moonbeam/src/lib.rs#L698){target=\\_blank}."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 13, "depth": 2, "title": "pallet-contracts (Legacy)", "anchor": "pallet-contracts-legacy", "start_char": 5720, "end_char": 6051, "estimated_token_count": 81, "token_estimator": "heuristic-v1", "text": "## pallet-contracts (Legacy)\n\n[`pallet-contracts`](https://docs.rs/pallet-contracts/latest/pallet_contracts/index.html#contracts-pallet){target=\\_blank} is the original Wasm-based smart contract pallet for Polkadot SDK chains. While still functional, it's considered legacy as development efforts have shifted to `pallet-revive`."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 14, "depth": 3, "title": "Implementation Example", "anchor": "implementation-example", "start_char": 6051, "end_char": 6304, "estimated_token_count": 59, "token_estimator": "heuristic-v1", "text": "### Implementation Example\n\nFor reference, Astar's implementation of [`pallet-contracts`](https://github.com/AstarNetwork/Astar/blob/b6f7a408d31377130c3713ed52941a06b5436402/runtime/astar/src/lib.rs#L693){target=\\_blank} demonstrates production usage."} +{"page_id": "parachains-customize-runtime-add-smart-contract-functionality", "page_title": "Add Smart Contract Functionality", "index": 15, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 6304, "end_char": 6655, "estimated_token_count": 92, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Guide __Add a Pallet to the Runtime__\n\n ---\n\n Learn the step-by-step process for integrating Polkadot SDK pallets into your blockchain's runtime.\n\n [:octicons-arrow-right-24: Get Started](/parachains/customize-runtime/add-existing-pallets/)\n\n
"} {"page_id": "parachains-customize-runtime-pallet-development-add-pallet-to-runtime", "page_title": "Add Pallets to the Runtime", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 30, "end_char": 866, "estimated_token_count": 192, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nIn previous tutorials, you learned how to [create a custom pallet](/tutorials/polkadot-sdk/parachains/zero-to-hero/build-custom-pallet/){target=\\_blank} and [test it](/tutorials/polkadot-sdk/parachains/zero-to-hero/pallet-unit-testing/){target=\\_blank}. The next step is to include this pallet in your runtime, integrating it into the core logic of your blockchain.\n\nThis tutorial will guide you through adding two pallets to your runtime: the custom pallet you previously developed and the [utility pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_utility/index.html){target=\\_blank}. This standard Polkadot SDK pallet provides powerful dispatch functionality. The utility pallet offers, for example, batch dispatch, a stateless operation that enables executing multiple calls in a single transaction."} {"page_id": "parachains-customize-runtime-pallet-development-add-pallet-to-runtime", "page_title": "Add Pallets to the Runtime", "index": 1, "depth": 2, "title": "Add the Pallets as Dependencies", "anchor": "add-the-pallets-as-dependencies", "start_char": 866, "end_char": 8510, "estimated_token_count": 1856, "token_estimator": "heuristic-v1", "text": "## Add the Pallets as Dependencies\n\nFirst, you'll update the runtime's `Cargo.toml` file to include the Utility pallet and your custom pallets as dependencies for the runtime. Follow these steps:\n\n1. Open the `runtime/Cargo.toml` file and locate the `[dependencies]` section. Add pallet-utility as one of the features for the `polkadot-sdk` dependency with the following line:\n\n ```toml hl_lines=\"4\" title=\"runtime/Cargo.toml\"\n [dependencies]\n ...\n polkadot-sdk = { workspace = true, features = [\n \"pallet-utility\",\n ...\n ], default-features = false }\n ```\n\n2. In the same `[dependencies]` section, add the custom pallet that you built from scratch with the following line:\n\n ```toml hl_lines=\"3\" title=\"Cargo.toml\"\n [dependencies]\n ...\n custom-pallet = { path = \"../pallets/custom-pallet\", default-features = false }\n ```\n\n3. In the `[features]` section, add the custom pallet to the `std` feature list:\n\n ```toml hl_lines=\"5\" title=\"Cargo.toml\"\n [features]\n default = [\"std\"]\n std = [\n ...\n \"custom-pallet/std\",\n ...\n ]\n ```\n\n3. Save the changes and close the `Cargo.toml` file.\n\n Once you have saved your file, it should look like the following:\n\n ???- code \"runtime/Cargo.toml\"\n \n ```rust title=\"runtime/Cargo.toml\"\n [package]\n name = \"parachain-template-runtime\"\n description = \"A parachain runtime template built with Substrate and Cumulus, part of Polkadot Sdk.\"\n version = \"0.1.0\"\n license = \"Unlicense\"\n authors.workspace = true\n homepage.workspace = true\n repository.workspace = true\n edition.workspace = true\n publish = false\n\n [package.metadata.docs.rs]\n targets = [\"x86_64-unknown-linux-gnu\"]\n\n [build-dependencies]\n docify = { workspace = true }\n substrate-wasm-builder = { optional = true, workspace = true, default-features = true }\n\n [dependencies]\n codec = { features = [\"derive\"], workspace = true }\n cumulus-pallet-parachain-system.workspace = true\n docify = { workspace = true }\n hex-literal = { optional = true, workspace = true, default-features = true }\n log = { workspace = true }\n pallet-parachain-template = { path = \"../pallets/template\", default-features = false }\n polkadot-sdk = { workspace = true, features = [\n \"pallet-utility\",\n \"cumulus-pallet-aura-ext\",\n \"cumulus-pallet-session-benchmarking\",\n \"cumulus-pallet-weight-reclaim\",\n \"cumulus-pallet-xcm\",\n \"cumulus-pallet-xcmp-queue\",\n \"cumulus-primitives-aura\",\n \"cumulus-primitives-core\",\n \"cumulus-primitives-utility\",\n \"pallet-aura\",\n \"pallet-authorship\",\n \"pallet-balances\",\n \"pallet-collator-selection\",\n \"pallet-message-queue\",\n \"pallet-session\",\n \"pallet-sudo\",\n \"pallet-timestamp\",\n \"pallet-transaction-payment\",\n \"pallet-transaction-payment-rpc-runtime-api\",\n \"pallet-xcm\",\n \"parachains-common\",\n \"polkadot-parachain-primitives\",\n \"polkadot-runtime-common\",\n \"runtime\",\n \"staging-parachain-info\",\n \"staging-xcm\",\n \"staging-xcm-builder\",\n \"staging-xcm-executor\",\n ], default-features = false }\n scale-info = { features = [\"derive\"], workspace = true }\n serde_json = { workspace = true, default-features = false, features = [\n \"alloc\",\n ] }\n smallvec = { workspace = true, default-features = true }\n\n custom-pallet = { path = \"../pallets/custom-pallet\", default-features = false }\n\n [features]\n default = [\"std\"]\n std = [\n \"codec/std\",\n \"cumulus-pallet-parachain-system/std\",\n \"log/std\",\n \"pallet-parachain-template/std\",\n \"polkadot-sdk/std\",\n \"scale-info/std\",\n \"serde_json/std\",\n \"substrate-wasm-builder\",\n \"custom-pallet/std\",\n ]\n\n runtime-benchmarks = [\n \"cumulus-pallet-parachain-system/runtime-benchmarks\",\n \"hex-literal\",\n \"pallet-parachain-template/runtime-benchmarks\",\n \"polkadot-sdk/runtime-benchmarks\",\n ]\n\n try-runtime = [\n \"cumulus-pallet-parachain-system/try-runtime\",\n \"pallet-parachain-template/try-runtime\",\n \"polkadot-sdk/try-runtime\",\n ]\n\n # Enable the metadata hash generation.\n #\n # This is hidden behind a feature because it increases the compile time.\n # The wasm binary needs to be compiled twice, once to fetch the metadata,\n # generate the metadata hash and then a second time with the\n # `RUNTIME_METADATA_HASH` environment variable set for the `CheckMetadataHash`\n # extension.\n metadata-hash = [\"substrate-wasm-builder/metadata-hash\"]\n\n # A convenience feature for enabling things when doing a build\n # for an on-chain release.\n on-chain-release-build = [\"metadata-hash\"]\n\n ```\n\nUpdate your root parachain template's `Cargo.toml` file to include your custom pallet as a dependency. Follow these steps:\n\n1. Open the `./Cargo.toml` file and locate the `[workspace]` section. \n \n Make sure the `custom-pallet` is a member of the workspace:\n\n ```toml hl_lines=\"4\" title=\"Cargo.toml\"\n [workspace]\n default-members = [\"pallets/template\", \"runtime\"]\n members = [\n \"node\", \"pallets/custom-pallet\",\n \"pallets/template\",\n \"runtime\",\n ]\n ```\n\n???- code \"./Cargo.toml\"\n\n ```rust title=\"./Cargo.toml\"\n [workspace.package]\n license = \"MIT-0\"\n authors = [\"Parity Technologies \"]\n homepage = \"https://paritytech.github.io/polkadot-sdk/\"\n repository = \"https://github.com/paritytech/polkadot-sdk-parachain-template.git\"\n edition = \"2021\"\n\n [workspace]\n default-members = [\"pallets/template\", \"runtime\"]\n members = [\n \"node\", \"pallets/custom-pallet\",\n \"pallets/template\",\n \"runtime\",\n ]\n resolver = \"2\"\n\n [workspace.dependencies]\n parachain-template-runtime = { path = \"./runtime\", default-features = false }\n pallet-parachain-template = { path = \"./pallets/template\", default-features = false }\n clap = { version = \"4.5.13\" }\n color-print = { version = \"0.3.4\" }\n docify = { version = \"0.2.9\" }\n futures = { version = \"0.3.31\" }\n jsonrpsee = { version = \"0.24.3\" }\n log = { version = \"0.4.22\", default-features = false }\n polkadot-sdk = { version = \"2503.0.1\", default-features = false }\n prometheus-endpoint = { version = \"0.17.2\", default-features = false, package = \"substrate-prometheus-endpoint\" }\n serde = { version = \"1.0.214\", default-features = false }\n codec = { version = \"3.7.4\", default-features = false, package = \"parity-scale-codec\" }\n cumulus-pallet-parachain-system = { version = \"0.20.0\", default-features = false }\n hex-literal = { version = \"0.4.1\", default-features = false }\n scale-info = { version = \"2.11.6\", default-features = false }\n serde_json = { version = \"1.0.132\", default-features = false }\n smallvec = { version = \"1.11.0\", default-features = false }\n substrate-wasm-builder = { version = \"26.0.1\", default-features = false }\n frame = { version = \"0.9.1\", default-features = false, package = \"polkadot-sdk-frame\" }\n\n [profile.release]\n opt-level = 3\n panic = \"unwind\"\n\n [profile.production]\n codegen-units = 1\n inherits = \"release\"\n lto = true\n ```"} {"page_id": "parachains-customize-runtime-pallet-development-add-pallet-to-runtime", "page_title": "Add Pallets to the Runtime", "index": 2, "depth": 3, "title": "Update the Runtime Configuration", "anchor": "update-the-runtime-configuration", "start_char": 8510, "end_char": 10415, "estimated_token_count": 406, "token_estimator": "heuristic-v1", "text": "### Update the Runtime Configuration\n\nConfigure the pallets by implementing their `Config` trait and update the runtime macro to include the new pallets:\n\n1. Add the `OriginCaller` import:\n\n ```rust title=\"mod.rs\" hl_lines=\"8\"\n // Local module imports\n use super::OriginCaller;\n ...\n ```\n\n2. Implement the [`Config`](https://paritytech.github.io/polkadot-sdk/master/pallet_utility/pallet/trait.Config.html){target=\\_blank} trait for both pallets at the end of the `runtime/src/config/mod.rs` file:\n\n ```rust title=\"mod.rs\" hl_lines=\"8-25\"\n ...\n /// Configure the pallet template in pallets/template.\n impl pallet_parachain_template::Config for Runtime {\n type RuntimeEvent = RuntimeEvent;\n type WeightInfo = pallet_parachain_template::weights::SubstrateWeight;\n }\n\n // Configure utility pallet.\n impl pallet_utility::Config for Runtime {\n type RuntimeEvent = RuntimeEvent;\n type RuntimeCall = RuntimeCall;\n type PalletsOrigin = OriginCaller;\n type WeightInfo = pallet_utility::weights::SubstrateWeight;\n }\n // Define counter max value runtime constant.\n parameter_types! {\n pub const CounterMaxValue: u32 = 500;\n }\n\n // Configure custom pallet.\n impl custom_pallet::Config for Runtime {\n type RuntimeEvent = RuntimeEvent;\n type CounterMaxValue = CounterMaxValue;\n }\n ```\n\n3. Locate the `#[frame_support::runtime]` macro in the `runtime/src/lib.rs` file and add the pallets:\n\n ```rust hl_lines=\"9-14\" title=\"lib.rs\"\n #[frame_support::runtime]\n mod runtime {\n #[runtime::runtime]\n #[runtime::derive(\n ...\n )]\n pub struct Runtime;\n #[runtime::pallet_index(51)]\n pub type Utility = pallet_utility;\n\n #[runtime::pallet_index(52)]\n pub type CustomPallet = custom_pallet;\n }\n ```"} {"page_id": "parachains-customize-runtime-pallet-development-add-pallet-to-runtime", "page_title": "Add Pallets to the Runtime", "index": 3, "depth": 2, "title": "Recompile the Runtime", "anchor": "recompile-the-runtime", "start_char": 10415, "end_char": 10864, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "## Recompile the Runtime\n\nAfter adding and configuring your pallets in the runtime, the next step is to ensure everything is set up correctly. To do this, recompile the runtime with the following command (make sure you're in the project's root directory):\n\n```bash\ncargo build --release\n```\n\nThis command ensures the runtime compiles without errors, validates the pallet configurations, and prepares the build for subsequent testing or deployment."} {"page_id": "parachains-customize-runtime-pallet-development-add-pallet-to-runtime", "page_title": "Add Pallets to the Runtime", "index": 4, "depth": 2, "title": "Run Your Chain Locally", "anchor": "run-your-chain-locally", "start_char": 10864, "end_char": 12339, "estimated_token_count": 365, "token_estimator": "heuristic-v1", "text": "## Run Your Chain Locally\n\nLaunch your parachain locally and start producing blocks:\n\n!!!tip\n Generated chain TestNet specifications include development accounts \"Alice\" and \"Bob.\" These accounts are pre-funded with native parachain currency, allowing you to sign and send TestNet transactions. Take a look at the [Polkadot.js Accounts section](https://polkadot.js.org/apps/#/accounts){target=\\_blank} to view the development accounts for your chain.\n\n1. Create a new chain specification file with the updated runtime:\n\n ```bash\n chain-spec-builder create -t development \\\n --relay-chain paseo \\\n --para-id 1000 \\\n --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \\\n named-preset development\n ```\n\n2. Start the omni node with the generated chain specification:\n\n ```bash\n polkadot-omni-node --chain ./chain_spec.json --dev\n ```\n\n3. Verify you can interact with the new pallets using the [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/extrinsics){target=\\_blank} interface. Navigate to the **Extrinsics** tab and check that you can see both pallets:\n\n - Utility pallet\n\n ![](/images/parachains/customize-runtime/pallet-development/add-pallet-to-runtime/add-pallets-to-runtime-01.webp)\n \n\n - Custom pallet\n\n ![](/images/parachains/customize-runtime/pallet-development/add-pallet-to-runtime/add-pallets-to-runtime-02.webp)"} {"page_id": "parachains-customize-runtime-pallet-development-add-pallet-to-runtime", "page_title": "Add Pallets to the Runtime", "index": 5, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 12339, "end_char": 13091, "estimated_token_count": 183, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Tutorial __Deploy on Paseo TestNet__\n\n ---\n\n Deploy your Polkadot SDK blockchain on Paseo! Follow this step-by-step guide for a seamless journey to a successful TestNet deployment.\n\n [:octicons-arrow-right-24: Get Started](/tutorials/polkadot-sdk/parachains/zero-to-hero/deploy-to-testnet/)\n\n- Tutorial __Pallet Benchmarking (Optional)__\n\n ---\n\n Discover how to measure extrinsic costs and assign precise weights to optimize your pallet for accurate fees and runtime performance.\n\n [:octicons-arrow-right-24: Get Started](/tutorials/polkadot-sdk/parachains/zero-to-hero/pallet-benchmarking/)\n\n
"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmarking FRAME Pallets", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 16, "end_char": 1205, "estimated_token_count": 235, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nBenchmarking is a critical component of developing efficient and secure blockchain runtimes. In the Polkadot ecosystem, accurately benchmarking your custom pallets ensures that each extrinsic has a precise [weight](/reference/glossary/#weight){target=\\_blank}, representing its computational and storage demands. This process is vital for maintaining the blockchain's performance and preventing potential vulnerabilities, such as Denial of Service (DoS) attacks.\n\nThe Polkadot SDK leverages the [FRAME](/reference/glossary/#frame-framework-for-runtime-aggregation-of-modularized-entities){target=\\_blank} benchmarking framework, offering tools to measure and assign weights to extrinsics. These weights help determine the maximum number of transactions or system-level calls processed within a block. This guide covers how to use FRAME's [benchmarking framework](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\\_blank}, from setting up your environment to writing and running benchmarks for your custom pallets. You'll understand how to generate accurate weights by the end, ensuring your runtime remains performant and secure."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmarking FRAME Pallets", "index": 1, "depth": 2, "title": "The Case for Benchmarking", "anchor": "the-case-for-benchmarking", "start_char": 1205, "end_char": 1999, "estimated_token_count": 114, "token_estimator": "heuristic-v1", "text": "## The Case for Benchmarking\n\nBenchmarking helps validate that the required execution time for different functions is within reasonable boundaries to ensure your blockchain runtime can handle transactions efficiently and securely. By accurately measuring the weight of each extrinsic, you can prevent service interruptions caused by computationally intensive calls that exceed block time limits. Without benchmarking, runtime performance could be vulnerable to DoS attacks, where malicious users exploit functions with unoptimized weights.\n\nBenchmarking also ensures predictable transaction fees. Weights derived from benchmark tests accurately reflect the resource usage of function calls, allowing fair fee calculation. This approach discourages abuse while maintaining network reliability."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmarking FRAME Pallets", "index": 2, "depth": 3, "title": "Benchmarking and Weight", "anchor": "benchmarking-and-weight", "start_char": 1999, "end_char": 3665, "estimated_token_count": 321, "token_estimator": "heuristic-v1", "text": "### Benchmarking and Weight \n\nIn Polkadot SDK-based chains, weight quantifies the computational effort needed to process transactions. This weight includes factors such as:\n\n- Computational complexity.\n- Storage complexity (proof size).\n- Database reads and writes.\n- Hardware specifications.\n\nBenchmarking uses real-world testing to simulate worst-case scenarios for extrinsics. The framework generates a linear model for weight calculation by running multiple iterations with varied parameters. These worst-case weights ensure blocks remain within execution limits, enabling the runtime to maintain throughput under varying loads. Excess fees can be refunded if a call uses fewer resources than expected, offering users a fair cost model.\n \nBecause weight is a generic unit of measurement based on computation time for a specific physical machine, the weight of any function can change based on the specifications of hardware used for benchmarking. By modeling the expected weight of each runtime function, the blockchain can calculate the number of transactions or system-level calls it can execute within a certain period.\n\nWithin FRAME, each function call that is dispatched must have a `#[pallet::weight]` annotation that can return the expected weight for the worst-case scenario execution of that function given its inputs:\n\n```rust hl_lines=\"2\"\n#[pallet::call_index(0)]\n#[pallet::weight(T::WeightInfo::do_something())]\npub fn do_something(origin: OriginFor) -> DispatchResultWithPostInfo { Ok(()) }\n```\n\nThe `WeightInfo` file is automatically generated during benchmarking. Based on these tests, this file provides accurate weights for each extrinsic."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmarking FRAME Pallets", "index": 3, "depth": 2, "title": "Benchmarking Process", "anchor": "benchmarking-process", "start_char": 3665, "end_char": 4208, "estimated_token_count": 98, "token_estimator": "heuristic-v1", "text": "## Benchmarking Process\n\nBenchmarking a pallet involves the following steps: \n\n1. Creating a `benchmarking.rs` file within your pallet's structure.\n2. Writing a benchmarking test for each extrinsic.\n3. Executing the benchmarking tool to calculate weights based on performance metrics.\n\nThe benchmarking tool runs multiple iterations to model worst-case execution times and determine the appropriate weight. By default, the benchmarking pipeline is deactivated. To activate it, compile your runtime with the `runtime-benchmarks` feature flag."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmarking FRAME Pallets", "index": 4, "depth": 3, "title": "Prepare Your Environment", "anchor": "prepare-your-environment", "start_char": 4208, "end_char": 5262, "estimated_token_count": 293, "token_estimator": "heuristic-v1", "text": "### Prepare Your Environment\n\nInstall the [`frame-omni-bencher`](https://crates.io/crates/frame-omni-bencher){target=\\_blank} command-line tool:\n\n```bash\ncargo install frame-omni-bencher\n```\n\nBefore writing benchmark tests, you need to ensure the `frame-benchmarking` crate is included in your pallet's `Cargo.toml` similar to the following:\n\n```toml title=\"Cargo.toml\"\nframe-benchmarking = { version = \"37.0.0\", default-features = false }\n```\n\nYou must also ensure that you add the `runtime-benchmarks` feature flag as follows under the `[features]` section of your pallet's `Cargo.toml`:\n\n```toml title=\"Cargo.toml\"\nruntime-benchmarks = [\n \"frame-benchmarking/runtime-benchmarks\",\n \"frame-support/runtime-benchmarks\",\n \"frame-system/runtime-benchmarks\",\n \"sp-runtime/runtime-benchmarks\",\n]\n```\n\nLastly, ensure that `frame-benchmarking` is included in `std = []`: \n\n```toml title=\"Cargo.toml\"\nstd = [\n # ...\n \"frame-benchmarking?/std\",\n # ...\n]\n```\n\nOnce complete, you have the required dependencies for writing benchmark tests for your pallet."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmarking FRAME Pallets", "index": 5, "depth": 3, "title": "Write Benchmark Tests", "anchor": "write-benchmark-tests", "start_char": 5262, "end_char": 7718, "estimated_token_count": 645, "token_estimator": "heuristic-v1", "text": "### Write Benchmark Tests\n\nCreate a `benchmarking.rs` file in your pallet's `src/`. Your directory structure should look similar to the following:\n\n```\nmy-pallet/\n├── src/\n│ ├── lib.rs # Main pallet implementation\n│ └── benchmarking.rs # Benchmarking\n└── Cargo.toml\n```\n\nWith the directory structure set, you can use the [`polkadot-sdk-parachain-template`](https://github.com/paritytech/polkadot-sdk-parachain-template/tree/master/pallets){target=\\_blank} to get started as follows:\n\n```rust title=\"benchmarking.rs (starter template)\"\n//! Benchmarking setup for pallet-template\n#![cfg(feature = \"runtime-benchmarks\")]\n\nuse super::*;\nuse frame_benchmarking::v2::*;\n\n#[benchmarks]\nmod benchmarks {\n\tuse super::*;\n\t#[cfg(test)]\n\tuse crate::pallet::Pallet as Template;\n\tuse frame_system::RawOrigin;\n\n\t#[benchmark]\n\tfn do_something() {\n\t\tlet caller: T::AccountId = whitelisted_caller();\n\t\t#[extrinsic_call]\n\t\tdo_something(RawOrigin::Signed(caller), 100);\n\n\t\tassert_eq!(Something::::get().map(|v| v.block_number), Some(100u32.into()));\n\t}\n\n\t#[benchmark]\n\tfn cause_error() {\n\t\tSomething::::put(CompositeStruct { block_number: 100u32.into() });\n\t\tlet caller: T::AccountId = whitelisted_caller();\n\t\t#[extrinsic_call]\n\t\tcause_error(RawOrigin::Signed(caller));\n\n\t\tassert_eq!(Something::::get().map(|v| v.block_number), Some(101u32.into()));\n\t}\n\n\timpl_benchmark_test_suite!(Template, crate::mock::new_test_ext(), crate::mock::Test);\n}\n```\n\nIn your benchmarking tests, employ these best practices:\n\n- **Write custom testing functions**: The function `do_something` in the preceding example is a placeholder. Similar to writing unit tests, you must write custom functions to benchmark test your extrinsics. Access the mock runtime and use functions such as `whitelisted_caller()` to sign transactions and facilitate testing.\n- **Use the `#[extrinsic_call]` macro**: This macro is used when calling the extrinsic itself and is a required part of a benchmarking function. See the [`extrinsic_call`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html#extrinsic_call-and-block){target=\\_blank} docs for more details.\n- **Validate extrinsic behavior**: The `assert_eq` expression ensures that the extrinsic is working properly within the benchmark context.\n\nAdd the `benchmarking` module to your pallet. In the pallet `lib.rs` file add the following:\n\n```rust\n#[cfg(feature = \"runtime-benchmarks\")]\nmod benchmarking;\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmarking FRAME Pallets", "index": 6, "depth": 3, "title": "Add Benchmarks to Runtime", "anchor": "add-benchmarks-to-runtime", "start_char": 7718, "end_char": 9847, "estimated_token_count": 418, "token_estimator": "heuristic-v1", "text": "### Add Benchmarks to Runtime\n\nBefore running the benchmarking tool, you must integrate benchmarks with your runtime as follows:\n\n1. Navigate to your `runtime/src` directory and check if a `benchmarks.rs` file exists. If not, create one. This file will contain the macro that registers all pallets for benchmarking along with their respective configurations:\n\n ```rust title=\"benchmarks.rs\"\n frame_benchmarking::define_benchmarks!(\n [frame_system, SystemBench::]\n [pallet_parachain_template, TemplatePallet]\n [pallet_balances, Balances]\n [pallet_session, SessionBench::]\n [pallet_timestamp, Timestamp]\n [pallet_message_queue, MessageQueue]\n [pallet_sudo, Sudo]\n [pallet_collator_selection, CollatorSelection]\n [cumulus_pallet_parachain_system, ParachainSystem]\n [cumulus_pallet_xcmp_queue, XcmpQueue]\n );\n ```\n\n For example, to add a new pallet named `pallet_parachain_template` for benchmarking, include it in the macro as shown:\n ```rust title=\"benchmarks.rs\" hl_lines=\"3\"\n frame_benchmarking::define_benchmarks!(\n [frame_system, SystemBench::]\n [pallet_parachain_template, TemplatePallet]\n );\n ```\n\n !!!warning \"Updating `define_benchmarks!` macro is required\"\n Any pallet that needs to be benchmarked must be included in the [`define_benchmarks!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.define_benchmarks.html){target=\\_blank} macro. The CLI will only be able to access and benchmark pallets that are registered here.\n\n2. Check your runtime's `lib.rs` file to ensure the `benchmarks` module is imported. The import should look like this:\n\n ```rust title=\"lib.rs\"\n #[cfg(feature = \"runtime-benchmarks\")]\n mod benchmarks;\n ```\n\n The `runtime-benchmarks` feature gate ensures benchmark tests are isolated from production runtime code.\n\n3. Enable runtime benchmarking for your pallet in `runtime/Cargo.toml`:\n\n ```toml\n runtime-benchmarks = [\n # ...\n \"pallet_parachain_template/runtime-benchmarks\",\n ]\n\n ```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmarking FRAME Pallets", "index": 7, "depth": 3, "title": "Run Benchmarks", "anchor": "run-benchmarks", "start_char": 9847, "end_char": 14232, "estimated_token_count": 1100, "token_estimator": "heuristic-v1", "text": "### Run Benchmarks\n\nYou can now compile your runtime with the `runtime-benchmarks` feature flag. This feature flag is crucial as the benchmarking tool will look for this feature being enabled to know when it should run benchmark tests. Follow these steps to compile the runtime with benchmarking enabled:\n\n1. Run `build` with the feature flag included:\n\n ```bash\n cargo build --features runtime-benchmarks --release\n ```\n\n2. Create a `weights.rs` file in your pallet's `src/` directory. This file will store the auto-generated weight calculations:\n\n ```bash\n touch weights.rs\n ```\n\n3. Before running the benchmarking tool, you'll need a template file that defines how weight information should be formatted. Download the official template from the Polkadot SDK repository and save it in your project folders for future use:\n\n ```bash\n curl https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \\\n --output ./pallets/benchmarking/frame-weight-template.hbs\n ```\n\n4. Run the benchmarking tool to measure extrinsic weights:\n\n ```bash\n frame-omni-bencher v1 benchmark pallet \\\n --runtime INSERT_PATH_TO_WASM_RUNTIME \\\n --pallet INSERT_NAME_OF_PALLET \\\n --extrinsic \"\" \\\n --template ./frame-weight-template.hbs \\\n --output weights.rs\n ```\n\n !!! tip \"Flag definitions\"\n - **`--runtime`**: The path to your runtime's Wasm.\n - **`--pallet`**: The name of the pallet you wish to benchmark. This pallet must be configured in your runtime and defined in `define_benchmarks`.\n - **`--extrinsic`**: Which extrinsic to test. Using `\"\"` implies all extrinsics will be benchmarked.\n - **`--template`**: Defines how weight information should be formatted.\n - **`--output`**: Where the output of the auto-generated weights will reside.\n\nThe generated `weights.rs` file contains weight annotations for your extrinsics, ready to be added to your pallet. The output should be similar to the following. Some output is omitted for brevity:\n\n
\n frame-omni-bencher v1 benchmark pallet \\\n --runtime INSERT_PATH_TO_WASM_RUNTIME \\\n --pallet \"INSERT_NAME_OF_PALLET\" \\\n --extrinsic \"\" \\\n --template ./frame-weight-template.hbs \\\n --output ./weights.rs\n ...\n 2025-01-15T16:41:33.557045Z INFO polkadot_sdk_frame::benchmark::pallet: [ 0 % ] Starting benchmark: pallet_parachain_template::do_something\n 2025-01-15T16:41:33.564644Z INFO polkadot_sdk_frame::benchmark::pallet: [ 50 % ] Starting benchmark: pallet_parachain_template::cause_error\n ...\n Created file: \"weights.rs\"\n \n
\n\n#### Add Benchmark Weights to Pallet\n\nOnce the `weights.rs` is generated, you must integrate it with your pallet. \n\n1. To begin the integration, import the `weights` module and the `WeightInfo` trait, then add both to your pallet's `Config` trait. Complete the following steps to set up the configuration:\n\n ```rust title=\"lib.rs\"\n pub mod weights;\n use crate::weights::WeightInfo;\n\n /// Configure the pallet by specifying the parameters and types on which it depends.\n #[pallet::config]\n pub trait Config: frame_system::Config {\n // ...\n /// A type representing the weights required by the dispatchables of this pallet.\n type WeightInfo: WeightInfo;\n }\n ```\n\n2. Next, you must add this to the `#[pallet::weight]` annotation in all the extrinsics via the `Config` as follows:\n\n ```rust hl_lines=\"2\" title=\"lib.rs\"\n #[pallet::call_index(0)]\n #[pallet::weight(T::WeightInfo::do_something())]\n pub fn do_something(origin: OriginFor) -> DispatchResultWithPostInfo { Ok(()) }\n ```\n\n3. Finally, configure the actual weight values in your runtime. In `runtime/src/config/mod.rs`, add the following code:\n\n ```rust title=\"mod.rs\"\n // Configure pallet.\n impl pallet_parachain_template::Config for Runtime {\n // ...\n type WeightInfo = pallet_parachain_template::weights::SubstrateWeight;\n }\n ```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmarking FRAME Pallets", "index": 8, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 14232, "end_char": 14715, "estimated_token_count": 114, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n- View the Rust Docs for a more comprehensive, low-level view of the [FRAME V2 Benchmarking Suite](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=_blank}.\n- Read the [FRAME Benchmarking and Weights](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_benchmarking_weight/index.html){target=_blank} reference document, a concise guide which details how weights and benchmarking work."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 0, "end_char": 868, "estimated_token_count": 183, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nBenchmarking is the process of measuring the computational resources (execution time and storage) required by your pallet's extrinsics. Accurate [weight](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/index.html){target=\\_blank} calculations are essential for ensuring your blockchain can process transactions efficiently while protecting against denial-of-service attacks.\n\nThis guide continues the pallet development series, building on the [Create a Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet), [Mock Your Runtime](/parachains/customize-runtime/pallet-development/mock-runtime), and [Test Your Pallet](/parachains/customize-runtime/pallet-development/pallet-testing) tutorials. You'll learn how to benchmark the counter pallet extrinsics and integrate the generated weights into your runtime."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 868, "end_char": 1071, "estimated_token_count": 32, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore you begin, ensure you have:\n\n- Completed the previous pallet development tutorials\n- Basic understanding of computational complexity\n- Familiarity with Rust's testing framework"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 2, "depth": 2, "title": "Why Benchmark?", "anchor": "why-benchmark", "start_char": 1071, "end_char": 1723, "estimated_token_count": 109, "token_estimator": "heuristic-v1", "text": "## Why Benchmark?\n\nIn blockchain systems, every operation consumes resources. Weight is the mechanism Polkadot SDK uses to measure and limit resource consumption. Without accurate weights:\n\n- **Security Risk**: Malicious actors could submit transactions that consume excessive resources, blocking legitimate transactions or halting the chain\n- **Inefficiency**: Over-estimated weights waste block space and reduce throughput\n- **User Experience**: Inaccurate weights lead to incorrect fee calculations\n\nBenchmarking provides empirical measurements of your extrinsics under various conditions, ensuring weights reflect real-world resource consumption."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 3, "depth": 2, "title": "Understanding Weights", "anchor": "understanding-weights", "start_char": 1723, "end_char": 2778, "estimated_token_count": 255, "token_estimator": "heuristic-v1", "text": "## Understanding Weights\n\nThe [weight system](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html){target=\\_blank} serves multiple purposes:\n\n- **DoS Protection**: Limits the computational work per block, preventing attackers from overwhelming the network\n- **Fee Calculation**: Determines transaction fees based on actual resource usage\n- **Block Production**: Helps block authors maximize throughput while staying within block limits\n\nWeights are expressed as [`Weight::from_parts(ref_time, proof_size)`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.from_parts){target=\\_blank} where:\n\n- [`ref_time`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.ref_time){target=\\_blank}: Computational time measured in picoseconds\n- [`proof_size`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.proof_size){target=\\_blank}: Storage proof size in bytes"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 4, "depth": 2, "title": "Step 1: Create the Benchmarking Module", "anchor": "step-1-create-the-benchmarking-module", "start_char": 2778, "end_char": 5474, "estimated_token_count": 728, "token_estimator": "heuristic-v1", "text": "## Step 1: Create the Benchmarking Module\n\nCreate a new file `benchmarking.rs` in your pallet's `src` directory. This module will contain all the [benchmarking definitions](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\\_blank} for your pallet:\n\n```rust title=\"pallets/pallet-custom/src/benchmarking.rs\"\n#![cfg(feature = \"runtime-benchmarks\")]\n\nuse super::*;\nuse frame::deps::frame_benchmarking::v2::*;\nuse frame::benchmarking::prelude::RawOrigin;\n\n#[benchmarks]\nmod benchmarks {\n use super::*;\n\n #[benchmark]\n fn set_counter_value() {\n let new_value: u32 = 100;\n\n #[extrinsic_call]\n _(RawOrigin::Root, new_value);\n\n assert_eq!(CounterValue::::get(), new_value);\n }\n\n #[benchmark]\n fn increment() {\n let caller: T::AccountId = whitelisted_caller();\n let amount: u32 = 50;\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller.clone()), amount);\n\n assert_eq!(CounterValue::::get(), amount);\n assert_eq!(UserInteractions::::get(caller), 1);\n }\n\n #[benchmark]\n fn decrement() {\n // First set the counter to a non-zero value\n CounterValue::::put(100);\n\n let caller: T::AccountId = whitelisted_caller();\n let amount: u32 = 30;\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller.clone()), amount);\n\n assert_eq!(CounterValue::::get(), 70);\n assert_eq!(UserInteractions::::get(caller), 1);\n }\n\n impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test);\n}\n```\n\n**Key components:**\n\n- **`#![cfg(feature = \"runtime-benchmarks\")]`**: Ensures benchmarking code only compiles when the feature is enabled\n- **[`#[benchmarks]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmarks.html){target=\\_blank}**: Marks the module containing benchmark definitions\n- **[`#[benchmark]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmark.html){target=\\_blank}**: Defines individual benchmark functions\n- **[`#[extrinsic_call]`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.extrinsic_call.html){target=\\_blank}**: Marks the actual extrinsic invocation to measure\n- **[`whitelisted_caller()`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/fn.whitelisted_caller.html){target=\\_blank}**: Generates a funded account for benchmarking\n- **[`impl_benchmark_test_suite!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.impl_benchmark_test_suite.html){target=\\_blank}**: Generates test functions to verify benchmarks work correctly"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 5, "depth": 2, "title": "Step 2: Define the Weight Trait", "anchor": "step-2-define-the-weight-trait", "start_char": 5474, "end_char": 6891, "estimated_token_count": 297, "token_estimator": "heuristic-v1", "text": "## Step 2: Define the Weight Trait\n\nThe [`WeightInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/trait.WeightInfo.html){target=\\_blank} trait provides an abstraction layer that allows weights to be swapped at runtime configuration. This enables you to use placeholder weights during development and testing, then switch to auto-generated benchmarked weights in production without modifying the pallet code itself.\n\nAdd a `weights` module to your pallet that defines the `WeightInfo` trait:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#[frame::pallet]\npub mod pallet {\n use frame::prelude::*;\n pub use weights::WeightInfo;\n\n pub mod weights {\n use frame::prelude::*;\n\n pub trait WeightInfo {\n fn set_counter_value() -> Weight;\n fn increment() -> Weight;\n fn decrement() -> Weight;\n }\n\n impl WeightInfo for () {\n fn set_counter_value() -> Weight {\n Weight::from_parts(10_000, 0)\n }\n fn increment() -> Weight {\n Weight::from_parts(15_000, 0)\n }\n fn decrement() -> Weight {\n Weight::from_parts(15_000, 0)\n }\n }\n }\n\n // ... rest of pallet\n}\n```\n\nThe `()` implementation provides placeholder weights for development. Later, this will be replaced with auto-generated weights from benchmarking."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 6, "depth": 2, "title": "Step 3: Add WeightInfo to Config", "anchor": "step-3-add-weightinfo-to-config", "start_char": 6891, "end_char": 7656, "estimated_token_count": 169, "token_estimator": "heuristic-v1", "text": "## Step 3: Add WeightInfo to Config\n\nBy making `WeightInfo` an associated type in the `Config` trait, you allow each runtime that uses your pallet to specify which weight implementation to use. Different deployment environments (testnets, production chains, or different hardware configurations) may have different performance characteristics and can use different weight calculations.\n\nUpdate your pallet's `Config` trait to include `WeightInfo`:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#[pallet::config]\npub trait Config: frame_system::Config {\n type RuntimeEvent: From> + IsType<::RuntimeEvent>;\n\n #[pallet::constant]\n type CounterMaxValue: Get;\n\n type WeightInfo: weights::WeightInfo;\n}\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 7, "depth": 2, "title": "Step 4: Update Extrinsic Weight Annotations", "anchor": "step-4-update-extrinsic-weight-annotations", "start_char": 7656, "end_char": 8833, "estimated_token_count": 290, "token_estimator": "heuristic-v1", "text": "## Step 4: Update Extrinsic Weight Annotations\n\nBy calling `T::WeightInfo::function_name()` instead of using hardcoded `Weight::from_parts()` values, your extrinsics automatically use whichever weight implementation is configured in the runtime. This allows you to easily switch between placeholder weights for testing and benchmarked weights for production without changing any pallet code.\n\nReplace the placeholder weights in your extrinsics with calls to the `WeightInfo` trait:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#[pallet::call]\nimpl Pallet {\n #[pallet::call_index(0)]\n #[pallet::weight(T::WeightInfo::set_counter_value())]\n pub fn set_counter_value(origin: OriginFor, new_value: u32) -> DispatchResult {\n // ... implementation\n }\n\n #[pallet::call_index(1)]\n #[pallet::weight(T::WeightInfo::increment())]\n pub fn increment(origin: OriginFor, amount: u32) -> DispatchResult {\n // ... implementation\n }\n\n #[pallet::call_index(2)]\n #[pallet::weight(T::WeightInfo::decrement())]\n pub fn decrement(origin: OriginFor, amount: u32) -> DispatchResult {\n // ... implementation\n }\n}\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 8, "depth": 2, "title": "Step 5: Include the Benchmarking Module", "anchor": "step-5-include-the-benchmarking-module", "start_char": 8833, "end_char": 9453, "estimated_token_count": 161, "token_estimator": "heuristic-v1", "text": "## Step 5: Include the Benchmarking Module\n\nThe `#[cfg(feature = \"runtime-benchmarks\")]` attribute ensures that benchmarking code is only compiled when explicitly needed. This keeps your production runtime lean by excluding benchmarking infrastructure from normal builds, as it's only needed when generating weights.\n\nAt the top of your `lib.rs`, add the module declaration:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#![cfg_attr(not(feature = \"std\"), no_std)]\n\nextern crate alloc;\nuse alloc::vec::Vec;\n\npub use pallet::*;\n\n#[cfg(feature = \"runtime-benchmarks\")]\nmod benchmarking;\n\n// ... rest of the pallet\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 9, "depth": 2, "title": "Step 6: Configure Pallet Dependencies", "anchor": "step-6-configure-pallet-dependencies", "start_char": 9453, "end_char": 10350, "estimated_token_count": 212, "token_estimator": "heuristic-v1", "text": "## Step 6: Configure Pallet Dependencies\n\nThe feature flag system in Cargo allows you to conditionally compile code based on which features are enabled. By defining a `runtime-benchmarks` feature that cascades to FRAME's benchmarking features, you create a clean way to build your pallet with or without benchmarking support, ensuring all necessary dependencies are available when needed but excluded from production builds.\n\nUpdate your pallet's `Cargo.toml` to enable the benchmarking feature:\n\n```toml title=\"pallets/pallet-custom/Cargo.toml\"\n[dependencies]\ncodec = { features = [\"derive\"], workspace = true }\nscale-info = { features = [\"derive\"], workspace = true }\nframe = { features = [\"experimental\", \"runtime\"], workspace = true }\n\n[features]\ndefault = [\"std\"]\nruntime-benchmarks = [\n \"frame/runtime-benchmarks\",\n]\nstd = [\n \"codec/std\",\n \"scale-info/std\",\n \"frame/std\",\n]\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 10, "depth": 2, "title": "Step 7: Update Mock Runtime", "anchor": "step-7-update-mock-runtime", "start_char": 10350, "end_char": 10898, "estimated_token_count": 117, "token_estimator": "heuristic-v1", "text": "## Step 7: Update Mock Runtime\n\nIn your mock runtime for testing, use the placeholder `()` implementation of `WeightInfo` since unit tests focus on verifying functional correctness rather than performance characteristics. This keeps tests fast and focused on validating logic.\n\nAdd the `WeightInfo` type to your test configuration in `mock.rs`:\n\n```rust title=\"pallets/pallet-custom/src/mock.rs\"\nimpl pallet_custom::Config for Test {\n type RuntimeEvent = RuntimeEvent;\n type CounterMaxValue = ConstU32<1000>;\n type WeightInfo = ();\n}\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 11, "depth": 2, "title": "Step 8: Configure Runtime Benchmarking", "anchor": "step-8-configure-runtime-benchmarking", "start_char": 10898, "end_char": 11085, "estimated_token_count": 31, "token_estimator": "heuristic-v1", "text": "## Step 8: Configure Runtime Benchmarking\n\nTo execute benchmarks, your pallet must be integrated into the runtime's benchmarking infrastructure. This involves three configuration steps:"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 12, "depth": 3, "title": "Update Runtime Cargo.toml", "anchor": "update-runtime-cargotoml", "start_char": 11085, "end_char": 11652, "estimated_token_count": 137, "token_estimator": "heuristic-v1", "text": "### Update Runtime Cargo.toml\n\nWhen you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included.\n\nAdd your pallet to the runtime's `runtime-benchmarks` feature in `runtime/Cargo.toml`:\n\n```toml title=\"runtime/Cargo.toml\"\nruntime-benchmarks = [\n \"cumulus-pallet-parachain-system/runtime-benchmarks\",\n \"hex-literal\",\n \"pallet-parachain-template/runtime-benchmarks\",\n \"polkadot-sdk/runtime-benchmarks\",\n \"pallet-custom/runtime-benchmarks\",\n]\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 13, "depth": 3, "title": "Update Runtime Configuration", "anchor": "update-runtime-configuration", "start_char": 11652, "end_char": 12130, "estimated_token_count": 103, "token_estimator": "heuristic-v1", "text": "### Update Runtime Configuration\n\nStart with the placeholder implementation during development. After successfully running benchmarks and generating the weights file, you'll update this to use the benchmarked weights.\n\nIn `runtime/src/configs/mod.rs`, add the `WeightInfo` type:\n\n```rust title=\"runtime/src/configs/mod.rs\"\nimpl pallet_custom::Config for Runtime {\n type RuntimeEvent = RuntimeEvent;\n type CounterMaxValue = ConstU32<1000>;\n type WeightInfo = ();\n}\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 14, "depth": 3, "title": "Register Benchmarks", "anchor": "register-benchmarks", "start_char": 12130, "end_char": 12611, "estimated_token_count": 104, "token_estimator": "heuristic-v1", "text": "### Register Benchmarks\n\nThe `define_benchmarks!` macro creates the infrastructure that allows the benchmarking CLI tool to discover and execute your pallet's benchmarks.\n\nAdd your pallet to the benchmark list in `runtime/src/benchmarks.rs`:\n\n```rust title=\"runtime/src/benchmarks.rs\"\npolkadot_sdk::frame_benchmarking::define_benchmarks!(\n [frame_system, SystemBench::]\n [pallet_balances, Balances]\n // ... other pallets\n [pallet_custom, CustomPallet]\n);\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 15, "depth": 2, "title": "Step 9: Run Benchmarks", "anchor": "step-9-run-benchmarks", "start_char": 12611, "end_char": 12638, "estimated_token_count": 7, "token_estimator": "heuristic-v1", "text": "## Step 9: Run Benchmarks"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 16, "depth": 3, "title": "Test Benchmark Compilation", "anchor": "test-benchmark-compilation", "start_char": 12638, "end_char": 13283, "estimated_token_count": 128, "token_estimator": "heuristic-v1", "text": "### Test Benchmark Compilation\n\nThe `impl_benchmark_test_suite!` macro generates unit tests for each benchmark. Running these tests verifies that your benchmarks compile correctly, execute without panicking, and pass their assertions, catching issues early before building the full runtime.\n\nFirst, verify your benchmarks compile and run as tests:\n\n```bash\ncargo test -p pallet-custom --features runtime-benchmarks\n```\n\nYou should see your benchmark tests passing:\n\n```\ntest benchmarking::benchmarks::bench_set_counter_value ... ok\ntest benchmarking::benchmarks::bench_increment ... ok\ntest benchmarking::benchmarks::bench_decrement ... ok\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 17, "depth": 3, "title": "Build the Runtime with Benchmarks", "anchor": "build-the-runtime-with-benchmarks", "start_char": 13283, "end_char": 13996, "estimated_token_count": 132, "token_estimator": "heuristic-v1", "text": "### Build the Runtime with Benchmarks\n\nThis build includes all the benchmarking infrastructure and special host functions needed for measurement. The resulting WASM runtime contains your benchmark code and can communicate with the benchmarking tool's execution environment. This is a special build used only for benchmarking - you'll create a different build later for actually running your chain.\n\nCompile the runtime with benchmarking enabled to generate the WASM binary:\n\n```bash\ncargo build --release --features runtime-benchmarks\n```\n\nThis produces the runtime WASM file needed for benchmarking, typically located at:\n```\ntarget/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 18, "depth": 3, "title": "Install the Benchmarking Tool", "anchor": "install-the-benchmarking-tool", "start_char": 13996, "end_char": 14536, "estimated_token_count": 118, "token_estimator": "heuristic-v1", "text": "### Install the Benchmarking Tool\n\n[`frame-omni-bencher`](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\\_blank} is the official Polkadot SDK tool specifically designed for FRAME pallet benchmarking. It provides a standardized way to execute benchmarks, measure execution times and storage operations, and generate properly formatted weight files with full integration into the FRAME weight system.\n\nInstall the `frame-omni-bencher` CLI tool:\n\n```bash\ncargo install frame-omni-bencher --locked\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 19, "depth": 3, "title": "Download the Weight Template", "anchor": "download-the-weight-template", "start_char": 14536, "end_char": 15301, "estimated_token_count": 155, "token_estimator": "heuristic-v1", "text": "### Download the Weight Template\n\nThe weight template is a Handlebars file that transforms raw benchmark data into a properly formatted Rust source file. It defines the structure of the generated `weights.rs` file, including imports, trait definitions, documentation comments, and formatting. Using the official template ensures your weight files follow Polkadot SDK conventions and include all necessary metadata like benchmark execution parameters, storage operation counts, and hardware information.\n\nDownload the official weight template file:\n\n```bash\ncurl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \\\n--output ./pallets/pallet-custom/frame-weight-template.hbs\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 20, "depth": 3, "title": "Hardware Requirements for Benchmarking", "anchor": "hardware-requirements-for-benchmarking", "start_char": 15301, "end_char": 17789, "estimated_token_count": 432, "token_estimator": "heuristic-v1", "text": "### Hardware Requirements for Benchmarking\n\n!!! warning \"Critical: Benchmark on Production-Like Hardware\"\n Benchmarks must be executed on hardware similar to what will run your chain in production. Weight measurements are hardware-dependent, and benchmarking on different hardware can lead to dangerous under-estimation or wasteful over-estimation of weights.\n\nWeights represent the actual computational time and resources consumed by extrinsics. These measurements vary significantly across different hardware configurations:\n\n- **CPU Performance**: Different processors execute instructions at different speeds. A faster development laptop will produce lower weight values than production server hardware\n- **Storage Speed**: Database read/write performance varies between NVMe SSDs, SATA SSDs, and HDDs, affecting storage-related weights\n- **Memory Bandwidth**: RAM speed impacts how quickly data can be accessed during execution\n- **CPU Cache**: Cache size and architecture differences affect repeated operations\n\nBenchmarking on faster hardware than production leads to under-estimated weights - attackers could submit extrinsics that consume more resources than the weights suggest, potentially causing blocks to take longer than expected to produce or even halting the chain. Conversely, benchmarking on slower hardware creates over-estimated weights, resulting in unnecessarily high transaction fees and wasted block capacity.\n\n**Best practices:**\n\n1. **Match production specifications**: If your chain will run on specific validator hardware, benchmark on identical or very similar machines\n2. **Use reference hardware**: The Polkadot ecosystem often uses standardized reference hardware specifications for consistency. Consider following these standards if your chain will connect to Polkadot or Kusama\n3. **Dedicated benchmarking environment**: Run benchmarks on a machine without other heavy processes to ensure consistent measurements\n4. **Document your hardware**: The generated weight files include hardware information in comments. Review this to ensure it matches your production environment\n5. **Re-benchmark when hardware changes**: If your validator hardware specifications change, re-run benchmarks and update weights\n\nFor development and testing purposes, you can run benchmarks on any available hardware to verify that your benchmark functions work correctly. However, before deploying to production, always re-run benchmarks on production-equivalent hardware."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 21, "depth": 3, "title": "Execute Benchmarks", "anchor": "execute-benchmarks", "start_char": 17789, "end_char": 19210, "estimated_token_count": 294, "token_estimator": "heuristic-v1", "text": "### Execute Benchmarks\n\nBenchmarks execute against the compiled WASM runtime rather than native code because WASM is what actually runs in production on the blockchain. WASM execution can have different performance characteristics than native code due to compilation and sandboxing overhead, so benchmarking the WASM ensures your weight measurements reflect real-world conditions.\n\nRun benchmarks for your pallet to generate weight files:\n\n```bash\nframe-omni-bencher v1 benchmark pallet \\\n --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \\\n --pallet pallet_custom \\\n --extrinsic \"\" \\\n --template ./pallets/pallet-custom/frame-weight-template.hbs \\\n --output ./pallets/pallet-custom/src/weights.rs\n```\n\n**Command breakdown:**\n\n- `v1`: Specifies the benchmarking framework version (v2 API)\n- `benchmark pallet`: Subcommand indicating you want to benchmark pallet extrinsics\n- `--runtime`: Path to the compiled WASM runtime file that includes your pallet and benchmarks\n- `--pallet pallet_custom`: Name of the pallet to benchmark (must match the name used in `define_benchmarks!`)\n- `--extrinsic \"\"`: Empty string benchmarks all extrinsics in the pallet; you can specify a single extrinsic name to benchmark only that one\n- `--template`: Path to the Handlebars template that formats the output\n- `--output`: Destination file path for the generated weights module"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 22, "depth": 3, "title": "Advanced Options", "anchor": "advanced-options", "start_char": 19210, "end_char": 20357, "estimated_token_count": 242, "token_estimator": "heuristic-v1", "text": "### Advanced Options\n\nYou can customize benchmark execution with additional parameters for more detailed measurements:\n\n```bash\nframe-omni-bencher v1 benchmark pallet \\\n --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \\\n --pallet pallet_custom \\\n --extrinsic \"\" \\\n --steps 50 \\\n --repeat 20 \\\n --template ./pallets/pallet-custom/frame-weight-template.hbs \\\n --output ./pallets/pallet-custom/src/weights.rs\n```\n\n**Additional parameters:**\n\n- `--steps 50`: Number of different input values to test when using linear components (default: 50). More steps provide finer granularity for detecting complexity trends but increase benchmarking time\n- `--repeat 20`: Number of repetitions for each measurement (default: 20). More repetitions improve statistical accuracy by averaging out variance, reducing the impact of system noise and providing more reliable weight estimates\n- `--heap-pages 4096`: WASM heap pages allocation. Affects available memory during execution\n- `--wasm-execution compiled`: WASM execution method. Use `compiled` for performance closest to production conditions"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 23, "depth": 2, "title": "Step 10: Use Generated Weights", "anchor": "step-10-use-generated-weights", "start_char": 20357, "end_char": 21332, "estimated_token_count": 168, "token_estimator": "heuristic-v1", "text": "## Step 10: Use Generated Weights\n\nAfter running benchmarks, a `weights.rs` file is generated containing measured weights. The generated weights are based on actual measurements of your code running on real hardware, accounting for the specific complexity of your logic, storage access patterns, and computational requirements. Estimates or placeholder values cannot capture these nuances and will either waste block space (over-estimation) or create security risks (under-estimation).\n\nThe file includes:\n\n- Detailed documentation about the benchmark execution environment (date, hardware, parameters)\n- The `WeightInfo` trait definition matching your benchmark functions\n- `SubstrateWeight` implementation with measured weights from your benchmarks\n- Database read/write costs calculated based on observed storage operations\n- Component complexity annotations for variable inputs (if you use linear components)\n- A fallback `()` implementation for testing environments"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 24, "depth": 3, "title": "Integrate the Generated Weights", "anchor": "integrate-the-generated-weights", "start_char": 21332, "end_char": 22065, "estimated_token_count": 189, "token_estimator": "heuristic-v1", "text": "### Integrate the Generated Weights\n\nUnlike the benchmarking module (which is only needed when running benchmarks), the weights module must be available in all builds because the runtime needs to call the weight functions during normal operation to calculate transaction fees and enforce block limits.\n\nAdd the weights module to your pallet's `lib.rs`:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#![cfg_attr(not(feature = \"std\"), no_std)]\n\nextern crate alloc;\nuse alloc::vec::Vec;\n\npub use pallet::*;\n\n#[cfg(feature = \"runtime-benchmarks\")]\nmod benchmarking;\n\npub mod weights;\n\n#[frame::pallet]\npub mod pallet {\n use super::*;\n use frame::prelude::*;\n use crate::weights::WeightInfo;\n // ... rest of pallet\n}\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 25, "depth": 3, "title": "Update Runtime Configuration", "anchor": "update-runtime-configuration-2", "start_char": 22065, "end_char": 22694, "estimated_token_count": 121, "token_estimator": "heuristic-v1", "text": "### Update Runtime Configuration\n\nThis change activates your benchmarked weights in the production runtime. Now when users submit transactions that call your pallet's extrinsics, the runtime will use the actual measured weights to calculate fees and enforce block limits.\n\nUpdate your runtime configuration to use the generated weights instead of the placeholder `()` implementation:\n\n```rust title=\"runtime/src/configs/mod.rs\"\nimpl pallet_custom::Config for Runtime {\n type RuntimeEvent = RuntimeEvent;\n type CounterMaxValue = ConstU32<1000>;\n type WeightInfo = pallet_custom::weights::SubstrateWeight;\n}\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 26, "depth": 3, "title": "Example Generated Weight File", "anchor": "example-generated-weight-file", "start_char": 22694, "end_char": 24357, "estimated_token_count": 450, "token_estimator": "heuristic-v1", "text": "### Example Generated Weight File\n\nThe generated `weights.rs` file will look similar to this:\n\n```rust title=\"pallets/pallet-custom/src/weights.rs\"\n//! Autogenerated weights for `pallet_custom`\n//!\n//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0\n//! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20`\n\n#![cfg_attr(rustfmt, rustfmt_skip)]\n#![allow(unused_parens)]\n#![allow(unused_imports)]\n#![allow(missing_docs)]\n\nuse frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};\nuse core::marker::PhantomData;\n\npub trait WeightInfo {\n fn set_counter_value() -> Weight;\n fn increment() -> Weight;\n fn decrement() -> Weight;\n}\n\npub struct SubstrateWeight(PhantomData);\nimpl WeightInfo for SubstrateWeight {\n fn set_counter_value() -> Weight {\n Weight::from_parts(8_234_000, 0)\n .saturating_add(T::DbWeight::get().reads(1))\n .saturating_add(T::DbWeight::get().writes(1))\n }\n\n fn increment() -> Weight {\n Weight::from_parts(12_456_000, 0)\n .saturating_add(T::DbWeight::get().reads(2))\n .saturating_add(T::DbWeight::get().writes(2))\n }\n\n fn decrement() -> Weight {\n Weight::from_parts(11_987_000, 0)\n .saturating_add(T::DbWeight::get().reads(2))\n .saturating_add(T::DbWeight::get().writes(2))\n }\n}\n```\n\n**Note**: The actual numbers will vary based on your hardware and implementation complexity. The [`DbWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.RuntimeDbWeight.html){target=\\_blank} accounts for database read and write operations."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 27, "depth": 2, "title": "Benchmarking Best Practices", "anchor": "benchmarking-best-practices", "start_char": 24357, "end_char": 24389, "estimated_token_count": 5, "token_estimator": "heuristic-v1", "text": "## Benchmarking Best Practices"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 28, "depth": 3, "title": "1. Test Worst-Case Scenarios", "anchor": "1-test-worst-case-scenarios", "start_char": 24389, "end_char": 25006, "estimated_token_count": 138, "token_estimator": "heuristic-v1", "text": "### 1. Test Worst-Case Scenarios\n\nBenchmarks should always measure maximum possible resource consumption. If you benchmark average or best-case scenarios, malicious users could craft transactions that hit worst-case paths in your code, consuming more resources than the weights indicate and potentially slowing down or halting block production.\n\n```rust\n#[benchmark]\nfn complex_operation() {\n // Set up worst-case storage state\n for i in 0..100 {\n SomeStorage::::insert(i, vec![0u8; 1000]);\n }\n\n let caller = whitelisted_caller();\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller));\n}\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 29, "depth": 3, "title": "2. Use Linear Components for Variable Complexity", "anchor": "2-use-linear-components-for-variable-complexity", "start_char": 25006, "end_char": 25882, "estimated_token_count": 206, "token_estimator": "heuristic-v1", "text": "### 2. Use Linear Components for Variable Complexity\n\nMany extrinsics have variable costs depending on input parameters. [Linear components](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/trait.BenchmarkingSetup.html){target=\\_blank} tell the benchmarking framework to test your extrinsic with different values of `n`, measure the execution time for each, and calculate a formula like `Weight = base_weight + (n * per_item_weight)`. This produces dynamic weights that accurately reflect the actual work being done.\n\nWhen extrinsic complexity depends on input size, use linear components:\n\n```rust title=\"pallets/pallet-custom/src/benchmarking.rs\"\n#[benchmark]\nfn process_items(n: Linear<0, 100>) {\n let caller = whitelisted_caller();\n let items: Vec = (0..n).collect();\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller), items);\n}\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 30, "depth": 3, "title": "3. Verify Results", "anchor": "3-verify-results", "start_char": 25882, "end_char": 26518, "estimated_token_count": 144, "token_estimator": "heuristic-v1", "text": "### 3. Verify Results\n\nAssertions ensure that your benchmark is actually testing the code path you think it's testing. If your extrinsic fails silently or takes an early return, the benchmark would measure the wrong scenario and produce inaccurate weights.\n\nAlways assert the expected state after extrinsic execution:\n\n```rust title=\"pallets/pallet-custom/src/benchmarking.rs\"\n#[benchmark]\nfn my_extrinsic() {\n let caller = whitelisted_caller();\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller.clone()));\n\n // Verify the extrinsic had the expected effect\n assert_eq!(MyStorage::::get(&caller), expected_value);\n}\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 31, "depth": 3, "title": "4. Minimize Setup Code", "anchor": "4-minimize-setup-code", "start_char": 26518, "end_char": 27092, "estimated_token_count": 120, "token_estimator": "heuristic-v1", "text": "### 4. Minimize Setup Code\n\nWhile the benchmarking framework tries to isolate the extrinsic execution, excessive setup code can add noise to measurements. More importantly, setup code that doesn't reflect real-world pre-conditions can lead to benchmarking unrealistic scenarios.\n\nOnly include necessary setup in benchmarks:\n\n```rust title=\"pallets/pallet-custom/src/benchmarking.rs\"\n#[benchmark]\nfn efficient_benchmark() {\n // Minimal setup\n let caller = whitelisted_caller();\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller));\n\n // Minimal assertions\n}\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 32, "depth": 2, "title": "Run Your Chain Locally", "anchor": "run-your-chain-locally", "start_char": 27092, "end_char": 27618, "estimated_token_count": 141, "token_estimator": "heuristic-v1", "text": "## Run Your Chain Locally\n\nNow that you've added the pallet to your runtime, you can launch your parachain locally to test the new functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\\_blank}. For instructions on setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\\_blank}, refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\\_blank} guide."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 33, "depth": 3, "title": "Build the Production Runtime", "anchor": "build-the-production-runtime", "start_char": 27618, "end_char": 28821, "estimated_token_count": 223, "token_estimator": "heuristic-v1", "text": "### Build the Production Runtime\n\nThe `runtime-benchmarks` feature flag adds special host functions (like `ext_benchmarking_current_time` and `ext_benchmarking_get_read_and_written_keys`) that are only available in the benchmarking execution environment. These functions allow the benchmarking framework to precisely measure execution time and track storage operations. However, regular nodes don't provide these host functions, so a runtime compiled with benchmarking features will fail to start on a production node.\n\nBefore running your chain, rebuild the runtime **without** the `runtime-benchmarks` feature:\n\n```bash\ncargo build --release\n```\n\n!!! note \"Build Types\"\n Understanding the difference between builds is critical:\n\n - `cargo build --release --features runtime-benchmarks` - Compiles with benchmarking host functions for measurement. Use this ONLY when running benchmarks with `frame-omni-bencher`\n - `cargo build --release` - Compiles production runtime without benchmarking features. Use this for running your actual chain\n\nThis produces a production-ready WASM runtime at `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm`."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 34, "depth": 3, "title": "Generate a Chain Specification", "anchor": "generate-a-chain-specification", "start_char": 28821, "end_char": 29655, "estimated_token_count": 165, "token_estimator": "heuristic-v1", "text": "### Generate a Chain Specification\n\nThe chain specification defines the initial state and configuration of your blockchain, including the runtime WASM code, genesis storage, and network parameters. By generating a new chain spec with your updated runtime (now containing your benchmarked pallet), you ensure that nodes starting from this spec will use the correct version of your code with proper weight calculations.\n\nCreate a new chain specification file with the updated runtime:\n\n```bash\nchain-spec-builder create -t development \\\n--relay-chain paseo \\\n--para-id 1000 \\\n--runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \\\nnamed-preset development\n```\n\nThis command generates a chain specification file, `chain_spec.json`, for your parachain with the updated runtime."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 35, "depth": 3, "title": "Start the Parachain Node", "anchor": "start-the-parachain-node", "start_char": 29655, "end_char": 30074, "estimated_token_count": 84, "token_estimator": "heuristic-v1", "text": "### Start the Parachain Node\n\nLaunch the parachain using the Polkadot Omni Node with the generated chain specification by running the following command:\n\n```bash\npolkadot-omni-node --chain ./chain_spec.json --dev\n```\n\nThe node will start and display initialization information including:\n\n- The chain specification name\n- The node identity and peer ID\n- Database location\n- Network endpoints (JSON-RPC and Prometheus)"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 36, "depth": 3, "title": "Verify Block Production", "anchor": "verify-block-production", "start_char": 30074, "end_char": 30777, "estimated_token_count": 190, "token_estimator": "heuristic-v1", "text": "### Verify Block Production\n\nOnce the node is running, you should see log messages indicating successful block production:\n\n```\n[Parachain] 🔨 Initializing Genesis block/state (state: 0x47ce…ec8d, header-hash: 0xeb12…fecc)\n[Parachain] 🎁 Prepared block for proposing at 1 (3 ms) ...\n[Parachain] 🏆 Imported #1 (0xeb12…fecc → 0xee51…98d2)\n[Parachain] 🎁 Prepared block for proposing at 2 (3 ms) ...\n[Parachain] 🏆 Imported #2 (0xee51…98d2 → 0x35e0…cc32)\n```\n\nThe parachain will produce new blocks every few seconds. You can now interact with your pallet's extrinsics through the JSON-RPC endpoint at `http://127.0.0.1:9944` using tools like [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\\_blank}."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 37, "depth": 2, "title": "Related Resources", "anchor": "related-resources", "start_char": 30777, "end_char": 31318, "estimated_token_count": 153, "token_estimator": "heuristic-v1", "text": "## Related Resources\n\n- [FRAME Benchmarking Documentation](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/index.html){target=\\_blank}\n- [Weight Struct Documentation](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html){target=\\_blank}\n- [Benchmarking v2 API](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\\_blank}\n- [frame-omni-bencher Tool](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\\_blank}"} {"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 26, "end_char": 847, "estimated_token_count": 167, "token_estimator": "heuristic-v1", "text": "## Introduction\n\n[Framework for Runtime Aggregation of Modular Entities (FRAME)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\\_blank} provides a powerful set of tools for blockchain development through modular components called [pallets](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/pallet/index.html){target=\\_blank}. These Rust-based runtime modules allow you to build custom blockchain functionality with precision and flexibility. While FRAME includes a library of pre-built pallets, its true strength lies in creating custom pallets tailored to your specific needs.\n\nIn this guide, you'll learn how to build a custom counter pallet from scratch that demonstrates core pallet development concepts."} {"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 847, "end_char": 1217, "estimated_token_count": 99, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore you begin, ensure you have:\n\n- [Polkadot SDK dependencies installed](/parachains/install-polkadot-sdk/){target=\\_blank}.\n- A [Polkadot SDK Parchain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\\_blank} set up locally.\n- Basic familiarity with [FRAME concepts](/parachains/customize-runtime/){target=\\_blank}."} {"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 2, "depth": 2, "title": "Core Pallet Components", "anchor": "core-pallet-components", "start_char": 1217, "end_char": 2092, "estimated_token_count": 193, "token_estimator": "heuristic-v1", "text": "## Core Pallet Components\n\nAs you build your custom pallet, you'll work with these key sections:\n\n- **Imports and dependencies**: Bring in necessary FRAME libraries and external modules.\n- **Runtime configuration trait**: Specify types and constants for pallet-runtime interaction.\n- **Runtime events**: Define signals that communicate state changes.\n- **Runtime errors**: Define error types returned from dispatchable calls.\n- **Runtime storage**: Declare on-chain storage items for your pallet's state.\n- **Genesis configuration**: Set initial blockchain state.\n- **Dispatchable functions (extrinsics)**: Create callable functions for user interactions.\n\nFor additional macros beyond those covered here, refer to the [pallet_macros](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/index.html){target=\\_blank} section of the Polkadot SDK Docs."} @@ -591,12 +632,12 @@ {"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 17, "depth": 3, "title": "Add to Runtime Construct", "anchor": "add-to-runtime-construct", "start_char": 22324, "end_char": 23326, "estimated_token_count": 214, "token_estimator": "heuristic-v1", "text": "### Add to Runtime Construct\n\nIn the `runtime/src/lib.rs` file, locate the [`#[frame_support::runtime]`](https://paritytech.github.io/polkadot-sdk/master/frame_support/attr.runtime.html){target=\\_blank} section and add your pallet with a unique `pallet_index`:\n\n```rust title=\"runtime/src/lib.rs\"\n#[frame_support::runtime]\nmod runtime {\n #[runtime::runtime]\n #[runtime::derive(\n RuntimeCall,\n RuntimeEvent,\n RuntimeError,\n RuntimeOrigin,\n RuntimeTask,\n RuntimeFreezeReason,\n RuntimeHoldReason,\n RuntimeSlashReason,\n RuntimeLockId,\n RuntimeViewFunction\n )]\n pub struct Runtime;\n\n #[runtime::pallet_index(0)]\n pub type System = frame_system;\n\n // ... other pallets\n\n #[runtime::pallet_index(51)]\n pub type CustomPallet = pallet_custom;\n}\n```\n\n!!!warning\n Each pallet must have a unique index. Duplicate indices will cause compilation errors. Choose an index that doesn't conflict with existing pallets."} {"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 18, "depth": 3, "title": "Configure Genesis for Your Runtime", "anchor": "configure-genesis-for-your-runtime", "start_char": 23326, "end_char": 23824, "estimated_token_count": 100, "token_estimator": "heuristic-v1", "text": "### Configure Genesis for Your Runtime\n\nTo set initial values for your pallet when the chain starts, you'll need to configure the genesis in your chain specification. Genesis configuration is typically done in the `node/src/chain_spec.rs` file or when generating the chain specification.\n\nFor development and testing, you can use the default values provided by the `#[derive(DefaultNoBound)]` macro. For production networks, you'll want to explicitly set these values in your chain specification."} {"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 19, "depth": 3, "title": "Verify Runtime Compilation", "anchor": "verify-runtime-compilation", "start_char": 23824, "end_char": 24047, "estimated_token_count": 41, "token_estimator": "heuristic-v1", "text": "### Verify Runtime Compilation\n\nCompile the runtime to ensure everything is configured correctly:\n\n```bash\ncargo build --release\n```\n\nThis command validates all pallet configurations and prepares the build for deployment."} -{"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 20, "depth": 2, "title": "Run Your Chain Locally", "anchor": "run-your-chain-locally", "start_char": 24047, "end_char": 24235, "estimated_token_count": 47, "token_estimator": "heuristic-v1", "text": "## Run Your Chain Locally\n\nLaunch your parachain locally to test the new pallet functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\\_blank}."} -{"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 21, "depth": 3, "title": "Generate a Chain Specification", "anchor": "generate-a-chain-specification", "start_char": 24235, "end_char": 24644, "estimated_token_count": 92, "token_estimator": "heuristic-v1", "text": "### Generate a Chain Specification\n\nCreate a chain specification file with the updated runtime:\n\n```bash\nchain-spec-builder create -t development \\\n--relay-chain paseo \\\n--para-id 1000 \\\n--runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \\\nnamed-preset development\n```\n\nThis command generates a `chain_spec.json` that includes your custom pallet."} -{"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 22, "depth": 3, "title": "Start the Parachain Node", "anchor": "start-the-parachain-node", "start_char": 24644, "end_char": 24827, "estimated_token_count": 44, "token_estimator": "heuristic-v1", "text": "### Start the Parachain Node\n\nLaunch the parachain:\n\n```bash\npolkadot-omni-node --chain ./chain_spec.json --dev\n```\n\nVerify the node starts successfully and begins producing blocks."} -{"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 23, "depth": 2, "title": "Interact with Your Pallet", "anchor": "interact-with-your-pallet", "start_char": 24827, "end_char": 25599, "estimated_token_count": 234, "token_estimator": "heuristic-v1", "text": "## Interact with Your Pallet\n\nUse the Polkadot.js Apps interface to test your pallet:\n\n1. Navigate to [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/extrinsics){target=\\_blank}.\n\n2. Ensure you're connected to your local node at `ws://127.0.0.1:9944`.\n\n3. Go to **Developer** > **Extrinsics**.\n\n4. Locate **customPallet** in the pallet dropdown.\n\n5. You should see the available extrinsics:\n\n - **`increment(amount)`**: Increase the counter by a specified amount.\n - **`decrement(amount)`**: Decrease the counter by a specified amount.\n - **`setCounterValue(newValue)`**: Set counter to a specific value (requires sudo/root).\n\n![](/images/parachains/customize-runtime/pallet-development/create-a-pallet/create-a-pallet-01.webp)"} -{"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 24, "depth": 2, "title": "Key Takeaways", "anchor": "key-takeaways", "start_char": 25599, "end_char": 26322, "estimated_token_count": 129, "token_estimator": "heuristic-v1", "text": "## Key Takeaways\n\nYou've successfully created and integrated a custom pallet into a Polkadot SDK-based runtime. You have now successfully:\n\n- Defined runtime-specific types and constants via the `Config` trait.\n- Implemented on-chain state using `StorageValue` and `StorageMap`.\n- Created signals to communicate state changes to external systems.\n- Established clear error handling with descriptive error types.\n- Configured initial blockchain state for both production and testing.\n- Built callable functions with proper validation and access control.\n- Added the pallet to a runtime and tested it locally.\n\nThese components form the foundation for developing sophisticated blockchain logic in Polkadot SDK-based chains."} -{"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 25, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 26322, "end_char": 26671, "estimated_token_count": 86, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Guide __Mock Your Runtime__\n\n ---\n\n Learn to create a mock runtime environment for testing your pallet in isolation before integration.\n\n [:octicons-arrow-right-24: Continue](/parachains/customize-runtime/pallet-development/mock-runtime/)\n\n
"} +{"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 20, "depth": 2, "title": "Run Your Chain Locally", "anchor": "run-your-chain-locally", "start_char": 24047, "end_char": 24522, "estimated_token_count": 128, "token_estimator": "heuristic-v1", "text": "## Run Your Chain Locally\n\nLaunch your parachain locally to test the new pallet functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\\_blank}. For instructions on setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\\_blank}, refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\\_blank} guide."} +{"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 21, "depth": 3, "title": "Generate a Chain Specification", "anchor": "generate-a-chain-specification", "start_char": 24522, "end_char": 24931, "estimated_token_count": 92, "token_estimator": "heuristic-v1", "text": "### Generate a Chain Specification\n\nCreate a chain specification file with the updated runtime:\n\n```bash\nchain-spec-builder create -t development \\\n--relay-chain paseo \\\n--para-id 1000 \\\n--runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \\\nnamed-preset development\n```\n\nThis command generates a `chain_spec.json` that includes your custom pallet."} +{"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 22, "depth": 3, "title": "Start the Parachain Node", "anchor": "start-the-parachain-node", "start_char": 24931, "end_char": 25114, "estimated_token_count": 44, "token_estimator": "heuristic-v1", "text": "### Start the Parachain Node\n\nLaunch the parachain:\n\n```bash\npolkadot-omni-node --chain ./chain_spec.json --dev\n```\n\nVerify the node starts successfully and begins producing blocks."} +{"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 23, "depth": 2, "title": "Interact with Your Pallet", "anchor": "interact-with-your-pallet", "start_char": 25114, "end_char": 25886, "estimated_token_count": 234, "token_estimator": "heuristic-v1", "text": "## Interact with Your Pallet\n\nUse the Polkadot.js Apps interface to test your pallet:\n\n1. Navigate to [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/extrinsics){target=\\_blank}.\n\n2. Ensure you're connected to your local node at `ws://127.0.0.1:9944`.\n\n3. Go to **Developer** > **Extrinsics**.\n\n4. Locate **customPallet** in the pallet dropdown.\n\n5. You should see the available extrinsics:\n\n - **`increment(amount)`**: Increase the counter by a specified amount.\n - **`decrement(amount)`**: Decrease the counter by a specified amount.\n - **`setCounterValue(newValue)`**: Set counter to a specific value (requires sudo/root).\n\n![](/images/parachains/customize-runtime/pallet-development/create-a-pallet/create-a-pallet-01.webp)"} +{"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 24, "depth": 2, "title": "Key Takeaways", "anchor": "key-takeaways", "start_char": 25886, "end_char": 26609, "estimated_token_count": 129, "token_estimator": "heuristic-v1", "text": "## Key Takeaways\n\nYou've successfully created and integrated a custom pallet into a Polkadot SDK-based runtime. You have now successfully:\n\n- Defined runtime-specific types and constants via the `Config` trait.\n- Implemented on-chain state using `StorageValue` and `StorageMap`.\n- Created signals to communicate state changes to external systems.\n- Established clear error handling with descriptive error types.\n- Configured initial blockchain state for both production and testing.\n- Built callable functions with proper validation and access control.\n- Added the pallet to a runtime and tested it locally.\n\nThese components form the foundation for developing sophisticated blockchain logic in Polkadot SDK-based chains."} +{"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 25, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 26609, "end_char": 26958, "estimated_token_count": 86, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Guide __Mock Your Runtime__\n\n ---\n\n Learn to create a mock runtime environment for testing your pallet in isolation before integration.\n\n [:octicons-arrow-right-24: Continue](/parachains/customize-runtime/pallet-development/mock-runtime/)\n\n
"} {"page_id": "parachains-customize-runtime-pallet-development-mock-runtime", "page_title": "Mock Your Runtime", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 21, "end_char": 806, "estimated_token_count": 158, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nTesting is a critical part of pallet development. Before integrating your pallet into a full runtime, you need a way to test its functionality in isolation. A mock runtime provides a minimal, simulated blockchain environment where you can verify your pallet's logic without the overhead of running a full node.\n\nIn this guide, you'll learn how to create a mock runtime for the custom counter pallet built in the [Make a Custom Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet/){target=\\_blank} guide. This mock runtime will enable you to write comprehensive unit tests that verify:\n\n- Dispatchable function behavior.\n- Storage state changes.\n- Event emission.\n- Error handling.\n- Access control and origin validation.\n- Genesis configuration."} {"page_id": "parachains-customize-runtime-pallet-development-mock-runtime", "page_title": "Mock Your Runtime", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 806, "end_char": 1203, "estimated_token_count": 108, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore you begin, ensure you have:\n\n- Completed the [Make a Custom Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet/){target=\\_blank} guide.\n- The custom counter pallet from the Make a Custom Pallet guide. Available in `pallets/pallet-custom`.\n- Basic understanding of [Rust testing](https://doc.rust-lang.org/book/ch11-00-testing.html){target=\\_blank}."} {"page_id": "parachains-customize-runtime-pallet-development-mock-runtime", "page_title": "Mock Your Runtime", "index": 2, "depth": 2, "title": "Understand Mock Runtimes", "anchor": "understand-mock-runtimes", "start_char": 1203, "end_char": 1737, "estimated_token_count": 90, "token_estimator": "heuristic-v1", "text": "## Understand Mock Runtimes\n\nA mock runtime is a minimal implementation of the runtime environment that:\n\n- Simulates blockchain state to provide storage and state management.\n- Satisfies your pallet's `Config` trait requirements.\n- Allows isolated testing without external dependencies.\n- Supports genesis configuration to set initial blockchain state for tests.\n- Provides instant feedback on code changes for a faster development cycle.\n\nMock runtimes are used exclusively for testing and are never deployed to a live blockchain."} @@ -1214,21 +1255,21 @@ {"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 4, "depth": 3, "title": "Create the Storage Contract", "anchor": "create-the-storage-contract", "start_char": 3094, "end_char": 3633, "estimated_token_count": 112, "token_estimator": "heuristic-v1", "text": "### Create the Storage Contract\n\nIn the `contracts` directory, create a new file called `Storage.sol` and add the following code:\n\n```solidity title=\"Storage.sol\"\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ncontract Storage {\n uint256 private storedNumber;\n\n event NumberStored(uint256 newNumber);\n\n function setNumber(uint256 _number) public {\n storedNumber = _number;\n emit NumberStored(_number);\n }\n}\n```\n\nThis simple contract stores a single number and provides functions to read and update it."} {"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 5, "depth": 3, "title": "Configure Hardhat for Polkadot Hub", "anchor": "configure-hardhat-for-polkadot-hub", "start_char": 3633, "end_char": 5430, "estimated_token_count": 415, "token_estimator": "heuristic-v1", "text": "### Configure Hardhat for Polkadot Hub\n\nUpdate your `hardhat.config.ts` file to include the Polkadot Hub TestNet configuration:\n\n```typescript title=\"hardhat.config.ts\" hl_lines=\"39-44\"\nimport type { HardhatUserConfig } from \"hardhat/config\";\n\nimport hardhatToolboxViemPlugin from \"@nomicfoundation/hardhat-toolbox-viem\";\nimport { configVariable } from \"hardhat/config\";\n\nconst config: HardhatUserConfig = {\n plugins: [hardhatToolboxViemPlugin],\n solidity: {\n profiles: {\n default: {\n version: \"0.8.28\",\n },\n production: {\n version: \"0.8.28\",\n settings: {\n optimizer: {\n enabled: true,\n runs: 200,\n },\n },\n },\n },\n },\n networks: {\n hardhatMainnet: {\n type: \"edr-simulated\",\n chainType: \"l1\",\n },\n hardhatOp: {\n type: \"edr-simulated\",\n chainType: \"op\",\n },\n sepolia: {\n type: \"http\",\n chainType: \"l1\",\n url: configVariable(\"SEPOLIA_RPC_URL\"),\n accounts: [configVariable(\"SEPOLIA_PRIVATE_KEY\")],\n },\n polkadotTestNet: {\n type: \"http\",\n chainType: \"l1\",\n url: 'http://127.0.0.1:8545',\n accounts: [process.env.PRIVATE_KEY || ''],\n },\n },\n};\n\nexport default config;\n```\n\nCreate a `.env` file in the root of your Hardhat project:\n\n```text title=\".env\"\nPRIVATE_KEY=INSERT_PRIVATE_KEY_HERE\n```\n\nReplace `INSERT_PRIVATE_KEY_HERE` with your actual private key. You can get this by exporting the private key from your wallet (e.g., MetaMask).\n\n!!! warning\n Never commit your private key to version control. Use environment variables or a `.env` file (and add it to `.gitignore`) to manage sensitive information. Keep your private key safe, and never share it with anyone. If it is compromised, your funds can be stolen."} {"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 6, "depth": 3, "title": "Compile the Contract", "anchor": "compile-the-contract", "start_char": 5430, "end_char": 5579, "estimated_token_count": 29, "token_estimator": "heuristic-v1", "text": "### Compile the Contract\n\nCompile your Storage contract:\n\n```bash\nnpx hardhat compile\n```\n\nYou should see output indicating successful compilation."} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 7, "depth": 3, "title": "Deploy the Contract", "anchor": "deploy-the-contract", "start_char": 5579, "end_char": 7212, "estimated_token_count": 416, "token_estimator": "heuristic-v1", "text": "### Deploy the Contract\n\nCreate a deployment script in the `ignition/modules` directory called `Storage.ts`:\n\n```typescript title=\"Storage.ts\"\nimport { buildModule } from \"@nomicfoundation/hardhat-ignition/modules\";\n\nexport default buildModule(\"StorageModule\", (m) => {\n const storage = m.contract(\"Storage\");\n\n return { storage };\n});\n```\n\nDeploy the contract to Polkadot Hub TestNet:\n\n```bash\nnpx hardhat ignition deploy ./ignition/modules/Storage.ts --network polkadotHub\n```\n\nYou should see output similar to:\n\n
\n npx hardhat ignition deploy ./ignition/modules/Storage.ts --network polkadotTestNet\n WARNING: You are using Node.js 23.11.0 which is not supported by Hardhat.\n Please upgrade to 22.10.0 or a later LTS version (even major version number)\n ✔ Confirm deploy to network polkadotTestNet (420420420)? … yes\n Hardhat Ignition 🚀\n Deploying [ StorageModule ]\n Batch #1\n Executed StorageModule#Storage\n [ StorageModule ] successfully deployed 🚀\n Deployed Addresses\n StorageModule#Storage - 0xc01Ee7f10EA4aF4673cFff62710E1D7792aBa8f3\n
\n\n!!! note\n Save the deployed contract address - you'll need it when building your dApp. In the following sections, we'll reference a pre-deployed contract at `0xc01Ee7f10EA4aF4673cFff62710E1D7792aBa8f3`, but you can use your own deployed contract address instead."} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 8, "depth": 3, "title": "Export the Contract ABI", "anchor": "export-the-contract-abi", "start_char": 7212, "end_char": 7599, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "### Export the Contract ABI\n\nAfter deployment, you'll need the contract's Application Binary Interface (ABI) for your dApp. You can find it in the `artifacts/contracts/Storage.sol/Storage.json` file generated by Hardhat. You'll use this in the next section when setting up your dApp.\n\nNow that you have your contract deployed, you're ready to build the dApp that will interact with it!"} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 9, "depth": 2, "title": "Set Up the dApp Project", "anchor": "set-up-the-dapp-project", "start_char": 7599, "end_char": 7796, "estimated_token_count": 59, "token_estimator": "heuristic-v1", "text": "## Set Up the dApp Project\n\nNavigate to the root of the project, and create a new Next.js project called `dapp`:\n\n```bash\nnpx create-next-app dapp --ts --eslint --tailwind --app --yes\ncd dapp\n```"} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 10, "depth": 2, "title": "Install Dependencies", "anchor": "install-dependencies", "start_char": 7796, "end_char": 7955, "estimated_token_count": 50, "token_estimator": "heuristic-v1", "text": "## Install Dependencies\n\nInstall viem and related packages:\n\n```bash\nnpm install viem@2.38.5\nnpm install --save-dev typescript@5.9.3 @types/node@22.19.24\n```"} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 11, "depth": 2, "title": "Connect to Polkadot Hub", "anchor": "connect-to-polkadot-hub", "start_char": 7955, "end_char": 10052, "estimated_token_count": 509, "token_estimator": "heuristic-v1", "text": "## Connect to Polkadot Hub\n\nTo interact with Polkadot Hub, you need to set up a [Public Client](https://viem.sh/docs/clients/public#public-client){target=\\_blank} that connects to the blockchain. In this example, you will interact with the Polkadot Hub TestNet, to experiment safely. Start by creating a new file called `utils/viem.ts` and add the following code:\n\n```typescript title=\"viem.ts\"\nimport { createPublicClient, http, createWalletClient, custom } from 'viem'\nimport 'viem/window';\n\nconst transport = http('http://127.0.0.1:8545') // TODO: change to the paseo asset hub RPC URL when it's available\n\n// Configure the Polkadot Testnet Hub chain\nexport const polkadotTestnet = {\n id: 420420420,\n name: 'Polkadot Testnet',\n network: 'polkadot-testnet',\n nativeCurrency: {\n decimals: 18,\n name: 'PAS',\n symbol: 'PAS',\n },\n rpcUrls: {\n default: {\n http: ['http://127.0.0.1:8545'], // TODO: change to the paseo asset hub RPC URL\n },\n },\n} as const\n\n// Create a public client for reading data\nexport const publicClient = createPublicClient({\n chain: polkadotTestnet,\n transport\n})\n\n// Create a wallet client for signing transactions\nexport const getWalletClient = async () => {\n if (typeof window !== 'undefined' && window.ethereum) {\n const [account] = await window.ethereum.request({ method: 'eth_requestAccounts' });\n return createWalletClient({\n chain: polkadotTestnet,\n transport: custom(window.ethereum),\n account,\n });\n }\n throw new Error('No Ethereum browser provider detected');\n};\n```\n\nThis file initializes a viem client, providing helper functions for obtaining a Public Client and a [Wallet Client](https://viem.sh/docs/clients/wallet#wallet-client){target=\\_blank}. The Public Client enables reading blockchain data, while the Wallet Client allows users to sign and send transactions. Also, note that by importing `viem/window` the global `window.ethereum` will be typed as an `EIP1193Provider`, check the [`window` Polyfill](https://viem.sh/docs/typescript#window-polyfill){target=\\_blank} reference for more information."} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 12, "depth": 2, "title": "Set Up the Smart Contract Interface", "anchor": "set-up-the-smart-contract-interface", "start_char": 10052, "end_char": 11943, "estimated_token_count": 415, "token_estimator": "heuristic-v1", "text": "## Set Up the Smart Contract Interface\n\nFor this dApp, you'll use a simple [Storage contract](/tutorials/smart-contracts/launch-your-first-project/create-contracts){target=\\_blank} that's already deployed in the Polkadot Hub TestNet: `0xc01Ee7f10EA4aF4673cFff62710E1D7792aBa8f3`. To interact with it, you need to define the contract interface.\n\nCreate a folder called `abis` at the root of your project, then create a file named `Storage.json` and paste the corresponding ABI of the Storage contract. You can copy and paste the following:\n\n```bash\ncp ./storage-contract/artifacts/contracts/Storage.sol/Storage.json ./dapp/abis/Storage.json\n```\n\nNext, create a file called `utils/contract.ts`:\n\n```typescript title=\"contract.ts\"\nimport { getContract } from 'viem';\nimport { publicClient, getWalletClient } from './viem';\nimport StorageABI from '../abis/Storage.json';\n\nexport const CONTRACT_ADDRESS = '0xc01Ee7f10EA4aF4673cFff62710E1D7792aBa8f3'; // TODO: change when the paseo asset hub RPC URL is available, and the contract is redeployed\nexport const CONTRACT_ABI = StorageABI.abi;\n\n// Create a function to get a contract instance for reading\nexport const getContractInstance = () => {\n return getContract({\n address: CONTRACT_ADDRESS,\n abi: CONTRACT_ABI,\n client: publicClient,\n });\n};\n\n// Create a function to get a contract instance with a signer for writing\nexport const getSignedContract = async () => {\n const walletClient = await getWalletClient();\n return getContract({\n address: CONTRACT_ADDRESS,\n abi: CONTRACT_ABI,\n client: walletClient,\n });\n};\n```\n\nThis file defines the contract address, ABI, and functions to create a viem [contract instance](https://viem.sh/docs/contract/getContract#contract-instances){target=\\_blank} for reading and writing operations. viem's contract utilities enable more efficient, type-safe interaction with smart contracts."} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 13, "depth": 2, "title": "Create the Wallet Connection Component", "anchor": "create-the-wallet-connection-component", "start_char": 11943, "end_char": 17968, "estimated_token_count": 1343, "token_estimator": "heuristic-v1", "text": "## Create the Wallet Connection Component\n\nNow, let's create a component to handle wallet connections. Create a new file called `components/WalletConnect.tsx`:\n\n```typescript title=\"WalletConnect.tsx\"\n\"use client\";\n\nimport React, { useState, useEffect } from \"react\";\nimport { polkadotTestnet } from \"../utils/viem\";\n\ninterface WalletConnectProps {\n onConnect: (account: string) => void;\n}\n\nconst WalletConnect: React.FC = ({ onConnect }) => {\n const [account, setAccount] = useState(null);\n const [chainId, setChainId] = useState(null);\n const [error, setError] = useState(null);\n\n useEffect(() => {\n // Check if user already has an authorized wallet connection\n const checkConnection = async () => {\n if (typeof window !== 'undefined' && window.ethereum) {\n try {\n // eth_accounts doesn't trigger the wallet popup\n const accounts = await window.ethereum.request({\n method: 'eth_accounts',\n }) as string[];\n \n if (accounts.length > 0) {\n setAccount(accounts[0]);\n const chainIdHex = await window.ethereum.request({\n method: 'eth_chainId',\n }) as string;\n setChainId(parseInt(chainIdHex, 16));\n onConnect(accounts[0]);\n }\n } catch (err) {\n console.error('Error checking connection:', err);\n setError('Failed to check wallet connection');\n }\n }\n };\n\n checkConnection();\n\n if (typeof window !== 'undefined' && window.ethereum) {\n // Setup wallet event listeners\n window.ethereum.on('accountsChanged', (accounts: string[]) => {\n setAccount(accounts[0] || null);\n if (accounts[0]) onConnect(accounts[0]);\n });\n\n window.ethereum.on('chainChanged', (chainIdHex: string) => {\n setChainId(parseInt(chainIdHex, 16));\n });\n }\n\n return () => {\n // Cleanup event listeners\n if (typeof window !== 'undefined' && window.ethereum) {\n window.ethereum.removeListener('accountsChanged', () => {});\n window.ethereum.removeListener('chainChanged', () => {});\n }\n };\n }, [onConnect]);\n\n const connectWallet = async () => {\n if (typeof window === 'undefined' || !window.ethereum) {\n setError(\n 'MetaMask not detected! Please install MetaMask to use this dApp.'\n );\n return;\n }\n\n try {\n // eth_requestAccounts triggers the wallet popup\n const accounts = await window.ethereum.request({\n method: 'eth_requestAccounts',\n }) as string[];\n \n setAccount(accounts[0]);\n\n const chainIdHex = await window.ethereum.request({\n method: 'eth_chainId',\n }) as string;\n \n const currentChainId = parseInt(chainIdHex, 16);\n setChainId(currentChainId);\n\n // Prompt user to switch networks if needed\n if (currentChainId !== polkadotTestnet.id) {\n await switchNetwork();\n }\n\n onConnect(accounts[0]);\n } catch (err) {\n console.error('Error connecting to wallet:', err);\n setError('Failed to connect wallet');\n }\n };\n\n const switchNetwork = async () => {\n console.log('Switch network')\n try {\n await window.ethereum.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: `0x${polkadotTestnet.id.toString(16)}` }],\n });\n } catch (switchError: any) {\n // Error 4902 means the chain hasn't been added to MetaMask\n if (switchError.code === 4902) {\n try {\n await window.ethereum.request({\n method: 'wallet_addEthereumChain',\n params: [\n {\n chainId: `0x${polkadotTestnet.id.toString(16)}`,\n chainName: polkadotTestnet.name,\n rpcUrls: [polkadotTestnet.rpcUrls.default.http[0]],\n nativeCurrency: {\n name: polkadotTestnet.nativeCurrency.name,\n symbol: polkadotTestnet.nativeCurrency.symbol,\n decimals: polkadotTestnet.nativeCurrency.decimals,\n },\n },\n ],\n });\n } catch (addError) {\n setError('Failed to add network to wallet');\n }\n } else {\n setError('Failed to switch network');\n }\n }\n };\n\n // UI-only disconnection - MetaMask doesn't support programmatic disconnection\n const disconnectWallet = () => {\n setAccount(null);\n };\n\n return (\n
\n {error &&

{error}

}\n\n {!account ? (\n \n Connect Wallet\n \n ) : (\n
\n \n {`${account.substring(0, 6)}...${account.substring(38)}`}\n \n \n Disconnect\n \n {chainId !== polkadotTestnet.id && (\n \n Switch to Polkadot Testnet\n \n )}\n
\n )}\n
\n );\n};\n\nexport default WalletConnect;\n```\n\nThis component handles connecting to the wallet, switching networks if necessary, and keeping track of the connected account. It provides a button for users to connect their wallet and displays the connected account address once connected."} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 14, "depth": 2, "title": "Create the Read Contract Component", "anchor": "create-the-read-contract-component", "start_char": 17968, "end_char": 20502, "estimated_token_count": 617, "token_estimator": "heuristic-v1", "text": "## Create the Read Contract Component\n\nNow, let's create a component to read data from the contract. Create a file called `components/ReadContract.tsx`:\n\n```typescript title=\"ReadContract.tsx\"\n'use client';\n\nimport React, { useState, useEffect } from 'react';\nimport { publicClient } from '../utils/viem';\nimport { CONTRACT_ADDRESS, CONTRACT_ABI } from '../utils/contract';\n\nconst ReadContract: React.FC = () => {\n const [storedNumber, setStoredNumber] = useState(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState(null);\n\n useEffect(() => {\n // Function to read data from the blockchain\n const fetchData = async () => {\n try {\n setLoading(true);\n // Call the smart contract's storedNumber function\n const number = await publicClient.readContract({\n address: CONTRACT_ADDRESS,\n abi: CONTRACT_ABI,\n functionName: 'storedNumber',\n args: [],\n }) as bigint;\n\n setStoredNumber(number.toString());\n setError(null);\n } catch (err) {\n console.error('Error fetching stored number:', err);\n setError('Failed to fetch data from the contract');\n } finally {\n setLoading(false);\n }\n };\n\n fetchData();\n\n // Poll for updates every 10 seconds to keep UI in sync with blockchain\n const interval = setInterval(fetchData, 10000);\n\n // Clean up interval on component unmount\n return () => clearInterval(interval);\n }, []);\n\n return (\n
\n

Contract Data

\n {loading ? (\n
\n
\n
\n ) : error ? (\n

{error}

\n ) : (\n
\n

\n Stored Number: {storedNumber}\n

\n
\n )}\n
\n );\n};\n\nexport default ReadContract;\n```\n\nThis component reads the `storedNumber` value from the contract and displays it to the user. It also sets up a polling interval to refresh the data periodically, ensuring that the UI stays in sync with the blockchain state."} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 15, "depth": 2, "title": "Create the Write Contract Component", "anchor": "create-the-write-contract-component", "start_char": 20502, "end_char": 28611, "estimated_token_count": 1825, "token_estimator": "heuristic-v1", "text": "## Create the Write Contract Component\n\nFinally, let's create a component that allows users to update the stored number. Create a file called `components/WriteContract.tsx`:\n\n```typescript title=\"WriteContract.tsx\"\n\"use client\";\n\nimport React, { useState, useEffect } from \"react\";\nimport { publicClient, getWalletClient } from '../utils/viem';\nimport { CONTRACT_ADDRESS, CONTRACT_ABI } from '../utils/contract';\n\ninterface WriteContractProps {\n account: string | null;\n}\n\nconst WriteContract: React.FC = ({ account }) => {\n const [newNumber, setNewNumber] = useState(\"\");\n const [status, setStatus] = useState<{\n type: string | null;\n message: string;\n }>({\n type: null,\n message: \"\",\n });\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isCorrectNetwork, setIsCorrectNetwork] = useState(true);\n\n // Check if the account is on the correct network\n useEffect(() => {\n const checkNetwork = async () => {\n if (!account) return;\n\n try {\n // Get the chainId from the public client\n const chainId = await publicClient.getChainId();\n\n // Get the user's current chainId from their wallet\n const walletClient = await getWalletClient();\n if (!walletClient) return;\n\n const walletChainId = await walletClient.getChainId();\n\n // Check if they match\n setIsCorrectNetwork(chainId === walletChainId);\n } catch (err) {\n console.error(\"Error checking network:\", err);\n setIsCorrectNetwork(false);\n }\n };\n\n checkNetwork();\n }, [account]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n // Validation checks\n if (!account) {\n setStatus({ type: \"error\", message: \"Please connect your wallet first\" });\n return;\n }\n\n if (!isCorrectNetwork) {\n setStatus({\n type: \"error\",\n message: \"Please switch to the correct network in your wallet\",\n });\n return;\n }\n\n if (!newNumber || isNaN(Number(newNumber))) {\n setStatus({ type: \"error\", message: \"Please enter a valid number\" });\n return;\n }\n\n try {\n setIsSubmitting(true);\n setStatus({ type: \"info\", message: \"Initiating transaction...\" });\n\n // Get wallet client for transaction signing\n const walletClient = await getWalletClient();\n\n if (!walletClient) {\n setStatus({ type: \"error\", message: \"Wallet client not available\" });\n return;\n }\n\n // Check if account matches\n if (\n walletClient.account?.address.toLowerCase() !== account.toLowerCase()\n ) {\n setStatus({\n type: \"error\",\n message:\n \"Connected wallet account doesn't match the selected account\",\n });\n return;\n }\n\n // Prepare transaction and wait for user confirmation in wallet\n setStatus({\n type: \"info\",\n message: \"Please confirm the transaction in your wallet...\",\n });\n\n // Simulate the contract call first\n console.log('newNumber', newNumber);\n const { request } = await publicClient.simulateContract({\n address: CONTRACT_ADDRESS,\n abi: CONTRACT_ABI,\n functionName: \"setNumber\",\n args: [BigInt(newNumber)],\n account: walletClient.account,\n });\n\n // Send the transaction with wallet client\n const hash = await walletClient.writeContract(request);\n\n // Wait for transaction to be mined\n setStatus({\n type: \"info\",\n message: \"Transaction submitted. Waiting for confirmation...\",\n });\n\n const receipt = await publicClient.waitForTransactionReceipt({\n hash,\n });\n\n setStatus({\n type: \"success\",\n message: `Transaction confirmed! Transaction hash: ${receipt.transactionHash}`,\n });\n\n setNewNumber(\"\");\n } catch (err: any) {\n console.error(\"Error updating number:\", err);\n\n // Handle specific errors\n if (err.code === 4001) {\n // User rejected transaction\n setStatus({ type: \"error\", message: \"Transaction rejected by user.\" });\n } else if (err.message?.includes(\"Account not found\")) {\n // Account not found on the network\n setStatus({\n type: \"error\",\n message:\n \"Account not found on current network. Please check your wallet is connected to the correct network.\",\n });\n } else if (err.message?.includes(\"JSON is not a valid request object\")) {\n // JSON error - specific to your current issue\n setStatus({\n type: \"error\",\n message:\n \"Invalid request format. Please try again or contact support.\",\n });\n } else {\n // Other errors\n setStatus({\n type: \"error\",\n message: `Error: ${err.message || \"Failed to send transaction\"}`,\n });\n }\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n
\n

Update Stored Number

\n\n {!isCorrectNetwork && account && (\n
\n ⚠️ You are not connected to the correct network. Please switch\n networks in your wallet.\n
\n )}\n\n {status.message && (\n \n {status.message}\n
\n )}\n\n
\n setNewNumber(e.target.value)}\n disabled={isSubmitting || !account}\n className=\"w-full p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-pink-400\"\n />\n \n {isSubmitting ? \"Updating...\" : \"Update\"}\n \n \n\n {!account && (\n

\n Connect your wallet to update the stored number.\n

\n )}\n
\n );\n};\n\nexport default WriteContract;\n```\n\nThis component allows users to input a new number and send a transaction to update the value stored in the contract. It provides appropriate feedback during each step of the transaction process and handles error scenarios.\n\nUpdate the `app/page.tsx` file to integrate all components:\n\n```typescript title=\"page.tsx\"\n\"use client\";\n\nimport { useState } from \"react\";\nimport WalletConnect from \"./components/WalletConnect\";\nimport ReadContract from \"./components/ReadContract\";\nimport WriteContract from \"./components/WriteContract\";\n\nexport default function Home() {\n const [account, setAccount] = useState(null);\n\n const handleConnect = (connectedAccount: string) => {\n setAccount(connectedAccount);\n };\n\n return (\n
\n

\n Polkadot Hub - Zero To Hero DApp\n

\n \n \n \n
\n );\n}\n```\n\nRun the dApp:\n\n```bash\nnpm run dev\n```\n\nNavigate to `http://localhost:3000` in your browser, and you should see your dApp with the wallet connection button, the stored number displayed, and the form to update the number. You should see something like this:"} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 16, "depth": 2, "title": "How It Works", "anchor": "how-it-works", "start_char": 28611, "end_char": 28704, "estimated_token_count": 18, "token_estimator": "heuristic-v1", "text": "## How It Works\n\nThis dApp uses components to interact with the blockchain in several ways."} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 17, "depth": 3, "title": "Wallet Connection", "anchor": "wallet-connection", "start_char": 28704, "end_char": 29010, "estimated_token_count": 60, "token_estimator": "heuristic-v1", "text": "### Wallet Connection \n\nThe `WalletConnect` component uses the browser's Ethereum provider (MetaMask) to connect to the user's wallet and handles network switching to ensure the user is connected to the Polkadot Hub TestNet. Once connected, it provides the user's account address to the parent component."} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 18, "depth": 3, "title": "Data Reads", "anchor": "data-reads", "start_char": 29010, "end_char": 29311, "estimated_token_count": 57, "token_estimator": "heuristic-v1", "text": "### Data Reads\n\nThe `ReadContract` component uses viem's `readContract` function to call the `storedNumber` view function and periodically poll for updates to keep the UI in sync with the blockchain state. The component also displays a loading indicator while fetching data and handles error states."} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 19, "depth": 3, "title": "Data Writes", "anchor": "data-writes", "start_char": 29311, "end_char": 29713, "estimated_token_count": 71, "token_estimator": "heuristic-v1", "text": "### Data Writes\n\nThe `WriteContract` component uses viem's `writeContract` function to send a transaction to the `setNumber` function and ensures the wallet is connected before allowing a transaction. The component shows detailed feedback during transaction submission and confirmation. After a successful transaction, the value displayed in the `ReadContract` component will update on the next poll."} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 20, "depth": 2, "title": "Conclusion", "anchor": "conclusion", "start_char": 29713, "end_char": 30610, "estimated_token_count": 178, "token_estimator": "heuristic-v1", "text": "## Conclusion\n\nCongratulations! You've successfully built a fully functional dApp that interacts with a smart contract on Polkadot Hub using viem and Next.js. Your application can now:\n\n- Create a smart contract with Hardhat and deploy it to Polkadot Hub TestNet.\n- Connect to a user's wallet and handle network switching.\n- Read data from a smart contract and keep it updated.\n- Write data to the blockchain through transactions.\n\nThese fundamental skills provide the foundation for building more complex dApps on Polkadot Hub. With this knowledge, you can extend your application to interact with more sophisticated smart contracts and create advanced user interfaces.\n\nTo get started right away with a working example, you can clone the repository and navigate to the implementation:\n\n```bash\ngit clone https://github.com/polkadot-developers/revm-hardhat-examples.git\ncd zero-to-hero-dapp\n```"} -{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 21, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 30610, "end_char": 31203, "estimated_token_count": 147, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Guide __Port Ethereum Projects to Polkadot Hub__\n\n ---\n\n Learn how to port an Ethereum project to Polkadot Hub using Hardhat and Viem.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/eth-dapps/)\n\n- Guide __Dive Deeper into Polkadot Precompiles__\n\n ---\n\n Learn how to use the Polkadot precompiles to interact with the blockchain.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/polkadot-precompiles/)\n
"} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 7, "depth": 3, "title": "Deploy the Contract", "anchor": "deploy-the-contract", "start_char": 5579, "end_char": 7216, "estimated_token_count": 416, "token_estimator": "heuristic-v1", "text": "### Deploy the Contract\n\nCreate a deployment script in the `ignition/modules` directory called `Storage.ts`:\n\n```typescript title=\"Storage.ts\"\nimport { buildModule } from \"@nomicfoundation/hardhat-ignition/modules\";\n\nexport default buildModule(\"StorageModule\", (m) => {\n const storage = m.contract(\"Storage\");\n\n return { storage };\n});\n```\n\nDeploy the contract to Polkadot Hub TestNet:\n\n```bash\nnpx hardhat ignition deploy ./ignition/modules/Storage.ts --network polkadotTestNet\n```\n\nYou should see output similar to:\n\n
\n npx hardhat ignition deploy ./ignition/modules/Storage.ts --network polkadotTestNet\n WARNING: You are using Node.js 23.11.0 which is not supported by Hardhat.\n Please upgrade to 22.10.0 or a later LTS version (even major version number)\n ✔ Confirm deploy to network polkadotTestNet (420420420)? … yes\n Hardhat Ignition 🚀\n Deploying [ StorageModule ]\n Batch #1\n Executed StorageModule#Storage\n [ StorageModule ] successfully deployed 🚀\n Deployed Addresses\n StorageModule#Storage - 0xc01Ee7f10EA4aF4673cFff62710E1D7792aBa8f3\n
\n\n!!! note\n Save the deployed contract address - you'll need it when building your dApp. In the following sections, we'll reference a pre-deployed contract at `0xc01Ee7f10EA4aF4673cFff62710E1D7792aBa8f3`, but you can use your own deployed contract address instead."} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 8, "depth": 3, "title": "Export the Contract ABI", "anchor": "export-the-contract-abi", "start_char": 7216, "end_char": 7603, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "### Export the Contract ABI\n\nAfter deployment, you'll need the contract's Application Binary Interface (ABI) for your dApp. You can find it in the `artifacts/contracts/Storage.sol/Storage.json` file generated by Hardhat. You'll use this in the next section when setting up your dApp.\n\nNow that you have your contract deployed, you're ready to build the dApp that will interact with it!"} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 9, "depth": 2, "title": "Set Up the dApp Project", "anchor": "set-up-the-dapp-project", "start_char": 7603, "end_char": 7800, "estimated_token_count": 59, "token_estimator": "heuristic-v1", "text": "## Set Up the dApp Project\n\nNavigate to the root of the project, and create a new Next.js project called `dapp`:\n\n```bash\nnpx create-next-app dapp --ts --eslint --tailwind --app --yes\ncd dapp\n```"} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 10, "depth": 2, "title": "Install Dependencies", "anchor": "install-dependencies", "start_char": 7800, "end_char": 7959, "estimated_token_count": 50, "token_estimator": "heuristic-v1", "text": "## Install Dependencies\n\nInstall viem and related packages:\n\n```bash\nnpm install viem@2.38.5\nnpm install --save-dev typescript@5.9.3 @types/node@22.19.24\n```"} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 11, "depth": 2, "title": "Connect to Polkadot Hub", "anchor": "connect-to-polkadot-hub", "start_char": 7959, "end_char": 10056, "estimated_token_count": 509, "token_estimator": "heuristic-v1", "text": "## Connect to Polkadot Hub\n\nTo interact with Polkadot Hub, you need to set up a [Public Client](https://viem.sh/docs/clients/public#public-client){target=\\_blank} that connects to the blockchain. In this example, you will interact with the Polkadot Hub TestNet, to experiment safely. Start by creating a new file called `utils/viem.ts` and add the following code:\n\n```typescript title=\"viem.ts\"\nimport { createPublicClient, http, createWalletClient, custom } from 'viem'\nimport 'viem/window';\n\nconst transport = http('http://127.0.0.1:8545') // TODO: change to the paseo asset hub RPC URL when it's available\n\n// Configure the Polkadot Testnet Hub chain\nexport const polkadotTestnet = {\n id: 420420420,\n name: 'Polkadot Testnet',\n network: 'polkadot-testnet',\n nativeCurrency: {\n decimals: 18,\n name: 'PAS',\n symbol: 'PAS',\n },\n rpcUrls: {\n default: {\n http: ['http://127.0.0.1:8545'], // TODO: change to the paseo asset hub RPC URL\n },\n },\n} as const\n\n// Create a public client for reading data\nexport const publicClient = createPublicClient({\n chain: polkadotTestnet,\n transport\n})\n\n// Create a wallet client for signing transactions\nexport const getWalletClient = async () => {\n if (typeof window !== 'undefined' && window.ethereum) {\n const [account] = await window.ethereum.request({ method: 'eth_requestAccounts' });\n return createWalletClient({\n chain: polkadotTestnet,\n transport: custom(window.ethereum),\n account,\n });\n }\n throw new Error('No Ethereum browser provider detected');\n};\n```\n\nThis file initializes a viem client, providing helper functions for obtaining a Public Client and a [Wallet Client](https://viem.sh/docs/clients/wallet#wallet-client){target=\\_blank}. The Public Client enables reading blockchain data, while the Wallet Client allows users to sign and send transactions. Also, note that by importing `viem/window` the global `window.ethereum` will be typed as an `EIP1193Provider`, check the [`window` Polyfill](https://viem.sh/docs/typescript#window-polyfill){target=\\_blank} reference for more information."} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 12, "depth": 2, "title": "Set Up the Smart Contract Interface", "anchor": "set-up-the-smart-contract-interface", "start_char": 10056, "end_char": 11947, "estimated_token_count": 415, "token_estimator": "heuristic-v1", "text": "## Set Up the Smart Contract Interface\n\nFor this dApp, you'll use a simple [Storage contract](/tutorials/smart-contracts/launch-your-first-project/create-contracts){target=\\_blank} that's already deployed in the Polkadot Hub TestNet: `0xc01Ee7f10EA4aF4673cFff62710E1D7792aBa8f3`. To interact with it, you need to define the contract interface.\n\nCreate a folder called `abis` at the root of your project, then create a file named `Storage.json` and paste the corresponding ABI of the Storage contract. You can copy and paste the following:\n\n```bash\ncp ./storage-contract/artifacts/contracts/Storage.sol/Storage.json ./dapp/abis/Storage.json\n```\n\nNext, create a file called `utils/contract.ts`:\n\n```typescript title=\"contract.ts\"\nimport { getContract } from 'viem';\nimport { publicClient, getWalletClient } from './viem';\nimport StorageABI from '../abis/Storage.json';\n\nexport const CONTRACT_ADDRESS = '0xc01Ee7f10EA4aF4673cFff62710E1D7792aBa8f3'; // TODO: change when the paseo asset hub RPC URL is available, and the contract is redeployed\nexport const CONTRACT_ABI = StorageABI.abi;\n\n// Create a function to get a contract instance for reading\nexport const getContractInstance = () => {\n return getContract({\n address: CONTRACT_ADDRESS,\n abi: CONTRACT_ABI,\n client: publicClient,\n });\n};\n\n// Create a function to get a contract instance with a signer for writing\nexport const getSignedContract = async () => {\n const walletClient = await getWalletClient();\n return getContract({\n address: CONTRACT_ADDRESS,\n abi: CONTRACT_ABI,\n client: walletClient,\n });\n};\n```\n\nThis file defines the contract address, ABI, and functions to create a viem [contract instance](https://viem.sh/docs/contract/getContract#contract-instances){target=\\_blank} for reading and writing operations. viem's contract utilities enable more efficient, type-safe interaction with smart contracts."} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 13, "depth": 2, "title": "Create the Wallet Connection Component", "anchor": "create-the-wallet-connection-component", "start_char": 11947, "end_char": 17972, "estimated_token_count": 1343, "token_estimator": "heuristic-v1", "text": "## Create the Wallet Connection Component\n\nNow, let's create a component to handle wallet connections. Create a new file called `components/WalletConnect.tsx`:\n\n```typescript title=\"WalletConnect.tsx\"\n\"use client\";\n\nimport React, { useState, useEffect } from \"react\";\nimport { polkadotTestnet } from \"../utils/viem\";\n\ninterface WalletConnectProps {\n onConnect: (account: string) => void;\n}\n\nconst WalletConnect: React.FC = ({ onConnect }) => {\n const [account, setAccount] = useState(null);\n const [chainId, setChainId] = useState(null);\n const [error, setError] = useState(null);\n\n useEffect(() => {\n // Check if user already has an authorized wallet connection\n const checkConnection = async () => {\n if (typeof window !== 'undefined' && window.ethereum) {\n try {\n // eth_accounts doesn't trigger the wallet popup\n const accounts = await window.ethereum.request({\n method: 'eth_accounts',\n }) as string[];\n \n if (accounts.length > 0) {\n setAccount(accounts[0]);\n const chainIdHex = await window.ethereum.request({\n method: 'eth_chainId',\n }) as string;\n setChainId(parseInt(chainIdHex, 16));\n onConnect(accounts[0]);\n }\n } catch (err) {\n console.error('Error checking connection:', err);\n setError('Failed to check wallet connection');\n }\n }\n };\n\n checkConnection();\n\n if (typeof window !== 'undefined' && window.ethereum) {\n // Setup wallet event listeners\n window.ethereum.on('accountsChanged', (accounts: string[]) => {\n setAccount(accounts[0] || null);\n if (accounts[0]) onConnect(accounts[0]);\n });\n\n window.ethereum.on('chainChanged', (chainIdHex: string) => {\n setChainId(parseInt(chainIdHex, 16));\n });\n }\n\n return () => {\n // Cleanup event listeners\n if (typeof window !== 'undefined' && window.ethereum) {\n window.ethereum.removeListener('accountsChanged', () => {});\n window.ethereum.removeListener('chainChanged', () => {});\n }\n };\n }, [onConnect]);\n\n const connectWallet = async () => {\n if (typeof window === 'undefined' || !window.ethereum) {\n setError(\n 'MetaMask not detected! Please install MetaMask to use this dApp.'\n );\n return;\n }\n\n try {\n // eth_requestAccounts triggers the wallet popup\n const accounts = await window.ethereum.request({\n method: 'eth_requestAccounts',\n }) as string[];\n \n setAccount(accounts[0]);\n\n const chainIdHex = await window.ethereum.request({\n method: 'eth_chainId',\n }) as string;\n \n const currentChainId = parseInt(chainIdHex, 16);\n setChainId(currentChainId);\n\n // Prompt user to switch networks if needed\n if (currentChainId !== polkadotTestnet.id) {\n await switchNetwork();\n }\n\n onConnect(accounts[0]);\n } catch (err) {\n console.error('Error connecting to wallet:', err);\n setError('Failed to connect wallet');\n }\n };\n\n const switchNetwork = async () => {\n console.log('Switch network')\n try {\n await window.ethereum.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: `0x${polkadotTestnet.id.toString(16)}` }],\n });\n } catch (switchError: any) {\n // Error 4902 means the chain hasn't been added to MetaMask\n if (switchError.code === 4902) {\n try {\n await window.ethereum.request({\n method: 'wallet_addEthereumChain',\n params: [\n {\n chainId: `0x${polkadotTestnet.id.toString(16)}`,\n chainName: polkadotTestnet.name,\n rpcUrls: [polkadotTestnet.rpcUrls.default.http[0]],\n nativeCurrency: {\n name: polkadotTestnet.nativeCurrency.name,\n symbol: polkadotTestnet.nativeCurrency.symbol,\n decimals: polkadotTestnet.nativeCurrency.decimals,\n },\n },\n ],\n });\n } catch (addError) {\n setError('Failed to add network to wallet');\n }\n } else {\n setError('Failed to switch network');\n }\n }\n };\n\n // UI-only disconnection - MetaMask doesn't support programmatic disconnection\n const disconnectWallet = () => {\n setAccount(null);\n };\n\n return (\n
\n {error &&

{error}

}\n\n {!account ? (\n \n Connect Wallet\n \n ) : (\n
\n \n {`${account.substring(0, 6)}...${account.substring(38)}`}\n \n \n Disconnect\n \n {chainId !== polkadotTestnet.id && (\n \n Switch to Polkadot Testnet\n \n )}\n
\n )}\n
\n );\n};\n\nexport default WalletConnect;\n```\n\nThis component handles connecting to the wallet, switching networks if necessary, and keeping track of the connected account. It provides a button for users to connect their wallet and displays the connected account address once connected."} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 14, "depth": 2, "title": "Create the Read Contract Component", "anchor": "create-the-read-contract-component", "start_char": 17972, "end_char": 20506, "estimated_token_count": 617, "token_estimator": "heuristic-v1", "text": "## Create the Read Contract Component\n\nNow, let's create a component to read data from the contract. Create a file called `components/ReadContract.tsx`:\n\n```typescript title=\"ReadContract.tsx\"\n'use client';\n\nimport React, { useState, useEffect } from 'react';\nimport { publicClient } from '../utils/viem';\nimport { CONTRACT_ADDRESS, CONTRACT_ABI } from '../utils/contract';\n\nconst ReadContract: React.FC = () => {\n const [storedNumber, setStoredNumber] = useState(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState(null);\n\n useEffect(() => {\n // Function to read data from the blockchain\n const fetchData = async () => {\n try {\n setLoading(true);\n // Call the smart contract's storedNumber function\n const number = await publicClient.readContract({\n address: CONTRACT_ADDRESS,\n abi: CONTRACT_ABI,\n functionName: 'storedNumber',\n args: [],\n }) as bigint;\n\n setStoredNumber(number.toString());\n setError(null);\n } catch (err) {\n console.error('Error fetching stored number:', err);\n setError('Failed to fetch data from the contract');\n } finally {\n setLoading(false);\n }\n };\n\n fetchData();\n\n // Poll for updates every 10 seconds to keep UI in sync with blockchain\n const interval = setInterval(fetchData, 10000);\n\n // Clean up interval on component unmount\n return () => clearInterval(interval);\n }, []);\n\n return (\n
\n

Contract Data

\n {loading ? (\n
\n
\n
\n ) : error ? (\n

{error}

\n ) : (\n
\n

\n Stored Number: {storedNumber}\n

\n
\n )}\n
\n );\n};\n\nexport default ReadContract;\n```\n\nThis component reads the `storedNumber` value from the contract and displays it to the user. It also sets up a polling interval to refresh the data periodically, ensuring that the UI stays in sync with the blockchain state."} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 15, "depth": 2, "title": "Create the Write Contract Component", "anchor": "create-the-write-contract-component", "start_char": 20506, "end_char": 28615, "estimated_token_count": 1825, "token_estimator": "heuristic-v1", "text": "## Create the Write Contract Component\n\nFinally, let's create a component that allows users to update the stored number. Create a file called `components/WriteContract.tsx`:\n\n```typescript title=\"WriteContract.tsx\"\n\"use client\";\n\nimport React, { useState, useEffect } from \"react\";\nimport { publicClient, getWalletClient } from '../utils/viem';\nimport { CONTRACT_ADDRESS, CONTRACT_ABI } from '../utils/contract';\n\ninterface WriteContractProps {\n account: string | null;\n}\n\nconst WriteContract: React.FC = ({ account }) => {\n const [newNumber, setNewNumber] = useState(\"\");\n const [status, setStatus] = useState<{\n type: string | null;\n message: string;\n }>({\n type: null,\n message: \"\",\n });\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [isCorrectNetwork, setIsCorrectNetwork] = useState(true);\n\n // Check if the account is on the correct network\n useEffect(() => {\n const checkNetwork = async () => {\n if (!account) return;\n\n try {\n // Get the chainId from the public client\n const chainId = await publicClient.getChainId();\n\n // Get the user's current chainId from their wallet\n const walletClient = await getWalletClient();\n if (!walletClient) return;\n\n const walletChainId = await walletClient.getChainId();\n\n // Check if they match\n setIsCorrectNetwork(chainId === walletChainId);\n } catch (err) {\n console.error(\"Error checking network:\", err);\n setIsCorrectNetwork(false);\n }\n };\n\n checkNetwork();\n }, [account]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n // Validation checks\n if (!account) {\n setStatus({ type: \"error\", message: \"Please connect your wallet first\" });\n return;\n }\n\n if (!isCorrectNetwork) {\n setStatus({\n type: \"error\",\n message: \"Please switch to the correct network in your wallet\",\n });\n return;\n }\n\n if (!newNumber || isNaN(Number(newNumber))) {\n setStatus({ type: \"error\", message: \"Please enter a valid number\" });\n return;\n }\n\n try {\n setIsSubmitting(true);\n setStatus({ type: \"info\", message: \"Initiating transaction...\" });\n\n // Get wallet client for transaction signing\n const walletClient = await getWalletClient();\n\n if (!walletClient) {\n setStatus({ type: \"error\", message: \"Wallet client not available\" });\n return;\n }\n\n // Check if account matches\n if (\n walletClient.account?.address.toLowerCase() !== account.toLowerCase()\n ) {\n setStatus({\n type: \"error\",\n message:\n \"Connected wallet account doesn't match the selected account\",\n });\n return;\n }\n\n // Prepare transaction and wait for user confirmation in wallet\n setStatus({\n type: \"info\",\n message: \"Please confirm the transaction in your wallet...\",\n });\n\n // Simulate the contract call first\n console.log('newNumber', newNumber);\n const { request } = await publicClient.simulateContract({\n address: CONTRACT_ADDRESS,\n abi: CONTRACT_ABI,\n functionName: \"setNumber\",\n args: [BigInt(newNumber)],\n account: walletClient.account,\n });\n\n // Send the transaction with wallet client\n const hash = await walletClient.writeContract(request);\n\n // Wait for transaction to be mined\n setStatus({\n type: \"info\",\n message: \"Transaction submitted. Waiting for confirmation...\",\n });\n\n const receipt = await publicClient.waitForTransactionReceipt({\n hash,\n });\n\n setStatus({\n type: \"success\",\n message: `Transaction confirmed! Transaction hash: ${receipt.transactionHash}`,\n });\n\n setNewNumber(\"\");\n } catch (err: any) {\n console.error(\"Error updating number:\", err);\n\n // Handle specific errors\n if (err.code === 4001) {\n // User rejected transaction\n setStatus({ type: \"error\", message: \"Transaction rejected by user.\" });\n } else if (err.message?.includes(\"Account not found\")) {\n // Account not found on the network\n setStatus({\n type: \"error\",\n message:\n \"Account not found on current network. Please check your wallet is connected to the correct network.\",\n });\n } else if (err.message?.includes(\"JSON is not a valid request object\")) {\n // JSON error - specific to your current issue\n setStatus({\n type: \"error\",\n message:\n \"Invalid request format. Please try again or contact support.\",\n });\n } else {\n // Other errors\n setStatus({\n type: \"error\",\n message: `Error: ${err.message || \"Failed to send transaction\"}`,\n });\n }\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n
\n

Update Stored Number

\n\n {!isCorrectNetwork && account && (\n
\n ⚠️ You are not connected to the correct network. Please switch\n networks in your wallet.\n
\n )}\n\n {status.message && (\n \n {status.message}\n
\n )}\n\n
\n setNewNumber(e.target.value)}\n disabled={isSubmitting || !account}\n className=\"w-full p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-pink-400\"\n />\n \n {isSubmitting ? \"Updating...\" : \"Update\"}\n \n \n\n {!account && (\n

\n Connect your wallet to update the stored number.\n

\n )}\n
\n );\n};\n\nexport default WriteContract;\n```\n\nThis component allows users to input a new number and send a transaction to update the value stored in the contract. It provides appropriate feedback during each step of the transaction process and handles error scenarios.\n\nUpdate the `app/page.tsx` file to integrate all components:\n\n```typescript title=\"page.tsx\"\n\"use client\";\n\nimport { useState } from \"react\";\nimport WalletConnect from \"./components/WalletConnect\";\nimport ReadContract from \"./components/ReadContract\";\nimport WriteContract from \"./components/WriteContract\";\n\nexport default function Home() {\n const [account, setAccount] = useState(null);\n\n const handleConnect = (connectedAccount: string) => {\n setAccount(connectedAccount);\n };\n\n return (\n
\n

\n Polkadot Hub - Zero To Hero DApp\n

\n \n \n \n
\n );\n}\n```\n\nRun the dApp:\n\n```bash\nnpm run dev\n```\n\nNavigate to `http://localhost:3000` in your browser, and you should see your dApp with the wallet connection button, the stored number displayed, and the form to update the number. You should see something like this:"} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 16, "depth": 2, "title": "How It Works", "anchor": "how-it-works", "start_char": 28615, "end_char": 28708, "estimated_token_count": 18, "token_estimator": "heuristic-v1", "text": "## How It Works\n\nThis dApp uses components to interact with the blockchain in several ways."} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 17, "depth": 3, "title": "Wallet Connection", "anchor": "wallet-connection", "start_char": 28708, "end_char": 29014, "estimated_token_count": 60, "token_estimator": "heuristic-v1", "text": "### Wallet Connection \n\nThe `WalletConnect` component uses the browser's Ethereum provider (MetaMask) to connect to the user's wallet and handles network switching to ensure the user is connected to the Polkadot Hub TestNet. Once connected, it provides the user's account address to the parent component."} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 18, "depth": 3, "title": "Data Reads", "anchor": "data-reads", "start_char": 29014, "end_char": 29315, "estimated_token_count": 57, "token_estimator": "heuristic-v1", "text": "### Data Reads\n\nThe `ReadContract` component uses viem's `readContract` function to call the `storedNumber` view function and periodically poll for updates to keep the UI in sync with the blockchain state. The component also displays a loading indicator while fetching data and handles error states."} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 19, "depth": 3, "title": "Data Writes", "anchor": "data-writes", "start_char": 29315, "end_char": 29717, "estimated_token_count": 71, "token_estimator": "heuristic-v1", "text": "### Data Writes\n\nThe `WriteContract` component uses viem's `writeContract` function to send a transaction to the `setNumber` function and ensures the wallet is connected before allowing a transaction. The component shows detailed feedback during transaction submission and confirmation. After a successful transaction, the value displayed in the `ReadContract` component will update on the next poll."} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 20, "depth": 2, "title": "Conclusion", "anchor": "conclusion", "start_char": 29717, "end_char": 30614, "estimated_token_count": 178, "token_estimator": "heuristic-v1", "text": "## Conclusion\n\nCongratulations! You've successfully built a fully functional dApp that interacts with a smart contract on Polkadot Hub using viem and Next.js. Your application can now:\n\n- Create a smart contract with Hardhat and deploy it to Polkadot Hub TestNet.\n- Connect to a user's wallet and handle network switching.\n- Read data from a smart contract and keep it updated.\n- Write data to the blockchain through transactions.\n\nThese fundamental skills provide the foundation for building more complex dApps on Polkadot Hub. With this knowledge, you can extend your application to interact with more sophisticated smart contracts and create advanced user interfaces.\n\nTo get started right away with a working example, you can clone the repository and navigate to the implementation:\n\n```bash\ngit clone https://github.com/polkadot-developers/revm-hardhat-examples.git\ncd zero-to-hero-dapp\n```"} +{"page_id": "smart-contracts-cookbook-dapps-zero-to-hero", "page_title": "Zero to Hero Smart Contract DApp", "index": 21, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 30614, "end_char": 31207, "estimated_token_count": 147, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Guide __Port Ethereum Projects to Polkadot Hub__\n\n ---\n\n Learn how to port an Ethereum project to Polkadot Hub using Hardhat and Viem.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/eth-dapps/)\n\n- Guide __Dive Deeper into Polkadot Precompiles__\n\n ---\n\n Learn how to use the Polkadot precompiles to interact with the blockchain.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/polkadot-precompiles/)\n
"} {"page_id": "smart-contracts-cookbook-eth-dapps-uniswap-v2", "page_title": "Deploying Uniswap V2 on Polkadot", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 191, "end_char": 857, "estimated_token_count": 131, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nDecentralized exchanges (DEXs) are a cornerstone of the DeFi ecosystem, allowing for permissionless token swaps without intermediaries. [Uniswap V2](https://docs.uniswap.org/contracts/v2/overview){target=\\_blank}, with its Automated Market Maker (AMM) model, revolutionized DEXs by enabling liquidity provision for any ERC-20 token pair.\n\nThis tutorial will guide you through how Uniswap V2 works so you can take advantage of it in your projects deployed to Polkadot Hub. By understanding these contracts, you'll gain hands-on experience with one of the most influential DeFi protocols and understand how it functions across blockchain ecosystems."} {"page_id": "smart-contracts-cookbook-eth-dapps-uniswap-v2", "page_title": "Deploying Uniswap V2 on Polkadot", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 857, "end_char": 1357, "estimated_token_count": 124, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore starting, make sure you have:\n\n- Node.js (v16.0.0 or later) and npm installed.\n- Basic understanding of Solidity and JavaScript.\n- Familiarity with [`hardhat-polkadot`](/smart-contracts/dev-environments/hardhat/get-started/){target=\\_blank} development environment.\n- Some PAS test tokens to cover transaction fees (obtained from the [Polkadot faucet](https://faucet.polkadot.io/?parachain=1111){target=\\_blank}).\n- Basic understanding of how AMMs and liquidity pools work."} {"page_id": "smart-contracts-cookbook-eth-dapps-uniswap-v2", "page_title": "Deploying Uniswap V2 on Polkadot", "index": 2, "depth": 2, "title": "Set Up the Project", "anchor": "set-up-the-project", "start_char": 1357, "end_char": 3682, "estimated_token_count": 570, "token_estimator": "heuristic-v1", "text": "## Set Up the Project\n\nLet's start by cloning the Uniswap V2 project:\n\n1. Clone the Uniswap V2 repository:\n\n ```\n git clone https://github.com/polkadot-developers/polkavm-hardhat-examples.git -b v0.0.6\n cd polkavm-hardhat-examples/uniswap-v2-polkadot/\n ```\n\n2. Install the required dependencies:\n\n ```bash\n npm install\n ```\n\n3. Update the `hardhat.config.js` file so the paths for the Substrate node and the ETH-RPC adapter match with the paths on your machine. For more info, check the [Testing your Contract](/smart-contracts/dev-environments/hardhat/compile-and-test/){target=\\_blank} section in the Hardhat guide.\n\n ```js title=\"hardhat.config.js\"\n hardhat: {\n polkavm: true,\n nodeConfig: {\n nodeBinaryPath: '../bin/substrate-node',\n rpcPort: 8000,\n dev: true,\n },\n adapterConfig: {\n adapterBinaryPath: '../bin/eth-rpc',\n dev: true,\n },\n },\n ```\n\n4. Create a `.env` file in your project root to store your private keys (you can use as an example the `env.example` file):\n\n ```text title=\".env\"\n LOCAL_PRIV_KEY=\"INSERT_LOCAL_PRIVATE_KEY\"\n AH_PRIV_KEY=\"INSERT_AH_PRIVATE_KEY\"\n ```\n\n Ensure to replace `\"INSERT_LOCAL_PRIVATE_KEY\"` with a private key available in the local environment (you can get them from this [file](https://github.com/paritytech/hardhat-polkadot/blob/main/packages/hardhat-polkadot-node/src/constants.ts#L22){target=\\_blank}). And `\"INSERT_AH_PRIVATE_KEY\"` with the account's private key you want to use to deploy the contracts. You can get this by exporting the private key from your wallet (e.g., MetaMask).\n\n !!!warning\n Keep your private key safe, and never share it with anyone. If it is compromised, your funds can be stolen.\n\n5. Compile the contracts:\n\n ```bash\n npx hardhat compile\n ```\n\nIf the compilation is successful, you should see the following output:\n\n
\n npx hardhat compile\n Compiling 12 Solidity files\n Successfully compiled 12 Solidity files\n
\n\nAfter running the above command, you should see the compiled contracts in the `artifacts-pvm` directory. This directory contains the ABI and bytecode of your contracts."} @@ -1525,6 +1566,18 @@ {"page_id": "smart-contracts-for-eth-devs-json-rpc-apis", "page_title": "JSON-RPC APIs", "index": 32, "depth": 3, "title": "debug_traceCall", "anchor": "debug_tracecall", "start_char": 28867, "end_char": 31324, "estimated_token_count": 767, "token_estimator": "heuristic-v1", "text": "### debug_traceCall\n\nExecutes a new message call and returns a detailed execution trace without creating a transaction on the blockchain.\n\n**Parameters**:\n\n- **`transaction` ++\"object\"++**: The transaction call object, similar to `eth_call` parameters.\n - **`to` ++\"string\"++**: Recipient address of the call. Must be a [20-byte data](https://ethereum.org/en/developers/docs/apis/json-rpc/#unformatted-data-encoding){target=\\_blank} string.\n - **`data` ++\"string\"++**: Hash of the method signature and encoded parameters. Must be a [data](https://ethereum.org/en/developers/docs/apis/json-rpc/#unformatted-data-encoding){target=\\_blank} string.\n - **`from` ++\"string\"++**: (Optional) Sender's address for the call. Must be a [20-byte data](https://ethereum.org/en/developers/docs/apis/json-rpc/#unformatted-data-encoding){target=\\_blank} string.\n - **`gas` ++\"string\"++**: (Optional) Gas limit to execute the call. Must be a [quantity](https://ethereum.org/en/developers/docs/apis/json-rpc/#quantities-encoding){target=\\_blank} string.\n - **`gasPrice` ++\"string\"++**: (Optional) Gas price per unit of gas. Must be a [quantity](https://ethereum.org/en/developers/docs/apis/json-rpc/#quantities-encoding){target=\\_blank} string.\n - **`value` ++\"string\"++**: (Optional) Value in wei to send with the call. Must be a [quantity](https://ethereum.org/en/developers/docs/apis/json-rpc/#quantities-encoding){target=\\_blank} string.\n- **`blockValue` ++\"string\"++**: (Optional) Block tag or block number to execute the call at. Must be a [quantity](https://ethereum.org/en/developers/docs/apis/json-rpc/#quantities-encoding){target=\\_blank} string or a [default block parameter](https://ethereum.org/en/developers/docs/apis/json-rpc/#default-block){target=\\_blank}.\n- **`options` ++\"object\"++**: (Optional) An object containing tracer options (e.g., `tracer: \"callTracer\"`).\n\n**Example**:\n\n```bash title=\"debug_traceCall\"\ncurl -X POST https://testnet-passet-hub-eth-rpc.polkadot.io \\\n-H \"Content-Type: application/json\" \\\n--data '{\n \"jsonrpc\":\"2.0\",\n \"method\":\"debug_traceCall\",\n \"params\":[{\n \"from\": \"INSERT_SENDER_ADDRESS\",\n \"to\": \"INSERT_RECIPIENT_ADDRESS\",\n \"data\": \"INSERT_ENCODED_CALL\"\n }, \"INSERT_BLOCK_VALUE\", {\"tracer\": \"callTracer\"}],\n \"id\":1\n}'\n```\n\nEnsure to replace the `INSERT_SENDER_ADDRESS`, `INSERT_RECIPIENT_ADDRESS`, `INSERT_ENCODED_CALL`, and `INSERT_BLOCK_VALUE` with the proper value.\n\n---"} {"page_id": "smart-contracts-for-eth-devs-json-rpc-apis", "page_title": "JSON-RPC APIs", "index": 33, "depth": 2, "title": "Response Format", "anchor": "response-format", "start_char": 31324, "end_char": 31507, "estimated_token_count": 57, "token_estimator": "heuristic-v1", "text": "## Response Format\n\nAll responses follow the standard JSON-RPC 2.0 format:\n\n```json\n{\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"result\": ... // The return value varies by method\n}\n```"} {"page_id": "smart-contracts-for-eth-devs-json-rpc-apis", "page_title": "JSON-RPC APIs", "index": 34, "depth": 2, "title": "Error Handling", "anchor": "error-handling", "start_char": 31507, "end_char": 31726, "estimated_token_count": 64, "token_estimator": "heuristic-v1", "text": "## Error Handling\n\nIf an error occurs, the response will include an error object:\n\n```json\n{\n \"jsonrpc\": \"2.0\",\n \"id\": 1,\n \"error\": {\n \"code\": -32000,\n \"message\": \"Error message here\"\n }\n}\n```"} +{"page_id": "smart-contracts-for-eth-devs-migration", "page_title": "Migration FAQs and Considerations", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 37, "end_char": 303, "estimated_token_count": 40, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nThis guide helps Ethereum developers migrate their smart contracts to Polkadot Hub. Most contracts work without modifications on the REVM backend, while the PolkaVM backend offers enhanced performance with minimal adaptation for standard patterns."} +{"page_id": "smart-contracts-for-eth-devs-migration", "page_title": "Migration FAQs and Considerations", "index": 1, "depth": 2, "title": "Migration Considerations", "anchor": "migration-considerations", "start_char": 303, "end_char": 645, "estimated_token_count": 62, "token_estimator": "heuristic-v1", "text": "## Migration Considerations\n\nTake into account the following considerations before migrating your contracts:\n\n- Standard ERC-20, ERC-721, ERC-1155 tokens work without changes.\n- DeFi protocols, DEXs, and AMMs migrate seamlessly.\n- DAOs and governance contracts are fully compatible.\n- Most Solidity contracts deploy identically to Ethereum."} +{"page_id": "smart-contracts-for-eth-devs-migration", "page_title": "Migration FAQs and Considerations", "index": 2, "depth": 2, "title": "Migration Checklist", "anchor": "migration-checklist", "start_char": 645, "end_char": 1058, "estimated_token_count": 81, "token_estimator": "heuristic-v1", "text": "## Migration Checklist\n\nBefore migrating your contracts, review this checklist:\n\n- Factory contracts using PVM bytecode need pre-uploaded dependencies.\n- Contracts using `EXTCODECOPY` for runtime manipulation require review (for projects that will use PVM bytecode, not EVM bytecode).\n- Replace `transfer()` and `send()` with proper reentrancy guards (for projects that will use PVM bytecode, not EVM bytecode)."} +{"page_id": "smart-contracts-for-eth-devs-migration", "page_title": "Migration FAQs and Considerations", "index": 3, "depth": 2, "title": "Migration FAQs", "anchor": "migration-faqs", "start_char": 1058, "end_char": 1077, "estimated_token_count": 4, "token_estimator": "heuristic-v1", "text": "## Migration FAQs"} +{"page_id": "smart-contracts-for-eth-devs-migration", "page_title": "Migration FAQs and Considerations", "index": 4, "depth": 3, "title": "Which backend should I choose?", "anchor": "which-backend-should-i-choose", "start_char": 1077, "end_char": 1706, "estimated_token_count": 107, "token_estimator": "heuristic-v1", "text": "### Which backend should I choose?\n\n- Choose REVM if you want:\n\n - Zero-modification deployment of existing Ethereum contracts.\n - Exact EVM behavior for audited code.\n - Compatibility with tools that inspect EVM bytecode.\n - Rapid deployment without optimization.\n\n- Choose PolkaVM if you want:\n\n - Better performance for computation-heavy applications.\n - Lower execution costs for intensive operations.\n - Access to next-generation smart contract features.\n\nIf you are unsure which to choose, start with REVM for immediate compatibility, then consider PolkaVM for performance optimization once deployed."} +{"page_id": "smart-contracts-for-eth-devs-migration", "page_title": "Migration FAQs and Considerations", "index": 5, "depth": 3, "title": "Do I need to rewrite my Solidity code?", "anchor": "do-i-need-to-rewrite-my-solidity-code", "start_char": 1706, "end_char": 1825, "estimated_token_count": 26, "token_estimator": "heuristic-v1", "text": "### Do I need to rewrite my Solidity code?\n\nNo, for most contracts. Standard Solidity patterns work on both backends."} +{"page_id": "smart-contracts-for-eth-devs-migration", "page_title": "Migration FAQs and Considerations", "index": 6, "depth": 3, "title": "What about factory contracts?", "anchor": "what-about-factory-contracts", "start_char": 1825, "end_char": 3177, "estimated_token_count": 244, "token_estimator": "heuristic-v1", "text": "### What about factory contracts?\n\n- **REVM**: Factory contracts work identically to Ethereum with no changes needed. \n \n The original factory pattern is:\n\n ```solidity\n contract TokenFactory {\n function createToken(string memory name) public returns (address) {\n // Creates new contract at runtime\n Token newToken = new Token(name);\n return address(newToken);\n }\n }\n ```\n\n- **PolkaVM**: Factory contracts require pre-uploading dependent contracts. \n\n Here's how to adapt the original factory pattern:\n\n ```solidity\n contract TokenFactory {\n // Reference pre-uploaded Token contract by hash\n bytes32 public tokenCodeHash;\n \n constructor(bytes32 _tokenCodeHash) {\n tokenCodeHash = _tokenCodeHash;\n }\n \n function createToken(string memory name) public returns (address) {\n // Instantiate from pre-uploaded code\n Token newToken = new Token{salt: keccak256(abi.encode(name))}(name);\n return address(newToken);\n }\n }\n ```\n\nThe deployment steps for PolkaVM factories are:\n\n1. Upload the contract code to the chain.\n2. Note the returned code hash.\n3. Deploy the Factory contract with the contract code hash.\n4. Factory can now instantiate contracts using the pre-uploaded code."} +{"page_id": "smart-contracts-for-eth-devs-migration", "page_title": "Migration FAQs and Considerations", "index": 7, "depth": 3, "title": "How do gas costs compare?", "anchor": "how-do-gas-costs-compare", "start_char": 3177, "end_char": 3328, "estimated_token_count": 47, "token_estimator": "heuristic-v1", "text": "### How do gas costs compare?\n\nFor more information on gas costs, see the [Gas Model](/smart-contracts/for-eth-devs/gas-model/){target=\\_blank} page."} +{"page_id": "smart-contracts-for-eth-devs-migration", "page_title": "Migration FAQs and Considerations", "index": 8, "depth": 3, "title": "Which Solidity features are not supported?", "anchor": "which-solidity-features-are-not-supported", "start_char": 3328, "end_char": 3915, "estimated_token_count": 133, "token_estimator": "heuristic-v1", "text": "### Which Solidity features are not supported?\n\nFor REVM, any Solidity feature will function smoothly without requiring changes or adaptations. For PVM, there are considerations, as was mentioned above. \n\nFor PolkaVM, there are some considerations:\n\n- `EXTCODECOPY`: Only works in constructor code.\n- Runtime code modification: Use on-chain constructors instead.\n- **Gas stipends**: `address.send()` and `address.transfer()` don't provide reentrancy protection.\n- **Unsupported operations**: `pc`, `extcodecopy`, `selfdestruct`, `blobhash`, and `blobbasefee` (blob-related operations)."} +{"page_id": "smart-contracts-for-eth-devs-migration", "page_title": "Migration FAQs and Considerations", "index": 9, "depth": 3, "title": "How do I handle the existential deposit?", "anchor": "how-do-i-handle-the-existential-deposit", "start_char": 3915, "end_char": 4518, "estimated_token_count": 121, "token_estimator": "heuristic-v1", "text": "### How do I handle the existential deposit?\n\nPolkadot requires accounts to maintain a minimum balance (existential deposit or ED) to remain active.\n\nThis is handled automatically for you:\n\n- Balance queries via Ethereum RPC automatically deduct the ED.\n- New account transfers include ED in transaction fees.\n- Contract-to-contract transfers draw ED from the transaction signer.\n\nYou typically don't need to do anything special, but be aware:\n\n- Accounts below ED threshold are automatically deleted.\n- ED is around 0.01 DOT (varies by network).\n- Your contracts don't need to manage this explicitly."} +{"page_id": "smart-contracts-for-eth-devs-migration", "page_title": "Migration FAQs and Considerations", "index": 10, "depth": 3, "title": "Can I use my existing development tools?", "anchor": "can-i-use-my-existing-development-tools", "start_char": 4518, "end_char": 5499, "estimated_token_count": 304, "token_estimator": "heuristic-v1", "text": "### Can I use my existing development tools?\n\nYes. Both backends support:\n\n- **Wallets**: [MetaMask](https://metamask.io/){target=\\_blank}, [Talisman](https://talisman.xyz/){target=\\_blank}, [SubWallet](https://www.subwallet.app/){target=\\_blank}\n- **Development frameworks**: [Hardhat](/smart-contracts/cookbook/smart-contracts/deploy-basic/hardhat/){target=\\_blank}, [Foundry](/smart-contracts/cookbook/smart-contracts/deploy-basic/foundry/){target=\\_blank}, [Remix](/smart-contracts/cookbook/smart-contracts/deploy-basic/remix/){target=\\_blank} (just consider that for PVM bytecode, you will use the Polkadot version of the tooling)\n- **Libraries**: [ethers.js](/smart-contracts/libraries/ethers-js/){target=\\_blank}, [web3.js](/smart-contracts/libraries/web3-js/){target=\\_blank}, [viem](/smart-contracts/libraries/viem/){target=\\_blank}\n- **Testing tools**: Your existing test suites work\n\nConnect to Polkadot Hub's Ethereum JSON-RPC endpoint and use your familiar workflow."} +{"page_id": "smart-contracts-for-eth-devs-migration", "page_title": "Migration FAQs and Considerations", "index": 11, "depth": 2, "title": "Conclusion", "anchor": "conclusion", "start_char": 5499, "end_char": 6247, "estimated_token_count": 153, "token_estimator": "heuristic-v1", "text": "## Conclusion\n\nMost Ethereum contracts migrate to Polkadot Hub with minimal or no changes. Use REVM for seamless compatibility or PolkaVM for enhanced performance.\n\nThere are a few key points to keep in mind during migration:\n\n- Replace `transfer()` and `send()` with `.call{value}(\"\")` and use reentrancy guards (for projects that will use PVM bytecode, not EVM bytecode).\n- PolkaVM factory contracts using PVM bytecode need pre-uploaded dependencies.\n- Don't hardcode gas values.\n- Test thoroughly on [TestNet](/smart-contracts/connect/#__tabbed_1_1){target=\\_blank} before mainnet deployment.\n\nYour existing Solidity knowledge and tooling transfer directly to Polkadot Hub, making migration straightforward for standard smart contract patterns."} {"page_id": "smart-contracts-get-started", "page_title": "Get Started with Smart Contracts", "index": 0, "depth": 2, "title": "Quick Starts", "anchor": "quick-starts", "start_char": 173, "end_char": 1843, "estimated_token_count": 456, "token_estimator": "heuristic-v1", "text": "## Quick Starts\n\nKick off development fast with curated links for connecting, funding, exploring, and deploying your first contract.\n\n| Quick Start | Tools | Description |\n| :-------------------------------------------------------------------------------------------------: | :-------------------: | :-------------------------------------------------------------: |\n| [Connect to Polkadot](/smart-contracts/connect/){target=\\_blank} | Polkadot.js, MetaMask | Add the network, configure RPC, verify activity in the explorer |\n| [Get Test Tokens](/smart-contracts/faucets/){target=\\_blank} | - | Request test funds to deploy and interact with contracts |\n| [Explore Transactions](/smart-contracts/explorers/){target=\\_blank} | Subscan | Inspect transactions, logs, token transfers, and contract state |\n| [Deploy with Remix](/smart-contracts/dev-environments/remix/deploy-a-contract/){target=\\_blank} | Remix | One‑click browser deployment to Polkadot Hub |\n| [Deploy with Foundry](/smart-contracts/dev-environments/foundry/deploy-a-contract/){target=\\_blank} | Foundry | Scripted deployments and testing from the CLI |\n| [Deploy with Hardhat](/smart-contracts/dev-environments/hardhat/deploy-a-contract/){target=\\_blank} | Hardhat | Project scaffolding, testing, and deployments |"} {"page_id": "smart-contracts-get-started", "page_title": "Get Started with Smart Contracts", "index": 1, "depth": 2, "title": "Build and Test Locally", "anchor": "build-and-test-locally", "start_char": 1843, "end_char": 4050, "estimated_token_count": 596, "token_estimator": "heuristic-v1", "text": "## Build and Test Locally\n\nSet up local environments and CI-friendly workflows to iterate quickly and validate changes before deploying.\n\n| Build and Test Locally | Tools | Description |\n| :--------------------------------------------------------------------------------------------------------: | :---------------: | :--------------------------------------------------: |\n| [Run a Local Dev Node](/smart-contracts/dev-environments/local-dev-node/){target=\\_blank} | Polkadot SDK node | Spin up a local node for iterative development |\n| [Remix: Get Started](/smart-contracts/dev-environments/remix/get-started/){target=\\_blank} | Remix | Connect Remix to Polkadot Hub and configure accounts |\n| [Remix: Verify a Contract](/smart-contracts/dev-environments/remix/verify-a-contract/){target=\\_blank} | Remix | Publish verified source on explorers |\n| [Foundry: Install and Config](/smart-contracts/dev-environments/foundry/install-and-config/){target=\\_blank} | Foundry | Install toolchain and configure networks |\n| [Foundry: Compile and Test](/smart-contracts/dev-environments/foundry/compile-and-test/){target=\\_blank} | Foundry | Write and run Solidity tests locally |\n| [Foundry: Verify a Contract](/smart-contracts/dev-environments/foundry/verify-a-contract/){target=\\_blank} | Foundry | Verify deployed bytecode and metadata |\n| [Hardhat: Install and Config](/smart-contracts/dev-environments/hardhat/install-and-config/){target=\\_blank} | Hardhat | Initialize a project and configure networks |\n| [Hardhat: Compile and Test](/smart-contracts/dev-environments/hardhat/compile-and-test/){target=\\_blank} | Hardhat | Unit test contracts and run scripts |\n| [Hardhat: Verify a Contract](/smart-contracts/dev-environments/hardhat/verify-a-contract/){target=\\_blank} | Hardhat | Verify deployments on explorers |"} {"page_id": "smart-contracts-get-started", "page_title": "Get Started with Smart Contracts", "index": 2, "depth": 2, "title": "Ethereum Developer Resources", "anchor": "ethereum-developer-resources", "start_char": 4050, "end_char": 5794, "estimated_token_count": 488, "token_estimator": "heuristic-v1", "text": "## Ethereum Developer Resources\n\nBridge your Ethereum knowledge with Polkadot Hub specifics: account mapping, fees, JSON‑RPC, and deployment.\n\n| Ethereum Developer Guides | Description |\n| :-------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------: |\n| [Accounts](/smart-contracts/for-eth-devs/accounts/){target=\\_blank} | How 20‑byte Ethereum addresses map to 32‑byte Polkadot accounts |\n| [Blocks, Transactions, and Fees](/smart-contracts/for-eth-devs/blocks-transactions-fees/){target=\\_blank} | Transaction types, fees, and multi‑dimensional metering |\n| [Gas Model](/smart-contracts/for-eth-devs/gas-model/){target=\\_blank} | Gas vs. weight, proof size, and storage deposits |\n| [Contract Deployment](/smart-contracts/for-eth-devs/contract-deployment/){target=\\_blank} | Deployment patterns and best practices on Polkadot Hub |\n| [JSON‑RPC APIs](/smart-contracts/for-eth-devs/json-rpc-apis/){target=\\_blank} | Supported Ethereum JSON‑RPC methods and examples |\n| [Migration](/smart-contracts/for-eth-devs/migration/){target=\\_blank} | Port existing apps and tooling to Polkadot Hub |\n| [Dual VM Stack](/smart-contracts/for-eth-devs/dual-vm-stack/){target=\\_blank} | Overview of EVM and native execution on the Hub |"} diff --git a/llms.txt b/llms.txt index 3ba08e18f..370da25f6 100644 --- a/llms.txt +++ b/llms.txt @@ -10,6 +10,7 @@ This directory lists URLs for raw Markdown pages that complement the rendered pa - Categories: 12 ## Docs +This section lists documentation pages by category. Each entry links to a raw markdown version of the page and includes a short description. A page may appear in multiple categories. Docs: Basics - [Register a Local Asset](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/chain-interactions-token-operations-register-local-asset.md): Comprehensive guide to registering a local asset on the Asset Hub system parachain, including step-by-step instructions. @@ -95,6 +96,7 @@ Docs: Smart Contracts - [Block Explorers](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-explorers.md): Access PolkaVM explorers like Subscan, BlockScout, and Routescan to track transactions, analyze contracts, and view on-chain data from smart contracts. - [Faucet](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-faucet.md): Learn how to obtain test tokens from Polkadot faucets for development and testing purposes across different networks. - [Contract Deployment](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-contract-deployment.md): Compare deployment flows for REVM and PVM-based smart contracts on the Polkadot Hub. Includes single-step REVM flows and PVM’s two-step deployment model. +- [Migration FAQs and Considerations](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-migration.md): Learn how to migrate your existing Ethereum contracts to the Polkadot Hub using REVM and PolkaVM by following these considerations. - [Get Started with Smart Contracts](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-get-started.md): Practical examples for building and deploying smart contracts on Polkadot Hub, from connecting and tooling to deployment, integrations, and precompiles. - [Wallets for Polkadot Hub](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-integrations-wallets.md): Comprehensive guide to connecting and managing wallets for Polkadot Hub, covering step-by-step instructions for interacting with the ecosystem. - [Deploy Contracts to Polkadot Hub with Ethers.js](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-libraries-ethers-js.md): Learn how to interact with Polkadot Hub using Ethers.js, from compiling and deploying Solidity contracts to interacting with deployed smart contracts. @@ -118,9 +120,9 @@ Docs: Parachains - [Write Tests](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-toolkit-parachains-spawn-chains-zombienet-write-tests.md): Write and execute tests for blockchain networks with Zombienet's DSL. Learn to evaluate metrics, logs, events, and more for robust validation. - [Add an Existing Pallet to the Runtime](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-add-existing-pallets.md): Learn how to include and configure pallets in a Polkadot SDK-based runtime, from adding dependencies to implementing necessary traits. - [Add Multiple Pallet Instances](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-add-pallet-instances.md): Learn how to implement multiple instances of the same pallet in your Polkadot SDK-based runtime, from adding dependencies to configuring unique instances. -- [Add Smart Contract Functionality](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-add-smart-contract-functionality.md): Add smart contract capabilities to your Polkadot SDK-based blockchain. Explore EVM and Wasm integration for enhanced chain functionality. +- [Add Smart Contract Functionality](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-add-smart-contract-functionality.md): Add smart contract capabilities to your Polkadot SDK-based blockchain. Explore PVM, EVM, and Wasm integration for enhanced chain functionality. - [Add Pallets to the Runtime](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-add-pallet-to-runtime.md): Add pallets to your runtime for custom functionality. Learn to configure and integrate pallets in Polkadot SDK-based blockchains. -- [Benchmarking FRAME Pallets](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md): Learn how to use FRAME's benchmarking framework to measure extrinsic execution costs and provide accurate weights for on-chain computations. +- [Benchmark Your Pallet](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md): Learn how to benchmark your custom pallet extrinsics to generate accurate weight calculations for production use. - [Create a Custom Pallet](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-create-a-pallet.md): Learn how to create custom pallets using FRAME, allowing for flexible, modular, and scalable blockchain development. Follow the step-by-step guide. - [Mock Your Runtime](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-mock-runtime.md): Learn how to create a mock runtime environment for testing your custom pallets in isolation, enabling comprehensive unit testing before runtime integration. - [Pallet Testing](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-pallet-testing.md): Learn how to efficiently test pallets in the Polkadot SDK, ensuring the reliability and security of your pallets operations. @@ -353,7 +355,6 @@ Docs: Uncategorized - [ParaSpell XCM SDK](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-paraspell.md): A powerful open-source library that simplifies XCM integration, enabling developers to easily build interoperable dApps on Polkadot. - [reference-tools-zombienet](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-tools-zombienet.md): No description available. - [reference](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference.md): No description available. -- [smart-contracts-cookbook-dapps-zero-to-hero](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-dapps-zero-to-hero.md): No description available. - [smart-contracts-cookbook-smart-contracts-deploy-basic](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic.md): No description available. - [smart-contracts-dev-environments-foundry-compile-and-test](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-dev-environments-foundry-compile-and-test.md): No description available. - [smart-contracts-dev-environments-foundry-deploy-a-contract](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-dev-environments-foundry-deploy-a-contract.md): No description available. @@ -370,7 +371,6 @@ Docs: Uncategorized - [smart-contracts-dev-environments-remix-troubleshooting](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-dev-environments-remix-troubleshooting.md): No description available. - [smart-contracts-dev-environments-remix-verify-a-contract](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-dev-environments-remix-verify-a-contract.md): No description available. - [Gas Model on the Polkadot Hub](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-gas-model.md): Learn how gas estimation, pricing, and weight mapping work in the Polkadot Hub. -- [smart-contracts-for-eth-devs-migration](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-for-eth-devs-migration.md): No description available. - [smart-contracts-integrations-indexers](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-integrations-indexers.md): No description available. - [smart-contracts-integrations-oracles](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-integrations-oracles.md): No description available. - [Advanced Functionalities via Precompiles](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-precompiles.md): Explores how Polkadot integrates precompiles to run essential functions natively, improving the speed and efficiency of smart contracts on the Hub. diff --git a/parachains/customize-runtime/pallet-development/benchmark-pallet.md b/parachains/customize-runtime/pallet-development/benchmark-pallet.md index dd02ee0b4..9eae75314 100644 --- a/parachains/customize-runtime/pallet-development/benchmark-pallet.md +++ b/parachains/customize-runtime/pallet-development/benchmark-pallet.md @@ -1,215 +1,681 @@ --- -title: Benchmarking FRAME Pallets -description: Learn how to use FRAME's benchmarking framework to measure extrinsic execution costs and provide accurate weights for on-chain computations. +title: Benchmark Your Pallet +description: Learn how to benchmark your custom pallet extrinsics to generate accurate weight calculations for production use. categories: Parachains --- -# Benchmarking - ## Introduction -Benchmarking is a critical component of developing efficient and secure blockchain runtimes. In the Polkadot ecosystem, accurately benchmarking your custom pallets ensures that each extrinsic has a precise [weight](/reference/glossary/#weight){target=\_blank}, representing its computational and storage demands. This process is vital for maintaining the blockchain's performance and preventing potential vulnerabilities, such as Denial of Service (DoS) attacks. +Benchmarking is the process of measuring the computational resources (execution time and storage) required by your pallet's extrinsics. Accurate [weight](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/index.html){target=\_blank} calculations are essential for ensuring your blockchain can process transactions efficiently while protecting against denial-of-service attacks. + +This guide continues the pallet development series, building on the [Create a Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet), [Mock Your Runtime](/parachains/customize-runtime/pallet-development/mock-runtime), and [Test Your Pallet](/parachains/customize-runtime/pallet-development/pallet-testing) tutorials. You'll learn how to benchmark the counter pallet extrinsics and integrate the generated weights into your runtime. + +## Prerequisites + +Before you begin, ensure you have: + +- Completed the previous pallet development tutorials +- Basic understanding of computational complexity +- Familiarity with Rust's testing framework + +## Why Benchmark? + +In blockchain systems, every operation consumes resources. Weight is the mechanism Polkadot SDK uses to measure and limit resource consumption. Without accurate weights: + +- **Security Risk**: Malicious actors could submit transactions that consume excessive resources, blocking legitimate transactions or halting the chain +- **Inefficiency**: Over-estimated weights waste block space and reduce throughput +- **User Experience**: Inaccurate weights lead to incorrect fee calculations + +Benchmarking provides empirical measurements of your extrinsics under various conditions, ensuring weights reflect real-world resource consumption. + +## Understanding Weights + +The [weight system](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html){target=\_blank} serves multiple purposes: + +- **DoS Protection**: Limits the computational work per block, preventing attackers from overwhelming the network +- **Fee Calculation**: Determines transaction fees based on actual resource usage +- **Block Production**: Helps block authors maximize throughput while staying within block limits + +Weights are expressed as [`Weight::from_parts(ref_time, proof_size)`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.from_parts){target=\_blank} where: + +- [`ref_time`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.ref_time){target=\_blank}: Computational time measured in picoseconds +- [`proof_size`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.proof_size){target=\_blank}: Storage proof size in bytes + +## Step 1: Create the Benchmarking Module + +Create a new file `benchmarking.rs` in your pallet's `src` directory. This module will contain all the [benchmarking definitions](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank} for your pallet: + +```rust title="pallets/pallet-custom/src/benchmarking.rs" +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use frame::deps::frame_benchmarking::v2::*; +use frame::benchmarking::prelude::RawOrigin; + +#[benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn set_counter_value() { + let new_value: u32 = 100; + + #[extrinsic_call] + _(RawOrigin::Root, new_value); + + assert_eq!(CounterValue::::get(), new_value); + } + + #[benchmark] + fn increment() { + let caller: T::AccountId = whitelisted_caller(); + let amount: u32 = 50; + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), amount); + + assert_eq!(CounterValue::::get(), amount); + assert_eq!(UserInteractions::::get(caller), 1); + } + + #[benchmark] + fn decrement() { + // First set the counter to a non-zero value + CounterValue::::put(100); + + let caller: T::AccountId = whitelisted_caller(); + let amount: u32 = 30; + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), amount); + + assert_eq!(CounterValue::::get(), 70); + assert_eq!(UserInteractions::::get(caller), 1); + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); +} +``` + +**Key components:** + +- **`#![cfg(feature = "runtime-benchmarks")]`**: Ensures benchmarking code only compiles when the feature is enabled +- **[`#[benchmarks]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmarks.html){target=\_blank}**: Marks the module containing benchmark definitions +- **[`#[benchmark]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmark.html){target=\_blank}**: Defines individual benchmark functions +- **[`#[extrinsic_call]`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.extrinsic_call.html){target=\_blank}**: Marks the actual extrinsic invocation to measure +- **[`whitelisted_caller()`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/fn.whitelisted_caller.html){target=\_blank}**: Generates a funded account for benchmarking +- **[`impl_benchmark_test_suite!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.impl_benchmark_test_suite.html){target=\_blank}**: Generates test functions to verify benchmarks work correctly + +## Step 2: Define the Weight Trait + +The [`WeightInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/trait.WeightInfo.html){target=\_blank} trait provides an abstraction layer that allows weights to be swapped at runtime configuration. This enables you to use placeholder weights during development and testing, then switch to auto-generated benchmarked weights in production without modifying the pallet code itself. + +Add a `weights` module to your pallet that defines the `WeightInfo` trait: + +```rust title="pallets/pallet-custom/src/lib.rs" +#[frame::pallet] +pub mod pallet { + use frame::prelude::*; + pub use weights::WeightInfo; + + pub mod weights { + use frame::prelude::*; + + pub trait WeightInfo { + fn set_counter_value() -> Weight; + fn increment() -> Weight; + fn decrement() -> Weight; + } + + impl WeightInfo for () { + fn set_counter_value() -> Weight { + Weight::from_parts(10_000, 0) + } + fn increment() -> Weight { + Weight::from_parts(15_000, 0) + } + fn decrement() -> Weight { + Weight::from_parts(15_000, 0) + } + } + } + + // ... rest of pallet +} +``` + +The `()` implementation provides placeholder weights for development. Later, this will be replaced with auto-generated weights from benchmarking. + +## Step 3: Add WeightInfo to Config + +By making `WeightInfo` an associated type in the `Config` trait, you allow each runtime that uses your pallet to specify which weight implementation to use. Different deployment environments (testnets, production chains, or different hardware configurations) may have different performance characteristics and can use different weight calculations. -The Polkadot SDK leverages the [FRAME](/reference/glossary/#frame-framework-for-runtime-aggregation-of-modularized-entities){target=\_blank} benchmarking framework, offering tools to measure and assign weights to extrinsics. These weights help determine the maximum number of transactions or system-level calls processed within a block. This guide covers how to use FRAME's [benchmarking framework](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank}, from setting up your environment to writing and running benchmarks for your custom pallets. You'll understand how to generate accurate weights by the end, ensuring your runtime remains performant and secure. +Update your pallet's `Config` trait to include `WeightInfo`: -## The Case for Benchmarking +```rust title="pallets/pallet-custom/src/lib.rs" +#[pallet::config] +pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; -Benchmarking helps validate that the required execution time for different functions is within reasonable boundaries to ensure your blockchain runtime can handle transactions efficiently and securely. By accurately measuring the weight of each extrinsic, you can prevent service interruptions caused by computationally intensive calls that exceed block time limits. Without benchmarking, runtime performance could be vulnerable to DoS attacks, where malicious users exploit functions with unoptimized weights. + #[pallet::constant] + type CounterMaxValue: Get; -Benchmarking also ensures predictable transaction fees. Weights derived from benchmark tests accurately reflect the resource usage of function calls, allowing fair fee calculation. This approach discourages abuse while maintaining network reliability. + type WeightInfo: weights::WeightInfo; +} +``` + +## Step 4: Update Extrinsic Weight Annotations + +By calling `T::WeightInfo::function_name()` instead of using hardcoded `Weight::from_parts()` values, your extrinsics automatically use whichever weight implementation is configured in the runtime. This allows you to easily switch between placeholder weights for testing and benchmarked weights for production without changing any pallet code. + +Replace the placeholder weights in your extrinsics with calls to the `WeightInfo` trait: + +```rust title="pallets/pallet-custom/src/lib.rs" +#[pallet::call] +impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::set_counter_value())] + pub fn set_counter_value(origin: OriginFor, new_value: u32) -> DispatchResult { + // ... implementation + } + + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::increment())] + pub fn increment(origin: OriginFor, amount: u32) -> DispatchResult { + // ... implementation + } + + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::decrement())] + pub fn decrement(origin: OriginFor, amount: u32) -> DispatchResult { + // ... implementation + } +} +``` + +## Step 5: Include the Benchmarking Module + +The `#[cfg(feature = "runtime-benchmarks")]` attribute ensures that benchmarking code is only compiled when explicitly needed. This keeps your production runtime lean by excluding benchmarking infrastructure from normal builds, as it's only needed when generating weights. + +At the top of your `lib.rs`, add the module declaration: + +```rust title="pallets/pallet-custom/src/lib.rs" +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; +use alloc::vec::Vec; + +pub use pallet::*; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +// ... rest of the pallet +``` + +## Step 6: Configure Pallet Dependencies + +The feature flag system in Cargo allows you to conditionally compile code based on which features are enabled. By defining a `runtime-benchmarks` feature that cascades to FRAME's benchmarking features, you create a clean way to build your pallet with or without benchmarking support, ensuring all necessary dependencies are available when needed but excluded from production builds. + +Update your pallet's `Cargo.toml` to enable the benchmarking feature: + +```toml title="pallets/pallet-custom/Cargo.toml" +[dependencies] +codec = { features = ["derive"], workspace = true } +scale-info = { features = ["derive"], workspace = true } +frame = { features = ["experimental", "runtime"], workspace = true } -### Benchmarking and Weight +[features] +default = ["std"] +runtime-benchmarks = [ + "frame/runtime-benchmarks", +] +std = [ + "codec/std", + "scale-info/std", + "frame/std", +] +``` + +## Step 7: Update Mock Runtime + +In your mock runtime for testing, use the placeholder `()` implementation of `WeightInfo` since unit tests focus on verifying functional correctness rather than performance characteristics. This keeps tests fast and focused on validating logic. + +Add the `WeightInfo` type to your test configuration in `mock.rs`: + +```rust title="pallets/pallet-custom/src/mock.rs" +impl pallet_custom::Config for Test { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = (); +} +``` + +## Step 8: Configure Runtime Benchmarking + +To execute benchmarks, your pallet must be integrated into the runtime's benchmarking infrastructure. This involves three configuration steps: + +### Update Runtime Cargo.toml -In Polkadot SDK-based chains, weight quantifies the computational effort needed to process transactions. This weight includes factors such as: +When you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included. -- Computational complexity. -- Storage complexity (proof size). -- Database reads and writes. -- Hardware specifications. +Add your pallet to the runtime's `runtime-benchmarks` feature in `runtime/Cargo.toml`: -Benchmarking uses real-world testing to simulate worst-case scenarios for extrinsics. The framework generates a linear model for weight calculation by running multiple iterations with varied parameters. These worst-case weights ensure blocks remain within execution limits, enabling the runtime to maintain throughput under varying loads. Excess fees can be refunded if a call uses fewer resources than expected, offering users a fair cost model. - -Because weight is a generic unit of measurement based on computation time for a specific physical machine, the weight of any function can change based on the specifications of hardware used for benchmarking. By modeling the expected weight of each runtime function, the blockchain can calculate the number of transactions or system-level calls it can execute within a certain period. +```toml title="runtime/Cargo.toml" +runtime-benchmarks = [ + "cumulus-pallet-parachain-system/runtime-benchmarks", + "hex-literal", + "pallet-parachain-template/runtime-benchmarks", + "polkadot-sdk/runtime-benchmarks", + "pallet-custom/runtime-benchmarks", +] +``` + +### Update Runtime Configuration + +Start with the placeholder implementation during development. After successfully running benchmarks and generating the weights file, you'll update this to use the benchmarked weights. -Within FRAME, each function call that is dispatched must have a `#[pallet::weight]` annotation that can return the expected weight for the worst-case scenario execution of that function given its inputs: +In `runtime/src/configs/mod.rs`, add the `WeightInfo` type: -```rust hl_lines="2" ---8<-- 'code/parachains/customize-runtime/pallet-development/benchmark-pallet/dispatchable-pallet-weight.rs' +```rust title="runtime/src/configs/mod.rs" +impl pallet_custom::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = (); +} ``` -The `WeightInfo` file is automatically generated during benchmarking. Based on these tests, this file provides accurate weights for each extrinsic. +### Register Benchmarks -## Benchmarking Process +The `define_benchmarks!` macro creates the infrastructure that allows the benchmarking CLI tool to discover and execute your pallet's benchmarks. -Benchmarking a pallet involves the following steps: +Add your pallet to the benchmark list in `runtime/src/benchmarks.rs`: + +```rust title="runtime/src/benchmarks.rs" +polkadot_sdk::frame_benchmarking::define_benchmarks!( + [frame_system, SystemBench::] + [pallet_balances, Balances] + // ... other pallets + [pallet_custom, CustomPallet] +); +``` -1. Creating a `benchmarking.rs` file within your pallet's structure. -2. Writing a benchmarking test for each extrinsic. -3. Executing the benchmarking tool to calculate weights based on performance metrics. +## Step 9: Run Benchmarks -The benchmarking tool runs multiple iterations to model worst-case execution times and determine the appropriate weight. By default, the benchmarking pipeline is deactivated. To activate it, compile your runtime with the `runtime-benchmarks` feature flag. +### Test Benchmark Compilation -### Prepare Your Environment +The `impl_benchmark_test_suite!` macro generates unit tests for each benchmark. Running these tests verifies that your benchmarks compile correctly, execute without panicking, and pass their assertions, catching issues early before building the full runtime. -Install the [`frame-omni-bencher`](https://crates.io/crates/frame-omni-bencher){target=\_blank} command-line tool: +First, verify your benchmarks compile and run as tests: ```bash -cargo install frame-omni-bencher +cargo test -p pallet-custom --features runtime-benchmarks ``` -Before writing benchmark tests, you need to ensure the `frame-benchmarking` crate is included in your pallet's `Cargo.toml` similar to the following: +You should see your benchmark tests passing: -```toml title="Cargo.toml" ---8<-- 'code/parachains/customize-runtime/pallet-development/benchmark-pallet/cargo.toml::1' ``` +test benchmarking::benchmarks::bench_set_counter_value ... ok +test benchmarking::benchmarks::bench_increment ... ok +test benchmarking::benchmarks::bench_decrement ... ok +``` + +### Build the Runtime with Benchmarks + +This build includes all the benchmarking infrastructure and special host functions needed for measurement. The resulting WASM runtime contains your benchmark code and can communicate with the benchmarking tool's execution environment. This is a special build used only for benchmarking - you'll create a different build later for actually running your chain. + +Compile the runtime with benchmarking enabled to generate the WASM binary: -You must also ensure that you add the `runtime-benchmarks` feature flag as follows under the `[features]` section of your pallet's `Cargo.toml`: +```bash +cargo build --release --features runtime-benchmarks +``` -```toml title="Cargo.toml" ---8<-- 'code/parachains/customize-runtime/pallet-development/benchmark-pallet/cargo.toml:2:7' +This produces the runtime WASM file needed for benchmarking, typically located at: +``` +target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm ``` -Lastly, ensure that `frame-benchmarking` is included in `std = []`: +### Install the Benchmarking Tool + +[`frame-omni-bencher`](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} is the official Polkadot SDK tool specifically designed for FRAME pallet benchmarking. It provides a standardized way to execute benchmarks, measure execution times and storage operations, and generate properly formatted weight files with full integration into the FRAME weight system. + +Install the `frame-omni-bencher` CLI tool: -```toml title="Cargo.toml" ---8<-- 'code/parachains/customize-runtime/pallet-development/benchmark-pallet/cargo.toml:8:12' +```bash +cargo install frame-omni-bencher --locked ``` -Once complete, you have the required dependencies for writing benchmark tests for your pallet. +### Download the Weight Template -### Write Benchmark Tests +The weight template is a Handlebars file that transforms raw benchmark data into a properly formatted Rust source file. It defines the structure of the generated `weights.rs` file, including imports, trait definitions, documentation comments, and formatting. Using the official template ensures your weight files follow Polkadot SDK conventions and include all necessary metadata like benchmark execution parameters, storage operation counts, and hardware information. -Create a `benchmarking.rs` file in your pallet's `src/`. Your directory structure should look similar to the following: +Download the official weight template file: +```bash +curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \ +--output ./pallets/pallet-custom/frame-weight-template.hbs ``` -my-pallet/ -├── src/ -│ ├── lib.rs # Main pallet implementation -│ └── benchmarking.rs # Benchmarking -└── Cargo.toml + +### Hardware Requirements for Benchmarking + +!!! warning "Critical: Benchmark on Production-Like Hardware" + Benchmarks must be executed on hardware similar to what will run your chain in production. Weight measurements are hardware-dependent, and benchmarking on different hardware can lead to dangerous under-estimation or wasteful over-estimation of weights. + +Weights represent the actual computational time and resources consumed by extrinsics. These measurements vary significantly across different hardware configurations: + +- **CPU Performance**: Different processors execute instructions at different speeds. A faster development laptop will produce lower weight values than production server hardware +- **Storage Speed**: Database read/write performance varies between NVMe SSDs, SATA SSDs, and HDDs, affecting storage-related weights +- **Memory Bandwidth**: RAM speed impacts how quickly data can be accessed during execution +- **CPU Cache**: Cache size and architecture differences affect repeated operations + +Benchmarking on faster hardware than production leads to under-estimated weights - attackers could submit extrinsics that consume more resources than the weights suggest, potentially causing blocks to take longer than expected to produce or even halting the chain. Conversely, benchmarking on slower hardware creates over-estimated weights, resulting in unnecessarily high transaction fees and wasted block capacity. + +**Best practices:** + +1. **Match production specifications**: If your chain will run on specific validator hardware, benchmark on identical or very similar machines +2. **Use reference hardware**: The Polkadot ecosystem often uses standardized reference hardware specifications for consistency. Consider following these standards if your chain will connect to Polkadot or Kusama +3. **Dedicated benchmarking environment**: Run benchmarks on a machine without other heavy processes to ensure consistent measurements +4. **Document your hardware**: The generated weight files include hardware information in comments. Review this to ensure it matches your production environment +5. **Re-benchmark when hardware changes**: If your validator hardware specifications change, re-run benchmarks and update weights + +For development and testing purposes, you can run benchmarks on any available hardware to verify that your benchmark functions work correctly. However, before deploying to production, always re-run benchmarks on production-equivalent hardware. + +### Execute Benchmarks + +Benchmarks execute against the compiled WASM runtime rather than native code because WASM is what actually runs in production on the blockchain. WASM execution can have different performance characteristics than native code due to compilation and sandboxing overhead, so benchmarking the WASM ensures your weight measurements reflect real-world conditions. + +Run benchmarks for your pallet to generate weight files: + +```bash +frame-omni-bencher v1 benchmark pallet \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ + --pallet pallet_custom \ + --extrinsic "" \ + --template ./pallets/pallet-custom/frame-weight-template.hbs \ + --output ./pallets/pallet-custom/src/weights.rs ``` -With the directory structure set, you can use the [`polkadot-sdk-parachain-template`](https://github.com/paritytech/polkadot-sdk-parachain-template/tree/master/pallets){target=\_blank} to get started as follows: +**Command breakdown:** + +- `v1`: Specifies the benchmarking framework version (v2 API) +- `benchmark pallet`: Subcommand indicating you want to benchmark pallet extrinsics +- `--runtime`: Path to the compiled WASM runtime file that includes your pallet and benchmarks +- `--pallet pallet_custom`: Name of the pallet to benchmark (must match the name used in `define_benchmarks!`) +- `--extrinsic ""`: Empty string benchmarks all extrinsics in the pallet; you can specify a single extrinsic name to benchmark only that one +- `--template`: Path to the Handlebars template that formats the output +- `--output`: Destination file path for the generated weights module + +### Advanced Options -```rust title="benchmarking.rs (starter template)" ---8<-- 'https://raw.githubusercontent.com/paritytech/polkadot-sdk-parachain-template/refs/tags/v0.0.2/pallets/template/src/benchmarking.rs' +You can customize benchmark execution with additional parameters for more detailed measurements: + +```bash +frame-omni-bencher v1 benchmark pallet \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ + --pallet pallet_custom \ + --extrinsic "" \ + --steps 50 \ + --repeat 20 \ + --template ./pallets/pallet-custom/frame-weight-template.hbs \ + --output ./pallets/pallet-custom/src/weights.rs ``` -In your benchmarking tests, employ these best practices: +**Additional parameters:** -- **Write custom testing functions**: The function `do_something` in the preceding example is a placeholder. Similar to writing unit tests, you must write custom functions to benchmark test your extrinsics. Access the mock runtime and use functions such as `whitelisted_caller()` to sign transactions and facilitate testing. -- **Use the `#[extrinsic_call]` macro**: This macro is used when calling the extrinsic itself and is a required part of a benchmarking function. See the [`extrinsic_call`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html#extrinsic_call-and-block){target=\_blank} docs for more details. -- **Validate extrinsic behavior**: The `assert_eq` expression ensures that the extrinsic is working properly within the benchmark context. +- `--steps 50`: Number of different input values to test when using linear components (default: 50). More steps provide finer granularity for detecting complexity trends but increase benchmarking time +- `--repeat 20`: Number of repetitions for each measurement (default: 20). More repetitions improve statistical accuracy by averaging out variance, reducing the impact of system noise and providing more reliable weight estimates +- `--heap-pages 4096`: WASM heap pages allocation. Affects available memory during execution +- `--wasm-execution compiled`: WASM execution method. Use `compiled` for performance closest to production conditions -Add the `benchmarking` module to your pallet. In the pallet `lib.rs` file add the following: +## Step 10: Use Generated Weights + +After running benchmarks, a `weights.rs` file is generated containing measured weights. The generated weights are based on actual measurements of your code running on real hardware, accounting for the specific complexity of your logic, storage access patterns, and computational requirements. Estimates or placeholder values cannot capture these nuances and will either waste block space (over-estimation) or create security risks (under-estimation). + +The file includes: + +- Detailed documentation about the benchmark execution environment (date, hardware, parameters) +- The `WeightInfo` trait definition matching your benchmark functions +- `SubstrateWeight` implementation with measured weights from your benchmarks +- Database read/write costs calculated based on observed storage operations +- Component complexity annotations for variable inputs (if you use linear components) +- A fallback `()` implementation for testing environments + +### Integrate the Generated Weights + +Unlike the benchmarking module (which is only needed when running benchmarks), the weights module must be available in all builds because the runtime needs to call the weight functions during normal operation to calculate transaction fees and enforce block limits. + +Add the weights module to your pallet's `lib.rs`: + +```rust title="pallets/pallet-custom/src/lib.rs" +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; +use alloc::vec::Vec; + +pub use pallet::*; -```rust #[cfg(feature = "runtime-benchmarks")] mod benchmarking; + +pub mod weights; + +#[frame::pallet] +pub mod pallet { + use super::*; + use frame::prelude::*; + use crate::weights::WeightInfo; + // ... rest of pallet +} ``` -### Add Benchmarks to Runtime +### Update Runtime Configuration -Before running the benchmarking tool, you must integrate benchmarks with your runtime as follows: +This change activates your benchmarked weights in the production runtime. Now when users submit transactions that call your pallet's extrinsics, the runtime will use the actual measured weights to calculate fees and enforce block limits. -1. Navigate to your `runtime/src` directory and check if a `benchmarks.rs` file exists. If not, create one. This file will contain the macro that registers all pallets for benchmarking along with their respective configurations: +Update your runtime configuration to use the generated weights instead of the placeholder `()` implementation: - ```rust title="benchmarks.rs" - --8<-- 'code/parachains/customize-runtime/pallet-development/benchmark-pallet/frame-benchmark-macro.rs' - ``` +```rust title="runtime/src/configs/mod.rs" +impl pallet_custom::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = pallet_custom::weights::SubstrateWeight; +} +``` - For example, to add a new pallet named `pallet_parachain_template` for benchmarking, include it in the macro as shown: - ```rust title="benchmarks.rs" hl_lines="3" - --8<-- 'code/parachains/customize-runtime/pallet-development/benchmark-pallet/frame-benchmark-macro.rs::3' - ); - ``` +### Example Generated Weight File + +The generated `weights.rs` file will look similar to this: + +```rust title="pallets/pallet-custom/src/weights.rs" +//! Autogenerated weights for `pallet_custom` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20` + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +pub trait WeightInfo { + fn set_counter_value() -> Weight; + fn increment() -> Weight; + fn decrement() -> Weight; +} + +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn set_counter_value() -> Weight { + Weight::from_parts(8_234_000, 0) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + + fn increment() -> Weight { + Weight::from_parts(12_456_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + + fn decrement() -> Weight { + Weight::from_parts(11_987_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } +} +``` - !!!warning "Updating `define_benchmarks!` macro is required" - Any pallet that needs to be benchmarked must be included in the [`define_benchmarks!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.define_benchmarks.html){target=\_blank} macro. The CLI will only be able to access and benchmark pallets that are registered here. +**Note**: The actual numbers will vary based on your hardware and implementation complexity. The [`DbWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.RuntimeDbWeight.html){target=\_blank} accounts for database read and write operations. -2. Check your runtime's `lib.rs` file to ensure the `benchmarks` module is imported. The import should look like this: +## Benchmarking Best Practices - ```rust title="lib.rs" - #[cfg(feature = "runtime-benchmarks")] - mod benchmarks; - ``` +### 1. Test Worst-Case Scenarios - The `runtime-benchmarks` feature gate ensures benchmark tests are isolated from production runtime code. +Benchmarks should always measure maximum possible resource consumption. If you benchmark average or best-case scenarios, malicious users could craft transactions that hit worst-case paths in your code, consuming more resources than the weights indicate and potentially slowing down or halting block production. -3. Enable runtime benchmarking for your pallet in `runtime/Cargo.toml`: +```rust +#[benchmark] +fn complex_operation() { + // Set up worst-case storage state + for i in 0..100 { + SomeStorage::::insert(i, vec![0u8; 1000]); + } + + let caller = whitelisted_caller(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller)); +} +``` - ```toml - --8<-- 'code/parachains/customize-runtime/pallet-development/benchmark-pallet/runtime-cargo.toml' - ``` +### 2. Use Linear Components for Variable Complexity -### Run Benchmarks +Many extrinsics have variable costs depending on input parameters. [Linear components](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/trait.BenchmarkingSetup.html){target=\_blank} tell the benchmarking framework to test your extrinsic with different values of `n`, measure the execution time for each, and calculate a formula like `Weight = base_weight + (n * per_item_weight)`. This produces dynamic weights that accurately reflect the actual work being done. -You can now compile your runtime with the `runtime-benchmarks` feature flag. This feature flag is crucial as the benchmarking tool will look for this feature being enabled to know when it should run benchmark tests. Follow these steps to compile the runtime with benchmarking enabled: +When extrinsic complexity depends on input size, use linear components: -1. Run `build` with the feature flag included: +```rust title="pallets/pallet-custom/src/benchmarking.rs" +#[benchmark] +fn process_items(n: Linear<0, 100>) { + let caller = whitelisted_caller(); + let items: Vec = (0..n).collect(); - ```bash - cargo build --features runtime-benchmarks --release - ``` + #[extrinsic_call] + _(RawOrigin::Signed(caller), items); +} +``` -2. Create a `weights.rs` file in your pallet's `src/` directory. This file will store the auto-generated weight calculations: +### 3. Verify Results - ```bash - touch weights.rs - ``` +Assertions ensure that your benchmark is actually testing the code path you think it's testing. If your extrinsic fails silently or takes an early return, the benchmark would measure the wrong scenario and produce inaccurate weights. -3. Before running the benchmarking tool, you'll need a template file that defines how weight information should be formatted. Download the official template from the Polkadot SDK repository and save it in your project folders for future use: +Always assert the expected state after extrinsic execution: - ```bash - curl https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \ - --output ./pallets/benchmarking/frame-weight-template.hbs - ``` +```rust title="pallets/pallet-custom/src/benchmarking.rs" +#[benchmark] +fn my_extrinsic() { + let caller = whitelisted_caller(); -4. Run the benchmarking tool to measure extrinsic weights: + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone())); - ```bash - frame-omni-bencher v1 benchmark pallet \ - --runtime INSERT_PATH_TO_WASM_RUNTIME \ - --pallet INSERT_NAME_OF_PALLET \ - --extrinsic "" \ - --template ./frame-weight-template.hbs \ - --output weights.rs - ``` + // Verify the extrinsic had the expected effect + assert_eq!(MyStorage::::get(&caller), expected_value); +} +``` + +### 4. Minimize Setup Code + +While the benchmarking framework tries to isolate the extrinsic execution, excessive setup code can add noise to measurements. More importantly, setup code that doesn't reflect real-world pre-conditions can lead to benchmarking unrealistic scenarios. + +Only include necessary setup in benchmarks: + +```rust title="pallets/pallet-custom/src/benchmarking.rs" +#[benchmark] +fn efficient_benchmark() { + // Minimal setup + let caller = whitelisted_caller(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller)); + + // Minimal assertions +} +``` + +## Run Your Chain Locally + +Now that you've added the pallet to your runtime, you can launch your parachain locally to test the new functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}. For instructions on setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\_blank}, refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\_blank} guide. - !!! tip "Flag definitions" - - **`--runtime`**: The path to your runtime's Wasm. - - **`--pallet`**: The name of the pallet you wish to benchmark. This pallet must be configured in your runtime and defined in `define_benchmarks`. - - **`--extrinsic`**: Which extrinsic to test. Using `""` implies all extrinsics will be benchmarked. - - **`--template`**: Defines how weight information should be formatted. - - **`--output`**: Where the output of the auto-generated weights will reside. +### Build the Production Runtime -The generated `weights.rs` file contains weight annotations for your extrinsics, ready to be added to your pallet. The output should be similar to the following. Some output is omitted for brevity: +The `runtime-benchmarks` feature flag adds special host functions (like `ext_benchmarking_current_time` and `ext_benchmarking_get_read_and_written_keys`) that are only available in the benchmarking execution environment. These functions allow the benchmarking framework to precisely measure execution time and track storage operations. However, regular nodes don't provide these host functions, so a runtime compiled with benchmarking features will fail to start on a production node. ---8<-- 'code/parachains/customize-runtime/pallet-development/benchmark-pallet/benchmark-output.html' +Before running your chain, rebuild the runtime **without** the `runtime-benchmarks` feature: -#### Add Benchmark Weights to Pallet +```bash +cargo build --release +``` + +!!! note "Build Types" + Understanding the difference between builds is critical: + + - `cargo build --release --features runtime-benchmarks` - Compiles with benchmarking host functions for measurement. Use this ONLY when running benchmarks with `frame-omni-bencher` + - `cargo build --release` - Compiles production runtime without benchmarking features. Use this for running your actual chain + +This produces a production-ready WASM runtime at `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm`. + +### Generate a Chain Specification + +The chain specification defines the initial state and configuration of your blockchain, including the runtime WASM code, genesis storage, and network parameters. By generating a new chain spec with your updated runtime (now containing your benchmarked pallet), you ensure that nodes starting from this spec will use the correct version of your code with proper weight calculations. + +Create a new chain specification file with the updated runtime: + +```bash +chain-spec-builder create -t development \ +--relay-chain paseo \ +--para-id 1000 \ +--runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ +named-preset development +``` + +This command generates a chain specification file, `chain_spec.json`, for your parachain with the updated runtime. -Once the `weights.rs` is generated, you must integrate it with your pallet. +### Start the Parachain Node -1. To begin the integration, import the `weights` module and the `WeightInfo` trait, then add both to your pallet's `Config` trait. Complete the following steps to set up the configuration: +Launch the parachain using the Polkadot Omni Node with the generated chain specification by running the following command: - ```rust title="lib.rs" - --8<-- 'code/parachains/customize-runtime/pallet-development/benchmark-pallet/weight-config.rs' - ``` +```bash +polkadot-omni-node --chain ./chain_spec.json --dev +``` -2. Next, you must add this to the `#[pallet::weight]` annotation in all the extrinsics via the `Config` as follows: +The node will start and display initialization information including: - ```rust hl_lines="2" title="lib.rs" - --8<-- 'code/parachains/customize-runtime/pallet-development/benchmark-pallet/dispatchable-pallet-weight.rs' - ``` +- The chain specification name +- The node identity and peer ID +- Database location +- Network endpoints (JSON-RPC and Prometheus) -3. Finally, configure the actual weight values in your runtime. In `runtime/src/config/mod.rs`, add the following code: +### Verify Block Production + +Once the node is running, you should see log messages indicating successful block production: + +``` +[Parachain] 🔨 Initializing Genesis block/state (state: 0x47ce…ec8d, header-hash: 0xeb12…fecc) +[Parachain] 🎁 Prepared block for proposing at 1 (3 ms) ... +[Parachain] 🏆 Imported #1 (0xeb12…fecc → 0xee51…98d2) +[Parachain] 🎁 Prepared block for proposing at 2 (3 ms) ... +[Parachain] 🏆 Imported #2 (0xee51…98d2 → 0x35e0…cc32) +``` - ```rust title="mod.rs" - --8<-- 'code/parachains/customize-runtime/pallet-development/benchmark-pallet/runtime-pallet-config.rs' - ``` +The parachain will produce new blocks every few seconds. You can now interact with your pallet's extrinsics through the JSON-RPC endpoint at `http://127.0.0.1:9944` using tools like [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\_blank}. -## Where to Go Next +## Related Resources -- View the Rust Docs for a more comprehensive, low-level view of the [FRAME V2 Benchmarking Suite](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=_blank}. -- Read the [FRAME Benchmarking and Weights](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_benchmarking_weight/index.html){target=_blank} reference document, a concise guide which details how weights and benchmarking work. +- [FRAME Benchmarking Documentation](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/index.html){target=\_blank} +- [Weight Struct Documentation](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html){target=\_blank} +- [Benchmarking v2 API](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank} +- [frame-omni-bencher Tool](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} diff --git a/parachains/customize-runtime/pallet-development/create-a-pallet.md b/parachains/customize-runtime/pallet-development/create-a-pallet.md index 26d75c2b8..f86b7b83b 100644 --- a/parachains/customize-runtime/pallet-development/create-a-pallet.md +++ b/parachains/customize-runtime/pallet-development/create-a-pallet.md @@ -340,7 +340,7 @@ This command validates all pallet configurations and prepares the build for depl ## Run Your Chain Locally -Launch your parachain locally to test the new pallet functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}. +Launch your parachain locally to test the new pallet functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}. For instructions on setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\_blank}, refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\_blank} guide. ### Generate a Chain Specification From 6b7cbecb07b54aab6ecc95e1aa69796372febaf3 Mon Sep 17 00:00:00 2001 From: DAWN KELLY Date: Tue, 18 Nov 2025 13:37:00 -0500 Subject: [PATCH 2/4] cleanup and grammarly --- .../pallet-development/.nav.yml | 2 +- .../pallet-development/benchmark-pallet.md | 590 +++++++----------- .../pallet-development/pallet-testing.md | 4 +- 3 files changed, 212 insertions(+), 384 deletions(-) diff --git a/parachains/customize-runtime/pallet-development/.nav.yml b/parachains/customize-runtime/pallet-development/.nav.yml index a6c7e9399..43f919978 100644 --- a/parachains/customize-runtime/pallet-development/.nav.yml +++ b/parachains/customize-runtime/pallet-development/.nav.yml @@ -1,6 +1,6 @@ nav: - 'Create a Custom Pallet': create-a-pallet.md - 'Mock Your Runtime': mock-runtime.md - - 'Pallet Unit Testing': pallet-testing.md + - 'Unit Test Pallets': pallet-testing.md - 'Add a Custom Pallet to Your Runtime': add-pallet-to-runtime.md - 'Benchmark a Custom Pallet': benchmark-pallet.md \ No newline at end of file diff --git a/parachains/customize-runtime/pallet-development/benchmark-pallet.md b/parachains/customize-runtime/pallet-development/benchmark-pallet.md index 9eae75314..092b8d6e1 100644 --- a/parachains/customize-runtime/pallet-development/benchmark-pallet.md +++ b/parachains/customize-runtime/pallet-development/benchmark-pallet.md @@ -8,42 +8,23 @@ categories: Parachains Benchmarking is the process of measuring the computational resources (execution time and storage) required by your pallet's extrinsics. Accurate [weight](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/index.html){target=\_blank} calculations are essential for ensuring your blockchain can process transactions efficiently while protecting against denial-of-service attacks. -This guide continues the pallet development series, building on the [Create a Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet), [Mock Your Runtime](/parachains/customize-runtime/pallet-development/mock-runtime), and [Test Your Pallet](/parachains/customize-runtime/pallet-development/pallet-testing) tutorials. You'll learn how to benchmark the counter pallet extrinsics and integrate the generated weights into your runtime. +This guide continues building on what you've learned through the pallet development series. You'll learn how to benchmark the custom counter pallet extrinsics and integrate the generated weights into your runtime. ## Prerequisites Before you begin, ensure you have: -- Completed the previous pallet development tutorials -- Basic understanding of computational complexity -- Familiarity with Rust's testing framework +- Completed the previous pallet development tutorials: + - [Create a Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet/){target=\_blank} + - [Mock Your Runtime](/parachains/customize-runtime/pallet-development/mock-runtime/){target=\_blank} + - [Unit Test Pallets](/parachains/customize-runtime/pallet-development/pallet-testing/){target=\_blank} +- Basic understanding of [computational complexity](https://en.wikipedia.org/wiki/Computational_complexity){target=\_blank}. +- Familiarity with [Rust's testing framework](https://doc.rust-lang.org/book/ch11-00-testing.html){target=\_blank}. +- Familiarity setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\_blank}. Refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\_blank} guide for instructions if needed. -## Why Benchmark? +## Create the Benchmarking Module -In blockchain systems, every operation consumes resources. Weight is the mechanism Polkadot SDK uses to measure and limit resource consumption. Without accurate weights: - -- **Security Risk**: Malicious actors could submit transactions that consume excessive resources, blocking legitimate transactions or halting the chain -- **Inefficiency**: Over-estimated weights waste block space and reduce throughput -- **User Experience**: Inaccurate weights lead to incorrect fee calculations - -Benchmarking provides empirical measurements of your extrinsics under various conditions, ensuring weights reflect real-world resource consumption. - -## Understanding Weights - -The [weight system](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html){target=\_blank} serves multiple purposes: - -- **DoS Protection**: Limits the computational work per block, preventing attackers from overwhelming the network -- **Fee Calculation**: Determines transaction fees based on actual resource usage -- **Block Production**: Helps block authors maximize throughput while staying within block limits - -Weights are expressed as [`Weight::from_parts(ref_time, proof_size)`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.from_parts){target=\_blank} where: - -- [`ref_time`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.ref_time){target=\_blank}: Computational time measured in picoseconds -- [`proof_size`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.proof_size){target=\_blank}: Storage proof size in bytes - -## Step 1: Create the Benchmarking Module - -Create a new file `benchmarking.rs` in your pallet's `src` directory. This module will contain all the [benchmarking definitions](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank} for your pallet: +Create a new file `benchmarking.rs` in your pallet's `src` directory and add the following code: ```rust title="pallets/pallet-custom/src/benchmarking.rs" #![cfg(feature = "runtime-benchmarks")] @@ -80,7 +61,7 @@ mod benchmarks { #[benchmark] fn decrement() { - // First set the counter to a non-zero value + // First, set the counter to a non-zero value CounterValue::::put(100); let caller: T::AccountId = whitelisted_caller(); @@ -97,20 +78,11 @@ mod benchmarks { } ``` -**Key components:** +This module contains all the [benchmarking definitions](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank} for your pallet. -- **`#![cfg(feature = "runtime-benchmarks")]`**: Ensures benchmarking code only compiles when the feature is enabled -- **[`#[benchmarks]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmarks.html){target=\_blank}**: Marks the module containing benchmark definitions -- **[`#[benchmark]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmark.html){target=\_blank}**: Defines individual benchmark functions -- **[`#[extrinsic_call]`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.extrinsic_call.html){target=\_blank}**: Marks the actual extrinsic invocation to measure -- **[`whitelisted_caller()`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/fn.whitelisted_caller.html){target=\_blank}**: Generates a funded account for benchmarking -- **[`impl_benchmark_test_suite!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.impl_benchmark_test_suite.html){target=\_blank}**: Generates test functions to verify benchmarks work correctly +## Define the Weight Trait -## Step 2: Define the Weight Trait - -The [`WeightInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/trait.WeightInfo.html){target=\_blank} trait provides an abstraction layer that allows weights to be swapped at runtime configuration. This enables you to use placeholder weights during development and testing, then switch to auto-generated benchmarked weights in production without modifying the pallet code itself. - -Add a `weights` module to your pallet that defines the `WeightInfo` trait: +Add a `weights` module to your pallet that defines the `WeightInfo` trait using the following code: ```rust title="pallets/pallet-custom/src/lib.rs" #[frame::pallet] @@ -144,13 +116,11 @@ pub mod pallet { } ``` -The `()` implementation provides placeholder weights for development. Later, this will be replaced with auto-generated weights from benchmarking. +The `()` implementation provides placeholder weights for development. -## Step 3: Add WeightInfo to Config +## Add WeightInfo to Config -By making `WeightInfo` an associated type in the `Config` trait, you allow each runtime that uses your pallet to specify which weight implementation to use. Different deployment environments (testnets, production chains, or different hardware configurations) may have different performance characteristics and can use different weight calculations. - -Update your pallet's `Config` trait to include `WeightInfo`: +Update your pallet's `Config` trait to include `WeightInfo` by adding the following code: ```rust title="pallets/pallet-custom/src/lib.rs" #[pallet::config] @@ -164,11 +134,11 @@ pub trait Config: frame_system::Config { } ``` -## Step 4: Update Extrinsic Weight Annotations +The [`WeightInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/trait.WeightInfo.html){target=\_blank} trait provides an abstraction layer that allows weights to be swapped at runtime configuration. By making `WeightInfo` an associated type in the `Config` trait, you will enable each runtime that uses your pallet to specify which weight implementation to use. -By calling `T::WeightInfo::function_name()` instead of using hardcoded `Weight::from_parts()` values, your extrinsics automatically use whichever weight implementation is configured in the runtime. This allows you to easily switch between placeholder weights for testing and benchmarked weights for production without changing any pallet code. +## Update Extrinsic Weight Annotations -Replace the placeholder weights in your extrinsics with calls to the `WeightInfo` trait: +Replace the placeholder weights in your extrinsics with calls to the `WeightInfo` trait by adding the following code: ```rust title="pallets/pallet-custom/src/lib.rs" #[pallet::call] @@ -193,11 +163,11 @@ impl Pallet { } ``` -## Step 5: Include the Benchmarking Module +By calling `T::WeightInfo::function_name()` instead of using hardcoded `Weight::from_parts()` values, your extrinsics automatically use whichever weight implementation is configured in the runtime. You can switch between placeholder weights for testing and benchmarked weights for production easily, without changing any pallet code. -The `#[cfg(feature = "runtime-benchmarks")]` attribute ensures that benchmarking code is only compiled when explicitly needed. This keeps your production runtime lean by excluding benchmarking infrastructure from normal builds, as it's only needed when generating weights. +## Include the Benchmarking Module -At the top of your `lib.rs`, add the module declaration: +At the top of your `lib.rs`, add the module declaration by adding the following code: ```rust title="pallets/pallet-custom/src/lib.rs" #![cfg_attr(not(feature = "std"), no_std)] @@ -210,14 +180,14 @@ pub use pallet::*; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; -// ... rest of the pallet +// Additional pallet code ``` -## Step 6: Configure Pallet Dependencies +The `#[cfg(feature = "runtime-benchmarks")]` attribute ensures that benchmarking code is only compiled when explicitly needed to keep your production runtime efficient. -The feature flag system in Cargo allows you to conditionally compile code based on which features are enabled. By defining a `runtime-benchmarks` feature that cascades to FRAME's benchmarking features, you create a clean way to build your pallet with or without benchmarking support, ensuring all necessary dependencies are available when needed but excluded from production builds. +## Configure Pallet Dependencies -Update your pallet's `Cargo.toml` to enable the benchmarking feature: +Update your pallet's `Cargo.toml` to enable the benchmarking feature by adding the following code: ```toml title="pallets/pallet-custom/Cargo.toml" [dependencies] @@ -237,11 +207,11 @@ std = [ ] ``` -## Step 7: Update Mock Runtime +The Cargo feature flag system lets you conditionally compile code based on which features are enabled. By defining a `runtime-benchmarks` feature that cascades to FRAME's benchmarking features, you create a clean way to build your pallet with or without benchmarking support, ensuring all necessary dependencies are available when needed but excluded from production builds. -In your mock runtime for testing, use the placeholder `()` implementation of `WeightInfo` since unit tests focus on verifying functional correctness rather than performance characteristics. This keeps tests fast and focused on validating logic. +## Update Mock Runtime -Add the `WeightInfo` type to your test configuration in `mock.rs`: +Add the `WeightInfo` type to your test configuration in `mock.rs` by adding the following code: ```rust title="pallets/pallet-custom/src/mock.rs" impl pallet_custom::Config for Test { @@ -251,427 +221,285 @@ impl pallet_custom::Config for Test { } ``` -## Step 8: Configure Runtime Benchmarking - -To execute benchmarks, your pallet must be integrated into the runtime's benchmarking infrastructure. This involves three configuration steps: +In your mock runtime for testing, use the placeholder `()` implementation of `WeightInfo`, since unit tests focus on verifying functional correctness rather than performance. -### Update Runtime Cargo.toml +## Configure Runtime Benchmarking -When you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included. +To execute benchmarks, your pallet must be integrated into the runtime's benchmarking infrastructure. Follow these steps to update the runtime configuration: -Add your pallet to the runtime's `runtime-benchmarks` feature in `runtime/Cargo.toml`: - -```toml title="runtime/Cargo.toml" -runtime-benchmarks = [ - "cumulus-pallet-parachain-system/runtime-benchmarks", - "hex-literal", - "pallet-parachain-template/runtime-benchmarks", - "polkadot-sdk/runtime-benchmarks", - "pallet-custom/runtime-benchmarks", -] -``` +1. **Update `runtime/Cargo.toml`**: Add your pallet to the runtime's `runtime-benchmarks` feature as follows: -### Update Runtime Configuration + ```toml title="runtime/Cargo.toml" + runtime-benchmarks = [ + "cumulus-pallet-parachain-system/runtime-benchmarks", + "hex-literal", + "pallet-parachain-template/runtime-benchmarks", + "polkadot-sdk/runtime-benchmarks", + "pallet-custom/runtime-benchmarks", + ] + ``` -Start with the placeholder implementation during development. After successfully running benchmarks and generating the weights file, you'll update this to use the benchmarked weights. + When you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included. -In `runtime/src/configs/mod.rs`, add the `WeightInfo` type: +2. **Update runtime configuration**: Run development benchmarks with the placeholder implementation and use the resulting weights file to update benchmark weights as follows: -```rust title="runtime/src/configs/mod.rs" -impl pallet_custom::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type CounterMaxValue = ConstU32<1000>; - type WeightInfo = (); -} -``` - -### Register Benchmarks - -The `define_benchmarks!` macro creates the infrastructure that allows the benchmarking CLI tool to discover and execute your pallet's benchmarks. - -Add your pallet to the benchmark list in `runtime/src/benchmarks.rs`: + ```rust title="runtime/src/configs/mod.rs" + impl pallet_custom::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = (); + } + ``` -```rust title="runtime/src/benchmarks.rs" -polkadot_sdk::frame_benchmarking::define_benchmarks!( - [frame_system, SystemBench::] - [pallet_balances, Balances] - // ... other pallets - [pallet_custom, CustomPallet] -); -``` +3. **Register benchmarks**: Add your pallet to the benchmark list in `runtime/src/benchmarks.rs` as follows: -## Step 9: Run Benchmarks + ```rust title="runtime/src/benchmarks.rs" + polkadot_sdk::frame_benchmarking::define_benchmarks!( + [frame_system, SystemBench::] + [pallet_balances, Balances] + // ... other pallets + [pallet_custom, CustomPallet] + ); + ``` -### Test Benchmark Compilation + The [`define_benchmarks!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.define_benchmarks.html){target=\_blank} macro creates the infrastructure that allows the benchmarking CLI tool to discover and execute your pallet's benchmarks. -The `impl_benchmark_test_suite!` macro generates unit tests for each benchmark. Running these tests verifies that your benchmarks compile correctly, execute without panicking, and pass their assertions, catching issues early before building the full runtime. +## Test Benchmark Compilation -First, verify your benchmarks compile and run as tests: +Run the following command to verify your benchmarks compile and run as tests: ```bash cargo test -p pallet-custom --features runtime-benchmarks ``` -You should see your benchmark tests passing: +You will see terminal output similar to the following as your benchmark tests pass: -``` -test benchmarking::benchmarks::bench_set_counter_value ... ok -test benchmarking::benchmarks::bench_increment ... ok -test benchmarking::benchmarks::bench_decrement ... ok -``` +
+ cargo test -p pallet-custom --features runtime-benchmarks + test benchmarking::benchmarks::bench_set_counter_value ... ok + test benchmarking::benchmarks::bench_increment ... ok + test benchmarking::benchmarks::bench_decrement ... ok + +
-### Build the Runtime with Benchmarks +The `impl_benchmark_test_suite!` macro generates unit tests for each benchmark. Running these tests verifies that your benchmarks compile correctly, execute without panicking, and pass their assertions, catching issues early before building the entire runtime. -This build includes all the benchmarking infrastructure and special host functions needed for measurement. The resulting WASM runtime contains your benchmark code and can communicate with the benchmarking tool's execution environment. This is a special build used only for benchmarking - you'll create a different build later for actually running your chain. +## Build the Runtime with Benchmarks -Compile the runtime with benchmarking enabled to generate the WASM binary: +Compile the runtime with benchmarking enabled to generate the WASM binary using the following command: ```bash cargo build --release --features runtime-benchmarks ``` -This produces the runtime WASM file needed for benchmarking, typically located at: -``` -target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm -``` +This command produces the runtime WASM file needed for benchmarking, typically located at: `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm` -### Install the Benchmarking Tool +The build includes all the benchmarking infrastructure and special host functions needed for measurement. The resulting WASM runtime contains your benchmark code and can communicate with the benchmarking tool's execution environment. You'll create a different build later for operating your chain in production. -[`frame-omni-bencher`](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} is the official Polkadot SDK tool specifically designed for FRAME pallet benchmarking. It provides a standardized way to execute benchmarks, measure execution times and storage operations, and generate properly formatted weight files with full integration into the FRAME weight system. +## Install the Benchmarking Tool -Install the `frame-omni-bencher` CLI tool: +Install the `frame-omni-bencher` CLI tool using the following command: ```bash cargo install frame-omni-bencher --locked ``` -### Download the Weight Template +[`frame-omni-bencher`](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} is the official Polkadot SDK tool designed explicitly for FRAME pallet benchmarking. It provides a standardized way to execute benchmarks, measure execution times and storage operations, and generate properly formatted weight files with full integration into the FRAME weight system. -The weight template is a Handlebars file that transforms raw benchmark data into a properly formatted Rust source file. It defines the structure of the generated `weights.rs` file, including imports, trait definitions, documentation comments, and formatting. Using the official template ensures your weight files follow Polkadot SDK conventions and include all necessary metadata like benchmark execution parameters, storage operation counts, and hardware information. +## Download the Weight Template -Download the official weight template file: +Download the official weight template file using the following commands: ```bash curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \ --output ./pallets/pallet-custom/frame-weight-template.hbs ``` -### Hardware Requirements for Benchmarking - -!!! warning "Critical: Benchmark on Production-Like Hardware" - Benchmarks must be executed on hardware similar to what will run your chain in production. Weight measurements are hardware-dependent, and benchmarking on different hardware can lead to dangerous under-estimation or wasteful over-estimation of weights. - -Weights represent the actual computational time and resources consumed by extrinsics. These measurements vary significantly across different hardware configurations: - -- **CPU Performance**: Different processors execute instructions at different speeds. A faster development laptop will produce lower weight values than production server hardware -- **Storage Speed**: Database read/write performance varies between NVMe SSDs, SATA SSDs, and HDDs, affecting storage-related weights -- **Memory Bandwidth**: RAM speed impacts how quickly data can be accessed during execution -- **CPU Cache**: Cache size and architecture differences affect repeated operations - -Benchmarking on faster hardware than production leads to under-estimated weights - attackers could submit extrinsics that consume more resources than the weights suggest, potentially causing blocks to take longer than expected to produce or even halting the chain. Conversely, benchmarking on slower hardware creates over-estimated weights, resulting in unnecessarily high transaction fees and wasted block capacity. - -**Best practices:** - -1. **Match production specifications**: If your chain will run on specific validator hardware, benchmark on identical or very similar machines -2. **Use reference hardware**: The Polkadot ecosystem often uses standardized reference hardware specifications for consistency. Consider following these standards if your chain will connect to Polkadot or Kusama -3. **Dedicated benchmarking environment**: Run benchmarks on a machine without other heavy processes to ensure consistent measurements -4. **Document your hardware**: The generated weight files include hardware information in comments. Review this to ensure it matches your production environment -5. **Re-benchmark when hardware changes**: If your validator hardware specifications change, re-run benchmarks and update weights - -For development and testing purposes, you can run benchmarks on any available hardware to verify that your benchmark functions work correctly. However, before deploying to production, always re-run benchmarks on production-equivalent hardware. - -### Execute Benchmarks - -Benchmarks execute against the compiled WASM runtime rather than native code because WASM is what actually runs in production on the blockchain. WASM execution can have different performance characteristics than native code due to compilation and sandboxing overhead, so benchmarking the WASM ensures your weight measurements reflect real-world conditions. - -Run benchmarks for your pallet to generate weight files: - -```bash -frame-omni-bencher v1 benchmark pallet \ - --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ - --pallet pallet_custom \ - --extrinsic "" \ - --template ./pallets/pallet-custom/frame-weight-template.hbs \ - --output ./pallets/pallet-custom/src/weights.rs -``` - -**Command breakdown:** - -- `v1`: Specifies the benchmarking framework version (v2 API) -- `benchmark pallet`: Subcommand indicating you want to benchmark pallet extrinsics -- `--runtime`: Path to the compiled WASM runtime file that includes your pallet and benchmarks -- `--pallet pallet_custom`: Name of the pallet to benchmark (must match the name used in `define_benchmarks!`) -- `--extrinsic ""`: Empty string benchmarks all extrinsics in the pallet; you can specify a single extrinsic name to benchmark only that one -- `--template`: Path to the Handlebars template that formats the output -- `--output`: Destination file path for the generated weights module +The weight template is a Handlebars file that transforms raw benchmark data into a correctly formatted Rust source file. It defines the structure of the generated `weights.rs` file, including imports, trait definitions, documentation comments, and formatting. Using the official template ensures your weight files follow the Polkadot SDK conventions and include all necessary metadata, such as benchmark execution parameters, storage operation counts, and hardware information. -### Advanced Options +## Execute Benchmarks -You can customize benchmark execution with additional parameters for more detailed measurements: +Run benchmarks for your pallet to generate weight files using the following commands: ```bash frame-omni-bencher v1 benchmark pallet \ --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ --pallet pallet_custom \ --extrinsic "" \ - --steps 50 \ - --repeat 20 \ --template ./pallets/pallet-custom/frame-weight-template.hbs \ --output ./pallets/pallet-custom/src/weights.rs ``` -**Additional parameters:** +Benchmarks execute against the compiled WASM runtime rather than native code because WASM is what actually runs in production on the blockchain. WASM execution can have different performance characteristics than native code due to compilation and sandboxing overhead, so benchmarking against the WASM ensures your weight measurements reflect real-world conditions. -- `--steps 50`: Number of different input values to test when using linear components (default: 50). More steps provide finer granularity for detecting complexity trends but increase benchmarking time -- `--repeat 20`: Number of repetitions for each measurement (default: 20). More repetitions improve statistical accuracy by averaging out variance, reducing the impact of system noise and providing more reliable weight estimates -- `--heap-pages 4096`: WASM heap pages allocation. Affects available memory during execution -- `--wasm-execution compiled`: WASM execution method. Use `compiled` for performance closest to production conditions +??? note "Additional customization" -## Step 10: Use Generated Weights + You can customize benchmark execution with additional parameters for more detailed measurements, as shown in the sample code below: -After running benchmarks, a `weights.rs` file is generated containing measured weights. The generated weights are based on actual measurements of your code running on real hardware, accounting for the specific complexity of your logic, storage access patterns, and computational requirements. Estimates or placeholder values cannot capture these nuances and will either waste block space (over-estimation) or create security risks (under-estimation). + ```bash + frame-omni-bencher v1 benchmark pallet \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ + --pallet pallet_custom \ + --extrinsic "" \ + --steps 50 \ + --repeat 20 \ + --template ./pallets/pallet-custom/frame-weight-template.hbs \ + --output ./pallets/pallet-custom/src/weights.rs + ``` + + - `--steps 50`: Number of different input values to test when using linear components (default: 50). More steps provide finer granularity for detecting complexity trends but increase benchmarking time. + - `--repeat 20`: Number of repetitions for each measurement (default: 20). More repetitions improve statistical accuracy by averaging out variance, reducing the impact of system noise, and providing more reliable weight estimates. + - `--heap-pages 4096`: WASM heap pages allocation. Affects available memory during execution. + - `--wasm-execution compiled`: WASM execution method. Use `compiled` for performance closest to production conditions. -The file includes: +## Use Generated Weights -- Detailed documentation about the benchmark execution environment (date, hardware, parameters) -- The `WeightInfo` trait definition matching your benchmark functions -- `SubstrateWeight` implementation with measured weights from your benchmarks -- Database read/write costs calculated based on observed storage operations -- Component complexity annotations for variable inputs (if you use linear components) -- A fallback `()` implementation for testing environments +After running benchmarks, a `weights.rs` file is generated containing measured weights based on actual measurements of your code running on real hardware, accounting for the specific complexity of your logic, storage access patterns, and computational requirements. -### Integrate the Generated Weights +Follow these steps to use the generated weights with your pallet: -Unlike the benchmarking module (which is only needed when running benchmarks), the weights module must be available in all builds because the runtime needs to call the weight functions during normal operation to calculate transaction fees and enforce block limits. +1. Integrate the generated weights by adding the weights module to your pallet's `lib.rs` as follows: -Add the weights module to your pallet's `lib.rs`: - -```rust title="pallets/pallet-custom/src/lib.rs" -#![cfg_attr(not(feature = "std"), no_std)] + ```rust title="pallets/pallet-custom/src/lib.rs" + #![cfg_attr(not(feature = "std"), no_std)] -extern crate alloc; -use alloc::vec::Vec; + extern crate alloc; + use alloc::vec::Vec; -pub use pallet::*; + pub use pallet::*; -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; + #[cfg(feature = "runtime-benchmarks")] + mod benchmarking; -pub mod weights; + pub mod weights; -#[frame::pallet] -pub mod pallet { - use super::*; - use frame::prelude::*; - use crate::weights::WeightInfo; - // ... rest of pallet -} -``` - -### Update Runtime Configuration - -This change activates your benchmarked weights in the production runtime. Now when users submit transactions that call your pallet's extrinsics, the runtime will use the actual measured weights to calculate fees and enforce block limits. - -Update your runtime configuration to use the generated weights instead of the placeholder `()` implementation: - -```rust title="runtime/src/configs/mod.rs" -impl pallet_custom::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type CounterMaxValue = ConstU32<1000>; - type WeightInfo = pallet_custom::weights::SubstrateWeight; -} -``` - -### Example Generated Weight File - -The generated `weights.rs` file will look similar to this: - -```rust title="pallets/pallet-custom/src/weights.rs" -//! Autogenerated weights for `pallet_custom` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20` - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use core::marker::PhantomData; - -pub trait WeightInfo { - fn set_counter_value() -> Weight; - fn increment() -> Weight; - fn decrement() -> Weight; -} - -pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { - fn set_counter_value() -> Weight { - Weight::from_parts(8_234_000, 0) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) - } - - fn increment() -> Weight { - Weight::from_parts(12_456_000, 0) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } - - fn decrement() -> Weight { - Weight::from_parts(11_987_000, 0) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) + #[frame::pallet] + pub mod pallet { + use super::*; + use frame::prelude::*; + use crate::weights::WeightInfo; + // ... rest of pallet } -} -``` - -**Note**: The actual numbers will vary based on your hardware and implementation complexity. The [`DbWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.RuntimeDbWeight.html){target=\_blank} accounts for database read and write operations. + ``` -## Benchmarking Best Practices + Unlike the benchmarking module (which is only needed when running benchmarks), the weights module must be available in all builds because the runtime needs to call the weight functions during regular operation to calculate transaction fees and enforce block limits. -### 1. Test Worst-Case Scenarios +2. Update your runtime configuration to use the generated weights instead of the placeholder `()` implementation by adding the following code: -Benchmarks should always measure maximum possible resource consumption. If you benchmark average or best-case scenarios, malicious users could craft transactions that hit worst-case paths in your code, consuming more resources than the weights indicate and potentially slowing down or halting block production. - -```rust -#[benchmark] -fn complex_operation() { - // Set up worst-case storage state - for i in 0..100 { - SomeStorage::::insert(i, vec![0u8; 1000]); + ```rust title="runtime/src/configs/mod.rs" + impl pallet_custom::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = pallet_custom::weights::SubstrateWeight; } + ``` - let caller = whitelisted_caller(); - - #[extrinsic_call] - _(RawOrigin::Signed(caller)); -} -``` - -### 2. Use Linear Components for Variable Complexity + This change activates your benchmarked weights in the production runtime. Now, when users submit transactions that call your pallet's extrinsics, the runtime will use the actual measured weights to calculate fees and enforce block limits. -Many extrinsics have variable costs depending on input parameters. [Linear components](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/trait.BenchmarkingSetup.html){target=\_blank} tell the benchmarking framework to test your extrinsic with different values of `n`, measure the execution time for each, and calculate a formula like `Weight = base_weight + (n * per_item_weight)`. This produces dynamic weights that accurately reflect the actual work being done. +??? code "Example generated weight file" + + The generated `weights.rs` file will look similar to this: -When extrinsic complexity depends on input size, use linear components: + ```rust title="pallets/pallet-custom/src/weights.rs" + //! Autogenerated weights for `pallet_custom` + //! + //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 + //! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20` -```rust title="pallets/pallet-custom/src/benchmarking.rs" -#[benchmark] -fn process_items(n: Linear<0, 100>) { - let caller = whitelisted_caller(); - let items: Vec = (0..n).collect(); + #![cfg_attr(rustfmt, rustfmt_skip)] + #![allow(unused_parens)] + #![allow(unused_imports)] + #![allow(missing_docs)] - #[extrinsic_call] - _(RawOrigin::Signed(caller), items); -} -``` + use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; + use core::marker::PhantomData; -### 3. Verify Results - -Assertions ensure that your benchmark is actually testing the code path you think it's testing. If your extrinsic fails silently or takes an early return, the benchmark would measure the wrong scenario and produce inaccurate weights. - -Always assert the expected state after extrinsic execution: - -```rust title="pallets/pallet-custom/src/benchmarking.rs" -#[benchmark] -fn my_extrinsic() { - let caller = whitelisted_caller(); - - #[extrinsic_call] - _(RawOrigin::Signed(caller.clone())); - - // Verify the extrinsic had the expected effect - assert_eq!(MyStorage::::get(&caller), expected_value); -} -``` - -### 4. Minimize Setup Code - -While the benchmarking framework tries to isolate the extrinsic execution, excessive setup code can add noise to measurements. More importantly, setup code that doesn't reflect real-world pre-conditions can lead to benchmarking unrealistic scenarios. + pub trait WeightInfo { + fn set_counter_value() -> Weight; + fn increment() -> Weight; + fn decrement() -> Weight; + } -Only include necessary setup in benchmarks: + pub struct SubstrateWeight(PhantomData); + impl WeightInfo for SubstrateWeight { + fn set_counter_value() -> Weight { + Weight::from_parts(8_234_000, 0) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } -```rust title="pallets/pallet-custom/src/benchmarking.rs" -#[benchmark] -fn efficient_benchmark() { - // Minimal setup - let caller = whitelisted_caller(); + fn increment() -> Weight { + Weight::from_parts(12_456_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } - #[extrinsic_call] - _(RawOrigin::Signed(caller)); + fn decrement() -> Weight { + Weight::from_parts(11_987_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + } + ``` - // Minimal assertions -} -``` + The actual numbers in your `weights.rs` file will vary based on your hardware and implementation complexity. The [`DbWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.RuntimeDbWeight.html){target=\_blank} accounts for database read and write operations. ## Run Your Chain Locally -Now that you've added the pallet to your runtime, you can launch your parachain locally to test the new functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}. For instructions on setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\_blank}, refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\_blank} guide. - -### Build the Production Runtime - -The `runtime-benchmarks` feature flag adds special host functions (like `ext_benchmarking_current_time` and `ext_benchmarking_get_read_and_written_keys`) that are only available in the benchmarking execution environment. These functions allow the benchmarking framework to precisely measure execution time and track storage operations. However, regular nodes don't provide these host functions, so a runtime compiled with benchmarking features will fail to start on a production node. - -Before running your chain, rebuild the runtime **without** the `runtime-benchmarks` feature: - -```bash -cargo build --release -``` - -!!! note "Build Types" - Understanding the difference between builds is critical: - - - `cargo build --release --features runtime-benchmarks` - Compiles with benchmarking host functions for measurement. Use this ONLY when running benchmarks with `frame-omni-bencher` - - `cargo build --release` - Compiles production runtime without benchmarking features. Use this for running your actual chain +Now that you've added the pallet to your runtime, you can follow these steps to launch your parachain locally to test the new functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}: -This produces a production-ready WASM runtime at `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm`. +1. Before running your chain, rebuild the production runtime without the `runtime-benchmarks` feature using the following command: -### Generate a Chain Specification + ```bash + cargo build --release + ``` -The chain specification defines the initial state and configuration of your blockchain, including the runtime WASM code, genesis storage, and network parameters. By generating a new chain spec with your updated runtime (now containing your benchmarked pallet), you ensure that nodes starting from this spec will use the correct version of your code with proper weight calculations. + The `runtime-benchmarks` feature flag adds special host functions that are only available in the benchmarking execution environment. A runtime compiled with benchmarking features will fail to start on a production node. -Create a new chain specification file with the updated runtime: + This build produces a production-ready WASM runtime at `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm`. -```bash -chain-spec-builder create -t development \ ---relay-chain paseo \ ---para-id 1000 \ ---runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ -named-preset development -``` + !!! note "Compare build types" + - `cargo build --release --features runtime-benchmarks` - Compiles with benchmarking host functions for measurement. Use this ONLY when running benchmarks with `frame-omni-bencher`. + - `cargo build --release` - Compiles production runtime without benchmarking features. Use this for running your chain in production. -This command generates a chain specification file, `chain_spec.json`, for your parachain with the updated runtime. +2. Generate a new chain specification file with the updated runtime using the following commands: -### Start the Parachain Node + ```bash + chain-spec-builder create -t development \ + --relay-chain paseo \ + --para-id 1000 \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ + named-preset development + ``` -Launch the parachain using the Polkadot Omni Node with the generated chain specification by running the following command: + This command generates a chain specification file, `chain_spec.json`, for your parachain with the updated runtime, which defines the initial state and configuration of your blockchain, including the runtime WASM code, genesis storage, and network parameters. Generating this new chain spec with your updated runtime ensures nodes starting from this spec will use the correct version of your code with proper weight calculations. -```bash -polkadot-omni-node --chain ./chain_spec.json --dev -``` +3. Start the parachain node using the Polkadot Omni Node with the generated chain specification by running the following command: -The node will start and display initialization information including: + ```bash + polkadot-omni-node --chain ./chain_spec.json --dev + ``` -- The chain specification name -- The node identity and peer ID -- Database location -- Network endpoints (JSON-RPC and Prometheus) + The node will start and display initialization information, including: -### Verify Block Production + - The chain specification name + - The node identity and peer ID + - Database location + - Network endpoints (JSON-RPC and Prometheus) -Once the node is running, you should see log messages indicating successful block production: +4. Once the node is running, you will see log messages confirming successful production of blocks similar to the following: -``` -[Parachain] 🔨 Initializing Genesis block/state (state: 0x47ce…ec8d, header-hash: 0xeb12…fecc) -[Parachain] 🎁 Prepared block for proposing at 1 (3 ms) ... -[Parachain] 🏆 Imported #1 (0xeb12…fecc → 0xee51…98d2) -[Parachain] 🎁 Prepared block for proposing at 2 (3 ms) ... -[Parachain] 🏆 Imported #2 (0xee51…98d2 → 0x35e0…cc32) -``` +
+ polkadot-omni-node --chain ./chain_spec.json --dev + [Parachain] 🔨 Initializing Genesis block/state (state: 0x47ce…ec8d, header-hash: 0xeb12…fecc) + [Parachain] 🎁 Prepared block for proposing at 1 (3 ms) ... + [Parachain] 🏆 Imported #1 (0xeb12…fecc → 0xee51…98d2) + [Parachain] 🎁 Prepared block for proposing at 2 (3 ms) ... + [Parachain] 🏆 Imported #2 (0xee51…98d2 → 0x35e0…cc32) + +
-The parachain will produce new blocks every few seconds. You can now interact with your pallet's extrinsics through the JSON-RPC endpoint at `http://127.0.0.1:9944` using tools like [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\_blank}. + The parachain will produce new blocks every few seconds. You can now interact with your pallet's extrinsics through the JSON-RPC endpoint at `http://127.0.0.1:9944` using tools like [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\_blank}. ## Related Resources diff --git a/parachains/customize-runtime/pallet-development/pallet-testing.md b/parachains/customize-runtime/pallet-development/pallet-testing.md index 6dc75eb5e..816a2401a 100644 --- a/parachains/customize-runtime/pallet-development/pallet-testing.md +++ b/parachains/customize-runtime/pallet-development/pallet-testing.md @@ -1,10 +1,10 @@ --- -title: Pallet Testing +title: Unit Test Pallets description: Learn how to efficiently test pallets in the Polkadot SDK, ensuring the reliability and security of your pallets operations. categories: Parachains --- -# Pallet Testing +# Unit Test Pallets ## Introduction From c876bcef289d1157019a3a9c6cf48fd5dac70647 Mon Sep 17 00:00:00 2001 From: DAWN KELLY Date: Tue, 18 Nov 2025 13:42:01 -0500 Subject: [PATCH 3/4] fresh llms --- .ai/categories/parachains.md | 868 +++++++----------- ...ime-pallet-development-benchmark-pallet.md | 590 +++++------- ...ntime-pallet-development-pallet-testing.md | 4 +- llms-full.jsonl | 70 +- llms.txt | 2 +- 5 files changed, 585 insertions(+), 949 deletions(-) diff --git a/.ai/categories/parachains.md b/.ai/categories/parachains.md index 94700e0e8..309865038 100644 --- a/.ai/categories/parachains.md +++ b/.ai/categories/parachains.md @@ -1336,42 +1336,23 @@ Page Title: Benchmark Your Pallet Benchmarking is the process of measuring the computational resources (execution time and storage) required by your pallet's extrinsics. Accurate [weight](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/index.html){target=\_blank} calculations are essential for ensuring your blockchain can process transactions efficiently while protecting against denial-of-service attacks. -This guide continues the pallet development series, building on the [Create a Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet), [Mock Your Runtime](/parachains/customize-runtime/pallet-development/mock-runtime), and [Test Your Pallet](/parachains/customize-runtime/pallet-development/pallet-testing) tutorials. You'll learn how to benchmark the counter pallet extrinsics and integrate the generated weights into your runtime. +This guide continues building on what you've learned through the pallet development series. You'll learn how to benchmark the custom counter pallet extrinsics and integrate the generated weights into your runtime. ## Prerequisites Before you begin, ensure you have: -- Completed the previous pallet development tutorials -- Basic understanding of computational complexity -- Familiarity with Rust's testing framework +- Completed the previous pallet development tutorials: + - [Create a Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet/){target=\_blank} + - [Mock Your Runtime](/parachains/customize-runtime/pallet-development/mock-runtime/){target=\_blank} + - [Unit Test Pallets](/parachains/customize-runtime/pallet-development/pallet-testing/){target=\_blank} +- Basic understanding of [computational complexity](https://en.wikipedia.org/wiki/Computational_complexity){target=\_blank}. +- Familiarity with [Rust's testing framework](https://doc.rust-lang.org/book/ch11-00-testing.html){target=\_blank}. +- Familiarity setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\_blank}. Refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\_blank} guide for instructions if needed. -## Why Benchmark? +## Create the Benchmarking Module -In blockchain systems, every operation consumes resources. Weight is the mechanism Polkadot SDK uses to measure and limit resource consumption. Without accurate weights: - -- **Security Risk**: Malicious actors could submit transactions that consume excessive resources, blocking legitimate transactions or halting the chain -- **Inefficiency**: Over-estimated weights waste block space and reduce throughput -- **User Experience**: Inaccurate weights lead to incorrect fee calculations - -Benchmarking provides empirical measurements of your extrinsics under various conditions, ensuring weights reflect real-world resource consumption. - -## Understanding Weights - -The [weight system](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html){target=\_blank} serves multiple purposes: - -- **DoS Protection**: Limits the computational work per block, preventing attackers from overwhelming the network -- **Fee Calculation**: Determines transaction fees based on actual resource usage -- **Block Production**: Helps block authors maximize throughput while staying within block limits - -Weights are expressed as [`Weight::from_parts(ref_time, proof_size)`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.from_parts){target=\_blank} where: - -- [`ref_time`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.ref_time){target=\_blank}: Computational time measured in picoseconds -- [`proof_size`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.proof_size){target=\_blank}: Storage proof size in bytes - -## Step 1: Create the Benchmarking Module - -Create a new file `benchmarking.rs` in your pallet's `src` directory. This module will contain all the [benchmarking definitions](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank} for your pallet: +Create a new file `benchmarking.rs` in your pallet's `src` directory and add the following code: ```rust title="pallets/pallet-custom/src/benchmarking.rs" #![cfg(feature = "runtime-benchmarks")] @@ -1408,7 +1389,7 @@ mod benchmarks { #[benchmark] fn decrement() { - // First set the counter to a non-zero value + // First, set the counter to a non-zero value CounterValue::::put(100); let caller: T::AccountId = whitelisted_caller(); @@ -1425,20 +1406,11 @@ mod benchmarks { } ``` -**Key components:** - -- **`#![cfg(feature = "runtime-benchmarks")]`**: Ensures benchmarking code only compiles when the feature is enabled -- **[`#[benchmarks]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmarks.html){target=\_blank}**: Marks the module containing benchmark definitions -- **[`#[benchmark]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmark.html){target=\_blank}**: Defines individual benchmark functions -- **[`#[extrinsic_call]`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.extrinsic_call.html){target=\_blank}**: Marks the actual extrinsic invocation to measure -- **[`whitelisted_caller()`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/fn.whitelisted_caller.html){target=\_blank}**: Generates a funded account for benchmarking -- **[`impl_benchmark_test_suite!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.impl_benchmark_test_suite.html){target=\_blank}**: Generates test functions to verify benchmarks work correctly +This module contains all the [benchmarking definitions](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank} for your pallet. -## Step 2: Define the Weight Trait +## Define the Weight Trait -The [`WeightInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/trait.WeightInfo.html){target=\_blank} trait provides an abstraction layer that allows weights to be swapped at runtime configuration. This enables you to use placeholder weights during development and testing, then switch to auto-generated benchmarked weights in production without modifying the pallet code itself. - -Add a `weights` module to your pallet that defines the `WeightInfo` trait: +Add a `weights` module to your pallet that defines the `WeightInfo` trait using the following code: ```rust title="pallets/pallet-custom/src/lib.rs" #[frame::pallet] @@ -1472,13 +1444,11 @@ pub mod pallet { } ``` -The `()` implementation provides placeholder weights for development. Later, this will be replaced with auto-generated weights from benchmarking. - -## Step 3: Add WeightInfo to Config +The `()` implementation provides placeholder weights for development. -By making `WeightInfo` an associated type in the `Config` trait, you allow each runtime that uses your pallet to specify which weight implementation to use. Different deployment environments (testnets, production chains, or different hardware configurations) may have different performance characteristics and can use different weight calculations. +## Add WeightInfo to Config -Update your pallet's `Config` trait to include `WeightInfo`: +Update your pallet's `Config` trait to include `WeightInfo` by adding the following code: ```rust title="pallets/pallet-custom/src/lib.rs" #[pallet::config] @@ -1492,11 +1462,11 @@ pub trait Config: frame_system::Config { } ``` -## Step 4: Update Extrinsic Weight Annotations +The [`WeightInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/trait.WeightInfo.html){target=\_blank} trait provides an abstraction layer that allows weights to be swapped at runtime configuration. By making `WeightInfo` an associated type in the `Config` trait, you will enable each runtime that uses your pallet to specify which weight implementation to use. -By calling `T::WeightInfo::function_name()` instead of using hardcoded `Weight::from_parts()` values, your extrinsics automatically use whichever weight implementation is configured in the runtime. This allows you to easily switch between placeholder weights for testing and benchmarked weights for production without changing any pallet code. +## Update Extrinsic Weight Annotations -Replace the placeholder weights in your extrinsics with calls to the `WeightInfo` trait: +Replace the placeholder weights in your extrinsics with calls to the `WeightInfo` trait by adding the following code: ```rust title="pallets/pallet-custom/src/lib.rs" #[pallet::call] @@ -1521,11 +1491,11 @@ impl Pallet { } ``` -## Step 5: Include the Benchmarking Module +By calling `T::WeightInfo::function_name()` instead of using hardcoded `Weight::from_parts()` values, your extrinsics automatically use whichever weight implementation is configured in the runtime. You can switch between placeholder weights for testing and benchmarked weights for production easily, without changing any pallet code. -The `#[cfg(feature = "runtime-benchmarks")]` attribute ensures that benchmarking code is only compiled when explicitly needed. This keeps your production runtime lean by excluding benchmarking infrastructure from normal builds, as it's only needed when generating weights. +## Include the Benchmarking Module -At the top of your `lib.rs`, add the module declaration: +At the top of your `lib.rs`, add the module declaration by adding the following code: ```rust title="pallets/pallet-custom/src/lib.rs" #![cfg_attr(not(feature = "std"), no_std)] @@ -1538,14 +1508,14 @@ pub use pallet::*; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; -// ... rest of the pallet +// Additional pallet code ``` -## Step 6: Configure Pallet Dependencies +The `#[cfg(feature = "runtime-benchmarks")]` attribute ensures that benchmarking code is only compiled when explicitly needed to keep your production runtime efficient. -The feature flag system in Cargo allows you to conditionally compile code based on which features are enabled. By defining a `runtime-benchmarks` feature that cascades to FRAME's benchmarking features, you create a clean way to build your pallet with or without benchmarking support, ensuring all necessary dependencies are available when needed but excluded from production builds. +## Configure Pallet Dependencies -Update your pallet's `Cargo.toml` to enable the benchmarking feature: +Update your pallet's `Cargo.toml` to enable the benchmarking feature by adding the following code: ```toml title="pallets/pallet-custom/Cargo.toml" [dependencies] @@ -1565,11 +1535,11 @@ std = [ ] ``` -## Step 7: Update Mock Runtime +The Cargo feature flag system lets you conditionally compile code based on which features are enabled. By defining a `runtime-benchmarks` feature that cascades to FRAME's benchmarking features, you create a clean way to build your pallet with or without benchmarking support, ensuring all necessary dependencies are available when needed but excluded from production builds. -In your mock runtime for testing, use the placeholder `()` implementation of `WeightInfo` since unit tests focus on verifying functional correctness rather than performance characteristics. This keeps tests fast and focused on validating logic. +## Update Mock Runtime -Add the `WeightInfo` type to your test configuration in `mock.rs`: +Add the `WeightInfo` type to your test configuration in `mock.rs` by adding the following code: ```rust title="pallets/pallet-custom/src/mock.rs" impl pallet_custom::Config for Test { @@ -1579,427 +1549,285 @@ impl pallet_custom::Config for Test { } ``` -## Step 8: Configure Runtime Benchmarking +In your mock runtime for testing, use the placeholder `()` implementation of `WeightInfo`, since unit tests focus on verifying functional correctness rather than performance. -To execute benchmarks, your pallet must be integrated into the runtime's benchmarking infrastructure. This involves three configuration steps: +## Configure Runtime Benchmarking -### Update Runtime Cargo.toml +To execute benchmarks, your pallet must be integrated into the runtime's benchmarking infrastructure. Follow these steps to update the runtime configuration: -When you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included. +1. **Update `runtime/Cargo.toml`**: Add your pallet to the runtime's `runtime-benchmarks` feature as follows: -Add your pallet to the runtime's `runtime-benchmarks` feature in `runtime/Cargo.toml`: - -```toml title="runtime/Cargo.toml" -runtime-benchmarks = [ - "cumulus-pallet-parachain-system/runtime-benchmarks", - "hex-literal", - "pallet-parachain-template/runtime-benchmarks", - "polkadot-sdk/runtime-benchmarks", - "pallet-custom/runtime-benchmarks", -] -``` - -### Update Runtime Configuration - -Start with the placeholder implementation during development. After successfully running benchmarks and generating the weights file, you'll update this to use the benchmarked weights. - -In `runtime/src/configs/mod.rs`, add the `WeightInfo` type: - -```rust title="runtime/src/configs/mod.rs" -impl pallet_custom::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type CounterMaxValue = ConstU32<1000>; - type WeightInfo = (); -} -``` + ```toml title="runtime/Cargo.toml" + runtime-benchmarks = [ + "cumulus-pallet-parachain-system/runtime-benchmarks", + "hex-literal", + "pallet-parachain-template/runtime-benchmarks", + "polkadot-sdk/runtime-benchmarks", + "pallet-custom/runtime-benchmarks", + ] + ``` -### Register Benchmarks + When you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included. -The `define_benchmarks!` macro creates the infrastructure that allows the benchmarking CLI tool to discover and execute your pallet's benchmarks. +2. **Update runtime configuration**: Run development benchmarks with the placeholder implementation and use the resulting weights file to update benchmark weights as follows: -Add your pallet to the benchmark list in `runtime/src/benchmarks.rs`: + ```rust title="runtime/src/configs/mod.rs" + impl pallet_custom::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = (); + } + ``` -```rust title="runtime/src/benchmarks.rs" -polkadot_sdk::frame_benchmarking::define_benchmarks!( - [frame_system, SystemBench::] - [pallet_balances, Balances] - // ... other pallets - [pallet_custom, CustomPallet] -); -``` +3. **Register benchmarks**: Add your pallet to the benchmark list in `runtime/src/benchmarks.rs` as follows: -## Step 9: Run Benchmarks + ```rust title="runtime/src/benchmarks.rs" + polkadot_sdk::frame_benchmarking::define_benchmarks!( + [frame_system, SystemBench::] + [pallet_balances, Balances] + // ... other pallets + [pallet_custom, CustomPallet] + ); + ``` -### Test Benchmark Compilation + The [`define_benchmarks!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.define_benchmarks.html){target=\_blank} macro creates the infrastructure that allows the benchmarking CLI tool to discover and execute your pallet's benchmarks. -The `impl_benchmark_test_suite!` macro generates unit tests for each benchmark. Running these tests verifies that your benchmarks compile correctly, execute without panicking, and pass their assertions, catching issues early before building the full runtime. +## Test Benchmark Compilation -First, verify your benchmarks compile and run as tests: +Run the following command to verify your benchmarks compile and run as tests: ```bash cargo test -p pallet-custom --features runtime-benchmarks ``` -You should see your benchmark tests passing: +You will see terminal output similar to the following as your benchmark tests pass: -``` -test benchmarking::benchmarks::bench_set_counter_value ... ok -test benchmarking::benchmarks::bench_increment ... ok -test benchmarking::benchmarks::bench_decrement ... ok -``` +
+ cargo test -p pallet-custom --features runtime-benchmarks + test benchmarking::benchmarks::bench_set_counter_value ... ok + test benchmarking::benchmarks::bench_increment ... ok + test benchmarking::benchmarks::bench_decrement ... ok + +
-### Build the Runtime with Benchmarks +The `impl_benchmark_test_suite!` macro generates unit tests for each benchmark. Running these tests verifies that your benchmarks compile correctly, execute without panicking, and pass their assertions, catching issues early before building the entire runtime. -This build includes all the benchmarking infrastructure and special host functions needed for measurement. The resulting WASM runtime contains your benchmark code and can communicate with the benchmarking tool's execution environment. This is a special build used only for benchmarking - you'll create a different build later for actually running your chain. +## Build the Runtime with Benchmarks -Compile the runtime with benchmarking enabled to generate the WASM binary: +Compile the runtime with benchmarking enabled to generate the WASM binary using the following command: ```bash cargo build --release --features runtime-benchmarks ``` -This produces the runtime WASM file needed for benchmarking, typically located at: -``` -target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm -``` +This command produces the runtime WASM file needed for benchmarking, typically located at: `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm` -### Install the Benchmarking Tool +The build includes all the benchmarking infrastructure and special host functions needed for measurement. The resulting WASM runtime contains your benchmark code and can communicate with the benchmarking tool's execution environment. You'll create a different build later for operating your chain in production. -[`frame-omni-bencher`](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} is the official Polkadot SDK tool specifically designed for FRAME pallet benchmarking. It provides a standardized way to execute benchmarks, measure execution times and storage operations, and generate properly formatted weight files with full integration into the FRAME weight system. +## Install the Benchmarking Tool -Install the `frame-omni-bencher` CLI tool: +Install the `frame-omni-bencher` CLI tool using the following command: ```bash cargo install frame-omni-bencher --locked ``` -### Download the Weight Template +[`frame-omni-bencher`](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} is the official Polkadot SDK tool designed explicitly for FRAME pallet benchmarking. It provides a standardized way to execute benchmarks, measure execution times and storage operations, and generate properly formatted weight files with full integration into the FRAME weight system. -The weight template is a Handlebars file that transforms raw benchmark data into a properly formatted Rust source file. It defines the structure of the generated `weights.rs` file, including imports, trait definitions, documentation comments, and formatting. Using the official template ensures your weight files follow Polkadot SDK conventions and include all necessary metadata like benchmark execution parameters, storage operation counts, and hardware information. +## Download the Weight Template -Download the official weight template file: +Download the official weight template file using the following commands: ```bash curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \ --output ./pallets/pallet-custom/frame-weight-template.hbs ``` -### Hardware Requirements for Benchmarking - -!!! warning "Critical: Benchmark on Production-Like Hardware" - Benchmarks must be executed on hardware similar to what will run your chain in production. Weight measurements are hardware-dependent, and benchmarking on different hardware can lead to dangerous under-estimation or wasteful over-estimation of weights. - -Weights represent the actual computational time and resources consumed by extrinsics. These measurements vary significantly across different hardware configurations: - -- **CPU Performance**: Different processors execute instructions at different speeds. A faster development laptop will produce lower weight values than production server hardware -- **Storage Speed**: Database read/write performance varies between NVMe SSDs, SATA SSDs, and HDDs, affecting storage-related weights -- **Memory Bandwidth**: RAM speed impacts how quickly data can be accessed during execution -- **CPU Cache**: Cache size and architecture differences affect repeated operations - -Benchmarking on faster hardware than production leads to under-estimated weights - attackers could submit extrinsics that consume more resources than the weights suggest, potentially causing blocks to take longer than expected to produce or even halting the chain. Conversely, benchmarking on slower hardware creates over-estimated weights, resulting in unnecessarily high transaction fees and wasted block capacity. - -**Best practices:** - -1. **Match production specifications**: If your chain will run on specific validator hardware, benchmark on identical or very similar machines -2. **Use reference hardware**: The Polkadot ecosystem often uses standardized reference hardware specifications for consistency. Consider following these standards if your chain will connect to Polkadot or Kusama -3. **Dedicated benchmarking environment**: Run benchmarks on a machine without other heavy processes to ensure consistent measurements -4. **Document your hardware**: The generated weight files include hardware information in comments. Review this to ensure it matches your production environment -5. **Re-benchmark when hardware changes**: If your validator hardware specifications change, re-run benchmarks and update weights - -For development and testing purposes, you can run benchmarks on any available hardware to verify that your benchmark functions work correctly. However, before deploying to production, always re-run benchmarks on production-equivalent hardware. - -### Execute Benchmarks - -Benchmarks execute against the compiled WASM runtime rather than native code because WASM is what actually runs in production on the blockchain. WASM execution can have different performance characteristics than native code due to compilation and sandboxing overhead, so benchmarking the WASM ensures your weight measurements reflect real-world conditions. - -Run benchmarks for your pallet to generate weight files: - -```bash -frame-omni-bencher v1 benchmark pallet \ - --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ - --pallet pallet_custom \ - --extrinsic "" \ - --template ./pallets/pallet-custom/frame-weight-template.hbs \ - --output ./pallets/pallet-custom/src/weights.rs -``` - -**Command breakdown:** - -- `v1`: Specifies the benchmarking framework version (v2 API) -- `benchmark pallet`: Subcommand indicating you want to benchmark pallet extrinsics -- `--runtime`: Path to the compiled WASM runtime file that includes your pallet and benchmarks -- `--pallet pallet_custom`: Name of the pallet to benchmark (must match the name used in `define_benchmarks!`) -- `--extrinsic ""`: Empty string benchmarks all extrinsics in the pallet; you can specify a single extrinsic name to benchmark only that one -- `--template`: Path to the Handlebars template that formats the output -- `--output`: Destination file path for the generated weights module +The weight template is a Handlebars file that transforms raw benchmark data into a correctly formatted Rust source file. It defines the structure of the generated `weights.rs` file, including imports, trait definitions, documentation comments, and formatting. Using the official template ensures your weight files follow the Polkadot SDK conventions and include all necessary metadata, such as benchmark execution parameters, storage operation counts, and hardware information. -### Advanced Options +## Execute Benchmarks -You can customize benchmark execution with additional parameters for more detailed measurements: +Run benchmarks for your pallet to generate weight files using the following commands: ```bash frame-omni-bencher v1 benchmark pallet \ --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ --pallet pallet_custom \ --extrinsic "" \ - --steps 50 \ - --repeat 20 \ --template ./pallets/pallet-custom/frame-weight-template.hbs \ --output ./pallets/pallet-custom/src/weights.rs ``` -**Additional parameters:** - -- `--steps 50`: Number of different input values to test when using linear components (default: 50). More steps provide finer granularity for detecting complexity trends but increase benchmarking time -- `--repeat 20`: Number of repetitions for each measurement (default: 20). More repetitions improve statistical accuracy by averaging out variance, reducing the impact of system noise and providing more reliable weight estimates -- `--heap-pages 4096`: WASM heap pages allocation. Affects available memory during execution -- `--wasm-execution compiled`: WASM execution method. Use `compiled` for performance closest to production conditions - -## Step 10: Use Generated Weights - -After running benchmarks, a `weights.rs` file is generated containing measured weights. The generated weights are based on actual measurements of your code running on real hardware, accounting for the specific complexity of your logic, storage access patterns, and computational requirements. Estimates or placeholder values cannot capture these nuances and will either waste block space (over-estimation) or create security risks (under-estimation). - -The file includes: - -- Detailed documentation about the benchmark execution environment (date, hardware, parameters) -- The `WeightInfo` trait definition matching your benchmark functions -- `SubstrateWeight` implementation with measured weights from your benchmarks -- Database read/write costs calculated based on observed storage operations -- Component complexity annotations for variable inputs (if you use linear components) -- A fallback `()` implementation for testing environments +Benchmarks execute against the compiled WASM runtime rather than native code because WASM is what actually runs in production on the blockchain. WASM execution can have different performance characteristics than native code due to compilation and sandboxing overhead, so benchmarking against the WASM ensures your weight measurements reflect real-world conditions. -### Integrate the Generated Weights +??? note "Additional customization" -Unlike the benchmarking module (which is only needed when running benchmarks), the weights module must be available in all builds because the runtime needs to call the weight functions during normal operation to calculate transaction fees and enforce block limits. + You can customize benchmark execution with additional parameters for more detailed measurements, as shown in the sample code below: -Add the weights module to your pallet's `lib.rs`: - -```rust title="pallets/pallet-custom/src/lib.rs" -#![cfg_attr(not(feature = "std"), no_std)] - -extern crate alloc; -use alloc::vec::Vec; - -pub use pallet::*; - -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; + ```bash + frame-omni-bencher v1 benchmark pallet \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ + --pallet pallet_custom \ + --extrinsic "" \ + --steps 50 \ + --repeat 20 \ + --template ./pallets/pallet-custom/frame-weight-template.hbs \ + --output ./pallets/pallet-custom/src/weights.rs + ``` + + - `--steps 50`: Number of different input values to test when using linear components (default: 50). More steps provide finer granularity for detecting complexity trends but increase benchmarking time. + - `--repeat 20`: Number of repetitions for each measurement (default: 20). More repetitions improve statistical accuracy by averaging out variance, reducing the impact of system noise, and providing more reliable weight estimates. + - `--heap-pages 4096`: WASM heap pages allocation. Affects available memory during execution. + - `--wasm-execution compiled`: WASM execution method. Use `compiled` for performance closest to production conditions. -pub mod weights; +## Use Generated Weights -#[frame::pallet] -pub mod pallet { - use super::*; - use frame::prelude::*; - use crate::weights::WeightInfo; - // ... rest of pallet -} -``` +After running benchmarks, a `weights.rs` file is generated containing measured weights based on actual measurements of your code running on real hardware, accounting for the specific complexity of your logic, storage access patterns, and computational requirements. -### Update Runtime Configuration +Follow these steps to use the generated weights with your pallet: -This change activates your benchmarked weights in the production runtime. Now when users submit transactions that call your pallet's extrinsics, the runtime will use the actual measured weights to calculate fees and enforce block limits. +1. Integrate the generated weights by adding the weights module to your pallet's `lib.rs` as follows: -Update your runtime configuration to use the generated weights instead of the placeholder `()` implementation: + ```rust title="pallets/pallet-custom/src/lib.rs" + #![cfg_attr(not(feature = "std"), no_std)] -```rust title="runtime/src/configs/mod.rs" -impl pallet_custom::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type CounterMaxValue = ConstU32<1000>; - type WeightInfo = pallet_custom::weights::SubstrateWeight; -} -``` + extern crate alloc; + use alloc::vec::Vec; -### Example Generated Weight File + pub use pallet::*; -The generated `weights.rs` file will look similar to this: + #[cfg(feature = "runtime-benchmarks")] + mod benchmarking; -```rust title="pallets/pallet-custom/src/weights.rs" -//! Autogenerated weights for `pallet_custom` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20` + pub mod weights; -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] + #[frame::pallet] + pub mod pallet { + use super::*; + use frame::prelude::*; + use crate::weights::WeightInfo; + // ... rest of pallet + } + ``` -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use core::marker::PhantomData; + Unlike the benchmarking module (which is only needed when running benchmarks), the weights module must be available in all builds because the runtime needs to call the weight functions during regular operation to calculate transaction fees and enforce block limits. -pub trait WeightInfo { - fn set_counter_value() -> Weight; - fn increment() -> Weight; - fn decrement() -> Weight; -} +2. Update your runtime configuration to use the generated weights instead of the placeholder `()` implementation by adding the following code: -pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { - fn set_counter_value() -> Weight { - Weight::from_parts(8_234_000, 0) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) + ```rust title="runtime/src/configs/mod.rs" + impl pallet_custom::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = pallet_custom::weights::SubstrateWeight; } + ``` - fn increment() -> Weight { - Weight::from_parts(12_456_000, 0) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } + This change activates your benchmarked weights in the production runtime. Now, when users submit transactions that call your pallet's extrinsics, the runtime will use the actual measured weights to calculate fees and enforce block limits. - fn decrement() -> Weight { - Weight::from_parts(11_987_000, 0) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) +??? code "Example generated weight file" + + The generated `weights.rs` file will look similar to this: + + ```rust title="pallets/pallet-custom/src/weights.rs" + //! Autogenerated weights for `pallet_custom` + //! + //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 + //! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20` + + #![cfg_attr(rustfmt, rustfmt_skip)] + #![allow(unused_parens)] + #![allow(unused_imports)] + #![allow(missing_docs)] + + use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; + use core::marker::PhantomData; + + pub trait WeightInfo { + fn set_counter_value() -> Weight; + fn increment() -> Weight; + fn decrement() -> Weight; } -} -``` - -**Note**: The actual numbers will vary based on your hardware and implementation complexity. The [`DbWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.RuntimeDbWeight.html){target=\_blank} accounts for database read and write operations. -## Benchmarking Best Practices - -### 1. Test Worst-Case Scenarios + pub struct SubstrateWeight(PhantomData); + impl WeightInfo for SubstrateWeight { + fn set_counter_value() -> Weight { + Weight::from_parts(8_234_000, 0) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } -Benchmarks should always measure maximum possible resource consumption. If you benchmark average or best-case scenarios, malicious users could craft transactions that hit worst-case paths in your code, consuming more resources than the weights indicate and potentially slowing down or halting block production. + fn increment() -> Weight { + Weight::from_parts(12_456_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } -```rust -#[benchmark] -fn complex_operation() { - // Set up worst-case storage state - for i in 0..100 { - SomeStorage::::insert(i, vec![0u8; 1000]); + fn decrement() -> Weight { + Weight::from_parts(11_987_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } } + ``` - let caller = whitelisted_caller(); - - #[extrinsic_call] - _(RawOrigin::Signed(caller)); -} -``` - -### 2. Use Linear Components for Variable Complexity - -Many extrinsics have variable costs depending on input parameters. [Linear components](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/trait.BenchmarkingSetup.html){target=\_blank} tell the benchmarking framework to test your extrinsic with different values of `n`, measure the execution time for each, and calculate a formula like `Weight = base_weight + (n * per_item_weight)`. This produces dynamic weights that accurately reflect the actual work being done. - -When extrinsic complexity depends on input size, use linear components: - -```rust title="pallets/pallet-custom/src/benchmarking.rs" -#[benchmark] -fn process_items(n: Linear<0, 100>) { - let caller = whitelisted_caller(); - let items: Vec = (0..n).collect(); - - #[extrinsic_call] - _(RawOrigin::Signed(caller), items); -} -``` - -### 3. Verify Results - -Assertions ensure that your benchmark is actually testing the code path you think it's testing. If your extrinsic fails silently or takes an early return, the benchmark would measure the wrong scenario and produce inaccurate weights. - -Always assert the expected state after extrinsic execution: - -```rust title="pallets/pallet-custom/src/benchmarking.rs" -#[benchmark] -fn my_extrinsic() { - let caller = whitelisted_caller(); - - #[extrinsic_call] - _(RawOrigin::Signed(caller.clone())); - - // Verify the extrinsic had the expected effect - assert_eq!(MyStorage::::get(&caller), expected_value); -} -``` - -### 4. Minimize Setup Code - -While the benchmarking framework tries to isolate the extrinsic execution, excessive setup code can add noise to measurements. More importantly, setup code that doesn't reflect real-world pre-conditions can lead to benchmarking unrealistic scenarios. - -Only include necessary setup in benchmarks: - -```rust title="pallets/pallet-custom/src/benchmarking.rs" -#[benchmark] -fn efficient_benchmark() { - // Minimal setup - let caller = whitelisted_caller(); - - #[extrinsic_call] - _(RawOrigin::Signed(caller)); - - // Minimal assertions -} -``` + The actual numbers in your `weights.rs` file will vary based on your hardware and implementation complexity. The [`DbWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.RuntimeDbWeight.html){target=\_blank} accounts for database read and write operations. ## Run Your Chain Locally -Now that you've added the pallet to your runtime, you can launch your parachain locally to test the new functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}. For instructions on setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\_blank}, refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\_blank} guide. - -### Build the Production Runtime - -The `runtime-benchmarks` feature flag adds special host functions (like `ext_benchmarking_current_time` and `ext_benchmarking_get_read_and_written_keys`) that are only available in the benchmarking execution environment. These functions allow the benchmarking framework to precisely measure execution time and track storage operations. However, regular nodes don't provide these host functions, so a runtime compiled with benchmarking features will fail to start on a production node. - -Before running your chain, rebuild the runtime **without** the `runtime-benchmarks` feature: +Now that you've added the pallet to your runtime, you can follow these steps to launch your parachain locally to test the new functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}: -```bash -cargo build --release -``` +1. Before running your chain, rebuild the production runtime without the `runtime-benchmarks` feature using the following command: -!!! note "Build Types" - Understanding the difference between builds is critical: - - - `cargo build --release --features runtime-benchmarks` - Compiles with benchmarking host functions for measurement. Use this ONLY when running benchmarks with `frame-omni-bencher` - - `cargo build --release` - Compiles production runtime without benchmarking features. Use this for running your actual chain - -This produces a production-ready WASM runtime at `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm`. + ```bash + cargo build --release + ``` -### Generate a Chain Specification + The `runtime-benchmarks` feature flag adds special host functions that are only available in the benchmarking execution environment. A runtime compiled with benchmarking features will fail to start on a production node. -The chain specification defines the initial state and configuration of your blockchain, including the runtime WASM code, genesis storage, and network parameters. By generating a new chain spec with your updated runtime (now containing your benchmarked pallet), you ensure that nodes starting from this spec will use the correct version of your code with proper weight calculations. + This build produces a production-ready WASM runtime at `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm`. -Create a new chain specification file with the updated runtime: + !!! note "Compare build types" + - `cargo build --release --features runtime-benchmarks` - Compiles with benchmarking host functions for measurement. Use this ONLY when running benchmarks with `frame-omni-bencher`. + - `cargo build --release` - Compiles production runtime without benchmarking features. Use this for running your chain in production. -```bash -chain-spec-builder create -t development \ ---relay-chain paseo \ ---para-id 1000 \ ---runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ -named-preset development -``` +2. Generate a new chain specification file with the updated runtime using the following commands: -This command generates a chain specification file, `chain_spec.json`, for your parachain with the updated runtime. - -### Start the Parachain Node + ```bash + chain-spec-builder create -t development \ + --relay-chain paseo \ + --para-id 1000 \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ + named-preset development + ``` -Launch the parachain using the Polkadot Omni Node with the generated chain specification by running the following command: + This command generates a chain specification file, `chain_spec.json`, for your parachain with the updated runtime, which defines the initial state and configuration of your blockchain, including the runtime WASM code, genesis storage, and network parameters. Generating this new chain spec with your updated runtime ensures nodes starting from this spec will use the correct version of your code with proper weight calculations. -```bash -polkadot-omni-node --chain ./chain_spec.json --dev -``` +3. Start the parachain node using the Polkadot Omni Node with the generated chain specification by running the following command: -The node will start and display initialization information including: + ```bash + polkadot-omni-node --chain ./chain_spec.json --dev + ``` -- The chain specification name -- The node identity and peer ID -- Database location -- Network endpoints (JSON-RPC and Prometheus) + The node will start and display initialization information, including: -### Verify Block Production + - The chain specification name + - The node identity and peer ID + - Database location + - Network endpoints (JSON-RPC and Prometheus) -Once the node is running, you should see log messages indicating successful block production: +4. Once the node is running, you will see log messages confirming successful production of blocks similar to the following: -``` -[Parachain] 🔨 Initializing Genesis block/state (state: 0x47ce…ec8d, header-hash: 0xeb12…fecc) -[Parachain] 🎁 Prepared block for proposing at 1 (3 ms) ... -[Parachain] 🏆 Imported #1 (0xeb12…fecc → 0xee51…98d2) -[Parachain] 🎁 Prepared block for proposing at 2 (3 ms) ... -[Parachain] 🏆 Imported #2 (0xee51…98d2 → 0x35e0…cc32) -``` +
+ polkadot-omni-node --chain ./chain_spec.json --dev + [Parachain] 🔨 Initializing Genesis block/state (state: 0x47ce…ec8d, header-hash: 0xeb12…fecc) + [Parachain] 🎁 Prepared block for proposing at 1 (3 ms) ... + [Parachain] 🏆 Imported #1 (0xeb12…fecc → 0xee51…98d2) + [Parachain] 🎁 Prepared block for proposing at 2 (3 ms) ... + [Parachain] 🏆 Imported #2 (0xee51…98d2 → 0x35e0…cc32) + +
-The parachain will produce new blocks every few seconds. You can now interact with your pallet's extrinsics through the JSON-RPC endpoint at `http://127.0.0.1:9944` using tools like [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\_blank}. + The parachain will produce new blocks every few seconds. You can now interact with your pallet's extrinsics through the JSON-RPC endpoint at `http://127.0.0.1:9944` using tools like [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\_blank}. ## Related Resources @@ -10042,142 +9870,6 @@ JAM removes many of the opinions and constraints of the current relay chain whil This architectural evolution promises to enhance Polkadot's scalability and flexibility while maintaining robust security guarantees. JAM is planned to be rolled out to Polkadot as a single, complete upgrade rather than a stream of smaller updates. This approach seeks to minimize the developer overhead required to address any breaking changes. ---- - -Page Title: Pallet Testing - -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-pallet-testing.md -- Canonical (HTML): https://docs.polkadot.com/parachains/customize-runtime/pallet-development/pallet-testing/ -- Summary: Learn how to efficiently test pallets in the Polkadot SDK, ensuring the reliability and security of your pallets operations. - -# Pallet Testing - -## Introduction - -Unit testing in the Polkadot SDK helps ensure that the functions provided by a pallet behave as expected. It also confirms that data and events associated with a pallet are processed correctly during interactions. The Polkadot SDK offers a set of APIs to create a test environment to simulate runtime and mock transaction execution for extrinsics and queries. - -To begin unit testing, you must first set up a mock runtime that simulates blockchain behavior, incorporating the necessary pallets. For a deeper understanding, consult the [Mock Runtime](/parachains/customize-runtime/pallet-development/mock-runtime/){target=\_blank} guide. - -## Writing Unit Tests - -Once the mock runtime is in place, the next step is to write unit tests that evaluate the functionality of your pallet. Unit tests allow you to test specific pallet features in isolation, ensuring that each function behaves correctly under various conditions. These tests typically reside in your pallet module's `test.rs` file. - -Unit tests in the Polkadot SDK use the Rust testing framework, and the mock runtime you've defined earlier will serve as the test environment. Below are the typical steps involved in writing unit tests for a pallet. - -The tests confirm that: - -- **Pallets initialize correctly**: At the start of each test, the system should initialize with block number 0, and the pallets should be in their default states. -- **Pallets modify each other's state**: The second test shows how one pallet can trigger changes in another pallet's internal state, confirming proper cross-pallet interactions. -- **State transitions between blocks are seamless**: By simulating block transitions, the tests validate that the runtime responds correctly to changes in the block number. - -Testing pallet interactions within the runtime is critical for ensuring the blockchain behaves as expected under real-world conditions. Writing integration tests allows validation of how pallets function together, preventing issues that might arise when the system is fully assembled. - -This approach provides a comprehensive view of the runtime's functionality, ensuring the blockchain is stable and reliable. - -### Test Initialization - -Each test starts by initializing the runtime environment, typically using the `new_test_ext()` function, which sets up the mock storage and environment. - -```rust -#[test] -fn test_pallet_functionality() { - new_test_ext().execute_with(|| { - // Test logic goes here - }); -} -``` - -### Function Call Testing - -Call the pallet's extrinsics or functions to simulate user interaction or internal logic. Use the `assert_ok!` macro to check for successful execution and `assert_err!` to verify that errors are correctly handled. - -```rust -#[test] -fn it_works_for_valid_input() { - new_test_ext().execute_with(|| { - // Call an extrinsic or function - assert_ok!(TemplateModule::some_function(Origin::signed(1), valid_param)); - }); -} - -#[test] -fn it_fails_for_invalid_input() { - new_test_ext().execute_with(|| { - // Call an extrinsic with invalid input and expect an error - assert_err!( - TemplateModule::some_function(Origin::signed(1), invalid_param), - Error::::InvalidInput - ); - }); -} -``` - -### Storage Testing - -After calling a function or extrinsic in your pallet, it's essential to verify that the state changes in the pallet's storage match the expected behavior to ensure data is updated correctly based on the actions taken. - -The following example shows how to test the storage behavior before and after the function call: - -```rust -#[test] -fn test_storage_update_on_extrinsic_call() { - new_test_ext().execute_with(|| { - // Check the initial storage state (before the call) - assert_eq!(Something::::get(), None); - - // Dispatch a signed extrinsic, which modifies storage - assert_ok!(TemplateModule::do_something(RuntimeOrigin::signed(1), 42)); - - // Validate that the storage has been updated as expected (after the call) - assert_eq!(Something::::get(), Some(42)); - }); -} - -``` - -### Event Testing - -It's also crucial to test the events that your pallet emits during execution. By default, events generated in a pallet using the [`#generate_deposit`](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/attr.generate_deposit.html){target=\_blank} macro are stored under the system's event storage key (system/events) as [`EventRecord`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.EventRecord.html){target=\_blank} entries. These can be accessed using [`System::events()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.events){target=\_blank} or verified with specific helper methods provided by the system pallet, such as [`assert_has_event`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.assert_has_event){target=\_blank} and [`assert_last_event`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.assert_last_event){target=\_blank}. - -Here's an example of testing events in a mock runtime: - -```rust -#[test] -fn it_emits_events_on_success() { - new_test_ext().execute_with(|| { - // Call an extrinsic or function - assert_ok!(TemplateModule::some_function(Origin::signed(1), valid_param)); - - // Verify that the expected event was emitted - assert!(System::events().iter().any(|record| { - record.event == Event::TemplateModule(TemplateEvent::SomeEvent) - })); - }); -} -``` - -Some key considerations are: - -- **Block number**: Events are not emitted on the genesis block, so you need to set the block number using [`System::set_block_number()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.set_block_number){target=\_blank} to ensure events are triggered. -- **Converting events**: Use `.into()` when instantiating your pallet's event to convert it into a generic event type, as required by the system's event storage. - -## Where to Go Next - -- Dive into the full implementation of the [`mock.rs`](https://github.com/paritytech/polkadot-sdk/blob/master/templates/solochain/pallets/template/src/mock.rs){target=\_blank} and [`test.rs`](https://github.com/paritytech/polkadot-sdk/blob/master/templates/solochain/pallets/template/src/tests.rs){target=\_blank} files in the [Solochain Template](https://github.com/paritytech/polkadot-sdk/tree/master/templates/solochain){target=_blank}. - -
- -- Guide __Benchmarking__ - - --- - - Explore methods to measure the performance and execution cost of your pallet. - - [:octicons-arrow-right-24: Reference](/develop/parachains/testing/benchmarking) - -
- - --- Page Title: Parachains Overview @@ -12776,6 +12468,142 @@ You now know the weight system, how it affects transaction fee computation, and - [Web3 Foundation Research](https://research.web3.foundation/Polkadot/overview/token-economics#relay-chain-transaction-fees-and-per-block-transaction-limits){target=\_blank} +--- + +Page Title: Unit Test Pallets + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-pallet-testing.md +- Canonical (HTML): https://docs.polkadot.com/parachains/customize-runtime/pallet-development/pallet-testing/ +- Summary: Learn how to efficiently test pallets in the Polkadot SDK, ensuring the reliability and security of your pallets operations. + +# Unit Test Pallets + +## Introduction + +Unit testing in the Polkadot SDK helps ensure that the functions provided by a pallet behave as expected. It also confirms that data and events associated with a pallet are processed correctly during interactions. The Polkadot SDK offers a set of APIs to create a test environment to simulate runtime and mock transaction execution for extrinsics and queries. + +To begin unit testing, you must first set up a mock runtime that simulates blockchain behavior, incorporating the necessary pallets. For a deeper understanding, consult the [Mock Runtime](/parachains/customize-runtime/pallet-development/mock-runtime/){target=\_blank} guide. + +## Writing Unit Tests + +Once the mock runtime is in place, the next step is to write unit tests that evaluate the functionality of your pallet. Unit tests allow you to test specific pallet features in isolation, ensuring that each function behaves correctly under various conditions. These tests typically reside in your pallet module's `test.rs` file. + +Unit tests in the Polkadot SDK use the Rust testing framework, and the mock runtime you've defined earlier will serve as the test environment. Below are the typical steps involved in writing unit tests for a pallet. + +The tests confirm that: + +- **Pallets initialize correctly**: At the start of each test, the system should initialize with block number 0, and the pallets should be in their default states. +- **Pallets modify each other's state**: The second test shows how one pallet can trigger changes in another pallet's internal state, confirming proper cross-pallet interactions. +- **State transitions between blocks are seamless**: By simulating block transitions, the tests validate that the runtime responds correctly to changes in the block number. + +Testing pallet interactions within the runtime is critical for ensuring the blockchain behaves as expected under real-world conditions. Writing integration tests allows validation of how pallets function together, preventing issues that might arise when the system is fully assembled. + +This approach provides a comprehensive view of the runtime's functionality, ensuring the blockchain is stable and reliable. + +### Test Initialization + +Each test starts by initializing the runtime environment, typically using the `new_test_ext()` function, which sets up the mock storage and environment. + +```rust +#[test] +fn test_pallet_functionality() { + new_test_ext().execute_with(|| { + // Test logic goes here + }); +} +``` + +### Function Call Testing + +Call the pallet's extrinsics or functions to simulate user interaction or internal logic. Use the `assert_ok!` macro to check for successful execution and `assert_err!` to verify that errors are correctly handled. + +```rust +#[test] +fn it_works_for_valid_input() { + new_test_ext().execute_with(|| { + // Call an extrinsic or function + assert_ok!(TemplateModule::some_function(Origin::signed(1), valid_param)); + }); +} + +#[test] +fn it_fails_for_invalid_input() { + new_test_ext().execute_with(|| { + // Call an extrinsic with invalid input and expect an error + assert_err!( + TemplateModule::some_function(Origin::signed(1), invalid_param), + Error::::InvalidInput + ); + }); +} +``` + +### Storage Testing + +After calling a function or extrinsic in your pallet, it's essential to verify that the state changes in the pallet's storage match the expected behavior to ensure data is updated correctly based on the actions taken. + +The following example shows how to test the storage behavior before and after the function call: + +```rust +#[test] +fn test_storage_update_on_extrinsic_call() { + new_test_ext().execute_with(|| { + // Check the initial storage state (before the call) + assert_eq!(Something::::get(), None); + + // Dispatch a signed extrinsic, which modifies storage + assert_ok!(TemplateModule::do_something(RuntimeOrigin::signed(1), 42)); + + // Validate that the storage has been updated as expected (after the call) + assert_eq!(Something::::get(), Some(42)); + }); +} + +``` + +### Event Testing + +It's also crucial to test the events that your pallet emits during execution. By default, events generated in a pallet using the [`#generate_deposit`](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/attr.generate_deposit.html){target=\_blank} macro are stored under the system's event storage key (system/events) as [`EventRecord`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.EventRecord.html){target=\_blank} entries. These can be accessed using [`System::events()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.events){target=\_blank} or verified with specific helper methods provided by the system pallet, such as [`assert_has_event`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.assert_has_event){target=\_blank} and [`assert_last_event`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.assert_last_event){target=\_blank}. + +Here's an example of testing events in a mock runtime: + +```rust +#[test] +fn it_emits_events_on_success() { + new_test_ext().execute_with(|| { + // Call an extrinsic or function + assert_ok!(TemplateModule::some_function(Origin::signed(1), valid_param)); + + // Verify that the expected event was emitted + assert!(System::events().iter().any(|record| { + record.event == Event::TemplateModule(TemplateEvent::SomeEvent) + })); + }); +} +``` + +Some key considerations are: + +- **Block number**: Events are not emitted on the genesis block, so you need to set the block number using [`System::set_block_number()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.set_block_number){target=\_blank} to ensure events are triggered. +- **Converting events**: Use `.into()` when instantiating your pallet's event to convert it into a generic event type, as required by the system's event storage. + +## Where to Go Next + +- Dive into the full implementation of the [`mock.rs`](https://github.com/paritytech/polkadot-sdk/blob/master/templates/solochain/pallets/template/src/mock.rs){target=\_blank} and [`test.rs`](https://github.com/paritytech/polkadot-sdk/blob/master/templates/solochain/pallets/template/src/tests.rs){target=\_blank} files in the [Solochain Template](https://github.com/paritytech/polkadot-sdk/tree/master/templates/solochain){target=_blank}. + +
+ +- Guide __Benchmarking__ + + --- + + Explore methods to measure the performance and execution cost of your pallet. + + [:octicons-arrow-right-24: Reference](/develop/parachains/testing/benchmarking) + +
+ + --- Page Title: Unlock a Parachain diff --git a/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md b/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md index 263d742a9..d84e40e0f 100644 --- a/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md +++ b/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md @@ -9,42 +9,23 @@ url: https://docs.polkadot.com/parachains/customize-runtime/pallet-development/b Benchmarking is the process of measuring the computational resources (execution time and storage) required by your pallet's extrinsics. Accurate [weight](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/index.html){target=\_blank} calculations are essential for ensuring your blockchain can process transactions efficiently while protecting against denial-of-service attacks. -This guide continues the pallet development series, building on the [Create a Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet), [Mock Your Runtime](/parachains/customize-runtime/pallet-development/mock-runtime), and [Test Your Pallet](/parachains/customize-runtime/pallet-development/pallet-testing) tutorials. You'll learn how to benchmark the counter pallet extrinsics and integrate the generated weights into your runtime. +This guide continues building on what you've learned through the pallet development series. You'll learn how to benchmark the custom counter pallet extrinsics and integrate the generated weights into your runtime. ## Prerequisites Before you begin, ensure you have: -- Completed the previous pallet development tutorials -- Basic understanding of computational complexity -- Familiarity with Rust's testing framework +- Completed the previous pallet development tutorials: + - [Create a Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet/){target=\_blank} + - [Mock Your Runtime](/parachains/customize-runtime/pallet-development/mock-runtime/){target=\_blank} + - [Unit Test Pallets](/parachains/customize-runtime/pallet-development/pallet-testing/){target=\_blank} +- Basic understanding of [computational complexity](https://en.wikipedia.org/wiki/Computational_complexity){target=\_blank}. +- Familiarity with [Rust's testing framework](https://doc.rust-lang.org/book/ch11-00-testing.html){target=\_blank}. +- Familiarity setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\_blank}. Refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\_blank} guide for instructions if needed. -## Why Benchmark? +## Create the Benchmarking Module -In blockchain systems, every operation consumes resources. Weight is the mechanism Polkadot SDK uses to measure and limit resource consumption. Without accurate weights: - -- **Security Risk**: Malicious actors could submit transactions that consume excessive resources, blocking legitimate transactions or halting the chain -- **Inefficiency**: Over-estimated weights waste block space and reduce throughput -- **User Experience**: Inaccurate weights lead to incorrect fee calculations - -Benchmarking provides empirical measurements of your extrinsics under various conditions, ensuring weights reflect real-world resource consumption. - -## Understanding Weights - -The [weight system](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html){target=\_blank} serves multiple purposes: - -- **DoS Protection**: Limits the computational work per block, preventing attackers from overwhelming the network -- **Fee Calculation**: Determines transaction fees based on actual resource usage -- **Block Production**: Helps block authors maximize throughput while staying within block limits - -Weights are expressed as [`Weight::from_parts(ref_time, proof_size)`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.from_parts){target=\_blank} where: - -- [`ref_time`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.ref_time){target=\_blank}: Computational time measured in picoseconds -- [`proof_size`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.proof_size){target=\_blank}: Storage proof size in bytes - -## Step 1: Create the Benchmarking Module - -Create a new file `benchmarking.rs` in your pallet's `src` directory. This module will contain all the [benchmarking definitions](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank} for your pallet: +Create a new file `benchmarking.rs` in your pallet's `src` directory and add the following code: ```rust title="pallets/pallet-custom/src/benchmarking.rs" #![cfg(feature = "runtime-benchmarks")] @@ -81,7 +62,7 @@ mod benchmarks { #[benchmark] fn decrement() { - // First set the counter to a non-zero value + // First, set the counter to a non-zero value CounterValue::::put(100); let caller: T::AccountId = whitelisted_caller(); @@ -98,20 +79,11 @@ mod benchmarks { } ``` -**Key components:** +This module contains all the [benchmarking definitions](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\_blank} for your pallet. -- **`#![cfg(feature = "runtime-benchmarks")]`**: Ensures benchmarking code only compiles when the feature is enabled -- **[`#[benchmarks]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmarks.html){target=\_blank}**: Marks the module containing benchmark definitions -- **[`#[benchmark]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmark.html){target=\_blank}**: Defines individual benchmark functions -- **[`#[extrinsic_call]`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.extrinsic_call.html){target=\_blank}**: Marks the actual extrinsic invocation to measure -- **[`whitelisted_caller()`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/fn.whitelisted_caller.html){target=\_blank}**: Generates a funded account for benchmarking -- **[`impl_benchmark_test_suite!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.impl_benchmark_test_suite.html){target=\_blank}**: Generates test functions to verify benchmarks work correctly +## Define the Weight Trait -## Step 2: Define the Weight Trait - -The [`WeightInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/trait.WeightInfo.html){target=\_blank} trait provides an abstraction layer that allows weights to be swapped at runtime configuration. This enables you to use placeholder weights during development and testing, then switch to auto-generated benchmarked weights in production without modifying the pallet code itself. - -Add a `weights` module to your pallet that defines the `WeightInfo` trait: +Add a `weights` module to your pallet that defines the `WeightInfo` trait using the following code: ```rust title="pallets/pallet-custom/src/lib.rs" #[frame::pallet] @@ -145,13 +117,11 @@ pub mod pallet { } ``` -The `()` implementation provides placeholder weights for development. Later, this will be replaced with auto-generated weights from benchmarking. +The `()` implementation provides placeholder weights for development. -## Step 3: Add WeightInfo to Config +## Add WeightInfo to Config -By making `WeightInfo` an associated type in the `Config` trait, you allow each runtime that uses your pallet to specify which weight implementation to use. Different deployment environments (testnets, production chains, or different hardware configurations) may have different performance characteristics and can use different weight calculations. - -Update your pallet's `Config` trait to include `WeightInfo`: +Update your pallet's `Config` trait to include `WeightInfo` by adding the following code: ```rust title="pallets/pallet-custom/src/lib.rs" #[pallet::config] @@ -165,11 +135,11 @@ pub trait Config: frame_system::Config { } ``` -## Step 4: Update Extrinsic Weight Annotations +The [`WeightInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/trait.WeightInfo.html){target=\_blank} trait provides an abstraction layer that allows weights to be swapped at runtime configuration. By making `WeightInfo` an associated type in the `Config` trait, you will enable each runtime that uses your pallet to specify which weight implementation to use. -By calling `T::WeightInfo::function_name()` instead of using hardcoded `Weight::from_parts()` values, your extrinsics automatically use whichever weight implementation is configured in the runtime. This allows you to easily switch between placeholder weights for testing and benchmarked weights for production without changing any pallet code. +## Update Extrinsic Weight Annotations -Replace the placeholder weights in your extrinsics with calls to the `WeightInfo` trait: +Replace the placeholder weights in your extrinsics with calls to the `WeightInfo` trait by adding the following code: ```rust title="pallets/pallet-custom/src/lib.rs" #[pallet::call] @@ -194,11 +164,11 @@ impl Pallet { } ``` -## Step 5: Include the Benchmarking Module +By calling `T::WeightInfo::function_name()` instead of using hardcoded `Weight::from_parts()` values, your extrinsics automatically use whichever weight implementation is configured in the runtime. You can switch between placeholder weights for testing and benchmarked weights for production easily, without changing any pallet code. -The `#[cfg(feature = "runtime-benchmarks")]` attribute ensures that benchmarking code is only compiled when explicitly needed. This keeps your production runtime lean by excluding benchmarking infrastructure from normal builds, as it's only needed when generating weights. +## Include the Benchmarking Module -At the top of your `lib.rs`, add the module declaration: +At the top of your `lib.rs`, add the module declaration by adding the following code: ```rust title="pallets/pallet-custom/src/lib.rs" #![cfg_attr(not(feature = "std"), no_std)] @@ -211,14 +181,14 @@ pub use pallet::*; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; -// ... rest of the pallet +// Additional pallet code ``` -## Step 6: Configure Pallet Dependencies +The `#[cfg(feature = "runtime-benchmarks")]` attribute ensures that benchmarking code is only compiled when explicitly needed to keep your production runtime efficient. -The feature flag system in Cargo allows you to conditionally compile code based on which features are enabled. By defining a `runtime-benchmarks` feature that cascades to FRAME's benchmarking features, you create a clean way to build your pallet with or without benchmarking support, ensuring all necessary dependencies are available when needed but excluded from production builds. +## Configure Pallet Dependencies -Update your pallet's `Cargo.toml` to enable the benchmarking feature: +Update your pallet's `Cargo.toml` to enable the benchmarking feature by adding the following code: ```toml title="pallets/pallet-custom/Cargo.toml" [dependencies] @@ -238,11 +208,11 @@ std = [ ] ``` -## Step 7: Update Mock Runtime +The Cargo feature flag system lets you conditionally compile code based on which features are enabled. By defining a `runtime-benchmarks` feature that cascades to FRAME's benchmarking features, you create a clean way to build your pallet with or without benchmarking support, ensuring all necessary dependencies are available when needed but excluded from production builds. -In your mock runtime for testing, use the placeholder `()` implementation of `WeightInfo` since unit tests focus on verifying functional correctness rather than performance characteristics. This keeps tests fast and focused on validating logic. +## Update Mock Runtime -Add the `WeightInfo` type to your test configuration in `mock.rs`: +Add the `WeightInfo` type to your test configuration in `mock.rs` by adding the following code: ```rust title="pallets/pallet-custom/src/mock.rs" impl pallet_custom::Config for Test { @@ -252,427 +222,285 @@ impl pallet_custom::Config for Test { } ``` -## Step 8: Configure Runtime Benchmarking - -To execute benchmarks, your pallet must be integrated into the runtime's benchmarking infrastructure. This involves three configuration steps: +In your mock runtime for testing, use the placeholder `()` implementation of `WeightInfo`, since unit tests focus on verifying functional correctness rather than performance. -### Update Runtime Cargo.toml +## Configure Runtime Benchmarking -When you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included. +To execute benchmarks, your pallet must be integrated into the runtime's benchmarking infrastructure. Follow these steps to update the runtime configuration: -Add your pallet to the runtime's `runtime-benchmarks` feature in `runtime/Cargo.toml`: - -```toml title="runtime/Cargo.toml" -runtime-benchmarks = [ - "cumulus-pallet-parachain-system/runtime-benchmarks", - "hex-literal", - "pallet-parachain-template/runtime-benchmarks", - "polkadot-sdk/runtime-benchmarks", - "pallet-custom/runtime-benchmarks", -] -``` +1. **Update `runtime/Cargo.toml`**: Add your pallet to the runtime's `runtime-benchmarks` feature as follows: -### Update Runtime Configuration + ```toml title="runtime/Cargo.toml" + runtime-benchmarks = [ + "cumulus-pallet-parachain-system/runtime-benchmarks", + "hex-literal", + "pallet-parachain-template/runtime-benchmarks", + "polkadot-sdk/runtime-benchmarks", + "pallet-custom/runtime-benchmarks", + ] + ``` -Start with the placeholder implementation during development. After successfully running benchmarks and generating the weights file, you'll update this to use the benchmarked weights. + When you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included. -In `runtime/src/configs/mod.rs`, add the `WeightInfo` type: +2. **Update runtime configuration**: Run development benchmarks with the placeholder implementation and use the resulting weights file to update benchmark weights as follows: -```rust title="runtime/src/configs/mod.rs" -impl pallet_custom::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type CounterMaxValue = ConstU32<1000>; - type WeightInfo = (); -} -``` - -### Register Benchmarks - -The `define_benchmarks!` macro creates the infrastructure that allows the benchmarking CLI tool to discover and execute your pallet's benchmarks. - -Add your pallet to the benchmark list in `runtime/src/benchmarks.rs`: + ```rust title="runtime/src/configs/mod.rs" + impl pallet_custom::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = (); + } + ``` -```rust title="runtime/src/benchmarks.rs" -polkadot_sdk::frame_benchmarking::define_benchmarks!( - [frame_system, SystemBench::] - [pallet_balances, Balances] - // ... other pallets - [pallet_custom, CustomPallet] -); -``` +3. **Register benchmarks**: Add your pallet to the benchmark list in `runtime/src/benchmarks.rs` as follows: -## Step 9: Run Benchmarks + ```rust title="runtime/src/benchmarks.rs" + polkadot_sdk::frame_benchmarking::define_benchmarks!( + [frame_system, SystemBench::] + [pallet_balances, Balances] + // ... other pallets + [pallet_custom, CustomPallet] + ); + ``` -### Test Benchmark Compilation + The [`define_benchmarks!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.define_benchmarks.html){target=\_blank} macro creates the infrastructure that allows the benchmarking CLI tool to discover and execute your pallet's benchmarks. -The `impl_benchmark_test_suite!` macro generates unit tests for each benchmark. Running these tests verifies that your benchmarks compile correctly, execute without panicking, and pass their assertions, catching issues early before building the full runtime. +## Test Benchmark Compilation -First, verify your benchmarks compile and run as tests: +Run the following command to verify your benchmarks compile and run as tests: ```bash cargo test -p pallet-custom --features runtime-benchmarks ``` -You should see your benchmark tests passing: +You will see terminal output similar to the following as your benchmark tests pass: -``` -test benchmarking::benchmarks::bench_set_counter_value ... ok -test benchmarking::benchmarks::bench_increment ... ok -test benchmarking::benchmarks::bench_decrement ... ok -``` +
+ cargo test -p pallet-custom --features runtime-benchmarks + test benchmarking::benchmarks::bench_set_counter_value ... ok + test benchmarking::benchmarks::bench_increment ... ok + test benchmarking::benchmarks::bench_decrement ... ok + +
-### Build the Runtime with Benchmarks +The `impl_benchmark_test_suite!` macro generates unit tests for each benchmark. Running these tests verifies that your benchmarks compile correctly, execute without panicking, and pass their assertions, catching issues early before building the entire runtime. -This build includes all the benchmarking infrastructure and special host functions needed for measurement. The resulting WASM runtime contains your benchmark code and can communicate with the benchmarking tool's execution environment. This is a special build used only for benchmarking - you'll create a different build later for actually running your chain. +## Build the Runtime with Benchmarks -Compile the runtime with benchmarking enabled to generate the WASM binary: +Compile the runtime with benchmarking enabled to generate the WASM binary using the following command: ```bash cargo build --release --features runtime-benchmarks ``` -This produces the runtime WASM file needed for benchmarking, typically located at: -``` -target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm -``` +This command produces the runtime WASM file needed for benchmarking, typically located at: `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm` -### Install the Benchmarking Tool +The build includes all the benchmarking infrastructure and special host functions needed for measurement. The resulting WASM runtime contains your benchmark code and can communicate with the benchmarking tool's execution environment. You'll create a different build later for operating your chain in production. -[`frame-omni-bencher`](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} is the official Polkadot SDK tool specifically designed for FRAME pallet benchmarking. It provides a standardized way to execute benchmarks, measure execution times and storage operations, and generate properly formatted weight files with full integration into the FRAME weight system. +## Install the Benchmarking Tool -Install the `frame-omni-bencher` CLI tool: +Install the `frame-omni-bencher` CLI tool using the following command: ```bash cargo install frame-omni-bencher --locked ``` -### Download the Weight Template +[`frame-omni-bencher`](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\_blank} is the official Polkadot SDK tool designed explicitly for FRAME pallet benchmarking. It provides a standardized way to execute benchmarks, measure execution times and storage operations, and generate properly formatted weight files with full integration into the FRAME weight system. -The weight template is a Handlebars file that transforms raw benchmark data into a properly formatted Rust source file. It defines the structure of the generated `weights.rs` file, including imports, trait definitions, documentation comments, and formatting. Using the official template ensures your weight files follow Polkadot SDK conventions and include all necessary metadata like benchmark execution parameters, storage operation counts, and hardware information. +## Download the Weight Template -Download the official weight template file: +Download the official weight template file using the following commands: ```bash curl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \ --output ./pallets/pallet-custom/frame-weight-template.hbs ``` -### Hardware Requirements for Benchmarking - -!!! warning "Critical: Benchmark on Production-Like Hardware" - Benchmarks must be executed on hardware similar to what will run your chain in production. Weight measurements are hardware-dependent, and benchmarking on different hardware can lead to dangerous under-estimation or wasteful over-estimation of weights. - -Weights represent the actual computational time and resources consumed by extrinsics. These measurements vary significantly across different hardware configurations: - -- **CPU Performance**: Different processors execute instructions at different speeds. A faster development laptop will produce lower weight values than production server hardware -- **Storage Speed**: Database read/write performance varies between NVMe SSDs, SATA SSDs, and HDDs, affecting storage-related weights -- **Memory Bandwidth**: RAM speed impacts how quickly data can be accessed during execution -- **CPU Cache**: Cache size and architecture differences affect repeated operations - -Benchmarking on faster hardware than production leads to under-estimated weights - attackers could submit extrinsics that consume more resources than the weights suggest, potentially causing blocks to take longer than expected to produce or even halting the chain. Conversely, benchmarking on slower hardware creates over-estimated weights, resulting in unnecessarily high transaction fees and wasted block capacity. - -**Best practices:** - -1. **Match production specifications**: If your chain will run on specific validator hardware, benchmark on identical or very similar machines -2. **Use reference hardware**: The Polkadot ecosystem often uses standardized reference hardware specifications for consistency. Consider following these standards if your chain will connect to Polkadot or Kusama -3. **Dedicated benchmarking environment**: Run benchmarks on a machine without other heavy processes to ensure consistent measurements -4. **Document your hardware**: The generated weight files include hardware information in comments. Review this to ensure it matches your production environment -5. **Re-benchmark when hardware changes**: If your validator hardware specifications change, re-run benchmarks and update weights - -For development and testing purposes, you can run benchmarks on any available hardware to verify that your benchmark functions work correctly. However, before deploying to production, always re-run benchmarks on production-equivalent hardware. - -### Execute Benchmarks - -Benchmarks execute against the compiled WASM runtime rather than native code because WASM is what actually runs in production on the blockchain. WASM execution can have different performance characteristics than native code due to compilation and sandboxing overhead, so benchmarking the WASM ensures your weight measurements reflect real-world conditions. - -Run benchmarks for your pallet to generate weight files: - -```bash -frame-omni-bencher v1 benchmark pallet \ - --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ - --pallet pallet_custom \ - --extrinsic "" \ - --template ./pallets/pallet-custom/frame-weight-template.hbs \ - --output ./pallets/pallet-custom/src/weights.rs -``` - -**Command breakdown:** - -- `v1`: Specifies the benchmarking framework version (v2 API) -- `benchmark pallet`: Subcommand indicating you want to benchmark pallet extrinsics -- `--runtime`: Path to the compiled WASM runtime file that includes your pallet and benchmarks -- `--pallet pallet_custom`: Name of the pallet to benchmark (must match the name used in `define_benchmarks!`) -- `--extrinsic ""`: Empty string benchmarks all extrinsics in the pallet; you can specify a single extrinsic name to benchmark only that one -- `--template`: Path to the Handlebars template that formats the output -- `--output`: Destination file path for the generated weights module +The weight template is a Handlebars file that transforms raw benchmark data into a correctly formatted Rust source file. It defines the structure of the generated `weights.rs` file, including imports, trait definitions, documentation comments, and formatting. Using the official template ensures your weight files follow the Polkadot SDK conventions and include all necessary metadata, such as benchmark execution parameters, storage operation counts, and hardware information. -### Advanced Options +## Execute Benchmarks -You can customize benchmark execution with additional parameters for more detailed measurements: +Run benchmarks for your pallet to generate weight files using the following commands: ```bash frame-omni-bencher v1 benchmark pallet \ --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ --pallet pallet_custom \ --extrinsic "" \ - --steps 50 \ - --repeat 20 \ --template ./pallets/pallet-custom/frame-weight-template.hbs \ --output ./pallets/pallet-custom/src/weights.rs ``` -**Additional parameters:** +Benchmarks execute against the compiled WASM runtime rather than native code because WASM is what actually runs in production on the blockchain. WASM execution can have different performance characteristics than native code due to compilation and sandboxing overhead, so benchmarking against the WASM ensures your weight measurements reflect real-world conditions. -- `--steps 50`: Number of different input values to test when using linear components (default: 50). More steps provide finer granularity for detecting complexity trends but increase benchmarking time -- `--repeat 20`: Number of repetitions for each measurement (default: 20). More repetitions improve statistical accuracy by averaging out variance, reducing the impact of system noise and providing more reliable weight estimates -- `--heap-pages 4096`: WASM heap pages allocation. Affects available memory during execution -- `--wasm-execution compiled`: WASM execution method. Use `compiled` for performance closest to production conditions +??? note "Additional customization" -## Step 10: Use Generated Weights + You can customize benchmark execution with additional parameters for more detailed measurements, as shown in the sample code below: -After running benchmarks, a `weights.rs` file is generated containing measured weights. The generated weights are based on actual measurements of your code running on real hardware, accounting for the specific complexity of your logic, storage access patterns, and computational requirements. Estimates or placeholder values cannot capture these nuances and will either waste block space (over-estimation) or create security risks (under-estimation). + ```bash + frame-omni-bencher v1 benchmark pallet \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \ + --pallet pallet_custom \ + --extrinsic "" \ + --steps 50 \ + --repeat 20 \ + --template ./pallets/pallet-custom/frame-weight-template.hbs \ + --output ./pallets/pallet-custom/src/weights.rs + ``` + + - `--steps 50`: Number of different input values to test when using linear components (default: 50). More steps provide finer granularity for detecting complexity trends but increase benchmarking time. + - `--repeat 20`: Number of repetitions for each measurement (default: 20). More repetitions improve statistical accuracy by averaging out variance, reducing the impact of system noise, and providing more reliable weight estimates. + - `--heap-pages 4096`: WASM heap pages allocation. Affects available memory during execution. + - `--wasm-execution compiled`: WASM execution method. Use `compiled` for performance closest to production conditions. -The file includes: +## Use Generated Weights -- Detailed documentation about the benchmark execution environment (date, hardware, parameters) -- The `WeightInfo` trait definition matching your benchmark functions -- `SubstrateWeight` implementation with measured weights from your benchmarks -- Database read/write costs calculated based on observed storage operations -- Component complexity annotations for variable inputs (if you use linear components) -- A fallback `()` implementation for testing environments +After running benchmarks, a `weights.rs` file is generated containing measured weights based on actual measurements of your code running on real hardware, accounting for the specific complexity of your logic, storage access patterns, and computational requirements. -### Integrate the Generated Weights +Follow these steps to use the generated weights with your pallet: -Unlike the benchmarking module (which is only needed when running benchmarks), the weights module must be available in all builds because the runtime needs to call the weight functions during normal operation to calculate transaction fees and enforce block limits. +1. Integrate the generated weights by adding the weights module to your pallet's `lib.rs` as follows: -Add the weights module to your pallet's `lib.rs`: - -```rust title="pallets/pallet-custom/src/lib.rs" -#![cfg_attr(not(feature = "std"), no_std)] + ```rust title="pallets/pallet-custom/src/lib.rs" + #![cfg_attr(not(feature = "std"), no_std)] -extern crate alloc; -use alloc::vec::Vec; + extern crate alloc; + use alloc::vec::Vec; -pub use pallet::*; + pub use pallet::*; -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; + #[cfg(feature = "runtime-benchmarks")] + mod benchmarking; -pub mod weights; + pub mod weights; -#[frame::pallet] -pub mod pallet { - use super::*; - use frame::prelude::*; - use crate::weights::WeightInfo; - // ... rest of pallet -} -``` - -### Update Runtime Configuration - -This change activates your benchmarked weights in the production runtime. Now when users submit transactions that call your pallet's extrinsics, the runtime will use the actual measured weights to calculate fees and enforce block limits. - -Update your runtime configuration to use the generated weights instead of the placeholder `()` implementation: - -```rust title="runtime/src/configs/mod.rs" -impl pallet_custom::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type CounterMaxValue = ConstU32<1000>; - type WeightInfo = pallet_custom::weights::SubstrateWeight; -} -``` - -### Example Generated Weight File - -The generated `weights.rs` file will look similar to this: - -```rust title="pallets/pallet-custom/src/weights.rs" -//! Autogenerated weights for `pallet_custom` -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20` - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(missing_docs)] - -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use core::marker::PhantomData; - -pub trait WeightInfo { - fn set_counter_value() -> Weight; - fn increment() -> Weight; - fn decrement() -> Weight; -} - -pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { - fn set_counter_value() -> Weight { - Weight::from_parts(8_234_000, 0) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) - } - - fn increment() -> Weight { - Weight::from_parts(12_456_000, 0) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } - - fn decrement() -> Weight { - Weight::from_parts(11_987_000, 0) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) + #[frame::pallet] + pub mod pallet { + use super::*; + use frame::prelude::*; + use crate::weights::WeightInfo; + // ... rest of pallet } -} -``` - -**Note**: The actual numbers will vary based on your hardware and implementation complexity. The [`DbWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.RuntimeDbWeight.html){target=\_blank} accounts for database read and write operations. + ``` -## Benchmarking Best Practices + Unlike the benchmarking module (which is only needed when running benchmarks), the weights module must be available in all builds because the runtime needs to call the weight functions during regular operation to calculate transaction fees and enforce block limits. -### 1. Test Worst-Case Scenarios +2. Update your runtime configuration to use the generated weights instead of the placeholder `()` implementation by adding the following code: -Benchmarks should always measure maximum possible resource consumption. If you benchmark average or best-case scenarios, malicious users could craft transactions that hit worst-case paths in your code, consuming more resources than the weights indicate and potentially slowing down or halting block production. - -```rust -#[benchmark] -fn complex_operation() { - // Set up worst-case storage state - for i in 0..100 { - SomeStorage::::insert(i, vec![0u8; 1000]); + ```rust title="runtime/src/configs/mod.rs" + impl pallet_custom::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CounterMaxValue = ConstU32<1000>; + type WeightInfo = pallet_custom::weights::SubstrateWeight; } + ``` - let caller = whitelisted_caller(); - - #[extrinsic_call] - _(RawOrigin::Signed(caller)); -} -``` - -### 2. Use Linear Components for Variable Complexity + This change activates your benchmarked weights in the production runtime. Now, when users submit transactions that call your pallet's extrinsics, the runtime will use the actual measured weights to calculate fees and enforce block limits. -Many extrinsics have variable costs depending on input parameters. [Linear components](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/trait.BenchmarkingSetup.html){target=\_blank} tell the benchmarking framework to test your extrinsic with different values of `n`, measure the execution time for each, and calculate a formula like `Weight = base_weight + (n * per_item_weight)`. This produces dynamic weights that accurately reflect the actual work being done. +??? code "Example generated weight file" + + The generated `weights.rs` file will look similar to this: -When extrinsic complexity depends on input size, use linear components: + ```rust title="pallets/pallet-custom/src/weights.rs" + //! Autogenerated weights for `pallet_custom` + //! + //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 + //! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20` -```rust title="pallets/pallet-custom/src/benchmarking.rs" -#[benchmark] -fn process_items(n: Linear<0, 100>) { - let caller = whitelisted_caller(); - let items: Vec = (0..n).collect(); + #![cfg_attr(rustfmt, rustfmt_skip)] + #![allow(unused_parens)] + #![allow(unused_imports)] + #![allow(missing_docs)] - #[extrinsic_call] - _(RawOrigin::Signed(caller), items); -} -``` + use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; + use core::marker::PhantomData; -### 3. Verify Results - -Assertions ensure that your benchmark is actually testing the code path you think it's testing. If your extrinsic fails silently or takes an early return, the benchmark would measure the wrong scenario and produce inaccurate weights. - -Always assert the expected state after extrinsic execution: - -```rust title="pallets/pallet-custom/src/benchmarking.rs" -#[benchmark] -fn my_extrinsic() { - let caller = whitelisted_caller(); - - #[extrinsic_call] - _(RawOrigin::Signed(caller.clone())); - - // Verify the extrinsic had the expected effect - assert_eq!(MyStorage::::get(&caller), expected_value); -} -``` - -### 4. Minimize Setup Code - -While the benchmarking framework tries to isolate the extrinsic execution, excessive setup code can add noise to measurements. More importantly, setup code that doesn't reflect real-world pre-conditions can lead to benchmarking unrealistic scenarios. + pub trait WeightInfo { + fn set_counter_value() -> Weight; + fn increment() -> Weight; + fn decrement() -> Weight; + } -Only include necessary setup in benchmarks: + pub struct SubstrateWeight(PhantomData); + impl WeightInfo for SubstrateWeight { + fn set_counter_value() -> Weight { + Weight::from_parts(8_234_000, 0) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } -```rust title="pallets/pallet-custom/src/benchmarking.rs" -#[benchmark] -fn efficient_benchmark() { - // Minimal setup - let caller = whitelisted_caller(); + fn increment() -> Weight { + Weight::from_parts(12_456_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } - #[extrinsic_call] - _(RawOrigin::Signed(caller)); + fn decrement() -> Weight { + Weight::from_parts(11_987_000, 0) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + } + ``` - // Minimal assertions -} -``` + The actual numbers in your `weights.rs` file will vary based on your hardware and implementation complexity. The [`DbWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.RuntimeDbWeight.html){target=\_blank} accounts for database read and write operations. ## Run Your Chain Locally -Now that you've added the pallet to your runtime, you can launch your parachain locally to test the new functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}. For instructions on setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\_blank}, refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\_blank} guide. - -### Build the Production Runtime - -The `runtime-benchmarks` feature flag adds special host functions (like `ext_benchmarking_current_time` and `ext_benchmarking_get_read_and_written_keys`) that are only available in the benchmarking execution environment. These functions allow the benchmarking framework to precisely measure execution time and track storage operations. However, regular nodes don't provide these host functions, so a runtime compiled with benchmarking features will fail to start on a production node. - -Before running your chain, rebuild the runtime **without** the `runtime-benchmarks` feature: - -```bash -cargo build --release -``` - -!!! note "Build Types" - Understanding the difference between builds is critical: - - - `cargo build --release --features runtime-benchmarks` - Compiles with benchmarking host functions for measurement. Use this ONLY when running benchmarks with `frame-omni-bencher` - - `cargo build --release` - Compiles production runtime without benchmarking features. Use this for running your actual chain +Now that you've added the pallet to your runtime, you can follow these steps to launch your parachain locally to test the new functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\_blank}: -This produces a production-ready WASM runtime at `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm`. +1. Before running your chain, rebuild the production runtime without the `runtime-benchmarks` feature using the following command: -### Generate a Chain Specification + ```bash + cargo build --release + ``` -The chain specification defines the initial state and configuration of your blockchain, including the runtime WASM code, genesis storage, and network parameters. By generating a new chain spec with your updated runtime (now containing your benchmarked pallet), you ensure that nodes starting from this spec will use the correct version of your code with proper weight calculations. + The `runtime-benchmarks` feature flag adds special host functions that are only available in the benchmarking execution environment. A runtime compiled with benchmarking features will fail to start on a production node. -Create a new chain specification file with the updated runtime: + This build produces a production-ready WASM runtime at `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm`. -```bash -chain-spec-builder create -t development \ ---relay-chain paseo \ ---para-id 1000 \ ---runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ -named-preset development -``` + !!! note "Compare build types" + - `cargo build --release --features runtime-benchmarks` - Compiles with benchmarking host functions for measurement. Use this ONLY when running benchmarks with `frame-omni-bencher`. + - `cargo build --release` - Compiles production runtime without benchmarking features. Use this for running your chain in production. -This command generates a chain specification file, `chain_spec.json`, for your parachain with the updated runtime. +2. Generate a new chain specification file with the updated runtime using the following commands: -### Start the Parachain Node + ```bash + chain-spec-builder create -t development \ + --relay-chain paseo \ + --para-id 1000 \ + --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \ + named-preset development + ``` -Launch the parachain using the Polkadot Omni Node with the generated chain specification by running the following command: + This command generates a chain specification file, `chain_spec.json`, for your parachain with the updated runtime, which defines the initial state and configuration of your blockchain, including the runtime WASM code, genesis storage, and network parameters. Generating this new chain spec with your updated runtime ensures nodes starting from this spec will use the correct version of your code with proper weight calculations. -```bash -polkadot-omni-node --chain ./chain_spec.json --dev -``` +3. Start the parachain node using the Polkadot Omni Node with the generated chain specification by running the following command: -The node will start and display initialization information including: + ```bash + polkadot-omni-node --chain ./chain_spec.json --dev + ``` -- The chain specification name -- The node identity and peer ID -- Database location -- Network endpoints (JSON-RPC and Prometheus) + The node will start and display initialization information, including: -### Verify Block Production + - The chain specification name + - The node identity and peer ID + - Database location + - Network endpoints (JSON-RPC and Prometheus) -Once the node is running, you should see log messages indicating successful block production: +4. Once the node is running, you will see log messages confirming successful production of blocks similar to the following: -``` -[Parachain] 🔨 Initializing Genesis block/state (state: 0x47ce…ec8d, header-hash: 0xeb12…fecc) -[Parachain] 🎁 Prepared block for proposing at 1 (3 ms) ... -[Parachain] 🏆 Imported #1 (0xeb12…fecc → 0xee51…98d2) -[Parachain] 🎁 Prepared block for proposing at 2 (3 ms) ... -[Parachain] 🏆 Imported #2 (0xee51…98d2 → 0x35e0…cc32) -``` +
+ polkadot-omni-node --chain ./chain_spec.json --dev + [Parachain] 🔨 Initializing Genesis block/state (state: 0x47ce…ec8d, header-hash: 0xeb12…fecc) + [Parachain] 🎁 Prepared block for proposing at 1 (3 ms) ... + [Parachain] 🏆 Imported #1 (0xeb12…fecc → 0xee51…98d2) + [Parachain] 🎁 Prepared block for proposing at 2 (3 ms) ... + [Parachain] 🏆 Imported #2 (0xee51…98d2 → 0x35e0…cc32) + +
-The parachain will produce new blocks every few seconds. You can now interact with your pallet's extrinsics through the JSON-RPC endpoint at `http://127.0.0.1:9944` using tools like [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\_blank}. + The parachain will produce new blocks every few seconds. You can now interact with your pallet's extrinsics through the JSON-RPC endpoint at `http://127.0.0.1:9944` using tools like [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\_blank}. ## Related Resources diff --git a/.ai/pages/parachains-customize-runtime-pallet-development-pallet-testing.md b/.ai/pages/parachains-customize-runtime-pallet-development-pallet-testing.md index b26d07b1f..06a497f7c 100644 --- a/.ai/pages/parachains-customize-runtime-pallet-development-pallet-testing.md +++ b/.ai/pages/parachains-customize-runtime-pallet-development-pallet-testing.md @@ -1,11 +1,11 @@ --- -title: Pallet Testing +title: Unit Test Pallets description: Learn how to efficiently test pallets in the Polkadot SDK, ensuring the reliability and security of your pallets operations. categories: Parachains url: https://docs.polkadot.com/parachains/customize-runtime/pallet-development/pallet-testing/ --- -# Pallet Testing +# Unit Test Pallets ## Introduction diff --git a/llms-full.jsonl b/llms-full.jsonl index 5f037cdff..9c1a59263 100644 --- a/llms-full.jsonl +++ b/llms-full.jsonl @@ -268,44 +268,24 @@ {"page_id": "parachains-customize-runtime-pallet-development-add-pallet-to-runtime", "page_title": "Add Pallets to the Runtime", "index": 3, "depth": 2, "title": "Recompile the Runtime", "anchor": "recompile-the-runtime", "start_char": 10415, "end_char": 10864, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "## Recompile the Runtime\n\nAfter adding and configuring your pallets in the runtime, the next step is to ensure everything is set up correctly. To do this, recompile the runtime with the following command (make sure you're in the project's root directory):\n\n```bash\ncargo build --release\n```\n\nThis command ensures the runtime compiles without errors, validates the pallet configurations, and prepares the build for subsequent testing or deployment."} {"page_id": "parachains-customize-runtime-pallet-development-add-pallet-to-runtime", "page_title": "Add Pallets to the Runtime", "index": 4, "depth": 2, "title": "Run Your Chain Locally", "anchor": "run-your-chain-locally", "start_char": 10864, "end_char": 12339, "estimated_token_count": 365, "token_estimator": "heuristic-v1", "text": "## Run Your Chain Locally\n\nLaunch your parachain locally and start producing blocks:\n\n!!!tip\n Generated chain TestNet specifications include development accounts \"Alice\" and \"Bob.\" These accounts are pre-funded with native parachain currency, allowing you to sign and send TestNet transactions. Take a look at the [Polkadot.js Accounts section](https://polkadot.js.org/apps/#/accounts){target=\\_blank} to view the development accounts for your chain.\n\n1. Create a new chain specification file with the updated runtime:\n\n ```bash\n chain-spec-builder create -t development \\\n --relay-chain paseo \\\n --para-id 1000 \\\n --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \\\n named-preset development\n ```\n\n2. Start the omni node with the generated chain specification:\n\n ```bash\n polkadot-omni-node --chain ./chain_spec.json --dev\n ```\n\n3. Verify you can interact with the new pallets using the [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/extrinsics){target=\\_blank} interface. Navigate to the **Extrinsics** tab and check that you can see both pallets:\n\n - Utility pallet\n\n ![](/images/parachains/customize-runtime/pallet-development/add-pallet-to-runtime/add-pallets-to-runtime-01.webp)\n \n\n - Custom pallet\n\n ![](/images/parachains/customize-runtime/pallet-development/add-pallet-to-runtime/add-pallets-to-runtime-02.webp)"} {"page_id": "parachains-customize-runtime-pallet-development-add-pallet-to-runtime", "page_title": "Add Pallets to the Runtime", "index": 5, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 12339, "end_char": 13091, "estimated_token_count": 183, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Tutorial __Deploy on Paseo TestNet__\n\n ---\n\n Deploy your Polkadot SDK blockchain on Paseo! Follow this step-by-step guide for a seamless journey to a successful TestNet deployment.\n\n [:octicons-arrow-right-24: Get Started](/tutorials/polkadot-sdk/parachains/zero-to-hero/deploy-to-testnet/)\n\n- Tutorial __Pallet Benchmarking (Optional)__\n\n ---\n\n Discover how to measure extrinsic costs and assign precise weights to optimize your pallet for accurate fees and runtime performance.\n\n [:octicons-arrow-right-24: Get Started](/tutorials/polkadot-sdk/parachains/zero-to-hero/pallet-benchmarking/)\n\n
"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 0, "end_char": 868, "estimated_token_count": 183, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nBenchmarking is the process of measuring the computational resources (execution time and storage) required by your pallet's extrinsics. Accurate [weight](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/index.html){target=\\_blank} calculations are essential for ensuring your blockchain can process transactions efficiently while protecting against denial-of-service attacks.\n\nThis guide continues the pallet development series, building on the [Create a Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet), [Mock Your Runtime](/parachains/customize-runtime/pallet-development/mock-runtime), and [Test Your Pallet](/parachains/customize-runtime/pallet-development/pallet-testing) tutorials. You'll learn how to benchmark the counter pallet extrinsics and integrate the generated weights into your runtime."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 868, "end_char": 1071, "estimated_token_count": 32, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore you begin, ensure you have:\n\n- Completed the previous pallet development tutorials\n- Basic understanding of computational complexity\n- Familiarity with Rust's testing framework"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 2, "depth": 2, "title": "Why Benchmark?", "anchor": "why-benchmark", "start_char": 1071, "end_char": 1723, "estimated_token_count": 109, "token_estimator": "heuristic-v1", "text": "## Why Benchmark?\n\nIn blockchain systems, every operation consumes resources. Weight is the mechanism Polkadot SDK uses to measure and limit resource consumption. Without accurate weights:\n\n- **Security Risk**: Malicious actors could submit transactions that consume excessive resources, blocking legitimate transactions or halting the chain\n- **Inefficiency**: Over-estimated weights waste block space and reduce throughput\n- **User Experience**: Inaccurate weights lead to incorrect fee calculations\n\nBenchmarking provides empirical measurements of your extrinsics under various conditions, ensuring weights reflect real-world resource consumption."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 3, "depth": 2, "title": "Understanding Weights", "anchor": "understanding-weights", "start_char": 1723, "end_char": 2778, "estimated_token_count": 255, "token_estimator": "heuristic-v1", "text": "## Understanding Weights\n\nThe [weight system](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html){target=\\_blank} serves multiple purposes:\n\n- **DoS Protection**: Limits the computational work per block, preventing attackers from overwhelming the network\n- **Fee Calculation**: Determines transaction fees based on actual resource usage\n- **Block Production**: Helps block authors maximize throughput while staying within block limits\n\nWeights are expressed as [`Weight::from_parts(ref_time, proof_size)`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.from_parts){target=\\_blank} where:\n\n- [`ref_time`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.ref_time){target=\\_blank}: Computational time measured in picoseconds\n- [`proof_size`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html#method.proof_size){target=\\_blank}: Storage proof size in bytes"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 4, "depth": 2, "title": "Step 1: Create the Benchmarking Module", "anchor": "step-1-create-the-benchmarking-module", "start_char": 2778, "end_char": 5474, "estimated_token_count": 728, "token_estimator": "heuristic-v1", "text": "## Step 1: Create the Benchmarking Module\n\nCreate a new file `benchmarking.rs` in your pallet's `src` directory. This module will contain all the [benchmarking definitions](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\\_blank} for your pallet:\n\n```rust title=\"pallets/pallet-custom/src/benchmarking.rs\"\n#![cfg(feature = \"runtime-benchmarks\")]\n\nuse super::*;\nuse frame::deps::frame_benchmarking::v2::*;\nuse frame::benchmarking::prelude::RawOrigin;\n\n#[benchmarks]\nmod benchmarks {\n use super::*;\n\n #[benchmark]\n fn set_counter_value() {\n let new_value: u32 = 100;\n\n #[extrinsic_call]\n _(RawOrigin::Root, new_value);\n\n assert_eq!(CounterValue::::get(), new_value);\n }\n\n #[benchmark]\n fn increment() {\n let caller: T::AccountId = whitelisted_caller();\n let amount: u32 = 50;\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller.clone()), amount);\n\n assert_eq!(CounterValue::::get(), amount);\n assert_eq!(UserInteractions::::get(caller), 1);\n }\n\n #[benchmark]\n fn decrement() {\n // First set the counter to a non-zero value\n CounterValue::::put(100);\n\n let caller: T::AccountId = whitelisted_caller();\n let amount: u32 = 30;\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller.clone()), amount);\n\n assert_eq!(CounterValue::::get(), 70);\n assert_eq!(UserInteractions::::get(caller), 1);\n }\n\n impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test);\n}\n```\n\n**Key components:**\n\n- **`#![cfg(feature = \"runtime-benchmarks\")]`**: Ensures benchmarking code only compiles when the feature is enabled\n- **[`#[benchmarks]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmarks.html){target=\\_blank}**: Marks the module containing benchmark definitions\n- **[`#[benchmark]` macro](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.benchmark.html){target=\\_blank}**: Defines individual benchmark functions\n- **[`#[extrinsic_call]`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/attr.extrinsic_call.html){target=\\_blank}**: Marks the actual extrinsic invocation to measure\n- **[`whitelisted_caller()`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/fn.whitelisted_caller.html){target=\\_blank}**: Generates a funded account for benchmarking\n- **[`impl_benchmark_test_suite!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.impl_benchmark_test_suite.html){target=\\_blank}**: Generates test functions to verify benchmarks work correctly"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 5, "depth": 2, "title": "Step 2: Define the Weight Trait", "anchor": "step-2-define-the-weight-trait", "start_char": 5474, "end_char": 6891, "estimated_token_count": 297, "token_estimator": "heuristic-v1", "text": "## Step 2: Define the Weight Trait\n\nThe [`WeightInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/trait.WeightInfo.html){target=\\_blank} trait provides an abstraction layer that allows weights to be swapped at runtime configuration. This enables you to use placeholder weights during development and testing, then switch to auto-generated benchmarked weights in production without modifying the pallet code itself.\n\nAdd a `weights` module to your pallet that defines the `WeightInfo` trait:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#[frame::pallet]\npub mod pallet {\n use frame::prelude::*;\n pub use weights::WeightInfo;\n\n pub mod weights {\n use frame::prelude::*;\n\n pub trait WeightInfo {\n fn set_counter_value() -> Weight;\n fn increment() -> Weight;\n fn decrement() -> Weight;\n }\n\n impl WeightInfo for () {\n fn set_counter_value() -> Weight {\n Weight::from_parts(10_000, 0)\n }\n fn increment() -> Weight {\n Weight::from_parts(15_000, 0)\n }\n fn decrement() -> Weight {\n Weight::from_parts(15_000, 0)\n }\n }\n }\n\n // ... rest of pallet\n}\n```\n\nThe `()` implementation provides placeholder weights for development. Later, this will be replaced with auto-generated weights from benchmarking."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 6, "depth": 2, "title": "Step 3: Add WeightInfo to Config", "anchor": "step-3-add-weightinfo-to-config", "start_char": 6891, "end_char": 7656, "estimated_token_count": 169, "token_estimator": "heuristic-v1", "text": "## Step 3: Add WeightInfo to Config\n\nBy making `WeightInfo` an associated type in the `Config` trait, you allow each runtime that uses your pallet to specify which weight implementation to use. Different deployment environments (testnets, production chains, or different hardware configurations) may have different performance characteristics and can use different weight calculations.\n\nUpdate your pallet's `Config` trait to include `WeightInfo`:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#[pallet::config]\npub trait Config: frame_system::Config {\n type RuntimeEvent: From> + IsType<::RuntimeEvent>;\n\n #[pallet::constant]\n type CounterMaxValue: Get;\n\n type WeightInfo: weights::WeightInfo;\n}\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 7, "depth": 2, "title": "Step 4: Update Extrinsic Weight Annotations", "anchor": "step-4-update-extrinsic-weight-annotations", "start_char": 7656, "end_char": 8833, "estimated_token_count": 290, "token_estimator": "heuristic-v1", "text": "## Step 4: Update Extrinsic Weight Annotations\n\nBy calling `T::WeightInfo::function_name()` instead of using hardcoded `Weight::from_parts()` values, your extrinsics automatically use whichever weight implementation is configured in the runtime. This allows you to easily switch between placeholder weights for testing and benchmarked weights for production without changing any pallet code.\n\nReplace the placeholder weights in your extrinsics with calls to the `WeightInfo` trait:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#[pallet::call]\nimpl Pallet {\n #[pallet::call_index(0)]\n #[pallet::weight(T::WeightInfo::set_counter_value())]\n pub fn set_counter_value(origin: OriginFor, new_value: u32) -> DispatchResult {\n // ... implementation\n }\n\n #[pallet::call_index(1)]\n #[pallet::weight(T::WeightInfo::increment())]\n pub fn increment(origin: OriginFor, amount: u32) -> DispatchResult {\n // ... implementation\n }\n\n #[pallet::call_index(2)]\n #[pallet::weight(T::WeightInfo::decrement())]\n pub fn decrement(origin: OriginFor, amount: u32) -> DispatchResult {\n // ... implementation\n }\n}\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 8, "depth": 2, "title": "Step 5: Include the Benchmarking Module", "anchor": "step-5-include-the-benchmarking-module", "start_char": 8833, "end_char": 9453, "estimated_token_count": 161, "token_estimator": "heuristic-v1", "text": "## Step 5: Include the Benchmarking Module\n\nThe `#[cfg(feature = \"runtime-benchmarks\")]` attribute ensures that benchmarking code is only compiled when explicitly needed. This keeps your production runtime lean by excluding benchmarking infrastructure from normal builds, as it's only needed when generating weights.\n\nAt the top of your `lib.rs`, add the module declaration:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#![cfg_attr(not(feature = \"std\"), no_std)]\n\nextern crate alloc;\nuse alloc::vec::Vec;\n\npub use pallet::*;\n\n#[cfg(feature = \"runtime-benchmarks\")]\nmod benchmarking;\n\n// ... rest of the pallet\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 9, "depth": 2, "title": "Step 6: Configure Pallet Dependencies", "anchor": "step-6-configure-pallet-dependencies", "start_char": 9453, "end_char": 10350, "estimated_token_count": 212, "token_estimator": "heuristic-v1", "text": "## Step 6: Configure Pallet Dependencies\n\nThe feature flag system in Cargo allows you to conditionally compile code based on which features are enabled. By defining a `runtime-benchmarks` feature that cascades to FRAME's benchmarking features, you create a clean way to build your pallet with or without benchmarking support, ensuring all necessary dependencies are available when needed but excluded from production builds.\n\nUpdate your pallet's `Cargo.toml` to enable the benchmarking feature:\n\n```toml title=\"pallets/pallet-custom/Cargo.toml\"\n[dependencies]\ncodec = { features = [\"derive\"], workspace = true }\nscale-info = { features = [\"derive\"], workspace = true }\nframe = { features = [\"experimental\", \"runtime\"], workspace = true }\n\n[features]\ndefault = [\"std\"]\nruntime-benchmarks = [\n \"frame/runtime-benchmarks\",\n]\nstd = [\n \"codec/std\",\n \"scale-info/std\",\n \"frame/std\",\n]\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 10, "depth": 2, "title": "Step 7: Update Mock Runtime", "anchor": "step-7-update-mock-runtime", "start_char": 10350, "end_char": 10898, "estimated_token_count": 117, "token_estimator": "heuristic-v1", "text": "## Step 7: Update Mock Runtime\n\nIn your mock runtime for testing, use the placeholder `()` implementation of `WeightInfo` since unit tests focus on verifying functional correctness rather than performance characteristics. This keeps tests fast and focused on validating logic.\n\nAdd the `WeightInfo` type to your test configuration in `mock.rs`:\n\n```rust title=\"pallets/pallet-custom/src/mock.rs\"\nimpl pallet_custom::Config for Test {\n type RuntimeEvent = RuntimeEvent;\n type CounterMaxValue = ConstU32<1000>;\n type WeightInfo = ();\n}\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 11, "depth": 2, "title": "Step 8: Configure Runtime Benchmarking", "anchor": "step-8-configure-runtime-benchmarking", "start_char": 10898, "end_char": 11085, "estimated_token_count": 31, "token_estimator": "heuristic-v1", "text": "## Step 8: Configure Runtime Benchmarking\n\nTo execute benchmarks, your pallet must be integrated into the runtime's benchmarking infrastructure. This involves three configuration steps:"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 12, "depth": 3, "title": "Update Runtime Cargo.toml", "anchor": "update-runtime-cargotoml", "start_char": 11085, "end_char": 11652, "estimated_token_count": 137, "token_estimator": "heuristic-v1", "text": "### Update Runtime Cargo.toml\n\nWhen you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included.\n\nAdd your pallet to the runtime's `runtime-benchmarks` feature in `runtime/Cargo.toml`:\n\n```toml title=\"runtime/Cargo.toml\"\nruntime-benchmarks = [\n \"cumulus-pallet-parachain-system/runtime-benchmarks\",\n \"hex-literal\",\n \"pallet-parachain-template/runtime-benchmarks\",\n \"polkadot-sdk/runtime-benchmarks\",\n \"pallet-custom/runtime-benchmarks\",\n]\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 13, "depth": 3, "title": "Update Runtime Configuration", "anchor": "update-runtime-configuration", "start_char": 11652, "end_char": 12130, "estimated_token_count": 103, "token_estimator": "heuristic-v1", "text": "### Update Runtime Configuration\n\nStart with the placeholder implementation during development. After successfully running benchmarks and generating the weights file, you'll update this to use the benchmarked weights.\n\nIn `runtime/src/configs/mod.rs`, add the `WeightInfo` type:\n\n```rust title=\"runtime/src/configs/mod.rs\"\nimpl pallet_custom::Config for Runtime {\n type RuntimeEvent = RuntimeEvent;\n type CounterMaxValue = ConstU32<1000>;\n type WeightInfo = ();\n}\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 14, "depth": 3, "title": "Register Benchmarks", "anchor": "register-benchmarks", "start_char": 12130, "end_char": 12611, "estimated_token_count": 104, "token_estimator": "heuristic-v1", "text": "### Register Benchmarks\n\nThe `define_benchmarks!` macro creates the infrastructure that allows the benchmarking CLI tool to discover and execute your pallet's benchmarks.\n\nAdd your pallet to the benchmark list in `runtime/src/benchmarks.rs`:\n\n```rust title=\"runtime/src/benchmarks.rs\"\npolkadot_sdk::frame_benchmarking::define_benchmarks!(\n [frame_system, SystemBench::]\n [pallet_balances, Balances]\n // ... other pallets\n [pallet_custom, CustomPallet]\n);\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 15, "depth": 2, "title": "Step 9: Run Benchmarks", "anchor": "step-9-run-benchmarks", "start_char": 12611, "end_char": 12638, "estimated_token_count": 7, "token_estimator": "heuristic-v1", "text": "## Step 9: Run Benchmarks"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 16, "depth": 3, "title": "Test Benchmark Compilation", "anchor": "test-benchmark-compilation", "start_char": 12638, "end_char": 13283, "estimated_token_count": 128, "token_estimator": "heuristic-v1", "text": "### Test Benchmark Compilation\n\nThe `impl_benchmark_test_suite!` macro generates unit tests for each benchmark. Running these tests verifies that your benchmarks compile correctly, execute without panicking, and pass their assertions, catching issues early before building the full runtime.\n\nFirst, verify your benchmarks compile and run as tests:\n\n```bash\ncargo test -p pallet-custom --features runtime-benchmarks\n```\n\nYou should see your benchmark tests passing:\n\n```\ntest benchmarking::benchmarks::bench_set_counter_value ... ok\ntest benchmarking::benchmarks::bench_increment ... ok\ntest benchmarking::benchmarks::bench_decrement ... ok\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 17, "depth": 3, "title": "Build the Runtime with Benchmarks", "anchor": "build-the-runtime-with-benchmarks", "start_char": 13283, "end_char": 13996, "estimated_token_count": 132, "token_estimator": "heuristic-v1", "text": "### Build the Runtime with Benchmarks\n\nThis build includes all the benchmarking infrastructure and special host functions needed for measurement. The resulting WASM runtime contains your benchmark code and can communicate with the benchmarking tool's execution environment. This is a special build used only for benchmarking - you'll create a different build later for actually running your chain.\n\nCompile the runtime with benchmarking enabled to generate the WASM binary:\n\n```bash\ncargo build --release --features runtime-benchmarks\n```\n\nThis produces the runtime WASM file needed for benchmarking, typically located at:\n```\ntarget/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 18, "depth": 3, "title": "Install the Benchmarking Tool", "anchor": "install-the-benchmarking-tool", "start_char": 13996, "end_char": 14536, "estimated_token_count": 118, "token_estimator": "heuristic-v1", "text": "### Install the Benchmarking Tool\n\n[`frame-omni-bencher`](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\\_blank} is the official Polkadot SDK tool specifically designed for FRAME pallet benchmarking. It provides a standardized way to execute benchmarks, measure execution times and storage operations, and generate properly formatted weight files with full integration into the FRAME weight system.\n\nInstall the `frame-omni-bencher` CLI tool:\n\n```bash\ncargo install frame-omni-bencher --locked\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 19, "depth": 3, "title": "Download the Weight Template", "anchor": "download-the-weight-template", "start_char": 14536, "end_char": 15301, "estimated_token_count": 155, "token_estimator": "heuristic-v1", "text": "### Download the Weight Template\n\nThe weight template is a Handlebars file that transforms raw benchmark data into a properly formatted Rust source file. It defines the structure of the generated `weights.rs` file, including imports, trait definitions, documentation comments, and formatting. Using the official template ensures your weight files follow Polkadot SDK conventions and include all necessary metadata like benchmark execution parameters, storage operation counts, and hardware information.\n\nDownload the official weight template file:\n\n```bash\ncurl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \\\n--output ./pallets/pallet-custom/frame-weight-template.hbs\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 20, "depth": 3, "title": "Hardware Requirements for Benchmarking", "anchor": "hardware-requirements-for-benchmarking", "start_char": 15301, "end_char": 17789, "estimated_token_count": 432, "token_estimator": "heuristic-v1", "text": "### Hardware Requirements for Benchmarking\n\n!!! warning \"Critical: Benchmark on Production-Like Hardware\"\n Benchmarks must be executed on hardware similar to what will run your chain in production. Weight measurements are hardware-dependent, and benchmarking on different hardware can lead to dangerous under-estimation or wasteful over-estimation of weights.\n\nWeights represent the actual computational time and resources consumed by extrinsics. These measurements vary significantly across different hardware configurations:\n\n- **CPU Performance**: Different processors execute instructions at different speeds. A faster development laptop will produce lower weight values than production server hardware\n- **Storage Speed**: Database read/write performance varies between NVMe SSDs, SATA SSDs, and HDDs, affecting storage-related weights\n- **Memory Bandwidth**: RAM speed impacts how quickly data can be accessed during execution\n- **CPU Cache**: Cache size and architecture differences affect repeated operations\n\nBenchmarking on faster hardware than production leads to under-estimated weights - attackers could submit extrinsics that consume more resources than the weights suggest, potentially causing blocks to take longer than expected to produce or even halting the chain. Conversely, benchmarking on slower hardware creates over-estimated weights, resulting in unnecessarily high transaction fees and wasted block capacity.\n\n**Best practices:**\n\n1. **Match production specifications**: If your chain will run on specific validator hardware, benchmark on identical or very similar machines\n2. **Use reference hardware**: The Polkadot ecosystem often uses standardized reference hardware specifications for consistency. Consider following these standards if your chain will connect to Polkadot or Kusama\n3. **Dedicated benchmarking environment**: Run benchmarks on a machine without other heavy processes to ensure consistent measurements\n4. **Document your hardware**: The generated weight files include hardware information in comments. Review this to ensure it matches your production environment\n5. **Re-benchmark when hardware changes**: If your validator hardware specifications change, re-run benchmarks and update weights\n\nFor development and testing purposes, you can run benchmarks on any available hardware to verify that your benchmark functions work correctly. However, before deploying to production, always re-run benchmarks on production-equivalent hardware."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 21, "depth": 3, "title": "Execute Benchmarks", "anchor": "execute-benchmarks", "start_char": 17789, "end_char": 19210, "estimated_token_count": 294, "token_estimator": "heuristic-v1", "text": "### Execute Benchmarks\n\nBenchmarks execute against the compiled WASM runtime rather than native code because WASM is what actually runs in production on the blockchain. WASM execution can have different performance characteristics than native code due to compilation and sandboxing overhead, so benchmarking the WASM ensures your weight measurements reflect real-world conditions.\n\nRun benchmarks for your pallet to generate weight files:\n\n```bash\nframe-omni-bencher v1 benchmark pallet \\\n --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \\\n --pallet pallet_custom \\\n --extrinsic \"\" \\\n --template ./pallets/pallet-custom/frame-weight-template.hbs \\\n --output ./pallets/pallet-custom/src/weights.rs\n```\n\n**Command breakdown:**\n\n- `v1`: Specifies the benchmarking framework version (v2 API)\n- `benchmark pallet`: Subcommand indicating you want to benchmark pallet extrinsics\n- `--runtime`: Path to the compiled WASM runtime file that includes your pallet and benchmarks\n- `--pallet pallet_custom`: Name of the pallet to benchmark (must match the name used in `define_benchmarks!`)\n- `--extrinsic \"\"`: Empty string benchmarks all extrinsics in the pallet; you can specify a single extrinsic name to benchmark only that one\n- `--template`: Path to the Handlebars template that formats the output\n- `--output`: Destination file path for the generated weights module"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 22, "depth": 3, "title": "Advanced Options", "anchor": "advanced-options", "start_char": 19210, "end_char": 20357, "estimated_token_count": 242, "token_estimator": "heuristic-v1", "text": "### Advanced Options\n\nYou can customize benchmark execution with additional parameters for more detailed measurements:\n\n```bash\nframe-omni-bencher v1 benchmark pallet \\\n --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \\\n --pallet pallet_custom \\\n --extrinsic \"\" \\\n --steps 50 \\\n --repeat 20 \\\n --template ./pallets/pallet-custom/frame-weight-template.hbs \\\n --output ./pallets/pallet-custom/src/weights.rs\n```\n\n**Additional parameters:**\n\n- `--steps 50`: Number of different input values to test when using linear components (default: 50). More steps provide finer granularity for detecting complexity trends but increase benchmarking time\n- `--repeat 20`: Number of repetitions for each measurement (default: 20). More repetitions improve statistical accuracy by averaging out variance, reducing the impact of system noise and providing more reliable weight estimates\n- `--heap-pages 4096`: WASM heap pages allocation. Affects available memory during execution\n- `--wasm-execution compiled`: WASM execution method. Use `compiled` for performance closest to production conditions"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 23, "depth": 2, "title": "Step 10: Use Generated Weights", "anchor": "step-10-use-generated-weights", "start_char": 20357, "end_char": 21332, "estimated_token_count": 168, "token_estimator": "heuristic-v1", "text": "## Step 10: Use Generated Weights\n\nAfter running benchmarks, a `weights.rs` file is generated containing measured weights. The generated weights are based on actual measurements of your code running on real hardware, accounting for the specific complexity of your logic, storage access patterns, and computational requirements. Estimates or placeholder values cannot capture these nuances and will either waste block space (over-estimation) or create security risks (under-estimation).\n\nThe file includes:\n\n- Detailed documentation about the benchmark execution environment (date, hardware, parameters)\n- The `WeightInfo` trait definition matching your benchmark functions\n- `SubstrateWeight` implementation with measured weights from your benchmarks\n- Database read/write costs calculated based on observed storage operations\n- Component complexity annotations for variable inputs (if you use linear components)\n- A fallback `()` implementation for testing environments"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 24, "depth": 3, "title": "Integrate the Generated Weights", "anchor": "integrate-the-generated-weights", "start_char": 21332, "end_char": 22065, "estimated_token_count": 189, "token_estimator": "heuristic-v1", "text": "### Integrate the Generated Weights\n\nUnlike the benchmarking module (which is only needed when running benchmarks), the weights module must be available in all builds because the runtime needs to call the weight functions during normal operation to calculate transaction fees and enforce block limits.\n\nAdd the weights module to your pallet's `lib.rs`:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#![cfg_attr(not(feature = \"std\"), no_std)]\n\nextern crate alloc;\nuse alloc::vec::Vec;\n\npub use pallet::*;\n\n#[cfg(feature = \"runtime-benchmarks\")]\nmod benchmarking;\n\npub mod weights;\n\n#[frame::pallet]\npub mod pallet {\n use super::*;\n use frame::prelude::*;\n use crate::weights::WeightInfo;\n // ... rest of pallet\n}\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 25, "depth": 3, "title": "Update Runtime Configuration", "anchor": "update-runtime-configuration-2", "start_char": 22065, "end_char": 22694, "estimated_token_count": 121, "token_estimator": "heuristic-v1", "text": "### Update Runtime Configuration\n\nThis change activates your benchmarked weights in the production runtime. Now when users submit transactions that call your pallet's extrinsics, the runtime will use the actual measured weights to calculate fees and enforce block limits.\n\nUpdate your runtime configuration to use the generated weights instead of the placeholder `()` implementation:\n\n```rust title=\"runtime/src/configs/mod.rs\"\nimpl pallet_custom::Config for Runtime {\n type RuntimeEvent = RuntimeEvent;\n type CounterMaxValue = ConstU32<1000>;\n type WeightInfo = pallet_custom::weights::SubstrateWeight;\n}\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 26, "depth": 3, "title": "Example Generated Weight File", "anchor": "example-generated-weight-file", "start_char": 22694, "end_char": 24357, "estimated_token_count": 450, "token_estimator": "heuristic-v1", "text": "### Example Generated Weight File\n\nThe generated `weights.rs` file will look similar to this:\n\n```rust title=\"pallets/pallet-custom/src/weights.rs\"\n//! Autogenerated weights for `pallet_custom`\n//!\n//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0\n//! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20`\n\n#![cfg_attr(rustfmt, rustfmt_skip)]\n#![allow(unused_parens)]\n#![allow(unused_imports)]\n#![allow(missing_docs)]\n\nuse frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};\nuse core::marker::PhantomData;\n\npub trait WeightInfo {\n fn set_counter_value() -> Weight;\n fn increment() -> Weight;\n fn decrement() -> Weight;\n}\n\npub struct SubstrateWeight(PhantomData);\nimpl WeightInfo for SubstrateWeight {\n fn set_counter_value() -> Weight {\n Weight::from_parts(8_234_000, 0)\n .saturating_add(T::DbWeight::get().reads(1))\n .saturating_add(T::DbWeight::get().writes(1))\n }\n\n fn increment() -> Weight {\n Weight::from_parts(12_456_000, 0)\n .saturating_add(T::DbWeight::get().reads(2))\n .saturating_add(T::DbWeight::get().writes(2))\n }\n\n fn decrement() -> Weight {\n Weight::from_parts(11_987_000, 0)\n .saturating_add(T::DbWeight::get().reads(2))\n .saturating_add(T::DbWeight::get().writes(2))\n }\n}\n```\n\n**Note**: The actual numbers will vary based on your hardware and implementation complexity. The [`DbWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.RuntimeDbWeight.html){target=\\_blank} accounts for database read and write operations."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 27, "depth": 2, "title": "Benchmarking Best Practices", "anchor": "benchmarking-best-practices", "start_char": 24357, "end_char": 24389, "estimated_token_count": 5, "token_estimator": "heuristic-v1", "text": "## Benchmarking Best Practices"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 28, "depth": 3, "title": "1. Test Worst-Case Scenarios", "anchor": "1-test-worst-case-scenarios", "start_char": 24389, "end_char": 25006, "estimated_token_count": 138, "token_estimator": "heuristic-v1", "text": "### 1. Test Worst-Case Scenarios\n\nBenchmarks should always measure maximum possible resource consumption. If you benchmark average or best-case scenarios, malicious users could craft transactions that hit worst-case paths in your code, consuming more resources than the weights indicate and potentially slowing down or halting block production.\n\n```rust\n#[benchmark]\nfn complex_operation() {\n // Set up worst-case storage state\n for i in 0..100 {\n SomeStorage::::insert(i, vec![0u8; 1000]);\n }\n\n let caller = whitelisted_caller();\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller));\n}\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 29, "depth": 3, "title": "2. Use Linear Components for Variable Complexity", "anchor": "2-use-linear-components-for-variable-complexity", "start_char": 25006, "end_char": 25882, "estimated_token_count": 206, "token_estimator": "heuristic-v1", "text": "### 2. Use Linear Components for Variable Complexity\n\nMany extrinsics have variable costs depending on input parameters. [Linear components](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/trait.BenchmarkingSetup.html){target=\\_blank} tell the benchmarking framework to test your extrinsic with different values of `n`, measure the execution time for each, and calculate a formula like `Weight = base_weight + (n * per_item_weight)`. This produces dynamic weights that accurately reflect the actual work being done.\n\nWhen extrinsic complexity depends on input size, use linear components:\n\n```rust title=\"pallets/pallet-custom/src/benchmarking.rs\"\n#[benchmark]\nfn process_items(n: Linear<0, 100>) {\n let caller = whitelisted_caller();\n let items: Vec = (0..n).collect();\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller), items);\n}\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 30, "depth": 3, "title": "3. Verify Results", "anchor": "3-verify-results", "start_char": 25882, "end_char": 26518, "estimated_token_count": 144, "token_estimator": "heuristic-v1", "text": "### 3. Verify Results\n\nAssertions ensure that your benchmark is actually testing the code path you think it's testing. If your extrinsic fails silently or takes an early return, the benchmark would measure the wrong scenario and produce inaccurate weights.\n\nAlways assert the expected state after extrinsic execution:\n\n```rust title=\"pallets/pallet-custom/src/benchmarking.rs\"\n#[benchmark]\nfn my_extrinsic() {\n let caller = whitelisted_caller();\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller.clone()));\n\n // Verify the extrinsic had the expected effect\n assert_eq!(MyStorage::::get(&caller), expected_value);\n}\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 31, "depth": 3, "title": "4. Minimize Setup Code", "anchor": "4-minimize-setup-code", "start_char": 26518, "end_char": 27092, "estimated_token_count": 120, "token_estimator": "heuristic-v1", "text": "### 4. Minimize Setup Code\n\nWhile the benchmarking framework tries to isolate the extrinsic execution, excessive setup code can add noise to measurements. More importantly, setup code that doesn't reflect real-world pre-conditions can lead to benchmarking unrealistic scenarios.\n\nOnly include necessary setup in benchmarks:\n\n```rust title=\"pallets/pallet-custom/src/benchmarking.rs\"\n#[benchmark]\nfn efficient_benchmark() {\n // Minimal setup\n let caller = whitelisted_caller();\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller));\n\n // Minimal assertions\n}\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 32, "depth": 2, "title": "Run Your Chain Locally", "anchor": "run-your-chain-locally", "start_char": 27092, "end_char": 27618, "estimated_token_count": 141, "token_estimator": "heuristic-v1", "text": "## Run Your Chain Locally\n\nNow that you've added the pallet to your runtime, you can launch your parachain locally to test the new functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\\_blank}. For instructions on setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\\_blank}, refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\\_blank} guide."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 33, "depth": 3, "title": "Build the Production Runtime", "anchor": "build-the-production-runtime", "start_char": 27618, "end_char": 28821, "estimated_token_count": 223, "token_estimator": "heuristic-v1", "text": "### Build the Production Runtime\n\nThe `runtime-benchmarks` feature flag adds special host functions (like `ext_benchmarking_current_time` and `ext_benchmarking_get_read_and_written_keys`) that are only available in the benchmarking execution environment. These functions allow the benchmarking framework to precisely measure execution time and track storage operations. However, regular nodes don't provide these host functions, so a runtime compiled with benchmarking features will fail to start on a production node.\n\nBefore running your chain, rebuild the runtime **without** the `runtime-benchmarks` feature:\n\n```bash\ncargo build --release\n```\n\n!!! note \"Build Types\"\n Understanding the difference between builds is critical:\n\n - `cargo build --release --features runtime-benchmarks` - Compiles with benchmarking host functions for measurement. Use this ONLY when running benchmarks with `frame-omni-bencher`\n - `cargo build --release` - Compiles production runtime without benchmarking features. Use this for running your actual chain\n\nThis produces a production-ready WASM runtime at `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm`."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 34, "depth": 3, "title": "Generate a Chain Specification", "anchor": "generate-a-chain-specification", "start_char": 28821, "end_char": 29655, "estimated_token_count": 165, "token_estimator": "heuristic-v1", "text": "### Generate a Chain Specification\n\nThe chain specification defines the initial state and configuration of your blockchain, including the runtime WASM code, genesis storage, and network parameters. By generating a new chain spec with your updated runtime (now containing your benchmarked pallet), you ensure that nodes starting from this spec will use the correct version of your code with proper weight calculations.\n\nCreate a new chain specification file with the updated runtime:\n\n```bash\nchain-spec-builder create -t development \\\n--relay-chain paseo \\\n--para-id 1000 \\\n--runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \\\nnamed-preset development\n```\n\nThis command generates a chain specification file, `chain_spec.json`, for your parachain with the updated runtime."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 35, "depth": 3, "title": "Start the Parachain Node", "anchor": "start-the-parachain-node", "start_char": 29655, "end_char": 30074, "estimated_token_count": 84, "token_estimator": "heuristic-v1", "text": "### Start the Parachain Node\n\nLaunch the parachain using the Polkadot Omni Node with the generated chain specification by running the following command:\n\n```bash\npolkadot-omni-node --chain ./chain_spec.json --dev\n```\n\nThe node will start and display initialization information including:\n\n- The chain specification name\n- The node identity and peer ID\n- Database location\n- Network endpoints (JSON-RPC and Prometheus)"} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 36, "depth": 3, "title": "Verify Block Production", "anchor": "verify-block-production", "start_char": 30074, "end_char": 30777, "estimated_token_count": 190, "token_estimator": "heuristic-v1", "text": "### Verify Block Production\n\nOnce the node is running, you should see log messages indicating successful block production:\n\n```\n[Parachain] 🔨 Initializing Genesis block/state (state: 0x47ce…ec8d, header-hash: 0xeb12…fecc)\n[Parachain] 🎁 Prepared block for proposing at 1 (3 ms) ...\n[Parachain] 🏆 Imported #1 (0xeb12…fecc → 0xee51…98d2)\n[Parachain] 🎁 Prepared block for proposing at 2 (3 ms) ...\n[Parachain] 🏆 Imported #2 (0xee51…98d2 → 0x35e0…cc32)\n```\n\nThe parachain will produce new blocks every few seconds. You can now interact with your pallet's extrinsics through the JSON-RPC endpoint at `http://127.0.0.1:9944` using tools like [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\\_blank}."} -{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 37, "depth": 2, "title": "Related Resources", "anchor": "related-resources", "start_char": 30777, "end_char": 31318, "estimated_token_count": 153, "token_estimator": "heuristic-v1", "text": "## Related Resources\n\n- [FRAME Benchmarking Documentation](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/index.html){target=\\_blank}\n- [Weight Struct Documentation](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html){target=\\_blank}\n- [Benchmarking v2 API](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\\_blank}\n- [frame-omni-bencher Tool](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\\_blank}"} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 0, "end_char": 631, "estimated_token_count": 119, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nBenchmarking is the process of measuring the computational resources (execution time and storage) required by your pallet's extrinsics. Accurate [weight](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/index.html){target=\\_blank} calculations are essential for ensuring your blockchain can process transactions efficiently while protecting against denial-of-service attacks.\n\nThis guide continues building on what you've learned through the pallet development series. You'll learn how to benchmark the custom counter pallet extrinsics and integrate the generated weights into your runtime."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 631, "end_char": 1611, "estimated_token_count": 262, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore you begin, ensure you have:\n\n- Completed the previous pallet development tutorials:\n - [Create a Pallet](/parachains/customize-runtime/pallet-development/create-a-pallet/){target=\\_blank}\n - [Mock Your Runtime](/parachains/customize-runtime/pallet-development/mock-runtime/){target=\\_blank}\n - [Unit Test Pallets](/parachains/customize-runtime/pallet-development/pallet-testing/){target=\\_blank}\n- Basic understanding of [computational complexity](https://en.wikipedia.org/wiki/Computational_complexity){target=\\_blank}.\n- Familiarity with [Rust's testing framework](https://doc.rust-lang.org/book/ch11-00-testing.html){target=\\_blank}.\n- Familiarity setting up the Polkadot Omni Node and [Polkadot Chain Spec Builder](https://crates.io/crates/staging-chain-spec-builder){target=\\_blank}. Refer to the [Set Up a Parachain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\\_blank} guide for instructions if needed."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 2, "depth": 2, "title": "Create the Benchmarking Module", "anchor": "create-the-benchmarking-module", "start_char": 1611, "end_char": 3218, "estimated_token_count": 430, "token_estimator": "heuristic-v1", "text": "## Create the Benchmarking Module\n\nCreate a new file `benchmarking.rs` in your pallet's `src` directory and add the following code:\n\n```rust title=\"pallets/pallet-custom/src/benchmarking.rs\"\n#![cfg(feature = \"runtime-benchmarks\")]\n\nuse super::*;\nuse frame::deps::frame_benchmarking::v2::*;\nuse frame::benchmarking::prelude::RawOrigin;\n\n#[benchmarks]\nmod benchmarks {\n use super::*;\n\n #[benchmark]\n fn set_counter_value() {\n let new_value: u32 = 100;\n\n #[extrinsic_call]\n _(RawOrigin::Root, new_value);\n\n assert_eq!(CounterValue::::get(), new_value);\n }\n\n #[benchmark]\n fn increment() {\n let caller: T::AccountId = whitelisted_caller();\n let amount: u32 = 50;\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller.clone()), amount);\n\n assert_eq!(CounterValue::::get(), amount);\n assert_eq!(UserInteractions::::get(caller), 1);\n }\n\n #[benchmark]\n fn decrement() {\n // First, set the counter to a non-zero value\n CounterValue::::put(100);\n\n let caller: T::AccountId = whitelisted_caller();\n let amount: u32 = 30;\n\n #[extrinsic_call]\n _(RawOrigin::Signed(caller.clone()), amount);\n\n assert_eq!(CounterValue::::get(), 70);\n assert_eq!(UserInteractions::::get(caller), 1);\n }\n\n impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test);\n}\n```\n\nThis module contains all the [benchmarking definitions](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\\_blank} for your pallet."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 3, "depth": 2, "title": "Define the Weight Trait", "anchor": "define-the-weight-trait", "start_char": 3218, "end_char": 4168, "estimated_token_count": 201, "token_estimator": "heuristic-v1", "text": "## Define the Weight Trait\n\nAdd a `weights` module to your pallet that defines the `WeightInfo` trait using the following code:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#[frame::pallet]\npub mod pallet {\n use frame::prelude::*;\n pub use weights::WeightInfo;\n\n pub mod weights {\n use frame::prelude::*;\n\n pub trait WeightInfo {\n fn set_counter_value() -> Weight;\n fn increment() -> Weight;\n fn decrement() -> Weight;\n }\n\n impl WeightInfo for () {\n fn set_counter_value() -> Weight {\n Weight::from_parts(10_000, 0)\n }\n fn increment() -> Weight {\n Weight::from_parts(15_000, 0)\n }\n fn decrement() -> Weight {\n Weight::from_parts(15_000, 0)\n }\n }\n }\n\n // ... rest of pallet\n}\n```\n\nThe `()` implementation provides placeholder weights for development."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 4, "depth": 2, "title": "Add WeightInfo to Config", "anchor": "add-weightinfo-to-config", "start_char": 4168, "end_char": 4994, "estimated_token_count": 200, "token_estimator": "heuristic-v1", "text": "## Add WeightInfo to Config \n\nUpdate your pallet's `Config` trait to include `WeightInfo` by adding the following code:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#[pallet::config]\npub trait Config: frame_system::Config {\n type RuntimeEvent: From> + IsType<::RuntimeEvent>;\n\n #[pallet::constant]\n type CounterMaxValue: Get;\n\n type WeightInfo: weights::WeightInfo;\n}\n```\n\nThe [`WeightInfo`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/trait.WeightInfo.html){target=\\_blank} trait provides an abstraction layer that allows weights to be swapped at runtime configuration. By making `WeightInfo` an associated type in the `Config` trait, you will enable each runtime that uses your pallet to specify which weight implementation to use."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 5, "depth": 2, "title": "Update Extrinsic Weight Annotations", "anchor": "update-extrinsic-weight-annotations", "start_char": 4994, "end_char": 6182, "estimated_token_count": 291, "token_estimator": "heuristic-v1", "text": "## Update Extrinsic Weight Annotations\n\nReplace the placeholder weights in your extrinsics with calls to the `WeightInfo` trait by adding the following code:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#[pallet::call]\nimpl Pallet {\n #[pallet::call_index(0)]\n #[pallet::weight(T::WeightInfo::set_counter_value())]\n pub fn set_counter_value(origin: OriginFor, new_value: u32) -> DispatchResult {\n // ... implementation\n }\n\n #[pallet::call_index(1)]\n #[pallet::weight(T::WeightInfo::increment())]\n pub fn increment(origin: OriginFor, amount: u32) -> DispatchResult {\n // ... implementation\n }\n\n #[pallet::call_index(2)]\n #[pallet::weight(T::WeightInfo::decrement())]\n pub fn decrement(origin: OriginFor, amount: u32) -> DispatchResult {\n // ... implementation\n }\n}\n```\n\nBy calling `T::WeightInfo::function_name()` instead of using hardcoded `Weight::from_parts()` values, your extrinsics automatically use whichever weight implementation is configured in the runtime. You can switch between placeholder weights for testing and benchmarked weights for production easily, without changing any pallet code."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 6, "depth": 2, "title": "Include the Benchmarking Module", "anchor": "include-the-benchmarking-module", "start_char": 6182, "end_char": 6719, "estimated_token_count": 141, "token_estimator": "heuristic-v1", "text": "## Include the Benchmarking Module\n\nAt the top of your `lib.rs`, add the module declaration by adding the following code:\n\n```rust title=\"pallets/pallet-custom/src/lib.rs\"\n#![cfg_attr(not(feature = \"std\"), no_std)]\n\nextern crate alloc;\nuse alloc::vec::Vec;\n\npub use pallet::*;\n\n#[cfg(feature = \"runtime-benchmarks\")]\nmod benchmarking;\n\n// Additional pallet code\n```\n\nThe `#[cfg(feature = \"runtime-benchmarks\")]` attribute ensures that benchmarking code is only compiled when explicitly needed to keep your production runtime efficient."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 7, "depth": 2, "title": "Configure Pallet Dependencies", "anchor": "configure-pallet-dependencies", "start_char": 6719, "end_char": 7629, "estimated_token_count": 212, "token_estimator": "heuristic-v1", "text": "## Configure Pallet Dependencies\n\nUpdate your pallet's `Cargo.toml` to enable the benchmarking feature by adding the following code:\n\n```toml title=\"pallets/pallet-custom/Cargo.toml\"\n[dependencies]\ncodec = { features = [\"derive\"], workspace = true }\nscale-info = { features = [\"derive\"], workspace = true }\nframe = { features = [\"experimental\", \"runtime\"], workspace = true }\n\n[features]\ndefault = [\"std\"]\nruntime-benchmarks = [\n \"frame/runtime-benchmarks\",\n]\nstd = [\n \"codec/std\",\n \"scale-info/std\",\n \"frame/std\",\n]\n```\n\nThe Cargo feature flag system lets you conditionally compile code based on which features are enabled. By defining a `runtime-benchmarks` feature that cascades to FRAME's benchmarking features, you create a clean way to build your pallet with or without benchmarking support, ensuring all necessary dependencies are available when needed but excluded from production builds."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 8, "depth": 2, "title": "Update Mock Runtime", "anchor": "update-mock-runtime", "start_char": 7629, "end_char": 8128, "estimated_token_count": 109, "token_estimator": "heuristic-v1", "text": "## Update Mock Runtime\n\nAdd the `WeightInfo` type to your test configuration in `mock.rs` by adding the following code:\n\n```rust title=\"pallets/pallet-custom/src/mock.rs\"\nimpl pallet_custom::Config for Test {\n type RuntimeEvent = RuntimeEvent;\n type CounterMaxValue = ConstU32<1000>;\n type WeightInfo = ();\n}\n```\n\nIn your mock runtime for testing, use the placeholder `()` implementation of `WeightInfo`, since unit tests focus on verifying functional correctness rather than performance."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 9, "depth": 2, "title": "Configure Runtime Benchmarking", "anchor": "configure-runtime-benchmarking", "start_char": 8128, "end_char": 9970, "estimated_token_count": 390, "token_estimator": "heuristic-v1", "text": "## Configure Runtime Benchmarking\n\nTo execute benchmarks, your pallet must be integrated into the runtime's benchmarking infrastructure. Follow these steps to update the runtime configuration:\n\n1. **Update `runtime/Cargo.toml`**: Add your pallet to the runtime's `runtime-benchmarks` feature as follows:\n\n ```toml title=\"runtime/Cargo.toml\"\n runtime-benchmarks = [\n \"cumulus-pallet-parachain-system/runtime-benchmarks\",\n \"hex-literal\",\n \"pallet-parachain-template/runtime-benchmarks\",\n \"polkadot-sdk/runtime-benchmarks\",\n \"pallet-custom/runtime-benchmarks\",\n ]\n ```\n\n When you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included.\n\n2. **Update runtime configuration**: Run development benchmarks with the placeholder implementation and use the resulting weights file to update benchmark weights as follows:\n\n ```rust title=\"runtime/src/configs/mod.rs\"\n impl pallet_custom::Config for Runtime {\n type RuntimeEvent = RuntimeEvent;\n type CounterMaxValue = ConstU32<1000>;\n type WeightInfo = ();\n }\n ```\n\n3. **Register benchmarks**: Add your pallet to the benchmark list in `runtime/src/benchmarks.rs` as follows:\n\n ```rust title=\"runtime/src/benchmarks.rs\"\n polkadot_sdk::frame_benchmarking::define_benchmarks!(\n [frame_system, SystemBench::]\n [pallet_balances, Balances]\n // ... other pallets\n [pallet_custom, CustomPallet]\n );\n ```\n\n The [`define_benchmarks!`](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/macro.define_benchmarks.html){target=\\_blank} macro creates the infrastructure that allows the benchmarking CLI tool to discover and execute your pallet's benchmarks."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 10, "depth": 2, "title": "Test Benchmark Compilation", "anchor": "test-benchmark-compilation", "start_char": 9970, "end_char": 10962, "estimated_token_count": 245, "token_estimator": "heuristic-v1", "text": "## Test Benchmark Compilation\n\nRun the following command to verify your benchmarks compile and run as tests:\n\n```bash\ncargo test -p pallet-custom --features runtime-benchmarks\n```\n\nYou will see terminal output similar to the following as your benchmark tests pass:\n\n
\n cargo test -p pallet-custom --features runtime-benchmarks\n test benchmarking::benchmarks::bench_set_counter_value ... ok\n test benchmarking::benchmarks::bench_increment ... ok\n test benchmarking::benchmarks::bench_decrement ... ok\n \n
\n\nThe `impl_benchmark_test_suite!` macro generates unit tests for each benchmark. Running these tests verifies that your benchmarks compile correctly, execute without panicking, and pass their assertions, catching issues early before building the entire runtime."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 11, "depth": 2, "title": "Build the Runtime with Benchmarks", "anchor": "build-the-runtime-with-benchmarks", "start_char": 10962, "end_char": 11657, "estimated_token_count": 123, "token_estimator": "heuristic-v1", "text": "## Build the Runtime with Benchmarks\n\nCompile the runtime with benchmarking enabled to generate the WASM binary using the following command:\n\n```bash\ncargo build --release --features runtime-benchmarks\n```\n\nThis command produces the runtime WASM file needed for benchmarking, typically located at: `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm`\n\nThe build includes all the benchmarking infrastructure and special host functions needed for measurement. The resulting WASM runtime contains your benchmark code and can communicate with the benchmarking tool's execution environment. You'll create a different build later for operating your chain in production."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 12, "depth": 2, "title": "Install the Benchmarking Tool", "anchor": "install-the-benchmarking-tool", "start_char": 11657, "end_char": 12222, "estimated_token_count": 121, "token_estimator": "heuristic-v1", "text": "## Install the Benchmarking Tool\n\nInstall the `frame-omni-bencher` CLI tool using the following command:\n\n```bash\ncargo install frame-omni-bencher --locked\n```\n\n[`frame-omni-bencher`](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\\_blank} is the official Polkadot SDK tool designed explicitly for FRAME pallet benchmarking. It provides a standardized way to execute benchmarks, measure execution times and storage operations, and generate properly formatted weight files with full integration into the FRAME weight system."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 13, "depth": 2, "title": "Download the Weight Template", "anchor": "download-the-weight-template", "start_char": 12222, "end_char": 13024, "estimated_token_count": 161, "token_estimator": "heuristic-v1", "text": "## Download the Weight Template\n\nDownload the official weight template file using the following commands:\n\n```bash\ncurl -L https://raw.githubusercontent.com/paritytech/polkadot-sdk/refs/tags/polkadot-stable2412/substrate/.maintain/frame-weight-template.hbs \\\n--output ./pallets/pallet-custom/frame-weight-template.hbs\n```\n\nThe weight template is a Handlebars file that transforms raw benchmark data into a correctly formatted Rust source file. It defines the structure of the generated `weights.rs` file, including imports, trait definitions, documentation comments, and formatting. Using the official template ensures your weight files follow the Polkadot SDK conventions and include all necessary metadata, such as benchmark execution parameters, storage operation counts, and hardware information."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 14, "depth": 2, "title": "Execute Benchmarks", "anchor": "execute-benchmarks", "start_char": 13024, "end_char": 15060, "estimated_token_count": 407, "token_estimator": "heuristic-v1", "text": "## Execute Benchmarks\n\nRun benchmarks for your pallet to generate weight files using the following commands:\n\n```bash\nframe-omni-bencher v1 benchmark pallet \\\n --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \\\n --pallet pallet_custom \\\n --extrinsic \"\" \\\n --template ./pallets/pallet-custom/frame-weight-template.hbs \\\n --output ./pallets/pallet-custom/src/weights.rs\n```\n\nBenchmarks execute against the compiled WASM runtime rather than native code because WASM is what actually runs in production on the blockchain. WASM execution can have different performance characteristics than native code due to compilation and sandboxing overhead, so benchmarking against the WASM ensures your weight measurements reflect real-world conditions.\n\n??? note \"Additional customization\"\n\n You can customize benchmark execution with additional parameters for more detailed measurements, as shown in the sample code below:\n\n ```bash\n frame-omni-bencher v1 benchmark pallet \\\n --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm \\\n --pallet pallet_custom \\\n --extrinsic \"\" \\\n --steps 50 \\\n --repeat 20 \\\n --template ./pallets/pallet-custom/frame-weight-template.hbs \\\n --output ./pallets/pallet-custom/src/weights.rs\n ```\n \n - `--steps 50`: Number of different input values to test when using linear components (default: 50). More steps provide finer granularity for detecting complexity trends but increase benchmarking time.\n - `--repeat 20`: Number of repetitions for each measurement (default: 20). More repetitions improve statistical accuracy by averaging out variance, reducing the impact of system noise, and providing more reliable weight estimates.\n - `--heap-pages 4096`: WASM heap pages allocation. Affects available memory during execution.\n - `--wasm-execution compiled`: WASM execution method. Use `compiled` for performance closest to production conditions."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 15, "depth": 2, "title": "Use Generated Weights", "anchor": "use-generated-weights", "start_char": 15060, "end_char": 18735, "estimated_token_count": 831, "token_estimator": "heuristic-v1", "text": "## Use Generated Weights\n\nAfter running benchmarks, a `weights.rs` file is generated containing measured weights based on actual measurements of your code running on real hardware, accounting for the specific complexity of your logic, storage access patterns, and computational requirements.\n\nFollow these steps to use the generated weights with your pallet:\n\n1. Integrate the generated weights by adding the weights module to your pallet's `lib.rs` as follows:\n\n ```rust title=\"pallets/pallet-custom/src/lib.rs\"\n #![cfg_attr(not(feature = \"std\"), no_std)]\n\n extern crate alloc;\n use alloc::vec::Vec;\n\n pub use pallet::*;\n\n #[cfg(feature = \"runtime-benchmarks\")]\n mod benchmarking;\n\n pub mod weights;\n\n #[frame::pallet]\n pub mod pallet {\n use super::*;\n use frame::prelude::*;\n use crate::weights::WeightInfo;\n // ... rest of pallet\n }\n ```\n\n Unlike the benchmarking module (which is only needed when running benchmarks), the weights module must be available in all builds because the runtime needs to call the weight functions during regular operation to calculate transaction fees and enforce block limits.\n\n2. Update your runtime configuration to use the generated weights instead of the placeholder `()` implementation by adding the following code:\n\n ```rust title=\"runtime/src/configs/mod.rs\"\n impl pallet_custom::Config for Runtime {\n type RuntimeEvent = RuntimeEvent;\n type CounterMaxValue = ConstU32<1000>;\n type WeightInfo = pallet_custom::weights::SubstrateWeight;\n }\n ```\n\n This change activates your benchmarked weights in the production runtime. Now, when users submit transactions that call your pallet's extrinsics, the runtime will use the actual measured weights to calculate fees and enforce block limits.\n\n??? code \"Example generated weight file\"\n \n The generated `weights.rs` file will look similar to this:\n\n ```rust title=\"pallets/pallet-custom/src/weights.rs\"\n //! Autogenerated weights for `pallet_custom`\n //!\n //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0\n //! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20`\n\n #![cfg_attr(rustfmt, rustfmt_skip)]\n #![allow(unused_parens)]\n #![allow(unused_imports)]\n #![allow(missing_docs)]\n\n use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};\n use core::marker::PhantomData;\n\n pub trait WeightInfo {\n fn set_counter_value() -> Weight;\n fn increment() -> Weight;\n fn decrement() -> Weight;\n }\n\n pub struct SubstrateWeight(PhantomData);\n impl WeightInfo for SubstrateWeight {\n fn set_counter_value() -> Weight {\n Weight::from_parts(8_234_000, 0)\n .saturating_add(T::DbWeight::get().reads(1))\n .saturating_add(T::DbWeight::get().writes(1))\n }\n\n fn increment() -> Weight {\n Weight::from_parts(12_456_000, 0)\n .saturating_add(T::DbWeight::get().reads(2))\n .saturating_add(T::DbWeight::get().writes(2))\n }\n\n fn decrement() -> Weight {\n Weight::from_parts(11_987_000, 0)\n .saturating_add(T::DbWeight::get().reads(2))\n .saturating_add(T::DbWeight::get().writes(2))\n }\n }\n ```\n\n The actual numbers in your `weights.rs` file will vary based on your hardware and implementation complexity. The [`DbWeight`](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.RuntimeDbWeight.html){target=\\_blank} accounts for database read and write operations."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 16, "depth": 2, "title": "Run Your Chain Locally", "anchor": "run-your-chain-locally", "start_char": 18735, "end_char": 22211, "estimated_token_count": 795, "token_estimator": "heuristic-v1", "text": "## Run Your Chain Locally\n\nNow that you've added the pallet to your runtime, you can follow these steps to launch your parachain locally to test the new functionality using the [Polkadot Omni Node](https://crates.io/crates/polkadot-omni-node){target=\\_blank}: \n\n1. Before running your chain, rebuild the production runtime without the `runtime-benchmarks` feature using the following command:\n\n ```bash\n cargo build --release\n ```\n\n The `runtime-benchmarks` feature flag adds special host functions that are only available in the benchmarking execution environment. A runtime compiled with benchmarking features will fail to start on a production node.\n\n This build produces a production-ready WASM runtime at `target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm`.\n\n !!! note \"Compare build types\"\n - `cargo build --release --features runtime-benchmarks` - Compiles with benchmarking host functions for measurement. Use this ONLY when running benchmarks with `frame-omni-bencher`.\n - `cargo build --release` - Compiles production runtime without benchmarking features. Use this for running your chain in production.\n\n2. Generate a new chain specification file with the updated runtime using the following commands:\n\n ```bash\n chain-spec-builder create -t development \\\n --relay-chain paseo \\\n --para-id 1000 \\\n --runtime ./target/release/wbuild/parachain-template-runtime/parachain_template_runtime.compact.compressed.wasm \\\n named-preset development\n ```\n\n This command generates a chain specification file, `chain_spec.json`, for your parachain with the updated runtime, which defines the initial state and configuration of your blockchain, including the runtime WASM code, genesis storage, and network parameters. Generating this new chain spec with your updated runtime ensures nodes starting from this spec will use the correct version of your code with proper weight calculations.\n\n3. Start the parachain node using the Polkadot Omni Node with the generated chain specification by running the following command:\n\n ```bash\n polkadot-omni-node --chain ./chain_spec.json --dev\n ```\n\n The node will start and display initialization information, including:\n\n - The chain specification name\n - The node identity and peer ID\n - Database location\n - Network endpoints (JSON-RPC and Prometheus)\n\n4. Once the node is running, you will see log messages confirming successful production of blocks similar to the following:\n\n
\n polkadot-omni-node --chain ./chain_spec.json --dev\n [Parachain] 🔨 Initializing Genesis block/state (state: 0x47ce…ec8d, header-hash: 0xeb12…fecc)\n [Parachain] 🎁 Prepared block for proposing at 1 (3 ms) ...\n [Parachain] 🏆 Imported #1 (0xeb12…fecc → 0xee51…98d2)\n [Parachain] 🎁 Prepared block for proposing at 2 (3 ms) ...\n [Parachain] 🏆 Imported #2 (0xee51…98d2 → 0x35e0…cc32)\n \n
\n\n The parachain will produce new blocks every few seconds. You can now interact with your pallet's extrinsics through the JSON-RPC endpoint at `http://127.0.0.1:9944` using tools like [Polkadot.js Apps](https://polkadot.js.org/apps/){target=\\_blank}."} +{"page_id": "parachains-customize-runtime-pallet-development-benchmark-pallet", "page_title": "Benchmark Your Pallet", "index": 17, "depth": 2, "title": "Related Resources", "anchor": "related-resources", "start_char": 22211, "end_char": 22752, "estimated_token_count": 153, "token_estimator": "heuristic-v1", "text": "## Related Resources\n\n- [FRAME Benchmarking Documentation](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/index.html){target=\\_blank}\n- [Weight Struct Documentation](https://paritytech.github.io/polkadot-sdk/master/frame_support/weights/struct.Weight.html){target=\\_blank}\n- [Benchmarking v2 API](https://paritytech.github.io/polkadot-sdk/master/frame_benchmarking/v2/index.html){target=\\_blank}\n- [frame-omni-bencher Tool](https://paritytech.github.io/polkadot-sdk/master/frame_omni_bencher/index.html){target=\\_blank}"} {"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 26, "end_char": 847, "estimated_token_count": 167, "token_estimator": "heuristic-v1", "text": "## Introduction\n\n[Framework for Runtime Aggregation of Modular Entities (FRAME)](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/index.html){target=\\_blank} provides a powerful set of tools for blockchain development through modular components called [pallets](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/frame_runtime/pallet/index.html){target=\\_blank}. These Rust-based runtime modules allow you to build custom blockchain functionality with precision and flexibility. While FRAME includes a library of pre-built pallets, its true strength lies in creating custom pallets tailored to your specific needs.\n\nIn this guide, you'll learn how to build a custom counter pallet from scratch that demonstrates core pallet development concepts."} {"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 847, "end_char": 1217, "estimated_token_count": 99, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore you begin, ensure you have:\n\n- [Polkadot SDK dependencies installed](/parachains/install-polkadot-sdk/){target=\\_blank}.\n- A [Polkadot SDK Parchain Template](/parachains/launch-a-parachain/set-up-the-parachain-template/){target=\\_blank} set up locally.\n- Basic familiarity with [FRAME concepts](/parachains/customize-runtime/){target=\\_blank}."} {"page_id": "parachains-customize-runtime-pallet-development-create-a-pallet", "page_title": "Create a Custom Pallet", "index": 2, "depth": 2, "title": "Core Pallet Components", "anchor": "core-pallet-components", "start_char": 1217, "end_char": 2092, "estimated_token_count": 193, "token_estimator": "heuristic-v1", "text": "## Core Pallet Components\n\nAs you build your custom pallet, you'll work with these key sections:\n\n- **Imports and dependencies**: Bring in necessary FRAME libraries and external modules.\n- **Runtime configuration trait**: Specify types and constants for pallet-runtime interaction.\n- **Runtime events**: Define signals that communicate state changes.\n- **Runtime errors**: Define error types returned from dispatchable calls.\n- **Runtime storage**: Declare on-chain storage items for your pallet's state.\n- **Genesis configuration**: Set initial blockchain state.\n- **Dispatchable functions (extrinsics)**: Create callable functions for user interactions.\n\nFor additional macros beyond those covered here, refer to the [pallet_macros](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/index.html){target=\\_blank} section of the Polkadot SDK Docs."} @@ -345,13 +325,13 @@ {"page_id": "parachains-customize-runtime-pallet-development-mock-runtime", "page_title": "Mock Your Runtime", "index": 10, "depth": 2, "title": "Verify Mock Compilation", "anchor": "verify-mock-compilation", "start_char": 7931, "end_char": 10853, "estimated_token_count": 564, "token_estimator": "heuristic-v1", "text": "## Verify Mock Compilation\n\nBefore proceeding to write tests, ensure your mock runtime compiles correctly:\n\n```bash\ncargo test --package pallet-custom --lib\n```\n\nThis command compiles the test code (including the mock and genesis configuration) without running tests yet. Address any compilation errors before continuing.\n\n??? code \"Complete mock runtime script\"\n\n Here's the complete `mock.rs` file for reference:\n\n ```rust title=\"src/mock.rs\"\n use crate as pallet_custom;\n use frame::{\n deps::{\n frame_support::{ derive_impl, traits::ConstU32 },\n sp_io,\n sp_runtime::{ traits::IdentityLookup, BuildStorage },\n },\n prelude::*,\n };\n\n type Block = frame_system::mocking::MockBlock;\n\n // Configure a mock runtime to test the pallet.\n frame::deps::frame_support::construct_runtime!(\n pub enum Test\n {\n System: frame_system,\n CustomPallet: pallet_custom,\n }\n );\n\n #[derive_impl(frame_system::config_preludes::TestDefaultConfig)]\n impl frame_system::Config for Test {\n type Block = Block;\n type AccountId = u64;\n type Lookup = IdentityLookup;\n }\n\n impl pallet_custom::Config for Test {\n type RuntimeEvent = RuntimeEvent;\n type CounterMaxValue = ConstU32<1000>;\n }\n\n // Build genesis storage according to the mock runtime.\n pub fn new_test_ext() -> sp_io::TestExternalities {\n let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap();\n\n (pallet_custom::GenesisConfig:: {\n initial_counter_value: 0,\n initial_user_interactions: vec![],\n })\n .assimilate_storage(&mut t)\n .unwrap();\n\n t.into()\n }\n\n // Helper function to create a test externalities with a specific initial counter value\n pub fn new_test_ext_with_counter(initial_value: u32) -> sp_io::TestExternalities {\n let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap();\n\n (pallet_custom::GenesisConfig:: {\n initial_counter_value: initial_value,\n initial_user_interactions: vec![],\n })\n .assimilate_storage(&mut t)\n .unwrap();\n\n t.into()\n }\n\n // Helper function to create a test externalities with initial user interactions\n pub fn new_test_ext_with_interactions(\n initial_value: u32,\n interactions: Vec<(u64, u32)>\n ) -> sp_io::TestExternalities {\n let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap();\n\n (pallet_custom::GenesisConfig:: {\n initial_counter_value: initial_value,\n initial_user_interactions: interactions,\n })\n .assimilate_storage(&mut t)\n .unwrap();\n\n t.into()\n }\n ```"} {"page_id": "parachains-customize-runtime-pallet-development-mock-runtime", "page_title": "Mock Your Runtime", "index": 11, "depth": 2, "title": "Key Takeaways", "anchor": "key-takeaways", "start_char": 10853, "end_char": 11416, "estimated_token_count": 98, "token_estimator": "heuristic-v1", "text": "## Key Takeaways\n\nYou've successfully created a mock runtime with a genesis configuration for your custom pallet. You can now:\n\n- Test your pallet without a full runtime.\n- Set initial blockchain state for different test scenarios.\n- Create different genesis setups for various testing needs.\n- Use this minimal setup to test all pallet functionality.\n\nThe mock runtime with a genesis configuration is essential for test-driven development, enabling you to verify logic under different initial conditions before integrating it into the actual parachain runtime."} {"page_id": "parachains-customize-runtime-pallet-development-mock-runtime", "page_title": "Mock Your Runtime", "index": 12, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 11416, "end_char": 11766, "estimated_token_count": 87, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Guide __Pallet Unit Testing__\n\n ---\n\n Learn to write comprehensive unit tests for your pallet using the mock runtime you just created.\n\n [:octicons-arrow-right-24: Continue](/parachains/customize-runtime/pallet-development/pallet-testing/)\n\n
"} -{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Pallet Testing", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 18, "end_char": 672, "estimated_token_count": 123, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nUnit testing in the Polkadot SDK helps ensure that the functions provided by a pallet behave as expected. It also confirms that data and events associated with a pallet are processed correctly during interactions. The Polkadot SDK offers a set of APIs to create a test environment to simulate runtime and mock transaction execution for extrinsics and queries.\n\nTo begin unit testing, you must first set up a mock runtime that simulates blockchain behavior, incorporating the necessary pallets. For a deeper understanding, consult the [Mock Runtime](/parachains/customize-runtime/pallet-development/mock-runtime/){target=\\_blank} guide."} -{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Pallet Testing", "index": 1, "depth": 2, "title": "Writing Unit Tests", "anchor": "writing-unit-tests", "start_char": 672, "end_char": 2195, "estimated_token_count": 285, "token_estimator": "heuristic-v1", "text": "## Writing Unit Tests\n\nOnce the mock runtime is in place, the next step is to write unit tests that evaluate the functionality of your pallet. Unit tests allow you to test specific pallet features in isolation, ensuring that each function behaves correctly under various conditions. These tests typically reside in your pallet module's `test.rs` file.\n\nUnit tests in the Polkadot SDK use the Rust testing framework, and the mock runtime you've defined earlier will serve as the test environment. Below are the typical steps involved in writing unit tests for a pallet.\n\nThe tests confirm that:\n\n- **Pallets initialize correctly**: At the start of each test, the system should initialize with block number 0, and the pallets should be in their default states.\n- **Pallets modify each other's state**: The second test shows how one pallet can trigger changes in another pallet's internal state, confirming proper cross-pallet interactions.\n- **State transitions between blocks are seamless**: By simulating block transitions, the tests validate that the runtime responds correctly to changes in the block number.\n\nTesting pallet interactions within the runtime is critical for ensuring the blockchain behaves as expected under real-world conditions. Writing integration tests allows validation of how pallets function together, preventing issues that might arise when the system is fully assembled.\n\nThis approach provides a comprehensive view of the runtime's functionality, ensuring the blockchain is stable and reliable."} -{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Pallet Testing", "index": 2, "depth": 3, "title": "Test Initialization", "anchor": "test-initialization", "start_char": 2195, "end_char": 2507, "estimated_token_count": 68, "token_estimator": "heuristic-v1", "text": "### Test Initialization\n\nEach test starts by initializing the runtime environment, typically using the `new_test_ext()` function, which sets up the mock storage and environment.\n\n```rust\n#[test]\nfn test_pallet_functionality() {\n new_test_ext().execute_with(|| {\n // Test logic goes here\n });\n}\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Pallet Testing", "index": 3, "depth": 3, "title": "Function Call Testing", "anchor": "function-call-testing", "start_char": 2507, "end_char": 3280, "estimated_token_count": 167, "token_estimator": "heuristic-v1", "text": "### Function Call Testing\n\nCall the pallet's extrinsics or functions to simulate user interaction or internal logic. Use the `assert_ok!` macro to check for successful execution and `assert_err!` to verify that errors are correctly handled.\n\n```rust\n#[test]\nfn it_works_for_valid_input() {\n new_test_ext().execute_with(|| {\n // Call an extrinsic or function\n assert_ok!(TemplateModule::some_function(Origin::signed(1), valid_param));\n });\n}\n\n#[test]\nfn it_fails_for_invalid_input() {\n new_test_ext().execute_with(|| {\n // Call an extrinsic with invalid input and expect an error\n assert_err!(\n TemplateModule::some_function(Origin::signed(1), invalid_param),\n Error::::InvalidInput\n );\n });\n}\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Pallet Testing", "index": 4, "depth": 3, "title": "Storage Testing", "anchor": "storage-testing", "start_char": 3280, "end_char": 4129, "estimated_token_count": 190, "token_estimator": "heuristic-v1", "text": "### Storage Testing\n\nAfter calling a function or extrinsic in your pallet, it's essential to verify that the state changes in the pallet's storage match the expected behavior to ensure data is updated correctly based on the actions taken.\n\nThe following example shows how to test the storage behavior before and after the function call:\n\n```rust\n#[test]\nfn test_storage_update_on_extrinsic_call() {\n new_test_ext().execute_with(|| {\n // Check the initial storage state (before the call)\n assert_eq!(Something::::get(), None);\n\n // Dispatch a signed extrinsic, which modifies storage\n assert_ok!(TemplateModule::do_something(RuntimeOrigin::signed(1), 42));\n\n // Validate that the storage has been updated as expected (after the call)\n assert_eq!(Something::::get(), Some(42));\n });\n}\n\n```"} -{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Pallet Testing", "index": 5, "depth": 3, "title": "Event Testing", "anchor": "event-testing", "start_char": 4129, "end_char": 6150, "estimated_token_count": 519, "token_estimator": "heuristic-v1", "text": "### Event Testing\n\nIt's also crucial to test the events that your pallet emits during execution. By default, events generated in a pallet using the [`#generate_deposit`](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/attr.generate_deposit.html){target=\\_blank} macro are stored under the system's event storage key (system/events) as [`EventRecord`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.EventRecord.html){target=\\_blank} entries. These can be accessed using [`System::events()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.events){target=\\_blank} or verified with specific helper methods provided by the system pallet, such as [`assert_has_event`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.assert_has_event){target=\\_blank} and [`assert_last_event`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.assert_last_event){target=\\_blank}.\n\nHere's an example of testing events in a mock runtime:\n\n```rust\n#[test]\nfn it_emits_events_on_success() {\n new_test_ext().execute_with(|| {\n // Call an extrinsic or function\n assert_ok!(TemplateModule::some_function(Origin::signed(1), valid_param));\n\n // Verify that the expected event was emitted\n assert!(System::events().iter().any(|record| {\n record.event == Event::TemplateModule(TemplateEvent::SomeEvent)\n }));\n });\n}\n```\n\nSome key considerations are:\n\n- **Block number**: Events are not emitted on the genesis block, so you need to set the block number using [`System::set_block_number()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.set_block_number){target=\\_blank} to ensure events are triggered.\n- **Converting events**: Use `.into()` when instantiating your pallet's event to convert it into a generic event type, as required by the system's event storage."} -{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Pallet Testing", "index": 6, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 6150, "end_char": 6892, "estimated_token_count": 211, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n- Dive into the full implementation of the [`mock.rs`](https://github.com/paritytech/polkadot-sdk/blob/master/templates/solochain/pallets/template/src/mock.rs){target=\\_blank} and [`test.rs`](https://github.com/paritytech/polkadot-sdk/blob/master/templates/solochain/pallets/template/src/tests.rs){target=\\_blank} files in the [Solochain Template](https://github.com/paritytech/polkadot-sdk/tree/master/templates/solochain){target=_blank}.\n\n
\n\n- Guide __Benchmarking__\n\n ---\n\n Explore methods to measure the performance and execution cost of your pallet.\n\n [:octicons-arrow-right-24: Reference](/develop/parachains/testing/benchmarking)\n\n
"} +{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Unit Test Pallets", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 21, "end_char": 675, "estimated_token_count": 123, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nUnit testing in the Polkadot SDK helps ensure that the functions provided by a pallet behave as expected. It also confirms that data and events associated with a pallet are processed correctly during interactions. The Polkadot SDK offers a set of APIs to create a test environment to simulate runtime and mock transaction execution for extrinsics and queries.\n\nTo begin unit testing, you must first set up a mock runtime that simulates blockchain behavior, incorporating the necessary pallets. For a deeper understanding, consult the [Mock Runtime](/parachains/customize-runtime/pallet-development/mock-runtime/){target=\\_blank} guide."} +{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Unit Test Pallets", "index": 1, "depth": 2, "title": "Writing Unit Tests", "anchor": "writing-unit-tests", "start_char": 675, "end_char": 2198, "estimated_token_count": 285, "token_estimator": "heuristic-v1", "text": "## Writing Unit Tests\n\nOnce the mock runtime is in place, the next step is to write unit tests that evaluate the functionality of your pallet. Unit tests allow you to test specific pallet features in isolation, ensuring that each function behaves correctly under various conditions. These tests typically reside in your pallet module's `test.rs` file.\n\nUnit tests in the Polkadot SDK use the Rust testing framework, and the mock runtime you've defined earlier will serve as the test environment. Below are the typical steps involved in writing unit tests for a pallet.\n\nThe tests confirm that:\n\n- **Pallets initialize correctly**: At the start of each test, the system should initialize with block number 0, and the pallets should be in their default states.\n- **Pallets modify each other's state**: The second test shows how one pallet can trigger changes in another pallet's internal state, confirming proper cross-pallet interactions.\n- **State transitions between blocks are seamless**: By simulating block transitions, the tests validate that the runtime responds correctly to changes in the block number.\n\nTesting pallet interactions within the runtime is critical for ensuring the blockchain behaves as expected under real-world conditions. Writing integration tests allows validation of how pallets function together, preventing issues that might arise when the system is fully assembled.\n\nThis approach provides a comprehensive view of the runtime's functionality, ensuring the blockchain is stable and reliable."} +{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Unit Test Pallets", "index": 2, "depth": 3, "title": "Test Initialization", "anchor": "test-initialization", "start_char": 2198, "end_char": 2510, "estimated_token_count": 68, "token_estimator": "heuristic-v1", "text": "### Test Initialization\n\nEach test starts by initializing the runtime environment, typically using the `new_test_ext()` function, which sets up the mock storage and environment.\n\n```rust\n#[test]\nfn test_pallet_functionality() {\n new_test_ext().execute_with(|| {\n // Test logic goes here\n });\n}\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Unit Test Pallets", "index": 3, "depth": 3, "title": "Function Call Testing", "anchor": "function-call-testing", "start_char": 2510, "end_char": 3283, "estimated_token_count": 167, "token_estimator": "heuristic-v1", "text": "### Function Call Testing\n\nCall the pallet's extrinsics or functions to simulate user interaction or internal logic. Use the `assert_ok!` macro to check for successful execution and `assert_err!` to verify that errors are correctly handled.\n\n```rust\n#[test]\nfn it_works_for_valid_input() {\n new_test_ext().execute_with(|| {\n // Call an extrinsic or function\n assert_ok!(TemplateModule::some_function(Origin::signed(1), valid_param));\n });\n}\n\n#[test]\nfn it_fails_for_invalid_input() {\n new_test_ext().execute_with(|| {\n // Call an extrinsic with invalid input and expect an error\n assert_err!(\n TemplateModule::some_function(Origin::signed(1), invalid_param),\n Error::::InvalidInput\n );\n });\n}\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Unit Test Pallets", "index": 4, "depth": 3, "title": "Storage Testing", "anchor": "storage-testing", "start_char": 3283, "end_char": 4132, "estimated_token_count": 190, "token_estimator": "heuristic-v1", "text": "### Storage Testing\n\nAfter calling a function or extrinsic in your pallet, it's essential to verify that the state changes in the pallet's storage match the expected behavior to ensure data is updated correctly based on the actions taken.\n\nThe following example shows how to test the storage behavior before and after the function call:\n\n```rust\n#[test]\nfn test_storage_update_on_extrinsic_call() {\n new_test_ext().execute_with(|| {\n // Check the initial storage state (before the call)\n assert_eq!(Something::::get(), None);\n\n // Dispatch a signed extrinsic, which modifies storage\n assert_ok!(TemplateModule::do_something(RuntimeOrigin::signed(1), 42));\n\n // Validate that the storage has been updated as expected (after the call)\n assert_eq!(Something::::get(), Some(42));\n });\n}\n\n```"} +{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Unit Test Pallets", "index": 5, "depth": 3, "title": "Event Testing", "anchor": "event-testing", "start_char": 4132, "end_char": 6153, "estimated_token_count": 519, "token_estimator": "heuristic-v1", "text": "### Event Testing\n\nIt's also crucial to test the events that your pallet emits during execution. By default, events generated in a pallet using the [`#generate_deposit`](https://paritytech.github.io/polkadot-sdk/master/frame_support/pallet_macros/attr.generate_deposit.html){target=\\_blank} macro are stored under the system's event storage key (system/events) as [`EventRecord`](https://paritytech.github.io/polkadot-sdk/master/frame_system/struct.EventRecord.html){target=\\_blank} entries. These can be accessed using [`System::events()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.events){target=\\_blank} or verified with specific helper methods provided by the system pallet, such as [`assert_has_event`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.assert_has_event){target=\\_blank} and [`assert_last_event`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.assert_last_event){target=\\_blank}.\n\nHere's an example of testing events in a mock runtime:\n\n```rust\n#[test]\nfn it_emits_events_on_success() {\n new_test_ext().execute_with(|| {\n // Call an extrinsic or function\n assert_ok!(TemplateModule::some_function(Origin::signed(1), valid_param));\n\n // Verify that the expected event was emitted\n assert!(System::events().iter().any(|record| {\n record.event == Event::TemplateModule(TemplateEvent::SomeEvent)\n }));\n });\n}\n```\n\nSome key considerations are:\n\n- **Block number**: Events are not emitted on the genesis block, so you need to set the block number using [`System::set_block_number()`](https://paritytech.github.io/polkadot-sdk/master/frame_system/pallet/struct.Pallet.html#method.set_block_number){target=\\_blank} to ensure events are triggered.\n- **Converting events**: Use `.into()` when instantiating your pallet's event to convert it into a generic event type, as required by the system's event storage."} +{"page_id": "parachains-customize-runtime-pallet-development-pallet-testing", "page_title": "Unit Test Pallets", "index": 6, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 6153, "end_char": 6895, "estimated_token_count": 211, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n- Dive into the full implementation of the [`mock.rs`](https://github.com/paritytech/polkadot-sdk/blob/master/templates/solochain/pallets/template/src/mock.rs){target=\\_blank} and [`test.rs`](https://github.com/paritytech/polkadot-sdk/blob/master/templates/solochain/pallets/template/src/tests.rs){target=\\_blank} files in the [Solochain Template](https://github.com/paritytech/polkadot-sdk/tree/master/templates/solochain){target=_blank}.\n\n
\n\n- Guide __Benchmarking__\n\n ---\n\n Explore methods to measure the performance and execution cost of your pallet.\n\n [:octicons-arrow-right-24: Reference](/develop/parachains/testing/benchmarking)\n\n
"} {"page_id": "parachains-customize-runtime", "page_title": "Overview of FRAME", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 26, "end_char": 754, "estimated_token_count": 146, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nA blockchain runtime is more than just a fixed set of rules—it's a dynamic foundation that you can shape to match your specific needs. With Polkadot SDK's [FRAME (Framework for Runtime Aggregation of Modularized Entities)](/reference/glossary/#frame-framework-for-runtime-aggregation-of-modularized-entities){target=\\_blank}, customizing your runtime is straightforward and modular. Instead of building everything from scratch, you combine pre-built pallets with your own custom logic to create a runtime suited to your blockchain's purpose.\n\nThis overview explains how runtime customization works, introduces the building blocks you'll use, and guides you through the key patterns for extending your runtime."} {"page_id": "parachains-customize-runtime", "page_title": "Overview of FRAME", "index": 1, "depth": 2, "title": "Understanding Your Runtime", "anchor": "understanding-your-runtime", "start_char": 754, "end_char": 1533, "estimated_token_count": 158, "token_estimator": "heuristic-v1", "text": "## Understanding Your Runtime\n\nThe runtime is the core logic of your blockchain—it processes transactions, manages state, and enforces the rules that govern your network. When a transaction arrives at your blockchain, the [`frame_executive`](https://paritytech.github.io/polkadot-sdk/master/frame_executive/index.html){target=\\_blank} pallet receives it and routes it to the appropriate pallet for execution.\n\nThink of your runtime as a collection of specialized modules, each handling a different aspect of your blockchain. Need token balances? Use the Balances pallet. Want governance? Add the Governance pallets. Need something custom? Create your own pallet. By mixing and matching these modules, you build a runtime that's efficient, secure, and tailored to your use case."} {"page_id": "parachains-customize-runtime", "page_title": "Overview of FRAME", "index": 2, "depth": 2, "title": "Runtime Architecture", "anchor": "runtime-architecture", "start_char": 1533, "end_char": 2085, "estimated_token_count": 121, "token_estimator": "heuristic-v1", "text": "## Runtime Architecture\n\nThe following diagram shows how FRAME components work together to form your runtime:\n\n![](/images/parachains/customize-runtime/index/frame-overview-01.webp)\n\nThe main components are:\n\n- **`frame_executive`**: Routes all incoming transactions to the correct pallet for execution.\n- **Pallets**: Domain-specific modules that implement your blockchain's features and business logic.\n- **`frame_system`**: Provides core runtime primitives and storage.\n- **`frame_support`**: Utilities and macros that simplify pallet development."} diff --git a/llms.txt b/llms.txt index 3a102f2bf..98d224c83 100644 --- a/llms.txt +++ b/llms.txt @@ -87,7 +87,7 @@ Docs: Parachains - [Benchmark Your Pallet](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-benchmark-pallet.md): Learn how to benchmark your custom pallet extrinsics to generate accurate weight calculations for production use. - [Create a Custom Pallet](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-create-a-pallet.md): Learn how to create custom pallets using FRAME, allowing for flexible, modular, and scalable blockchain development. Follow the step-by-step guide. - [Mock Your Runtime](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-mock-runtime.md): Learn how to create a mock runtime environment for testing your custom pallets in isolation, enabling comprehensive unit testing before runtime integration. -- [Pallet Testing](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-pallet-testing.md): Learn how to efficiently test pallets in the Polkadot SDK, ensuring the reliability and security of your pallets operations. +- [Unit Test Pallets](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime-pallet-development-pallet-testing.md): Learn how to efficiently test pallets in the Polkadot SDK, ensuring the reliability and security of your pallets operations. - [Overview of FRAME](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-customize-runtime.md): Learn how Polkadot SDK’s FRAME framework simplifies blockchain development with modular pallets and support libraries for efficient runtime design. - [Get Started with Parachain Development](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-get-started.md): Practical examples and tutorials for building and deploying Polkadot parachains, covering everything from launch to customization and cross-chain messaging. - [Opening HRMP Channels Between Parachains](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-interoperability-channels-between-parachains.md): Learn how to open HRMP channels between parachains on Polkadot. Discover the step-by-step process for establishing uni- and bidirectional communication. From 3a952dc4e13f248c40e444637d2a481ca8bfb94b Mon Sep 17 00:00:00 2001 From: DAWN KELLY Date: Tue, 18 Nov 2025 14:01:52 -0500 Subject: [PATCH 4/4] apply copilot feedback --- .../customize-runtime/pallet-development/benchmark-pallet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parachains/customize-runtime/pallet-development/benchmark-pallet.md b/parachains/customize-runtime/pallet-development/benchmark-pallet.md index 092b8d6e1..7c9407b07 100644 --- a/parachains/customize-runtime/pallet-development/benchmark-pallet.md +++ b/parachains/customize-runtime/pallet-development/benchmark-pallet.md @@ -241,7 +241,7 @@ To execute benchmarks, your pallet must be integrated into the runtime's benchma When you build the runtime with `--features runtime-benchmarks`, this configuration ensures all necessary benchmarking code across all pallets (including yours) is included. -2. **Update runtime configuration**: Run development benchmarks with the placeholder implementation and use the resulting weights file to update benchmark weights as follows: +2. **Update runtime configuration**: Using the the placeholder implementation, run development benchmarks as follows: ```rust title="runtime/src/configs/mod.rs" impl pallet_custom::Config for Runtime {