From 665fb9fa8027a1bcc38922ef4e636e76a16a4a37 Mon Sep 17 00:00:00 2001 From: Grigoriy Simonov Date: Thu, 21 Jul 2022 09:07:44 +0000 Subject: [PATCH] doc: add documentation for nonfungible palette --- --- a/pallets/nonfungible/src/common.rs +++ b/pallets/nonfungible/src/common.rs @@ -133,6 +133,8 @@ } } +/// Implementation of `CommonCollectionOperations` for `NonfungibleHandle`. It wraps Nonfungible Pallete +/// methods and adds weight info. impl CommonCollectionOperations for NonfungibleHandle { fn create_item( &self, --- a/pallets/nonfungible/src/lib.rs +++ b/pallets/nonfungible/src/lib.rs @@ -14,6 +14,81 @@ // You should have received a copy of the GNU General Public License // along with Unique Network. If not, see . +//! # Nonfungible Pallet +//! +//! The Nonfungible pallet provides functionality for handling nonfungible collections and tokens. +//! +//! - [`Config`] +//! - [`NonfungibleHandle`] +//! - [`Pallet`] +//! - [`CommonWeights`] +//! +//! ## Overview +//! +//! The Nonfungible pallet provides functions for: +//! +//! - NFT collection creation and removal +//! - Minting and burning of NFT tokens +//! - Retrieving account balances +//! - Transfering NFT tokens +//! - Setting and checking allowance for NFT tokens +//! - Setting properties and permissions for NFT collections and tokens +//! - Nesting and unnesting tokens +//! +//! ### Terminology +//! +//! - **NFT token:** Non fungible token. +//! +//! - **NFT Collection:** A collection of NFT tokens. All NFT tokens are part of a collection. +//! Each collection can define it's own properties, properties for it's tokens and set of permissions. +//! +//! - **Balance:** Number of NFT tokens owned by an account +//! +//! - **Allowance:** NFT tokens owned by one account that another account is allowed to make operations on +//! +//! - **Burning:** The process of “deleting” a token from a collection and from +//! an account balance of the owner. +//! +//! - **Nesting:** Setting up parent-child relationship between tokens. Nested tokens are inhereting +//! owner from their parent. There could be multiple levels of nesting. Token couldn't be nested in +//! it's child token i.e. parent-child relationship graph shouldn't have cycles. +//! +//! - **Properties:** Key-Values pairs. Token properties are attached to a token. Collection properties are +//! attached to a collection. Set of permissions could be defined for each property. +//! +//! ### Implementations +//! +//! The Nonfungible pallet provides implementations for the following traits. If these traits provide +//! the functionality that you need, then you can avoid coupling with the Nonfungible pallet. +//! +//! - [`CommonWeightInfo`](pallet_common::CommonWeightInfo): Functions for retrieval of transaction weight +//! - [`CommonCollectionOperations`](pallet_common::CommonCollectionOperations): Functions for dealing +//! with collections +//! +//! ## Interface +//! +//! ### Dispatchable Functions +//! +//! - `init_collection` - Create NFT collection. NFT collection can be configured to allow or deny access for +//! some accounts. +//! - `destroy_collection` - Destroy exising NFT collection. There should be no tokens in the collection. +//! - `burn` - Burn NFT token owned by account. +//! - `transfer` - Transfer NFT token. Transfers should be enabled for NFT collection. +//! Nests the NFT token if it is sent to another token. +//! - `create_item` - Mint NFT token in collection. Sender should have permission to mint tokens. +//! - `set_allowance` - Set allowance for another account. +//! - `set_token_property` - Set token property value. +//! - `delete_token_property` - Remove property from the token. +//! - `set_collection_properties` - Set collection properties. +//! - `delete_collection_properties` - Remove properties from the collection. +//! - `set_property_permission` - Set collection property permission. +//! - `set_token_property_permissions` - Set token property permissions. +//! +//! ## Assumptions +//! +//! * Total number of tokens of all types shouldn't be greater than `up_data_structs::MAX_TOKEN_PREFIX_LENGTH`. +//! * Sender should be in collection's allow list to perform operations on tokens. + #![cfg_attr(not(feature = "std"), no_std)] use erc::ERC721Events; @@ -102,13 +177,17 @@ #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(_); + /// Amount of tokens minted for collection. #[pallet::storage] pub type TokensMinted = StorageMap; + + /// Amount of burnt tokens for collection. #[pallet::storage] pub type TokensBurnt = StorageMap; + /// Custom data serialized to bytes for token. #[pallet::storage] pub type TokenData = StorageNMap< Key = (Key, Key), @@ -116,6 +195,7 @@ QueryKind = OptionQuery, >; + /// Key-Value map stored for token. #[pallet::storage] #[pallet::getter(fn token_properties)] pub type TokenProperties = StorageNMap< @@ -125,6 +205,7 @@ OnEmpty = up_data_structs::TokenProperties, >; + /// Custom data that is serialized to bytes and attached to a token property. #[pallet::storage] #[pallet::getter(fn token_aux_property)] pub type TokenAuxProperties = StorageNMap< @@ -138,7 +219,7 @@ QueryKind = OptionQuery, >; - /// Used to enumerate tokens owned by account + /// Used to enumerate tokens owned by account. #[pallet::storage] pub type Owned = StorageNMap< Key = ( @@ -150,7 +231,7 @@ QueryKind = ValueQuery, >; - /// Used to enumerate token's children + /// Used to enumerate token's children. #[pallet::storage] #[pallet::getter(fn token_children)] pub type TokenChildren = StorageNMap< @@ -163,6 +244,7 @@ QueryKind = ValueQuery, >; + /// Amount of tokens owned by account. #[pallet::storage] pub type AccountBalance = StorageNMap< Key = ( @@ -173,6 +255,7 @@ QueryKind = ValueQuery, >; + /// Allowance set by an owner for a spender for a token. #[pallet::storage] pub type Allowance = StorageNMap< Key = (Key, Key), @@ -273,13 +356,21 @@ } impl Pallet { + /// Get number of NFT tokens in collection. pub fn total_supply(collection: &NonfungibleHandle) -> u32 { >::get(collection.id) - >::get(collection.id) } + + /// Check that NFT token exists. + /// + /// - `token`: Token ID. pub fn token_exists(collection: &NonfungibleHandle, token: TokenId) -> bool { >::contains_key((collection.id, token)) } + /// Set the token property with the scope. + /// + /// - `property`: Contains key-value pair. pub fn set_scoped_token_property( collection_id: CollectionId, token_id: TokenId, @@ -294,6 +385,7 @@ Ok(()) } + /// Batch operation to set multiple properties with the same scope. pub fn set_scoped_token_properties( collection_id: CollectionId, token_id: TokenId, @@ -308,6 +400,9 @@ Ok(()) } + /// Add or edit auxiliary data for the property. + /// + /// - `f`: function that adds or edits auxiliary data. pub fn try_mutate_token_aux_property( collection_id: CollectionId, token_id: TokenId, @@ -318,6 +413,7 @@ >::try_mutate((collection_id, token_id, scope, key), f) } + /// Remove auxiliary data for the property. pub fn remove_token_aux_property( collection_id: CollectionId, token_id: TokenId, @@ -327,6 +423,9 @@ >::remove((collection_id, token_id, scope, key)); } + /// Get all auxiliary data in a given scope. + /// + /// Returns iterator over Property Key - Data pairs. pub fn iterate_token_aux_properties( collection_id: CollectionId, token_id: TokenId, @@ -335,6 +434,7 @@ >::iter_prefix((collection_id, token_id, scope)) } + /// Get ID of the last minted token pub fn current_token_id(collection_id: CollectionId) -> TokenId { TokenId(>::get(collection_id)) } @@ -342,6 +442,11 @@ // unchecked calls skips any permission checks impl Pallet { + /// Create ТFT collection + /// + /// `init_collection` will take non-refundable deposit for collection creation. + /// + /// - `data`: Contains settings for collection limits and permissions. pub fn init_collection( owner: T::CrossAccountId, data: CreateCollectionData, @@ -349,6 +454,11 @@ ) -> Result { >::init_collection(owner, data, is_external) } + + /// Destroy ТFT collection + /// + /// `destroy_collection` will throw error if collection contains any tokens. + /// Only owner can destroy collection. pub fn destroy_collection( collection: NonfungibleHandle, sender: &T::CrossAccountId, @@ -373,6 +483,15 @@ Ok(()) } + /// Burn NFT token + /// + /// `burn` removes `token` from the `collection`, from it's owner and from the parent token + /// if the token is nested. + /// Only the owner can `burn` the token. The `token` shouldn't have any nested tokens. + /// Also removes all corresponding properties and auxiliary properties. + /// + /// - `token`: Token that should be burned + /// - `collection`: Collection that contains the token pub fn burn( collection: &NonfungibleHandle, sender: &T::CrossAccountId, @@ -442,6 +561,12 @@ Ok(()) } + /// Same as [`burn`] but burns all the tokens that are nested in the token first + /// + /// - `self_budget`: Limit for searching children in depth. + /// - `breadth_budget`: Limit of breadth of searching children. + /// + /// [`burn`]: struct.Pallet.html#method.burn #[transactional] pub fn burn_recursively( collection: &NonfungibleHandle, @@ -481,6 +606,14 @@ }) } + /// Batch operation to add, edit or remove properties for the token + /// + /// All affected properties should have mutable permission and sender should have + /// permission to edit those properties. + /// + /// - `nesting_budget`: Limit for searching parents in depth to check ownership. + /// - `is_token_create`: Indicates that method is called during token initialization. + /// Allows to bypass ownership check. #[transactional] fn modify_token_properties( collection: &NonfungibleHandle, @@ -574,6 +707,11 @@ Ok(()) } + /// Batch operation to add or edit properties for the token + /// + /// Same as [`modify_token_properties`] but doesn't allow to remove properties + /// + /// [`modify_token_properties`]: struct.Pallet.html#method.modify_token_properties pub fn set_token_properties( collection: &NonfungibleHandle, sender: &T::CrossAccountId, @@ -592,6 +730,11 @@ ) } + /// Add or edit single property for the token + /// + /// Calls [`set_token_properties`] internally + /// + /// [`set_token_properties`]: struct.Pallet.html#method.set_token_properties pub fn set_token_property( collection: &NonfungibleHandle, sender: &T::CrossAccountId, @@ -611,6 +754,11 @@ ) } + /// Batch operation to remove properties from the token + /// + /// Same as [`modify_token_properties`] but doesn't allow to add or edit properties + /// + /// [`modify_token_properties`]: struct.Pallet.html#method.modify_token_properties pub fn delete_token_properties( collection: &NonfungibleHandle, sender: &T::CrossAccountId, @@ -630,6 +778,11 @@ ) } + /// Remove single property from the token + /// + /// Calls [`delete_token_properties`] internally + /// + /// [`delete_token_properties`]: struct.Pallet.html#method.delete_token_properties pub fn delete_token_property( collection: &NonfungibleHandle, sender: &T::CrossAccountId, @@ -646,6 +799,7 @@ ) } + /// Add or edit properties for the collection pub fn set_collection_properties( collection: &NonfungibleHandle, sender: &T::CrossAccountId, @@ -654,6 +808,7 @@ >::set_collection_properties(collection, sender, properties) } + /// Remove properties from the collection pub fn delete_collection_properties( collection: &CollectionHandle, sender: &T::CrossAccountId, @@ -662,6 +817,9 @@ >::delete_collection_properties(collection, sender, property_keys) } + /// Set property permissions for the token. + /// + /// Sender should be the owner or admin of token's collection. pub fn set_token_property_permissions( collection: &CollectionHandle, sender: &T::CrossAccountId, @@ -670,6 +828,9 @@ >::set_token_property_permissions(collection, sender, property_permissions) } + /// Set property permissions for the collection. + /// + /// Sender should be the owner or admin of the collection. pub fn set_property_permission( collection: &CollectionHandle, sender: &T::CrossAccountId, @@ -678,6 +839,14 @@ >::set_property_permission(collection, sender, permission) } + /// Transfer NFT token from one account to another. + /// + /// `from` account stops being the owner and `to` account becomes the owner of the token. + /// If `to` is token than `to` becomes owner of the token and the token become nested. + /// Unnests token from previous parent if it was nested before. + /// Removes allowance for the token if there was any. + /// + /// - `nesting_budget`: Limit for token nesting depth pub fn transfer( collection: &NonfungibleHandle, from: &T::CrossAccountId, @@ -769,6 +938,13 @@ Ok(()) } + /// Batch operation to mint multiple NFT tokens. + /// + /// The sender should be the owner/admin of the collection or collection should be configured + /// to allow public minting. + /// + /// - `data`: Contains list of token properties and users who will become the owners of the corresponging tokens. + /// - `nesting_budget`: Limit for token nesting depth pub fn create_multiple_items( collection: &NonfungibleHandle, sender: &T::CrossAccountId, @@ -953,6 +1129,9 @@ } } + /// Set allowance for the spender to `transfer` or `burn` sender's token. + /// + /// - `token`: Token the spender is allowed to `transfer` or `burn`. pub fn set_allowance( collection: &NonfungibleHandle, sender: &T::CrossAccountId, @@ -985,6 +1164,7 @@ Ok(()) } + /// Checks allowance for the spender to use the token. fn check_allowed( collection: &NonfungibleHandle, spender: &T::CrossAccountId, @@ -1027,6 +1207,12 @@ Ok(()) } + /// Transfer NFT token from one account to another. + /// + /// Same as the [`transfer`] but spender doesn't needs to be the owner of the token. + /// The owner should set allowance for the spender to transfer token. + /// + /// [`transfer`]: struct.Pallet.html#method.transfer pub fn transfer_from( collection: &NonfungibleHandle, spender: &T::CrossAccountId, @@ -1043,6 +1229,12 @@ Self::transfer(collection, from, to, token, nesting_budget) } + /// Burn NFT token for `from` account. + /// + /// Same as the [`burn`] but spender doesn't need to be an owner of the token. The owner should + /// set allowance for the spender to burn token. + /// + /// [`burn`]: struct.Pallet.html#method.burn pub fn burn_from( collection: &NonfungibleHandle, spender: &T::CrossAccountId, @@ -1057,6 +1249,8 @@ Self::burn(collection, from, token) } + /// Check that `from` token could be nested in `under` token. + /// pub fn check_nesting( handle: &NonfungibleHandle, sender: T::CrossAccountId, @@ -1126,7 +1320,11 @@ .collect() } - /// Delegated to `create_multiple_items` + /// Mint single NFT token. + /// + /// Delegated to [`create_multiple_items`] + /// + /// [`create_multiple_items`]: struct.Pallet.html#method.create_multiple_items pub fn create_item( collection: &NonfungibleHandle, sender: &T::CrossAccountId, -- gitstuff