git.delta.rocks / unique-network / refs/commits / c6eb2378a98c

difftreelog

doc: added docs for refungible pallet

Grigoriy Simonov2022-07-12parent: #12c8c8f.patch.diff
in: master

2 files changed

modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
145 }145 }
146}146}
147147
148/// Implementation of `CommonCollectionOperations` for `RefungibleHandle`. It wraps Refungible Pallete
149/// methods and adds weight info.
148impl<T: Config> CommonCollectionOperations<T> for RefungibleHandle<T> {150impl<T: Config> CommonCollectionOperations<T> for RefungibleHandle<T> {
149 fn create_item(151 fn create_item(
150 &self,152 &self,
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
16
17//! # Refungible Pallet
18//!
19//! The Refungible pallet provides functionality for handling refungible collections and tokens.
20//!
21//! - [`Config`]
22//! - [`RefungibleHandle`]
23//! - [`Pallet`]
24//! - [`CommonWeights`]
25//!
26//! ## Overview
27//!
28//! The Refungible pallet provides functions for:
29//!
30//! - RFT collection creation and removal
31//! - Minting and burning of RFT tokens
32//! - Partition and repartition of RFT tokens
33//! - Retrieving number of pieces of RFT token
34//! - Retrieving account balances
35//! - Transfering RFT token pieces
36//! - Burning RFT token pieces
37//! - Setting and checking allowance for RFT tokens
38//!
39//! ### Terminology
40//!
41//! - **RFT token:** Non fungible token that was partitioned to pieces. If an account owns all
42//! of the RFT token pieces than it owns the RFT token and can repartition it.
43//!
44//! - **RFT Collection:** A collection of RFT tokens. All RFT tokens are part of a collection.
45//! Each collection has its own settings and set of permissions.
46//!
47//! - **RFT token piece:** A fungible part of an RFT token.
48//!
49//! - **Balance:** RFT token pieces owned by an account
50//!
51//! - **Allowance:** Maximum number of RFT token pieces that one account is allowed to
52//! transfer from the balance of another account
53//!
54//! - **Burning:** The process of “deleting” a token from a collection or removing token pieces from
55//! an account balance.
56//!
57//! ### Implementations
58//!
59//! The Refungible pallet provides implementations for the following traits. If these traits provide
60//! the functionality that you need, then you can avoid coupling with the Refungible pallet.
61//!
62//! - [`CommonWeightInfo`](pallet_common::CommonWeightInfo): Functions for retrieval of transaction weight
63//! - [`CommonCollectionOperations`](pallet_common::CommonCollectionOperations): Functions for dealing
64//! with collections
65//! - [`RefungibleExtensions`](pallet_common::RefungibleExtensions): Functions specific for refungible
66//! collection
67//!
68//! ## Interface
69//!
70//! ### Dispatchable Functions
71//!
72//! - `init_collection` - Create RFT collection. RFT collection can be configured to allow or deny access for
73//! some accounts.
74//! - `destroy_collection` - Destroy exising RFT collection. There should be no tokens in the collection.
75//! - `burn` - Burn some amount of RFT token pieces owned by account. Burns the RFT token if no pieces left.
76//! - `transfer` - Transfer some amount of RFT token pieces. Transfers should be enabled for RFT collection.
77//! Nests the RFT token if RFT token pieces are sent to another token.
78//! - `create_item` - Mint RFT token in collection. Sender should have permission to mint tokens.
79//! - `set_allowance` - Set allowance for another account to transfer balance from sender's account.
80//! - `repartition` - Repartition token to selected number of pieces. Sender should own all existing pieces.
81//!
82//! ## Assumptions
83//!
84//! * Total number of pieces for one token shouldn't exceed `up_data_structs::MAX_REFUNGIBLE_PIECES`.
85//! * Total number of tokens of all types shouldn't be greater than `up_data_structs::MAX_TOKEN_PREFIX_LENGTH`.
86//! * Sender should be in collection's allow list to perform operations on tokens.
1687
17#![cfg_attr(not(feature = "std"), no_std)]88#![cfg_attr(not(feature = "std"), no_std)]
1889
86 #[pallet::generate_store(pub(super) trait Store)]157 #[pallet::generate_store(pub(super) trait Store)]
87 pub struct Pallet<T>(_);158 pub struct Pallet<T>(_);
88159
160 /// Amount of tokens minted for collection
89 #[pallet::storage]161 #[pallet::storage]
90 pub type TokensMinted<T: Config> =162 pub type TokensMinted<T: Config> =
91 StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;163 StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;
164
165 /// Amount of burnt tokens for collection
92 #[pallet::storage]166 #[pallet::storage]
93 pub type TokensBurnt<T: Config> =167 pub type TokensBurnt<T: Config> =
94 StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;168 StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;
95169
170 /// Custom data serialized to bytes for token
96 #[pallet::storage]171 #[pallet::storage]
97 pub type TokenData<T: Config> = StorageNMap<172 pub type TokenData<T: Config> = StorageNMap<
98 Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),173 Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
99 Value = ItemData,174 Value = ItemData,
100 QueryKind = ValueQuery,175 QueryKind = ValueQuery,
101 >;176 >;
102177
178 /// Total amount of pieces for token
103 #[pallet::storage]179 #[pallet::storage]
104 pub type TotalSupply<T: Config> = StorageNMap<180 pub type TotalSupply<T: Config> = StorageNMap<
105 Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),181 Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
119 QueryKind = ValueQuery,195 QueryKind = ValueQuery,
120 >;196 >;
121197
198 /// Amount of tokens owned by account
122 #[pallet::storage]199 #[pallet::storage]
123 pub type AccountBalance<T: Config> = StorageNMap<200 pub type AccountBalance<T: Config> = StorageNMap<
124 Key = (201 Key = (
130 QueryKind = ValueQuery,207 QueryKind = ValueQuery,
131 >;208 >;
132209
210 /// Amount of token pieces owned by account
133 #[pallet::storage]211 #[pallet::storage]
134 pub type Balance<T: Config> = StorageNMap<212 pub type Balance<T: Config> = StorageNMap<
135 Key = (213 Key = (
142 QueryKind = ValueQuery,220 QueryKind = ValueQuery,
143 >;221 >;
144222
223 /// Allowance set by an owner for a spender for a token
145 #[pallet::storage]224 #[pallet::storage]
146 pub type Allowance<T: Config> = StorageNMap<225 pub type Allowance<T: Config> = StorageNMap<
147 Key = (226 Key = (
188}267}
189268
190impl<T: Config> Pallet<T> {269impl<T: Config> Pallet<T> {
270 /// Get number of RFT tokens in collection
191 pub fn total_supply(collection: &RefungibleHandle<T>) -> u32 {271 pub fn total_supply(collection: &RefungibleHandle<T>) -> u32 {
192 <TokensMinted<T>>::get(collection.id) - <TokensBurnt<T>>::get(collection.id)272 <TokensMinted<T>>::get(collection.id) - <TokensBurnt<T>>::get(collection.id)
193 }273 }
274
275 /// Check that RFT token exists
276 ///
277 /// - `token`: Token ID.
194 pub fn token_exists(collection: &RefungibleHandle<T>, token: TokenId) -> bool {278 pub fn token_exists(collection: &RefungibleHandle<T>, token: TokenId) -> bool {
195 <TotalSupply<T>>::contains_key((collection.id, token))279 <TotalSupply<T>>::contains_key((collection.id, token))
196 }280 }
197}281}
198282
199// unchecked calls skips any permission checks283// unchecked calls skips any permission checks
200impl<T: Config> Pallet<T> {284impl<T: Config> Pallet<T> {
285 /// Create RFT collection
286 ///
287 /// `init_collection` will take non-refundable deposit for collection creation.
288 ///
289 /// - `data`: Contains settings for collection limits and permissions.
201 pub fn init_collection(290 pub fn init_collection(
202 owner: T::CrossAccountId,291 owner: T::CrossAccountId,
203 data: CreateCollectionData<T::AccountId>,292 data: CreateCollectionData<T::AccountId>,
204 ) -> Result<CollectionId, DispatchError> {293 ) -> Result<CollectionId, DispatchError> {
205 <PalletCommon<T>>::init_collection(owner, data, false)294 <PalletCommon<T>>::init_collection(owner, data, false)
206 }295 }
296
297 /// Destroy RFT collection
298 ///
299 /// `destroy_collection` will throw error if collection contains any tokens.
300 /// Only owner can destroy collection.
207 pub fn destroy_collection(301 pub fn destroy_collection(
208 collection: RefungibleHandle<T>,302 collection: RefungibleHandle<T>,
209 sender: &T::CrossAccountId,303 sender: &T::CrossAccountId,
235 .is_some()329 .is_some()
236 }330 }
237331
238 pub fn burn_token(collection: &RefungibleHandle<T>, token_id: TokenId) -> DispatchResult {332 pub fn burn_token_unchecked(
333 collection: &RefungibleHandle<T>,
334 token_id: TokenId,
335 ) -> DispatchResult {
249 Ok(())346 Ok(())
250 }347 }
251348
349 /// Burn RFT token pieces
350 ///
351 /// `burn` will decrease total amount of token pieces and amount owned by sender.
352 /// If sender wouldn't have any pieces left after `burn` than she will stop being
353 /// one of the owners of the token. If there is no account that owns any pieces of
354 /// the token than token will be burned too.
355 ///
356 /// - `amount`: Amount of token pieces to burn.
357 /// - `token`: Token who's pieces should be burned
358 /// - `collection`: Collection that contains the token
252 pub fn burn(359 pub fn burn(
253 collection: &RefungibleHandle<T>,360 collection: &RefungibleHandle<T>,
254 owner: &T::CrossAccountId,361 owner: &T::CrossAccountId,
276 <Owned<T>>::remove((collection.id, owner, token));383 <Owned<T>>::remove((collection.id, owner, token));
277 <PalletStructure<T>>::unnest_if_nested(owner, collection.id, token);384 <PalletStructure<T>>::unnest_if_nested(owner, collection.id, token);
278 <AccountBalance<T>>::insert((collection.id, owner), account_balance);385 <AccountBalance<T>>::insert((collection.id, owner), account_balance);
279 Self::burn_token(collection, token)?;386 Self::burn_token_unchecked(collection, token)?;
280 <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(387 <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(
281 collection.id,388 collection.id,
282 token,389 token,
319 Ok(())426 Ok(())
320 }427 }
321428
429 /// Transfer RFT token pieces from one account to another.
430 ///
431 /// If the sender is no longer owns any pieces after the `transfer` than she stops being an owner of the token.
432 ///
433 /// - `from`: Owner of token pieces to transfer.
434 /// - `to`: Recepient of transfered token pieces.
435 /// - `amount`: Amount of token pieces to transfer.
436 /// - `token`: Token whos pieces should be transfered
437 /// - `collection`: Collection that contains the token
322 pub fn transfer(438 pub fn transfer(
323 collection: &RefungibleHandle<T>,439 collection: &RefungibleHandle<T>,
324 from: &T::CrossAccountId,440 from: &T::CrossAccountId,
423 Ok(())539 Ok(())
424 }540 }
425541
542 /// Batched operation to create multiple RFT tokens.
543 ///
544 /// Same as `create_item` but creates multiple tokens.
545 ///
546 /// - `data`: Same as 'data` in `create_item` but contains data for multiple tokens.
426 pub fn create_multiple_items(547 pub fn create_multiple_items(
427 collection: &RefungibleHandle<T>,548 collection: &RefungibleHandle<T>,
428 sender: &T::CrossAccountId,549 sender: &T::CrossAccountId,
568 ))689 ))
569 }690 }
570691
692 /// Set allowance for the spender to `transfer` or `burn` sender's token pieces.
693 ///
694 /// - `amount`: Amount of token pieces the spender is allowed to `transfer` or `burn.
571 pub fn set_allowance(695 pub fn set_allowance(
572 collection: &RefungibleHandle<T>,696 collection: &RefungibleHandle<T>,
573 sender: &T::CrossAccountId,697 sender: &T::CrossAccountId,
636 Ok(allowance)760 Ok(allowance)
637 }761 }
638762
763 /// Transfer RFT token pieces from one account to another.
764 ///
765 /// Same as the [`transfer`] but spender doesn't needs to be an owner of the token pieces.
766 /// The owner should set allowance for the spender to transfer pieces.
767 ///
768 /// [`transfer`]: struct.Pallet.html#method.transfer
639 pub fn transfer_from(769 pub fn transfer_from(
640 collection: &RefungibleHandle<T>,770 collection: &RefungibleHandle<T>,
641 spender: &T::CrossAccountId,771 spender: &T::CrossAccountId,
657 Ok(())787 Ok(())
658 }788 }
659789
790 /// Burn RFT token pieces from the account.
791 ///
792 /// Same as the [`burn`] but spender doesn't need to be an owner of the token pieces. The owner should
793 /// set allowance for the spender to burn pieces
794 ///
795 /// [`burn`]: struct.Pallet.html#method.burn
660 pub fn burn_from(796 pub fn burn_from(
661 collection: &RefungibleHandle<T>,797 collection: &RefungibleHandle<T>,
662 spender: &T::CrossAccountId,798 spender: &T::CrossAccountId,
677 Ok(())813 Ok(())
678 }814 }
679815
680 /// Delegated to `create_multiple_items`816 /// Create RFT token.
817 ///
818 /// The sender should be the owner/admin of the collection or collection should be configured
819 /// to allow public minting.
820 ///
821 /// - `data`: Contains list of users who will become the owners of the token pieces and amount
822 /// of token pieces they will receive.
681 pub fn create_item(823 pub fn create_item(
682 collection: &RefungibleHandle<T>,824 collection: &RefungibleHandle<T>,
683 sender: &T::CrossAccountId,825 sender: &T::CrossAccountId,
687 Self::create_multiple_items(collection, sender, vec![data], nesting_budget)829 Self::create_multiple_items(collection, sender, vec![data], nesting_budget)
688 }830 }
689831
832 /// Repartition RFT token.
833 ///
834 /// Repartition will set token balance of the sender and total amount of token pieces.
835 /// Sender should own all of the token pieces.
836 ///
837 /// - `amount`: Total amount of token pieces that the token will have after `repartition`.
690 pub fn repartition(838 pub fn repartition(
691 collection: &RefungibleHandle<T>,839 collection: &RefungibleHandle<T>,
692 owner: &T::CrossAccountId,840 owner: &T::CrossAccountId,