polkadot_sdk_docs/reference_docs/frame_tokens.rs
1// This file is part of polkadot-sdk.
2//
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! # FRAME Tokens
19//!
20//! This reference doc serves as a high-level overview of the token-related logic in FRAME, and
21//! how to properly apply it to your use case.
22//!
23//! On completion of reading this doc, you should have a good understanding of:
24//! - The distinction between token traits and trait implementations in FRAME, and why this
25//! distinction is helpful.
26//! - Token-related traits available in FRAME.
27//! - Token-related trait implementations in FRAME.
28//! - How to choose the right trait or trait implementation for your use case.
29//! - Where to go next.
30//!
31//! ## Getting Started
32//!
33//! The most ubiquitous way to add a token to a FRAME runtime is [`pallet_balances`]. Read
34//! more about pallets [here](crate::polkadot_sdk::frame_runtime#pallets).
35//!
36//! You may then write custom pallets that interact with [`pallet_balances`]. The fastest way to
37//! get started with that is by
38//! [tightly coupling](crate::reference_docs::frame_pallet_coupling#tight-coupling-pallets) your
39//! custom pallet to [`pallet_balances`].
40//!
41//! However, to keep pallets flexible and modular, it is often preferred to
42//! [loosely couple](crate::reference_docs::frame_pallet_coupling#loosely--coupling-pallets).
43//!
44//! To achieve loose coupling,
45//! we separate token logic into traits and trait implementations.
46//!
47//! ## Traits and Trait Implementations
48//!
49//! Broadly speaking, token logic in FRAME can be divided into two categories: traits and
50//! trait implementations.
51//!
52//! **Traits** define common interfaces that types of tokens should implement. For example, the
53//! [`fungible::Inspect`](`frame_support::traits::fungible::Inspect`) trait specifies an interface
54//! for *inspecting* token state such as the total issuance of the token, the balance of individual
55//! accounts, etc.
56//!
57//! **Trait implementations** are concrete implementations of these traits. For example, one of the
58//! many traits [`pallet_balances`] implements is
59//! [`fungible::Inspect`](`frame_support::traits::fungible::Inspect`)[^1]. It provides the concrete
60//! way of inspecting the total issuance, balance of accounts, etc. There can be many
61//! implementations of the same traits.
62//!
63//! [^1]: Rust Advanced Tip: The knowledge that [`pallet_balances`] implements
64//! [`fungible::Inspect`](`frame_support::traits::fungible::Inspect`) is not some arcane knowledge
65//! that you have to know by heart or memorize. One can simply look at the list of the implementors
66//! of any trait in the Rust Doc to find all implementors (e.g.
67//! [Mutate trait implementors](https://paritytech.github.io/polkadot-sdk/master/frame_support/traits/tokens/fungible/trait.Mutate.html#implementors)),
68//! or use the `rust-analyzer`'s `Implementations` action.
69//!
70//! The distinction between traits and trait implementations is helpful because it allows pallets
71//! and other logic to be generic over their dependencies, avoiding tight coupling.
72//!
73//! To illustrate this with an example let's consider [`pallet_preimage`]. This pallet takes a
74//! deposit in exchange for storing a preimage for later use. A naive implementation of the
75//! pallet may use [`pallet_balances`] in a tightly coupled manner, directly calling methods
76//! on the pallet to reserve and unreserve deposits. This approach works well,
77//! until someone has a use case requiring that an asset from a different pallet such as
78//! [`pallet_assets`] is used for the deposit. Rather than tightly coupling [`pallet_preimage`] to
79//! [`pallet_balances`], [`pallet_assets`], and every other token-handling pallet, a user
80//! could possibly specify that [`pallet_preimage`] does not specify a concrete pallet as a
81//! dependency, but instead accepts any dependency which implements the
82//! [`currency::ReservableCurrency`](`frame_support::traits::tokens::currency::ReservableCurrency`)
83//! trait, namely via its [`Config::Currency`](`pallet_preimage::pallet::Config::Currency`)
84//! associated type. This allows [`pallet_preimage`] to support any arbitrary pallet implementing
85//! this trait, without needing any knowledge of what those pallets may be or requiring changes to
86//! support new pallets which may be written in the future.
87//!
88//! Read more about coupling, and the benefits of loose coupling
89//! [here](crate::reference_docs::frame_pallet_coupling).
90//!
91//! ## Fungible Token Traits in FRAME
92//!
93//! The [`fungible`](`frame_support::traits::fungible`) crate contains the latest set of FRAME
94//! fungible token traits, and is recommended to use for all new logic requiring a fungible token.
95//! See the crate documentation for more info about these fungible traits.
96//!
97//! [`fungibles`](`frame_support::traits::fungibles`) provides very similar functionality to
98//! [`fungible`](`frame_support::traits::fungible`), except it supports managing multiple tokens.
99//!
100//! You may notice the trait [`Currency`](`frame_support::traits::Currency`) with similar
101//! functionality is also used in the codebase, however this trait is deprecated and existing logic
102//! is in the process of being migrated to [`fungible`](`frame_support::traits::fungible`) ([tracking issue](https://github.com/paritytech/polkadot-sdk/issues/226)).
103//!
104//! ## Fungible Token Trait Implementations in FRAME
105//!
106//! [`pallet_balances`] implements [`fungible`](`frame_support::traits::fungible`), and is the most
107//! commonly used fungible implementation in FRAME. Most of the time, it's used for managing the
108//! native token of the blockchain network it's used in.
109//!
110//! [`pallet_assets`] implements [`fungibles`](`frame_support::traits::fungibles`), and is another
111//! popular fungible token implementation. It supports the creation and management of multiple
112//! assets in a single crate, making it a good choice when a network requires more assets in
113//! addition to its native token.
114//!
115//! ## Non-Fungible Tokens in FRAME
116//!
117//! [`pallet_nfts`] is recommended to use for all NFT use cases in FRAME.
118//! See the crate documentation for more info about this pallet.
119//!
120//! [`pallet_uniques`] is deprecated and should not be used.
121//!
122//!
123//! # What Next?
124//!
125//! - If you are interested in implementing a single fungible token, continue reading the
126//! [`fungible`](`frame_support::traits::fungible`) and [`pallet_balances`] docs.
127//! - If you are interested in implementing a set of fungible tokens, continue reading the
128//! [`fungibles`](`frame_support::traits::fungibles`) trait and [`pallet_assets`] docs.
129//! - If you are interested in implementing an NFT, continue reading the [`pallet_nfts`] docs.