From 76611ba6a3c297b8fe8988b04ad474759b7fe51a Mon Sep 17 00:00:00 2001 From: Dan Forbes Date: Wed, 28 Jul 2021 06:39:04 -0700 Subject: [PATCH] Add nonfungibles::Create Trait & Implement for Uniques (#9438) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add nonfungibles::Create Trait & Implement for Uniques Closes #9419 * Formatting * Remove default implementation (`TokenError::Unsupported`) from `Create` trait Co-authored-by: Bastian Köcher * Formatting * Do not wrap parameters in Options * Formatting Co-authored-by: Bastian Köcher --- .../support/src/traits/tokens/nonfungibles.rs | 6 +++ substrate/frame/uniques/src/functions.rs | 32 +++++++++++ .../frame/uniques/src/impl_nonfungibles.rs | 23 +++++++- substrate/frame/uniques/src/lib.rs | 53 +++++-------------- 4 files changed, 74 insertions(+), 40 deletions(-) diff --git a/substrate/frame/support/src/traits/tokens/nonfungibles.rs b/substrate/frame/support/src/traits/tokens/nonfungibles.rs index 64bbf3a8ed..452ee2212d 100644 --- a/substrate/frame/support/src/traits/tokens/nonfungibles.rs +++ b/substrate/frame/support/src/traits/tokens/nonfungibles.rs @@ -117,6 +117,12 @@ pub trait InspectEnumerable: Inspect { ) -> Box>; } +/// Trait for providing the ability to create classes of nonfungible assets. +pub trait Create: Inspect { + /// Create a `class` of nonfungible assets to be owned by `who` and managed by `admin`. + fn create_class(class: &Self::ClassId, who: &AccountId, admin: &AccountId) -> DispatchResult; +} + /// Trait for providing an interface for multiple classes of NFT-like assets which may be minted, /// burned and/or have attributes set on them. pub trait Mutate: Inspect { diff --git a/substrate/frame/uniques/src/functions.rs b/substrate/frame/uniques/src/functions.rs index 5d1e757357..a878a4910f 100644 --- a/substrate/frame/uniques/src/functions.rs +++ b/substrate/frame/uniques/src/functions.rs @@ -48,6 +48,38 @@ impl, I: 'static> Pallet { Ok(()) } + pub(super) fn do_create_class( + class: T::ClassId, + owner: T::AccountId, + admin: T::AccountId, + deposit: DepositBalanceOf, + free_holding: bool, + event: Event, + ) -> DispatchResult { + ensure!(!Class::::contains_key(class), Error::::InUse); + + T::Currency::reserve(&owner, deposit)?; + + Class::::insert( + class, + ClassDetails { + owner: owner.clone(), + issuer: admin.clone(), + admin: admin.clone(), + freezer: admin.clone(), + total_deposit: deposit, + free_holding, + instances: 0, + instance_metadatas: 0, + attributes: 0, + is_frozen: false, + }, + ); + + Self::deposit_event(event); + Ok(()) + } + pub(super) fn do_mint( class: T::ClassId, instance: T::InstanceId, diff --git a/substrate/frame/uniques/src/impl_nonfungibles.rs b/substrate/frame/uniques/src/impl_nonfungibles.rs index fb1e28d4c7..c5d5c6089f 100644 --- a/substrate/frame/uniques/src/impl_nonfungibles.rs +++ b/substrate/frame/uniques/src/impl_nonfungibles.rs @@ -19,7 +19,10 @@ use super::*; use frame_support::{ - traits::tokens::nonfungibles::{Inspect, InspectEnumerable, Mutate, Transfer}, + traits::{ + tokens::nonfungibles::{Create, Inspect, InspectEnumerable, Mutate, Transfer}, + Get, + }, BoundedSlice, }; use sp_runtime::DispatchResult; @@ -85,6 +88,24 @@ impl, I: 'static> Inspect<::AccountId> for Palle } } +impl, I: 'static> Create<::AccountId> for Pallet { + /// Create a `class` of nonfungible assets to be owned by `who` and managed by `admin`. + fn create_class( + class: &Self::ClassId, + who: &T::AccountId, + admin: &T::AccountId, + ) -> DispatchResult { + Self::do_create_class( + class.clone(), + who.clone(), + admin.clone(), + T::ClassDeposit::get(), + false, + Event::Created(class.clone(), who.clone(), admin.clone()), + ) + } +} + impl, I: 'static> Mutate<::AccountId> for Pallet { fn mint_into( class: &Self::ClassId, diff --git a/substrate/frame/uniques/src/lib.rs b/substrate/frame/uniques/src/lib.rs index d42b2ec55c..ee052486b0 100644 --- a/substrate/frame/uniques/src/lib.rs +++ b/substrate/frame/uniques/src/lib.rs @@ -316,28 +316,14 @@ pub mod pallet { let owner = ensure_signed(origin)?; let admin = T::Lookup::lookup(admin)?; - ensure!(!Class::::contains_key(class), Error::::InUse); - - let deposit = T::ClassDeposit::get(); - T::Currency::reserve(&owner, deposit)?; - - Class::::insert( + Self::do_create_class( class, - ClassDetails { - owner: owner.clone(), - issuer: admin.clone(), - admin: admin.clone(), - freezer: admin.clone(), - total_deposit: deposit, - free_holding: false, - instances: 0, - instance_metadatas: 0, - attributes: 0, - is_frozen: false, - }, - ); - Self::deposit_event(Event::Created(class, owner, admin)); - Ok(()) + owner.clone(), + admin.clone(), + T::ClassDeposit::get(), + false, + Event::Created(class, owner, admin), + ) } /// Issue a new class of non-fungible assets from a privileged origin. @@ -366,25 +352,14 @@ pub mod pallet { T::ForceOrigin::ensure_origin(origin)?; let owner = T::Lookup::lookup(owner)?; - ensure!(!Class::::contains_key(class), Error::::InUse); - - Class::::insert( + Self::do_create_class( class, - ClassDetails { - owner: owner.clone(), - issuer: owner.clone(), - admin: owner.clone(), - freezer: owner.clone(), - total_deposit: Zero::zero(), - free_holding, - instances: 0, - instance_metadatas: 0, - attributes: 0, - is_frozen: false, - }, - ); - Self::deposit_event(Event::ForceCreated(class, owner)); - Ok(()) + owner.clone(), + owner.clone(), + Zero::zero(), + free_holding, + Event::ForceCreated(class, owner), + ) } /// Destroy a class of fungible assets.