## Module frame_tokens

Source
Expand description

Learn about the token-related logic in FRAME and how to apply it to your use case.

## §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 available 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 [`pezpallet_balances`]. Read more about pallets here.

You may then write custom pallets that interact with [`pezpallet_balances`]. The fastest way to get started with that is by tightly coupling your custom pezpallet to [`pezpallet_balances`].

However, to keep pallets flexible and modular, it is often preferred to loosely couple.

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` 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 [`pezpallet_balances`] implements is `fungible::Inspect`1. 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 [`pezpallet_preimage`]. This pezpallet takes a deposit in exchange for storing a preimage for later use. A naive implementation of the pezpallet may use [`pezpallet_balances`] in a tightly coupled manner, directly calling methods on the pezpallet to reserve and unreserve deposits. This approach works well, until someone has a use case requiring that an asset from a different pezpallet such as [`pezpallet_assets`] is used for the deposit. Rather than tightly coupling [`pezpallet_preimage`] to [`pezpallet_balances`], [`pezpallet_assets`], and every other token-handling pezpallet, a user could possibly specify that [`pezpallet_preimage`] does not specify a concrete pezpallet as a dependency, but instead accepts any dependency which implements the `currency::ReservableCurrency` trait, namely via its `Config::Currency` associated type. This allows [`pezpallet_preimage`] to support any arbitrary pezpallet 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.

### §Fungible Token Traits in FRAME

The `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` provides very similar functionality to `fungible`, except it supports managing multiple tokens.

You may notice the trait `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` (tracking issue).

### §Fungible Token Trait Implementations in FRAME

[`pezpallet_balances`] implements `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.

[`pezpallet_assets`] implements `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

[`pezpallet_nfts`] is recommended to use for all NFT use cases in FRAME. See the crate documentation for more info about this pezpallet.

[`pezpallet_uniques`] is deprecated and should not be used.

## §What Next?

- If you are interested in implementing a single fungible token, continue reading the `fungible` and [`pezpallet_balances`] docs.
- If you are interested in implementing a set of fungible tokens, continue reading the `fungibles` trait and [`pezpallet_assets`] docs.
- If you are interested in implementing an NFT, continue reading the [`pezpallet_nfts`] docs.

1. Rust Advanced Tip: The knowledge that [`pezpallet_balances`] implements `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. Mutate trait implementors), or use the `rust-analyzer`’s `Implementations` action. ↩