2 releases
new 0.0.2 | Apr 14, 2025 |
---|---|
0.0.1 | Apr 11, 2025 |
#616 in Magic Beans
176 downloads per month
42KB
639 lines
๐ซ pallet-feeless: Feeless Transactions with Rate Limiting for Substrate ๐ซ
Welcome to pallet-feeless โ a plug-and-play solution to enable fully feeless transactions in any Substrate-based blockchain! โจ
Instead of charging transaction fees, this pallet uses a rate-limiting system to ensure fair usage and network security. It's perfect for applications where user experience, accessibility, and cost-efficiency are top priorities.
๐งฉ Introduction
Most blockchains rely on transaction fees to prevent spam and incentivize validators. While effective, this system can create friction, especially for:
- Microtransactions ๐ธ
- New users ๐งโ๐ป
- Developers building free-to-use apps ๐
This pallet removes transaction fees altogetherโeven during congestionโby using a rate-limiting extrinsic extension. This makes your blockchain:
- ๐ซ Free from fees
- ๐ Predictable for users
- ๐ก๏ธ Secure against spam
๐ก How It Works
Instead of fees, each account is subject to a rate limit:
- โฑ๏ธ Max Transactions per Period: The number of transactions allowed per account in a set block window.
- ๐ฆ Max Size per Period: The total size of allowed transactions during that window.
This is enforced via a custom extrinsic extension (CheckRate
) that plugs into Substrateโs transaction validation pipeline alongside checks like:
CheckNonce
CheckWeight
CheckEra
- ...
All validation and accounting are performed before and after dispatch, with minimal storage access to preserve performance and security.
โ๏ธ Runtime Integration
1. Define AccountData
in frame_system
type AccountData = pallet_feeless::AccountData<Balance, BlockNumber>;
This custom account type stores balance, last block, and rate data per account.
2. Set Up AccountStore
in pallet_balances
type AccountStore = Account;
Required to track the accountโs storage location and enable rate tracking.
3. Configure pallet_feeless
Add your custom settings in the runtime:
impl pallet_feeless::Config for Runtime {
type MaxTxByPeriod = ConstU32<128>; // Max transactions per period
type MaxSizeByPeriod = ConstU32<1>; // Max size in bytes per period
type Period = ConstU32<5>; // Length of the rate-limiting window (in blocks)
type RuntimeEvent = RuntimeEvent;
type WeightInfo = (); // Do not forget to generate and reference the weight after benchmarking
}
4. Update Your Transaction Extensions
Extend the runtime transaction validation to include CheckRate
:
pub type TxExtension = (
frame_system::CheckNonZeroSender<Runtime>,
frame_system::CheckSpecVersion<Runtime>,
frame_system::CheckTxVersion<Runtime>,
frame_system::CheckGenesis<Runtime>,
frame_system::CheckEra<Runtime>,
frame_system::CheckNonce<Runtime>,
pallet_feeless::CheckRate<Runtime>, // ๐ Rate limit extension
frame_system::CheckWeight<Runtime>,
pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
);
5. Benchmarking and Payload Setup
In benchmarking.rs
or similar:
let tx_ext: runtime::TxExtension = (
frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
frame_system::CheckTxVersion::<runtime::Runtime>::new(),
frame_system::CheckGenesis::<runtime::Runtime>::new(),
frame_system::CheckEra::<runtime::Runtime>::from(sp_runtime::generic::Era::mortal(
period,
best_block.saturated_into(),
)),
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
pallet_feeless::CheckRate::<runtime::Runtime>::new(), // ๐ Add this
frame_system::CheckWeight::<runtime::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
frame_metadata_hash_extension::CheckMetadataHash::<runtime::Runtime>::new(false),
);
let raw_payload = runtime::SignedPayload::from_raw(
call.clone(),
tx_ext.clone(),
(
(),
runtime::VERSION.spec_version,
runtime::VERSION.transaction_version,
genesis_hash,
best_hash,
(),
(), // ๐ Add this
(),
(),
None,
),
);
โ Benefits
-
๐ซ No Transaction Fees
Users never worry about price fluctuations. -
โ๏ธ Built-in Fairness
Every account gets a rate limit, ensuring equal access. -
๐ ๏ธ Developer Friendly
Build dApps without forcing users to hold or buy tokens. -
๐ Accessible UX
Lower onboarding friction and support for micro-use cases.
โ ๏ธ Considerations
While this system improves user experience, keep in mind:
- โ๏ธ Fine-tuning required: Limits must strike a balance between usability and protection.
- ๐ฏ No validator fees: Block rewards or other models must be used to incentivize validators.
- ๐ก๏ธ Spam resistance: Rate limits must be sufficient to deter Sybil attacks or multi-account spamming.
๐ฆ Want to Try It?
Just include this pallet in your Substrate runtime and configure the limits to your needs. No additional infrastructure or fee logic is required!
๐ License
MIT โ open-source and ready to use in your blockchain projects.
Dependencies
~23โ38MB
~635K SLoC