mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 10:41:09 +00:00
Tokens in FRAME Docs (#2802)
Closes https://github.com/paritytech/polkadot-sdk-docs/issues/70 WIP PR for an overview of how to develop tokens in FRAME. - [x] Tokens in Substrate Ref Doc - High-level overview of the token-related logic in FRAME - Improve docs with better explanation of how holds, freezes, ed, free balance, etc, all work - [x] Update `pallet_balances` docs - Clearly mark what is deprecated (currency) - [x] Write fungible trait docs - [x] Evaluate and if required update `pallet_assets`, `pallet_uniques`, `pallet_nfts` docs - [x] Absorb https://github.com/paritytech/polkadot-sdk/pull/2683/ - [x] Audit individual trait method docs, and improve if possible Feel free to suggest additional TODOs for this PR in the comments --------- Co-authored-by: Bill Laboon <laboon@users.noreply.github.com> Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Sebastian Kunert <skunert49@gmail.com>
This commit is contained in:
Generated
+3
@@ -13390,11 +13390,14 @@ dependencies = [
|
||||
"pallet-example-single-block-migrations",
|
||||
"pallet-examples",
|
||||
"pallet-multisig",
|
||||
"pallet-nfts",
|
||||
"pallet-preimage",
|
||||
"pallet-proxy",
|
||||
"pallet-referenda",
|
||||
"pallet-scheduler",
|
||||
"pallet-timestamp",
|
||||
"pallet-transaction-payment",
|
||||
"pallet-uniques",
|
||||
"pallet-utility",
|
||||
"parity-scale-codec",
|
||||
"sc-cli",
|
||||
|
||||
@@ -66,6 +66,7 @@ pallet-aura = { path = "../../substrate/frame/aura", default-features = false }
|
||||
pallet-timestamp = { path = "../../substrate/frame/timestamp" }
|
||||
pallet-balances = { path = "../../substrate/frame/balances" }
|
||||
pallet-assets = { path = "../../substrate/frame/assets" }
|
||||
pallet-preimage = { path = "../../substrate/frame/preimage" }
|
||||
pallet-transaction-payment = { path = "../../substrate/frame/transaction-payment" }
|
||||
pallet-utility = { path = "../../substrate/frame/utility" }
|
||||
pallet-multisig = { path = "../../substrate/frame/multisig" }
|
||||
@@ -73,6 +74,8 @@ pallet-proxy = { path = "../../substrate/frame/proxy" }
|
||||
pallet-authorship = { path = "../../substrate/frame/authorship" }
|
||||
pallet-collective = { path = "../../substrate/frame/collective" }
|
||||
pallet-democracy = { path = "../../substrate/frame/democracy" }
|
||||
pallet-uniques = { path = "../../substrate/frame/uniques" }
|
||||
pallet-nfts = { path = "../../substrate/frame/nfts" }
|
||||
pallet-scheduler = { path = "../../substrate/frame/scheduler" }
|
||||
|
||||
# Primitives
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
//! FRAME Currency Abstractions and Traits
|
||||
//!
|
||||
//! Notes:
|
||||
//!
|
||||
//! - History, `Currency` trait.
|
||||
//! - `Hold` and `Freeze` with diagram.
|
||||
//! - `HoldReason` and `FreezeReason`
|
||||
//! - This footgun: <https://github.com/paritytech/polkadot-sdk/pull/1900#discussion_r1363783609>
|
||||
@@ -143,7 +143,7 @@
|
||||
//! For example, all pallets in `polkadot-sdk` that needed to work with currencies could have been
|
||||
//! tightly coupled with [`pallet_balances`]. But, `polkadot-sdk` also provides [`pallet_assets`]
|
||||
//! (and more implementations by the community), therefore all pallets use traits to loosely couple
|
||||
//! with balances or assets pallet. More on this in [`crate::reference_docs::frame_currency`].
|
||||
//! with balances or assets pallet. More on this in [`crate::reference_docs::frame_tokens`].
|
||||
//!
|
||||
//! ## Further References
|
||||
//!
|
||||
|
||||
@@ -131,7 +131,6 @@
|
||||
//!
|
||||
//! TODO: Link to multi block migration example/s once PR is merged (<https://github.com/paritytech/polkadot-sdk/pull/2119>).
|
||||
//!
|
||||
//! [`GetStorageVersion`]: frame_support::traits::GetStorageVersion
|
||||
//! [`OnRuntimeUpgrade`]: frame_support::traits::OnRuntimeUpgrade
|
||||
//! [`StorageVersion`]: frame_support::traits::StorageVersion
|
||||
//! [`set_code`]: frame_system::Call::set_code
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
// This file is part of polkadot-sdk.
|
||||
//
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! # FRAME Tokens
|
||||
//!
|
||||
//! This reference doc serves as a high-level overview of the token-related logic in FRAME, and
|
||||
//! how to properly apply it to your use case.
|
||||
//!
|
||||
//! On completion of reading this doc, you should have a good understanding of:
|
||||
//! - The distinction between token traits and trait implementations in FRAME, and why this
|
||||
//! distinction is helpful
|
||||
//! - Token-related traits avaliable in FRAME
|
||||
//! - Token-related trait implementations in FRAME
|
||||
//! - How to choose the right trait or trait implementation for your use case
|
||||
//! - Where to go next
|
||||
//!
|
||||
//! ## Getting Started
|
||||
//!
|
||||
//! The most ubiquitous way to add a token to a FRAME runtime is [`pallet_balances`]. Read
|
||||
//! more about pallets [here](crate::polkadot_sdk::frame_runtime#pallets).
|
||||
//!
|
||||
//! You may then write custom pallets that interact with [`pallet_balances`]. The fastest way to
|
||||
//! get started with that is by
|
||||
//! [tightly coupling](crate::reference_docs::frame_pallet_coupling#tight-coupling-pallets) your
|
||||
//! custom pallet to [`pallet_balances`].
|
||||
//!
|
||||
//! However, to keep pallets flexible and modular, it is often prefered to
|
||||
//! [loosely couple](crate::reference_docs::frame_pallet_coupling#loosely--coupling-pallets).
|
||||
//!
|
||||
//! To achieve loose coupling,
|
||||
//! we separate token logic into traits and trait implementations.
|
||||
//!
|
||||
//! ## Traits and Trait Implementations
|
||||
//!
|
||||
//! Broadly speaking, token logic in FRAME can be divided into two categories: traits and
|
||||
//! trait implementations.
|
||||
//!
|
||||
//! **Traits** define common interfaces that types of tokens should implement. For example, the
|
||||
//! [`fungible::Inspect`](`frame_support::traits::fungible::Inspect`) trait specifies an interface
|
||||
//! for *inspecting* token state such as the total issuance of the token, the balance of individual
|
||||
//! accounts, etc.
|
||||
//!
|
||||
//! **Trait implementations** are concrete implementations of these traits. For example, one of the
|
||||
//! many traits [`pallet_balances`] implements is
|
||||
//! [`fungible::Inspect`](`frame_support::traits::fungible::Inspect`)*. It provides the concrete way
|
||||
//! of inspecting the total issuance, balance of accounts, etc. There can be many implementations of
|
||||
//! the same traits.
|
||||
//!
|
||||
//! The distinction between traits and trait implementations is helpful because it allows pallets
|
||||
//! and other logic to be generic over their dependencies, avoiding tight coupling.
|
||||
//!
|
||||
//! To illustrate this with an example let's consider [`pallet_preimage`]. This pallet takes a
|
||||
//! deposit in exchange for storing a preimage for later use. A naive implementation of the
|
||||
//! pallet may use [`pallet_balances`] in a tightly coupled manner, directly calling methods
|
||||
//! on the pallet to reserve and unreserve deposits. This approach works well,
|
||||
//! until someone has a use case requiring that an asset from a different pallet such as
|
||||
//! [`pallet_assets`] is used for the deposit. Rather than tightly couple [`pallet_preimage`] to
|
||||
//! [`pallet_balances`], [`pallet_assets`], and every other token-handling pallet a user
|
||||
//! could possibly specify, [`pallet_preimage`] does not specify a concrete pallet as a dependency
|
||||
//! but instead accepts any dependency which implements the
|
||||
//! [`currency::ReservableCurrency`](`frame_support::traits::tokens::currency::ReservableCurrency`)
|
||||
//! trait, namely via its [`Config::Currency`](`pallet_preimage::pallet::Config::Currency`)
|
||||
//! associated type. This allows [`pallet_preimage`] to support any arbitrary pallet implementing
|
||||
//! this trait, without needing any knowledge of what those pallets may be or requiring changes to
|
||||
//! support new pallets which may be written in the future.
|
||||
//!
|
||||
//! Read more about coupling, and the benefits of loose coupling
|
||||
//! [here](crate::reference_docs::frame_pallet_coupling).
|
||||
//!
|
||||
//! ##### *Rust Advanced Tip
|
||||
//!
|
||||
//! The knowledge that [`pallet_balances`] implements
|
||||
//! [`fungible::Inspect`](`frame_support::traits::fungible::Inspect`) is not some arcane knowledge
|
||||
//! that you have to know by heart or memorize. One can simply look at the list of the implementors
|
||||
//! of any trait in the Rust Doc to find all implementors (e.g.
|
||||
//! <https://paritytech.github.io/polkadot-sdk/master/frame/traits/tokens/fungible/trait.Mutate.html#implementors>),
|
||||
//! or use the `rust-analyzer` `Implementations` action.
|
||||
//!
|
||||
//! ## Fungible Token Traits in FRAME
|
||||
//!
|
||||
//! The [`fungible`](`frame_support::traits::fungible`) crate contains the latest set of FRAME
|
||||
//! fungible token traits, and is recommended to use for all new logic requiring a fungible token.
|
||||
//! See the crate documentation for more info about these fungible traits.
|
||||
//!
|
||||
//! [`fungibles`](`frame_support::traits::fungibles`) provides very similar functionality to
|
||||
//! [`fungible`](`frame_support::traits::fungible`), except it supports managing multiple tokens.
|
||||
//!
|
||||
//! You may notice the trait [`Currency`](`frame_support::traits::Currency`) with similar
|
||||
//! functionality is also used in the codebase, however this trait is deprecated and existing logic
|
||||
//! is in the process of being migrated to [`fungible`](`frame_support::traits::fungible`) ([tracking issue](https://github.com/paritytech/polkadot-sdk/issues/226)).
|
||||
//!
|
||||
//! ## Fungible Token Trait Implementations in FRAME
|
||||
//!
|
||||
//! [`pallet_balances`] implements [`fungible`](`frame_support::traits::fungible`), and is the most
|
||||
//! commonly used fungible implementation in FRAME. Most of the time, it's used for managing the
|
||||
//! native token of the blockchain network it's used in.
|
||||
//!
|
||||
//! [`pallet_assets`] implements [`fungibles`](`frame_support::traits::fungibles`), and is another
|
||||
//! popular fungible token implementation. It supports the creation and management of multiple
|
||||
//! assets in a single crate, making it a good choice when a network requires more assets in
|
||||
//! addition to its native token.
|
||||
//!
|
||||
//! ## Non-Fungible Tokens in FRAME
|
||||
//!
|
||||
//! [`pallet_nfts`] is recommended to use for all NFT use cases in FRAME.
|
||||
//! See the crate documentation for more info about this pallet.
|
||||
//!
|
||||
//! [`pallet_uniques`] is deprecated and should not be used.
|
||||
//!
|
||||
//!
|
||||
//! # What Next?
|
||||
//!
|
||||
//! - If you are interested in implementing a single fungible token, continue reading the
|
||||
//! [`fungible`](`frame_support::traits::fungible`) and [`pallet_balances`] docs.
|
||||
//! - If you are interested in implementing a set of fungible tokens, continue reading the
|
||||
//! [`fungibles`](`frame_support::traits::fungibles`) trait and [`pallet_assets`] docs.
|
||||
//! - If you are interested in implementing an NFT, continue reading the [`pallet_nfts`] docs.
|
||||
@@ -65,9 +65,6 @@ pub mod metadata;
|
||||
/// Learn about how frame-system handles `account-ids`, nonces, consumers and providers.
|
||||
pub mod frame_system_accounts;
|
||||
|
||||
/// Learn about the currency-related abstractions provided in FRAME.
|
||||
pub mod frame_currency;
|
||||
|
||||
/// Advice for configuring your development environment for Substrate development.
|
||||
pub mod development_environment_advice;
|
||||
|
||||
@@ -75,6 +72,9 @@ pub mod development_environment_advice;
|
||||
// TODO: @shawntabrizi @ggwpez https://github.com/paritytech/polkadot-sdk-docs/issues/50
|
||||
pub mod frame_benchmarking_weight;
|
||||
|
||||
/// Learn about the token-related logic in FRAME and how to apply it to your use case.
|
||||
pub mod frame_tokens;
|
||||
|
||||
/// Learn about chain specification file and the genesis state of the blockchain.
|
||||
// TODO: @michalkucharczyk https://github.com/paritytech/polkadot-sdk-docs/issues/51
|
||||
pub mod chain_spec_genesis;
|
||||
|
||||
@@ -17,7 +17,16 @@
|
||||
|
||||
//! # Assets Pallet
|
||||
//!
|
||||
//! A simple, secure module for dealing with fungible assets.
|
||||
//! A simple, secure module for dealing with sets of assets implementing
|
||||
//! [`fungible`](frame_support::traits::fungible) traits, via
|
||||
//! [`fungibles`](frame_support::traits::fungibles) traits.
|
||||
//!
|
||||
//! The pallet makes heavy use of concepts such as Holds and Freezes from the
|
||||
//! [`frame_support::traits::fungible`] traits, therefore you should read and understand those docs
|
||||
//! as a prerequisite to understanding this pallet.
|
||||
//!
|
||||
//! See the [`frame_tokens`] reference docs for more information about the place of the
|
||||
//! Assets pallet in FRAME.
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
@@ -133,6 +142,8 @@
|
||||
//!
|
||||
//! * [`System`](../frame_system/index.html)
|
||||
//! * [`Support`](../frame_support/index.html)
|
||||
//!
|
||||
//! [`frame_tokens`]: ../polkadot_sdk_docs/reference_docs/frame_tokens/index.html
|
||||
|
||||
// This recursion limit is needed because we have too many benchmarks and benchmarking will fail if
|
||||
// we add more without this limit.
|
||||
|
||||
@@ -17,11 +17,15 @@
|
||||
|
||||
//! # Balances Pallet
|
||||
//!
|
||||
//! The Balances pallet provides functionality for handling accounts and balances.
|
||||
//! The Balances pallet provides functionality for handling accounts and balances for a single
|
||||
//! token.
|
||||
//!
|
||||
//! - [`Config`]
|
||||
//! - [`Call`]
|
||||
//! - [`Pallet`]
|
||||
//! It makes heavy use of concepts such as Holds and Freezes from the
|
||||
//! [`frame_support::traits::fungible`] traits, therefore you should read and understand those docs
|
||||
//! as a prerequisite to understanding this pallet.
|
||||
//!
|
||||
//! Also see the [`frame_tokens`] reference docs for higher level information regarding the
|
||||
//! place of this palet in FRAME.
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
@@ -38,42 +42,30 @@
|
||||
//!
|
||||
//! ### Terminology
|
||||
//!
|
||||
//! - **Existential Deposit:** The minimum balance required to create or keep an account open. This
|
||||
//! prevents "dust accounts" from filling storage. When the free plus the reserved balance (i.e.
|
||||
//! the total balance) fall below this, then the account is said to be dead; and it loses its
|
||||
//! functionality as well as any prior history and all information on it is removed from the
|
||||
//! chain's state. No account should ever have a total balance that is strictly between 0 and the
|
||||
//! existential deposit (exclusive). If this ever happens, it indicates either a bug in this
|
||||
//! pallet or an erroneous raw mutation of storage.
|
||||
//!
|
||||
//! - **Total Issuance:** The total number of units in existence in a system.
|
||||
//!
|
||||
//! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after
|
||||
//! its total balance has become zero (or, strictly speaking, less than the Existential Deposit).
|
||||
//!
|
||||
//! - **Free Balance:** The portion of a balance that is not reserved. The free balance is the only
|
||||
//! balance that matters for most operations.
|
||||
//!
|
||||
//! - **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended.
|
||||
//! Reserved balance can still be slashed, but only after all the free balance has been slashed.
|
||||
//!
|
||||
//! - **Imbalance:** A condition when some funds were credited or debited without equal and opposite
|
||||
//! accounting (i.e. a difference between total issuance and account balances). Functions that
|
||||
//! result in an imbalance will return an object of the `Imbalance` trait that can be managed within
|
||||
//! your runtime logic. (If an imbalance is simply dropped, it should automatically maintain any
|
||||
//! book-keeping such as total issuance.)
|
||||
//!
|
||||
//! - **Lock:** A freeze on a specified amount of an account's free balance until a specified block
|
||||
//! number. Multiple locks always operate over the same funds, so they "overlay" rather than
|
||||
//! "stack".
|
||||
//! its total balance has become less than the Existential Deposit.
|
||||
//!
|
||||
//! ### Implementations
|
||||
//!
|
||||
//! The Balances pallet provides implementations for the following traits. If these traits provide
|
||||
//! the functionality that you need, then you can avoid coupling with the Balances pallet.
|
||||
//! The Balances pallet provides implementations for the following [`fungible`] traits. If these
|
||||
//! traits provide the functionality that you need, then you should avoid tight coupling with the
|
||||
//! Balances pallet.
|
||||
//!
|
||||
//! - [`Currency`]: Functions for dealing with a
|
||||
//! fungible assets system.
|
||||
//! - [`fungible::Inspect`]
|
||||
//! - [`fungible::Mutate`]
|
||||
//! - [`fungible::Unbalanced`]
|
||||
//! - [`fungible::Balanced`]
|
||||
//! - [`fungible::BalancedHold`]
|
||||
//! - [`fungible::InspectHold`]
|
||||
//! - [`fungible::MutateHold`]
|
||||
//! - [`fungible::InspectFreeze`]
|
||||
//! - [`fungible::MutateFreeze`]
|
||||
//! - [`fungible::Imbalance`]
|
||||
//!
|
||||
//! It also implements the following [`Currency`] related traits, however they are deprecated and
|
||||
//! will eventually be removed.
|
||||
//!
|
||||
//! - [`Currency`]: Functions for dealing with a fungible assets system.
|
||||
//! - [`ReservableCurrency`]
|
||||
//! - [`NamedReservableCurrency`](frame_support::traits::NamedReservableCurrency):
|
||||
//! Functions for dealing with assets that can be reserved from an account.
|
||||
@@ -83,14 +75,6 @@
|
||||
//! imbalances between total issuance in the system and account balances. Must be used when a
|
||||
//! function creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee).
|
||||
//!
|
||||
//! ## Interface
|
||||
//!
|
||||
//! ### Dispatchable Functions
|
||||
//!
|
||||
//! - `transfer_allow_death` - Transfer some liquid free balance to another account.
|
||||
//! - `force_set_balance` - Set the balances of a given account. The origin of this call must be
|
||||
//! root.
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! The following examples show how to use the Balances pallet in your custom pallet.
|
||||
@@ -151,8 +135,11 @@
|
||||
//! * Total issued balanced of all accounts should be less than `Config::Balance::max_value()`.
|
||||
//! * Existential Deposit is set to a value greater than zero.
|
||||
//!
|
||||
//! Note, you may find the Balances pallet still functions with an ED of zero in some circumstances,
|
||||
//! however this is not a configuration which is generally supported, nor will it be.
|
||||
//! Note, you may find the Balances pallet still functions with an ED of zero when the
|
||||
//! `insecure_zero_ed` cargo feature is enabled. However this is not a configuration which is
|
||||
//! generally supported, nor will it be.
|
||||
//!
|
||||
//! [`frame_tokens`]: ../polkadot_sdk_docs/reference_docs/frame_tokens/index.html
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
mod benchmarking;
|
||||
@@ -308,10 +295,14 @@ pub mod pallet {
|
||||
|
||||
/// The maximum number of locks that should exist on an account.
|
||||
/// Not strictly enforced, but used for weight estimation.
|
||||
///
|
||||
/// Use of locks is deprecated in favour of freezes. See `https://github.com/paritytech/substrate/pull/12951/`
|
||||
#[pallet::constant]
|
||||
type MaxLocks: Get<u32>;
|
||||
|
||||
/// The maximum number of named reserves that can exist on an account.
|
||||
///
|
||||
/// Use of reserves is deprecated in favour of holds. See `https://github.com/paritytech/substrate/pull/12951/`
|
||||
#[pallet::constant]
|
||||
type MaxReserves: Get<u32>;
|
||||
|
||||
@@ -455,6 +446,8 @@ pub mod pallet {
|
||||
|
||||
/// Any liquidity locks on some account balances.
|
||||
/// NOTE: Should only be accessed when setting, changing and freeing a lock.
|
||||
///
|
||||
/// Use of locks is deprecated in favour of freezes. See `https://github.com/paritytech/substrate/pull/12951/`
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn locks)]
|
||||
pub type Locks<T: Config<I>, I: 'static = ()> = StorageMap<
|
||||
@@ -466,6 +459,8 @@ pub mod pallet {
|
||||
>;
|
||||
|
||||
/// Named reserves on some account balances.
|
||||
///
|
||||
/// Use of reserves is deprecated in favour of holds. See `https://github.com/paritytech/substrate/pull/12951/`
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn reserves)]
|
||||
pub type Reserves<T: Config<I>, I: 'static = ()> = StorageMap<
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! The Currency trait and associated types.
|
||||
//!
|
||||
//! Note Currency and related traits are deprecated, instead
|
||||
//! [`fungible`](frame_support::traits::fungible) traits should be used.
|
||||
|
||||
use super::{
|
||||
imbalance::{Imbalance, SignedImbalance},
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! The traits for putting freezes within a single fungible token class.
|
||||
//!
|
||||
//! See the [`crate::traits::fungible`] doc for more information about fungible traits
|
||||
//! including the place of the Freezes in FRAME.
|
||||
|
||||
use scale_info::TypeInfo;
|
||||
use sp_arithmetic::{
|
||||
@@ -35,7 +38,7 @@ pub trait Inspect<AccountId>: super::Inspect<AccountId> {
|
||||
/// An identifier for a freeze.
|
||||
type Id: codec::Encode + TypeInfo + 'static;
|
||||
|
||||
/// Amount of funds held in reserve by `who` for the given `id`.
|
||||
/// Amount of funds frozen in reserve by `who` for the given `id`.
|
||||
fn balance_frozen(id: &Self::Id, who: &AccountId) -> Self::Balance;
|
||||
|
||||
/// The amount of the balance which can become frozen. Defaults to `total_balance()`.
|
||||
@@ -45,11 +48,11 @@ pub trait Inspect<AccountId>: super::Inspect<AccountId> {
|
||||
|
||||
/// Returns `true` if it's possible to introduce a freeze for the given `id` onto the
|
||||
/// account of `who`. This will be true as long as the implementor supports as many
|
||||
/// concurrent freeze locks as there are possible values of `id`.
|
||||
/// concurrent freezes as there are possible values of `id`.
|
||||
fn can_freeze(id: &Self::Id, who: &AccountId) -> bool;
|
||||
}
|
||||
|
||||
/// Trait for introducing, altering and removing locks to freeze an account's funds so they never
|
||||
/// Trait for introducing, altering and removing freezes for an account for its funds never
|
||||
/// go below a set minimum.
|
||||
pub trait Mutate<AccountId>: Inspect<AccountId> {
|
||||
/// Prevent actions which would reduce the balance of the account of `who` below the given
|
||||
@@ -66,16 +69,16 @@ pub trait Mutate<AccountId>: Inspect<AccountId> {
|
||||
/// counteract any pre-existing freezes in place for `who` under the `id`. Also unlike
|
||||
/// `set_freeze`, in the case that `amount` is zero, this is no-op and never fails.
|
||||
///
|
||||
/// Note that more funds can be locked than the total balance, if desired.
|
||||
/// Note that more funds can be frozen than the total balance, if desired.
|
||||
fn extend_freeze(id: &Self::Id, who: &AccountId, amount: Self::Balance) -> DispatchResult;
|
||||
|
||||
/// Remove an existing lock.
|
||||
/// Remove an existing freeze.
|
||||
fn thaw(id: &Self::Id, who: &AccountId) -> DispatchResult;
|
||||
|
||||
/// Attempt to alter the amount frozen under the given `id` to `amount`.
|
||||
///
|
||||
/// Fail if the account of `who` has fewer freezable funds than `amount`, unless `fortitude` is
|
||||
/// `Fortitude::Force`.
|
||||
/// [`Fortitude::Force`].
|
||||
fn set_frozen(
|
||||
id: &Self::Id,
|
||||
who: &AccountId,
|
||||
@@ -91,7 +94,7 @@ pub trait Mutate<AccountId>: Inspect<AccountId> {
|
||||
/// the amount frozen under `id`. Do nothing otherwise.
|
||||
///
|
||||
/// Fail if the account of `who` has fewer freezable funds than `amount`, unless `fortitude` is
|
||||
/// `Fortitude::Force`.
|
||||
/// [`Fortitude::Force`].
|
||||
fn ensure_frozen(
|
||||
id: &Self::Id,
|
||||
who: &AccountId,
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! The traits for putting holds within a single fungible token class.
|
||||
//!
|
||||
//! See the [`crate::traits::fungible`] doc for more information about fungible traits
|
||||
//! including the place of the Holds in FRAME.
|
||||
|
||||
use crate::{
|
||||
ensure,
|
||||
@@ -214,8 +217,8 @@ pub trait Mutate<AccountId>:
|
||||
///
|
||||
/// The actual amount released is returned with `Ok`.
|
||||
///
|
||||
/// If `precision` is `BestEffort`, then the amount actually unreserved and returned as the
|
||||
/// inner value of `Ok` may be smaller than the `amount` passed.
|
||||
/// If `precision` is [`Precision::BestEffort`], then the amount actually unreserved and
|
||||
/// returned as the inner value of `Ok` may be smaller than the `amount` passed.
|
||||
///
|
||||
/// NOTE! The inner of the `Ok` result variant returns the *actual* amount released. This is the
|
||||
/// opposite of the `ReservableCurrency::unreserve()` result, which gives the amount not able
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
//! The imbalance type and its associates, which handles keeps everything adding up properly with
|
||||
//! unbalanced operations.
|
||||
//!
|
||||
//! See the [`crate::traits::fungible`] doc for more information about fungible traits.
|
||||
|
||||
use super::{super::Imbalance as ImbalanceT, Balanced, *};
|
||||
use crate::traits::{
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! Adapter to use `fungibles::*` implementations as `fungible::*`.
|
||||
//!
|
||||
//! This allows for a `fungibles` asset, e.g. from the `pallet_assets` pallet, to be used when a
|
||||
//! `fungible` asset is expected.
|
||||
//!
|
||||
//! See the [`crate::traits::fungible`] doc for more information about fungible traits.
|
||||
|
||||
use super::*;
|
||||
use crate::traits::{
|
||||
|
||||
@@ -17,26 +17,135 @@
|
||||
|
||||
//! The traits for dealing with a single fungible token class and any associated types.
|
||||
//!
|
||||
//! ### User-implememted traits
|
||||
//! - `Inspect`: Regular balance inspector functions.
|
||||
//! - `Unbalanced`: Low-level balance mutating functions. Does not guarantee proper book-keeping and
|
||||
//! so should not be called into directly from application code. Other traits depend on this and
|
||||
//! provide default implementations based on it.
|
||||
//! - `UnbalancedHold`: Low-level balance mutating functions for balances placed on hold. Does not
|
||||
//! Also see the [`frame_tokens`] reference docs for more information about the place of
|
||||
//! `fungible` traits in Substrate.
|
||||
//!
|
||||
//! # Avaliable Traits
|
||||
//! - [`Inspect`]: Regular balance inspector functions.
|
||||
//! - [`Unbalanced`]: Low-level balance mutating functions. Does not guarantee proper book-keeping
|
||||
//! and so should not be called into directly from application code. Other traits depend on this
|
||||
//! and provide default implementations based on it.
|
||||
//! - [`UnbalancedHold`]: Low-level balance mutating functions for balances placed on hold. Does not
|
||||
//! guarantee proper book-keeping and so should not be called into directly from application code.
|
||||
//! Other traits depend on this and provide default implementations based on it.
|
||||
//! - `Mutate`: Regular balance mutator functions. Pre-implemented using `Unbalanced`, though the
|
||||
//! `done_*` functions should likely be reimplemented in case you want to do something following
|
||||
//! the operation such as emit events.
|
||||
//! - `InspectHold`: Inspector functions for balances on hold.
|
||||
//! - `MutateHold`: Mutator functions for balances on hold. Mostly pre-implemented using
|
||||
//! `UnbalancedHold`.
|
||||
//! - `InspectFreeze`: Inspector functions for frozen balance.
|
||||
//! - `MutateFreeze`: Mutator functions for frozen balance.
|
||||
//! - `Balanced`: One-sided mutator functions for regular balances, which return imbalance objects
|
||||
//! - [`Mutate`]: Regular balance mutator functions. Pre-implemented using [`Unbalanced`], though
|
||||
//! the `done_*` functions should likely be reimplemented in case you want to do something
|
||||
//! following the operation such as emit events.
|
||||
//! - [`InspectHold`]: Inspector functions for balances on hold.
|
||||
//! - [`MutateHold`]: Mutator functions for balances on hold. Mostly pre-implemented using
|
||||
//! [`UnbalancedHold`].
|
||||
//! - [`InspectFreeze`]: Inspector functions for frozen balance.
|
||||
//! - [`MutateFreeze`]: Mutator functions for frozen balance.
|
||||
//! - [`Balanced`]: One-sided mutator functions for regular balances, which return imbalance objects
|
||||
//! which guarantee eventual book-keeping. May be useful for some sophisticated operations where
|
||||
//! funds must be removed from an account before it is known precisely what should be done with
|
||||
//! them.
|
||||
//!
|
||||
//! ## Terminology
|
||||
//!
|
||||
//! - **Total Issuance**: The total number of units in existence in a system.
|
||||
//!
|
||||
//! - **Total Balance**: The sum of an account's free and held balances.
|
||||
//!
|
||||
//! - **Free Balance**: A portion of an account's total balance that is not held. Note this is
|
||||
//! distinct from the Spendable Balance, which represents how much Balance the user can actually
|
||||
//! transfer.
|
||||
//!
|
||||
//! - **Held Balance**: Held balance still belongs to the account holder, but is suspended. It can
|
||||
//! be slashed, but only after all the free balance has been slashed.
|
||||
//!
|
||||
//! Multiple holds stack rather than overlay. This means that if an account has
|
||||
//! 3 holds for 100 units, the account can spend its funds for any reason down to 300 units, at
|
||||
//! which point the holds will start to come into play.
|
||||
//!
|
||||
//! - **Frozen Balance**: A freeze on a specified amount of an account's free balance until a
|
||||
//! specified block number.
|
||||
//!
|
||||
//! Multiple freezes always operate over the same funds, so they "overlay" rather than
|
||||
//! "stack". This means that if an account has 3 freezes for 100 units, the account can spend its
|
||||
//! funds for any reason down to 100 units, at which point the freezes will start to come into
|
||||
//! play.
|
||||
//!
|
||||
//! - **Minimum Balance (a.k.a. Existential Deposit, a.k.a. ED)**: The minimum balance required to
|
||||
//! create or keep an account open. This is to prevent "dust accounts" from filling storage. When
|
||||
//! the free plus the held balance (i.e. the total balance) falls below this, then the account is
|
||||
//! said to be dead. It loses its functionality as well as any prior history and all information
|
||||
//! on it is removed from the chain's state. No account should ever have a total balance that is
|
||||
//! strictly between 0 and the existential deposit (exclusive). If this ever happens, it indicates
|
||||
//! either a bug in the implementation of this trait or an erroneous raw mutation of storage.
|
||||
//!
|
||||
//! - **Untouchable Balance**: The part of a user's free balance they cannot spend, due to ED or
|
||||
//! Freeze(s).
|
||||
//!
|
||||
//! - **Spendable Balance**: The part of a user's free balance they can actually transfer, after
|
||||
//! accounting for Holds and Freezes.
|
||||
//!
|
||||
//! - **Imbalance**: A condition when some funds were credited or debited without equal and opposite
|
||||
//! accounting (i.e. a difference between total issuance and account balances). Functions that
|
||||
//! result in an imbalance will return an object of the [`imbalance::Credit`] or
|
||||
//! [`imbalance::Debt`] traits that can be managed within your runtime logic.
|
||||
//!
|
||||
//! If an imbalance is simply dropped, it should automatically maintain any book-keeping such as
|
||||
//! total issuance.
|
||||
//!
|
||||
//! ## Visualising Balance Components Together 💫
|
||||
//!
|
||||
//! ```ignore
|
||||
//! |__total__________________________________|
|
||||
//! |__on_hold__|_____________free____________|
|
||||
//! |__________frozen___________|
|
||||
//! |__on_hold__|__ed__|
|
||||
//! |__untouchable__|__spendable__|
|
||||
//! ```
|
||||
//!
|
||||
//! ## Holds and Freezes
|
||||
//!
|
||||
//! Both holds and freezes are used to prevent an account from using some of its balance.
|
||||
//!
|
||||
//! The primary distinction between the two are that:
|
||||
//! - Holds are cumulative (do not overlap) and are distinct from the free balance
|
||||
//! - Freezes are not cumulative, and can overlap with each other or with holds
|
||||
//!
|
||||
//! ```ignore
|
||||
//! |__total_____________________________|
|
||||
//! |__hold_a__|__hold_b__|_____free_____|
|
||||
//! |__on_hold____________| // <- the sum of all holds
|
||||
//! |__freeze_a_______________|
|
||||
//! |__freeze_b____|
|
||||
//! |__freeze_c________|
|
||||
//! |__frozen_________________| // <- the max of all freezes
|
||||
//! ```
|
||||
//!
|
||||
//! Holds are designed to be infallibly slashed, meaning that any logic using a `Freeze`
|
||||
//! must handle the possibility of the frozen amount being reduced, potentially to zero. A
|
||||
//! permissionless function should be provided in order to allow bookkeeping to be updated in this
|
||||
//! instance. E.g. some balance is frozen when it is used for voting, one could use held balance for
|
||||
//! voting, but nothing prevents this frozen balance from being reduced if the overlapping hold is
|
||||
//! slashed.
|
||||
//!
|
||||
//! Every Hold and Freeze is accompanied by a unique `Reason`, making it clear for each instance
|
||||
//! what the originating pallet and purpose is. These reasons are amalgomated into a single enum
|
||||
//! `RuntimeHoldReason` and `RuntimeFreezeReason` respectively, when the runtime is compiled.
|
||||
//!
|
||||
//! Note that `Hold` and `Freeze` reasons should remain in your runtime for as long as storage
|
||||
//! could exist in your runtime with those reasons, otherwise your runtime state could become
|
||||
//! undecodable.
|
||||
//!
|
||||
//! ### Should I use a Hold or Freeze?
|
||||
//!
|
||||
//! If you require a balance to be infaillibly slashed, then you should use Holds.
|
||||
//!
|
||||
//! If you require setting a minimum account balance amount, then you should use a Freezes. Note
|
||||
//! Freezes do not carry the same guarantees as Holds. Although the account cannot voluntarily
|
||||
//! reduce their balance below the largest freeze, if Holds on the account are slashed then the
|
||||
//! balance could drop below the freeze amount.
|
||||
//!
|
||||
//! ## Sets of Tokens
|
||||
//!
|
||||
//! For managing sets of tokens, see the [`fungibles`](`frame_support::traits::fungibles`) trait
|
||||
//! which is a wrapper around this trait but supporting multiple asset instances.
|
||||
//!
|
||||
//! [`frame_tokens`]: ../../../../polkadot_sdk_docs/reference_docs/frame_tokens/index.html
|
||||
|
||||
pub mod conformance_tests;
|
||||
pub mod freeze;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! `Inspect` and `Mutate` traits for working with regular balances.
|
||||
//!
|
||||
//! See the [`crate::traits::fungible`] doc for more information about fungible traits.
|
||||
|
||||
use crate::{
|
||||
ensure,
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
//! Types to combine some `fungible::*` and `fungibles::*` implementations into one union
|
||||
//! `fungibles::*` implementation.
|
||||
//!
|
||||
//! See the [`crate::traits::fungible`] doc for more information about fungible traits.
|
||||
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use frame_support::traits::{
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! Inspect and Mutate traits for Asset approvals
|
||||
//!
|
||||
//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
|
||||
|
||||
use crate::dispatch::DispatchResult;
|
||||
pub trait Inspect<AccountId>: super::Inspect<AccountId> {
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Contains an interface for enumerating assets in existence or owned by a given account.
|
||||
//!
|
||||
//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
|
||||
|
||||
/// Interface for enumerating assets in existence or owned by a given account.
|
||||
pub trait Inspect<AccountId>: super::Inspect<AccountId> {
|
||||
type AssetsIterator;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! The traits for putting freezes within a single fungible token class.
|
||||
//!
|
||||
//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
|
||||
|
||||
use crate::{ensure, traits::tokens::Fortitude};
|
||||
use scale_info::TypeInfo;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! The traits for putting holds within a single fungible token class.
|
||||
//!
|
||||
//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
|
||||
|
||||
use crate::{
|
||||
ensure,
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
//! The imbalance type and its associates, which handles keeps everything adding up properly with
|
||||
//! unbalanced operations.
|
||||
//!
|
||||
//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
|
||||
|
||||
use super::*;
|
||||
use crate::traits::{
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! Traits for creating and destroying assets.
|
||||
//!
|
||||
//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
|
||||
|
||||
use sp_runtime::{DispatchError, DispatchResult};
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! Inspect and Mutate traits for Asset metadata
|
||||
//!
|
||||
//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
|
||||
|
||||
use crate::dispatch::DispatchResult;
|
||||
use sp_std::vec::Vec;
|
||||
|
||||
@@ -15,7 +15,16 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! The traits for sets of fungible tokens and any associated types.
|
||||
//! The traits for *sets* of [`fungible`](`frame_support::traits::fungible`) tokens and any
|
||||
//! associated types.
|
||||
//!
|
||||
//! Individual tokens in the `fungibles` set may be used when a `fungible` trait is expected using
|
||||
//! [`crate::traits::tokens::fungible::ItemOf`].
|
||||
//!
|
||||
//! Also see the [`frame_tokens`] reference docs for more information about the place of
|
||||
//! `fungible` traits in Substrate.
|
||||
//!
|
||||
//! [`frame_tokens`]: ../../../../polkadot_sdk_docs/reference_docs/frame_tokens/index.html
|
||||
|
||||
pub mod approvals;
|
||||
mod enumerable;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! `Inspect` and `Mutate` traits for working with regular balances.
|
||||
//!
|
||||
//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
|
||||
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! Inspect traits for Asset roles
|
||||
//!
|
||||
//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
|
||||
|
||||
pub trait Inspect<AccountId>: super::Inspect<AccountId> {
|
||||
// Get owner for an AssetId.
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! Type to combine two `fungibles::*` implementations into one union `fungibles::*` implementation.
|
||||
//!
|
||||
//! See the [`crate::traits::fungibles`] doc for more information about fungibles traits.
|
||||
|
||||
use frame_support::traits::{
|
||||
tokens::{
|
||||
|
||||
Reference in New Issue
Block a user