OpenZeppelin Pallet Abstractions
Introduction
openzeppelin-pallet-abstractions is a Rust macro library designed to simplify and secure the configuration of Polkadot parachain runtimes. By reducing repetitive boilerplate and providing sensible defaults, the library helps developers configure their runtimes with fewer lines of code while ensuring flexibility for customizations.
Note: This library has not been audited yet and should not be used in production environments.
1. Installation
To start using the openzeppelin-pallet-abstractions
, add it as a dependency in your Cargo.toml file:
[dependencies]
openzeppelin-pallet-abstractions = { git = "https://github.com/OpenZeppelin/openzeppelin-pallet-abstractions", tag = "v0.1.0" }
Then, import the required macros in your runtime configuration file.
2. Basic Usage
The library offers a collection of macros for configuring various core runtime elements such as system settings, assets, governance, consensus mechanisms, EVM integration, and XCM compatibility. Let’s walk through a basic example setup:
1. System configuration
The impl_openzeppelin_system!
macro facilitates the setup of foundational runtime components by implementing the SystemConfig
trait for your custom runtime structure.
use openzeppelin_pallet_abstractions::{impl_openzeppelin_system, SystemConfig};
pub struct OpenZeppelinRuntime;
impl SystemConfig for OpenZeppelinRuntime {
type AccountId = AccountId;
type ExistentialDeposit = ConstU128<EXISTENTIAL_DEPOSIT>;
type PreimageOrigin = EnsureRoot<AccountId>;
type ScheduleOrigin = EnsureRoot<AccountId>;
type Version = Version;
// Additional configurations...
}
impl_openzeppelin_system!(OpenZeppelinRuntime);
This expands to configure multiple core pallets like frame_system
, pallet_timestamp
, parachain_info
, and others essential for a functioning parachain runtime.
2. Additional configurations
Further configuration can be achieved for pallets grouped by functionality, such as Assets, Consensus, EVM, Governance, and XCM. Each grouping has its own macro and configuration trait, making it easier to set up advanced components without redundant code.
Example setup for additional configurations in an EVM-based runtime:
use openzeppelin_pallet_abstractions::{
impl_openzeppelin_assets, impl_openzeppelin_consensus, impl_openzeppelin_evm,
impl_openzeppelin_governance, impl_openzeppelin_xcm, AssetsConfig,
ConsensusConfig, EvmConfig, GovernanceConfig, XcmConfig,
};
impl ConsensusConfig for OpenZeppelinRuntime {
type CollatorSelectionUpdateOrigin = CollatorSelectionUpdateOrigin;
}
impl GovernanceConfig for OpenZeppelinRuntime {
type ConvictionVoteLockingPeriod = ConstU32<{ 7 * DAYS }>;
type DispatchWhitelistedOrigin = EitherOf<EnsureRoot<AccountId>, WhitelistedCaller>;
// Additional configurations...
}
// Further configuration implementations...
impl_openzeppelin_assets!(OpenZeppelinRuntime);
impl_openzeppelin_consensus!(OpenZeppelinRuntime);
impl_openzeppelin_governance!(OpenZeppelinRuntime);
impl_openzeppelin_xcm!(OpenZeppelinRuntime);
impl_openzeppelin_evm!(OpenZeppelinRuntime);
3. Advanced Configuration Options
Each macro allows optional parameters to override the default values. This enables fine-tuning of runtime settings according to the specific needs of your parachain while retaining the benefits of standardized, secure defaults.
Default Overrides: Customize specific parameters like ExistentialDeposit
, BaseXcmWeight
, or AssetId
while relying on default values for other settings.
Custom Implementations: Integrate custom types (like EitherOf
, ConstU32
) or origins (EnsureRoot
, WhitelistedCaller
) for advanced use cases.
4. Security Considerations
While the library is built with security in mind, it’s essential to review each configuration for your specific runtime and context.
5. Contributing and Feedback
We encourage contributions from the community to improve the library. Please refer to the CONTRIBUTING.md for guidelines.
3. Using Procedural Macros in OpenZeppelin Pallet Abstractions
1. construct_runtime!
Macro
The construct_runtime!
macro simplifies the assembly of runtime modules by abstracting over both OpenZeppelin abstractions and standard pallets. This is useful for developers aiming to build a runtime quickly, without manually managing each pallet’s configuration.
Usage Example
To use the macro, annotate a module with #[openzeppelin_construct_runtime]
and define structs for each desired abstraction or regular pallet. Here’s a basic example:
#[openzeppelin_construct_runtime]
mod runtime {
#[abstraction]
struct System; // Available abstractions: System, Consensus, XCM, Assets, Governance, EVM.
#[pallet]
type Pallet = pallet_crate; // Regular pallets defined with `#[pallet]` mimic the `construct_runtime!` structure.
}
Note: Pallet index assignments are handled automatically by this macro. If you require explicit control over pallet indices, please consider submitting a feature request.
Supported Abstractions and their Pallets:
-
System — frame_system, pallet_timestamp, parachain_info, pallet_scheduler, pallet_preimage, pallet_proxy, pallet_balances, pallet_utility, cumulus_pallet_parachain_system, pallet_multisig, pallet_session
-
Assets — pallet_assets, pallet_transaction_payment, pallet_asset_manager
-
Consensus — pallet_authorship, pallet_aura, cumulus_pallet_aura_ext, pallet_collator_selection
-
Governance — pallet_sudo, pallet_treasury, pallet_conviction_voting, pallet_whitelist, pallet_custom_origins, pallet_referenda
-
XCM — pallet_message_queue, cumulus_pallet_xcmp_queue, pallet_xcm, cumulus_pallet_xcm, pallet_xcm_transactor, orml_xtokens, pallet_xcm_weight_trader
-
EVM — pallet_ethereum, pallet_evm, pallet_base_fee, pallet_evm_chain_id, pallet_erc20_xcm_bridge
2. impl_runtime_apis!
Macro
The The impl_runtime_apis!
macro provides a clean interface for implementing runtime APIs. This macro reduces boilerplate by allowing you to specify types and structs, automatically generating the required API implementations.
Usage Example
To use this macro, annotate a module with #[openzeppelin_runtime_apis]
and define the types and abstractions needed.
#[openzeppelin_runtime_apis]
mod apis {
type Runtime = Runtime; // The runtime generated by `construct_runtime!`
type Block = Block; // Block type required by all abstractions
#[abstraction]
mod assets {
type TransactionPayment = TransactionPayment;
type RuntimeCall = RuntimeCall;
type Balance = Balance;
}
// Additional `impl` blocks can be added as necessary.
}
Supported Abstractions, APIs, and Required Configurations:
Abstraction name | Implemented APIs | Required configs |
---|---|---|
EVM |
* |
* |
assets |
* |
* |
consensus |
* |
* |
system |
* |
* |
benchmarks |
* |
* |
This macro allows for clear modularization of APIs, facilitating easier maintenance and extension of runtime functionalities.