difftreelog
warning removed
in: master
3 files changed
pallets/nft/src/lib.rsdiffbeforeafterboth--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -1,5 +1,6 @@
#![cfg_attr(not(feature = "std"), no_std)]
+use codec::{Decode, Encode};
/// A FRAME pallet template with necessary imports
/// Feel free to remove or edit this file as needed.
@@ -8,13 +9,8 @@
/// For more guidance on Substrate FRAME, see the example pallet
/// https://github.com/paritytech/substrate/blob/master/frame/example/src/lib.rs
-
-use frame_support::{
- dispatch::DispatchResult, decl_module, decl_storage, decl_event,
- ensure,
-};
-use frame_system::{self as system, ensure_signed };
-use codec::{Encode, Decode};
+use frame_support::{decl_event, decl_module, decl_storage, dispatch::DispatchResult, ensure};
+use frame_system::{self as system, ensure_signed};
use sp_runtime::sp_std::prelude::Vec;
#[cfg(test)]
@@ -26,391 +22,367 @@
#[derive(Encode, Decode, Default, Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct CollectionType<AccountId> {
- pub owner: AccountId,
- pub next_item_id: u64,
- pub custom_data_size: u32,
+ pub owner: AccountId,
+ pub next_item_id: u64,
+ pub custom_data_size: u32,
}
#[derive(Encode, Decode, Default, Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct CollectionAdminsType<AccountId> {
- pub admin: AccountId,
- pub collection_id: u64,
+ pub admin: AccountId,
+ pub collection_id: u64,
}
#[derive(Encode, Decode, Default, Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct NftItemType<AccountId> {
- pub collection: u64,
- pub owner: AccountId,
- pub data: Vec<u8>,
+ pub collection: u64,
+ pub owner: AccountId,
+ pub data: Vec<u8>,
}
/// The pallet's configuration trait.
pub trait Trait: system::Trait {
- // Add other types and constants required to configure this pallet.
+ // Add other types and constants required to configure this pallet.
- /// The overarching event type.
- type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
+ /// The overarching event type.
+ type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}
// This pallet's storage items.
decl_storage! {
- // It is important to update your storage name so that your pallet's
- // storage items are isolated from other pallets.
- trait Store for Module<T: Trait> as Nft {
+ // It is important to update your storage name so that your pallet's
+ // storage items are isolated from other pallets.
+ trait Store for Module<T: Trait> as Nft {
- /// Next available collection ID
- pub NextCollectionID get(fn next_collection_id): u64;
+ /// Next available collection ID
+ pub NextCollectionID get(fn next_collection_id): u64;
- /// Collection map
- pub Collection get(collection): map hasher(identity) u64 => CollectionType<T::AccountId>;
+ /// Collection map
+ pub Collection get(collection): map hasher(identity) u64 => CollectionType<T::AccountId>;
- /// Admins map (collection)
- pub AdminList get(admin_list_collection): map hasher(identity) u64 => Vec<T::AccountId>;
+ /// Admins map (collection)
+ pub AdminList get(admin_list_collection): map hasher(identity) u64 => Vec<T::AccountId>;
- /// Balance owner per collection map
- pub Balance get(balance_count): map hasher(blake2_128_concat) (u64, T::AccountId) => u64;
+ /// Balance owner per collection map
+ pub Balance get(balance_count): map hasher(blake2_128_concat) (u64, T::AccountId) => u64;
- pub ApprovedList get(approved): map hasher(blake2_128_concat) (u64, u64) => Vec<T::AccountId>;
- pub ItemList get(item_id): map hasher(blake2_128_concat) (u64, u64) => NftItemType<T::AccountId>;
- pub ItemListIndex get(item_index): map hasher(blake2_128_concat) u64 => u64;
- }
+ pub ApprovedList get(approved): map hasher(blake2_128_concat) (u64, u64) => Vec<T::AccountId>;
+ pub ItemList get(item_id): map hasher(blake2_128_concat) (u64, u64) => NftItemType<T::AccountId>;
+ pub ItemListIndex get(item_index): map hasher(blake2_128_concat) u64 => u64;
+ }
}
// The pallet's events
decl_event!(
- pub enum Event<T> where AccountId = <T as system::Trait>::AccountId {
- Created(u32, AccountId),
- }
+ pub enum Event<T>
+ where
+ AccountId = <T as system::Trait>::AccountId,
+ {
+ Created(u32, AccountId),
+ }
);
// The pallet's dispatchable functions.
decl_module! {
- /// The module declaration.
- pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+ /// The module declaration.
+ pub struct Module<T: Trait> for enum Call where origin: T::Origin {
- // Initializing events
- // this is needed only if you are using events in your pallet
- fn deposit_event() = default;
+ // Initializing events
+ // this is needed only if you are using events in your pallet
+ fn deposit_event() = default;
- // Initializing events
- // this is needed only if you are using events in your module
- // fn deposit_event<T>() = default;
+ // Initializing events
+ // this is needed only if you are using events in your module
+ // fn deposit_event<T>() = default;
- // Create collection of NFT with given parameters
- //
- // @param customDataSz size of custom data in each collection item
- // returns collection ID
+ // Create collection of NFT with given parameters
+ //
+ // @param customDataSz size of custom data in each collection item
+ // returns collection ID
- // Create collection of NFT with given parameters
- //
- // @param customDataSz size of custom data in each collection item
- // returns collection ID
- #[weight = frame_support::weights::SimpleDispatchInfo::default()]
- pub fn create_collection(origin, custom_data_sz: u32) -> DispatchResult {
- // Anyone can create a collection
- let who = ensure_signed(origin)?;
+ // Create collection of NFT with given parameters
+ //
+ // @param customDataSz size of custom data in each collection item
+ // returns collection ID
+ #[weight = frame_support::weights::SimpleDispatchInfo::default()]
+ pub fn create_collection(origin, custom_data_sz: u32) -> DispatchResult {
+ // Anyone can create a collection
+ let who = ensure_signed(origin)?;
- // Generate next collection ID
- let next_id = NextCollectionID::get()
- .checked_add(1)
- .expect("collection id error");
+ // Generate next collection ID
+ let next_id = NextCollectionID::get()
+ .checked_add(1)
+ .expect("collection id error");
- NextCollectionID::put(next_id);
+ NextCollectionID::put(next_id);
- // Create new collection
- let new_collection = CollectionType {
- owner: who,
- next_item_id: next_id,
- custom_data_size: custom_data_sz,
- };
-
- // Add new collection to map
- <Collection<T>>::insert(next_id, new_collection);
+ // Create new collection
+ let new_collection = CollectionType {
+ owner: who,
+ next_item_id: next_id,
+ custom_data_size: custom_data_sz,
+ };
- Ok(())
- }
+ // Add new collection to map
+ <Collection<T>>::insert(next_id, new_collection);
- #[weight = frame_support::weights::SimpleDispatchInfo::default()]
- pub fn destroy_collection(origin, collection_id: u64) -> DispatchResult {
+ Ok(())
+ }
- let sender = ensure_signed(origin)?;
- ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
+ #[weight = frame_support::weights::SimpleDispatchInfo::default()]
+ pub fn destroy_collection(origin, collection_id: u64) -> DispatchResult {
- let owner = <Collection<T>>::get(collection_id).owner;
- ensure!(sender == owner, "You do not own this collection");
- <Collection<T>>::remove(collection_id);
+ let sender = ensure_signed(origin)?;
+ ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
- Ok(())
- }
+ let owner = <Collection<T>>::get(collection_id).owner;
+ ensure!(sender == owner, "You do not own this collection");
+ <Collection<T>>::remove(collection_id);
- #[weight = frame_support::weights::SimpleDispatchInfo::default()]
- pub fn change_collection_owner(origin, collection_id: u64, new_owner: T::AccountId) -> DispatchResult {
+ Ok(())
+ }
- let sender = ensure_signed(origin)?;
- ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
+ #[weight = frame_support::weights::SimpleDispatchInfo::default()]
+ pub fn change_collection_owner(origin, collection_id: u64, new_owner: T::AccountId) -> DispatchResult {
- let mut target_collection = <Collection<T>>::get(collection_id);
- ensure!(sender == target_collection.owner, "You do not own this collection");
+ let sender = ensure_signed(origin)?;
+ ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
- target_collection.owner = new_owner;
- <Collection<T>>::insert(collection_id, target_collection);
+ let mut target_collection = <Collection<T>>::get(collection_id);
+ ensure!(sender == target_collection.owner, "You do not own this collection");
- Ok(())
- }
+ target_collection.owner = new_owner;
+ <Collection<T>>::insert(collection_id, target_collection);
- #[weight = frame_support::weights::SimpleDispatchInfo::default()]
- pub fn add_collection_admin(origin, collection_id: u64, new_admin_id: T::AccountId) -> DispatchResult {
+ Ok(())
+ }
- let sender = ensure_signed(origin)?;
- ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
+ #[weight = frame_support::weights::SimpleDispatchInfo::default()]
+ pub fn add_collection_admin(origin, collection_id: u64, new_admin_id: T::AccountId) -> DispatchResult {
- let target_collection = <Collection<T>>::get(collection_id);
- let is_owner = sender == target_collection.owner;
+ let sender = ensure_signed(origin)?;
+ ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
- let no_perm_mes = "You do not have permissions to modify this collection";
- let exists = <AdminList<T>>::contains_key(collection_id);
+ let target_collection = <Collection<T>>::get(collection_id);
+ let is_owner = sender == target_collection.owner;
- if !is_owner
- {
- ensure!(exists, no_perm_mes);
- ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
- }
-
- let mut admin_arr: Vec<T::AccountId> = Vec::new();
- if exists
- {
- admin_arr = <AdminList<T>>::get(collection_id);
- ensure!(!admin_arr.contains(&new_admin_id), "Account already has admin role");
- }
+ let no_perm_mes = "You do not have permissions to modify this collection";
+ let exists = <AdminList<T>>::contains_key(collection_id);
- admin_arr.push(new_admin_id);
- <AdminList<T>>::insert(collection_id, admin_arr);
+ if !is_owner
+ {
+ ensure!(exists, no_perm_mes);
+ ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
+ }
- Ok(())
- }
+ let mut admin_arr: Vec<T::AccountId> = Vec::new();
+ if exists
+ {
+ admin_arr = <AdminList<T>>::get(collection_id);
+ ensure!(!admin_arr.contains(&new_admin_id), "Account already has admin role");
+ }
- #[weight = frame_support::weights::SimpleDispatchInfo::default()]
- pub fn remove_collection_admin(origin, collection_id: u64, account_id: T::AccountId) -> DispatchResult {
+ admin_arr.push(new_admin_id);
+ <AdminList<T>>::insert(collection_id, admin_arr);
- let sender = ensure_signed(origin)?;
- ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
+ Ok(())
+ }
- let target_collection = <Collection<T>>::get(collection_id);
- let is_owner = sender == target_collection.owner;
+ #[weight = frame_support::weights::SimpleDispatchInfo::default()]
+ pub fn remove_collection_admin(origin, collection_id: u64, account_id: T::AccountId) -> DispatchResult {
- let no_perm_mes = "You do not have permissions to modify this collection";
- let exists = <AdminList<T>>::contains_key(collection_id);
+ let sender = ensure_signed(origin)?;
+ ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
- if !is_owner
- {
- ensure!(exists, no_perm_mes);
- ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
- }
+ let target_collection = <Collection<T>>::get(collection_id);
+ let is_owner = sender == target_collection.owner;
- if exists
- {
- let mut admin_arr = <AdminList<T>>::get(collection_id);
- admin_arr.retain(|i| *i != account_id);
- <AdminList<T>>::insert(collection_id, admin_arr);
- }
+ let no_perm_mes = "You do not have permissions to modify this collection";
+ let exists = <AdminList<T>>::contains_key(collection_id);
- Ok(())
- }
+ if !is_owner
+ {
+ ensure!(exists, no_perm_mes);
+ ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
+ }
- #[weight = frame_support::weights::SimpleDispatchInfo::default()]
- pub fn create_item(origin, collection_id: u64, properties: Vec<u8>) -> DispatchResult {
+ if exists
+ {
+ let mut admin_arr = <AdminList<T>>::get(collection_id);
+ admin_arr.retain(|i| *i != account_id);
+ <AdminList<T>>::insert(collection_id, admin_arr);
+ }
- let sender = ensure_signed(origin)?;
- ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
+ Ok(())
+ }
- let target_collection = <Collection<T>>::get(collection_id);
- ensure!(target_collection.custom_data_size >= properties.len() as u32, "Size of item is too large");
- let is_owner = sender == target_collection.owner;
-
- let no_perm_mes = "You do not have permissions to modify this collection";
- let exists = <AdminList<T>>::contains_key(collection_id);
-
- if !is_owner
- {
- ensure!(exists, no_perm_mes);
- ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
- }
-
- let new_balance = <Balance<T>>::get((collection_id, sender.clone())) + 1;
- <Balance<T>>::insert((collection_id, sender.clone()), new_balance);
-
- // Create new item
- let new_item = NftItemType {
- collection: collection_id,
- owner: sender,
- data: properties,
- };
+ #[weight = frame_support::weights::SimpleDispatchInfo::default()]
+ pub fn create_item(origin, collection_id: u64, properties: Vec<u8>) -> DispatchResult {
- let current_index = <ItemListIndex>::get(collection_id) + 1;
- <ItemListIndex>::insert(collection_id, current_index);
- <ItemList<T>>::insert((collection_id, current_index), new_item);
+ let sender = ensure_signed(origin)?;
+ ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
- Ok(())
- }
+ let target_collection = <Collection<T>>::get(collection_id);
+ ensure!(target_collection.custom_data_size >= properties.len() as u32, "Size of item is too large");
+ let is_owner = sender == target_collection.owner;
- #[weight = frame_support::weights::SimpleDispatchInfo::default()]
- pub fn burn_item(origin, collection_id: u64, item_id: u64) -> DispatchResult {
+ let no_perm_mes = "You do not have permissions to modify this collection";
+ let exists = <AdminList<T>>::contains_key(collection_id);
- let sender = ensure_signed(origin)?;
- ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
+ if !is_owner
+ {
+ ensure!(exists, no_perm_mes);
+ ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
+ }
- let target_collection = <Collection<T>>::get(collection_id);
- let is_owner = sender == target_collection.owner;
+ let new_balance = <Balance<T>>::get((collection_id, sender.clone())) + 1;
+ <Balance<T>>::insert((collection_id, sender.clone()), new_balance);
- ensure!(<ItemList<T>>::contains_key((collection_id, item_id)), "Item does not exists");
- let item = <ItemList<T>>::get((collection_id, item_id));
+ // Create new item
+ let new_item = NftItemType {
+ collection: collection_id,
+ owner: sender,
+ data: properties,
+ };
- if !is_owner
- {
- // check if item owner
- if item.owner != sender
- {
- let no_perm_mes = "You do not have permissions to modify this collection";
+ let current_index = <ItemListIndex>::get(collection_id) + 1;
+ <ItemListIndex>::insert(collection_id, current_index);
+ <ItemList<T>>::insert((collection_id, current_index), new_item);
- ensure!(<AdminList<T>>::contains_key(collection_id), no_perm_mes);
- ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
- }
- }
- <ItemList<T>>::remove((collection_id, item_id));
+ Ok(())
+ }
- // update balance
- let new_balance = <Balance<T>>::get((collection_id, item.owner.clone())) - 1;
- <Balance<T>>::insert((collection_id, item.owner.clone()), new_balance);
+ #[weight = frame_support::weights::SimpleDispatchInfo::default()]
+ pub fn burn_item(origin, collection_id: u64, item_id: u64) -> DispatchResult {
- Ok(())
- }
+ let sender = ensure_signed(origin)?;
+ ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
- #[weight = frame_support::weights::SimpleDispatchInfo::default()]
- pub fn transfer(origin, collection_id: u64, item_id: u64, new_owner: T::AccountId) -> DispatchResult {
+ let target_collection = <Collection<T>>::get(collection_id);
+ let is_owner = sender == target_collection.owner;
- let sender = ensure_signed(origin)?;
- ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
+ ensure!(<ItemList<T>>::contains_key((collection_id, item_id)), "Item does not exists");
+ let item = <ItemList<T>>::get((collection_id, item_id));
- let target_collection = <Collection<T>>::get(collection_id);
- let is_owner = sender == target_collection.owner;
+ if !is_owner
+ {
+ // check if item owner
+ if item.owner != sender
+ {
+ let no_perm_mes = "You do not have permissions to modify this collection";
- ensure!(<ItemList<T>>::contains_key((collection_id, item_id)), "Item does not exists");
- let mut item = <ItemList<T>>::get((collection_id, item_id));
+ ensure!(<AdminList<T>>::contains_key(collection_id), no_perm_mes);
+ ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
+ }
+ }
+ <ItemList<T>>::remove((collection_id, item_id));
- if !is_owner
- {
- // check if item owner
- if item.owner != sender
- {
- let no_perm_mes = "You do not have permissions to modify this collection";
+ // update balance
+ let new_balance = <Balance<T>>::get((collection_id, item.owner.clone())) - 1;
+ <Balance<T>>::insert((collection_id, item.owner.clone()), new_balance);
- ensure!(<AdminList<T>>::contains_key(collection_id), no_perm_mes);
- ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
- }
- }
- <ItemList<T>>::remove((collection_id, item_id));
+ Ok(())
+ }
- // update balance
- let balance_old_owner = <Balance<T>>::get((collection_id, item.owner.clone())) - 1;
- <Balance<T>>::insert((collection_id, item.owner.clone()), balance_old_owner);
+ #[weight = frame_support::weights::SimpleDispatchInfo::default()]
+ pub fn transfer(origin, collection_id: u64, item_id: u64, new_owner: T::AccountId) -> DispatchResult {
- let balance_new_owner = <Balance<T>>::get((collection_id, new_owner.clone())) + 1;
- <Balance<T>>::insert((collection_id, new_owner.clone()), balance_new_owner);
+ let sender = ensure_signed(origin)?;
+ ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
- // change owner
- item.owner = new_owner;
- <ItemList<T>>::insert((collection_id, item_id), item);
+ let target_collection = <Collection<T>>::get(collection_id);
+ let is_owner = sender == target_collection.owner;
- // reset approved list
- let itm: Vec<T::AccountId> = Vec::new();
- <ApprovedList<T>>::insert((collection_id, item_id), itm);
+ ensure!(<ItemList<T>>::contains_key((collection_id, item_id)), "Item does not exists");
+ let mut item = <ItemList<T>>::get((collection_id, item_id));
- Ok(())
- }
+ if !is_owner
+ {
+ // check if item owner
+ if item.owner != sender
+ {
+ let no_perm_mes = "You do not have permissions to modify this collection";
- #[weight = frame_support::weights::SimpleDispatchInfo::default()]
- pub fn approve(origin, approved: T::AccountId, collection_id: u64, item_id: u64) -> DispatchResult {
+ ensure!(<AdminList<T>>::contains_key(collection_id), no_perm_mes);
+ ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
+ }
+ }
+ <ItemList<T>>::remove((collection_id, item_id));
- let sender = ensure_signed(origin)?;
- ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
+ // update balance
+ let balance_old_owner = <Balance<T>>::get((collection_id, item.owner.clone())) - 1;
+ <Balance<T>>::insert((collection_id, item.owner.clone()), balance_old_owner);
- let target_collection = <Collection<T>>::get(collection_id);
- let is_owner = sender == target_collection.owner;
+ let balance_new_owner = <Balance<T>>::get((collection_id, new_owner.clone())) + 1;
+ <Balance<T>>::insert((collection_id, new_owner.clone()), balance_new_owner);
- ensure!(<ItemList<T>>::contains_key((collection_id, item_id)), "Item does not exists");
- let item = <ItemList<T>>::get((collection_id, item_id));
+ // change owner
+ item.owner = new_owner;
+ <ItemList<T>>::insert((collection_id, item_id), item);
- if !is_owner
- {
- // check if item owner
- if item.owner != sender
- {
- let no_perm_mes = "You do not have permissions to modify this collection";
+ // reset approved list
+ let itm: Vec<T::AccountId> = Vec::new();
+ <ApprovedList<T>>::insert((collection_id, item_id), itm);
- ensure!(<AdminList<T>>::contains_key(collection_id), no_perm_mes);
- ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
- }
- }
+ Ok(())
+ }
- let list_exists = <ApprovedList<T>>::contains_key((collection_id, item_id));
- if list_exists {
-
- let mut list = <ApprovedList<T>>::get((collection_id, item_id));
- let item_contains = list.contains(&approved.clone());
+ #[weight = frame_support::weights::SimpleDispatchInfo::default()]
+ pub fn approve(origin, approved: T::AccountId, collection_id: u64, item_id: u64) -> DispatchResult {
- if !item_contains {
- list.push(approved.clone());
- }
- } else {
-
- let mut itm = Vec::new();
- itm.push(approved.clone());
- <ApprovedList<T>>::insert((collection_id, item_id), itm);
- }
+ let sender = ensure_signed(origin)?;
+ ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
- Ok(())
- }
+ let target_collection = <Collection<T>>::get(collection_id);
+ let is_owner = sender == target_collection.owner;
- #[weight = frame_support::weights::SimpleDispatchInfo::default()]
- pub fn transfer_from(origin, collection_id: u64, item_id: u64, new_owner: T::AccountId) -> DispatchResult {
+ ensure!(<ItemList<T>>::contains_key((collection_id, item_id)), "Item does not exists");
+ let item = <ItemList<T>>::get((collection_id, item_id));
- // let sender = ensure_signed(origin)?;
- // ensure!(<Collection<T>>::contains_key(collection_id), "This collection does not exist");
+ if !is_owner
+ {
+ // check if item owner
+ if item.owner != sender
+ {
+ let no_perm_mes = "You do not have permissions to modify this collection";
- // let target_collection = <Collection<T>>::get(collection_id);
- // let is_owner = sender == target_collection.owner;
+ ensure!(<AdminList<T>>::contains_key(collection_id), no_perm_mes);
+ ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
+ }
+ }
- // ensure!(<ItemList<T>>::contains_key((collection_id, item_id)), "Item does not exists");
- // let mut item = <ItemList<T>>::get((collection_id, item_id));
+ let list_exists = <ApprovedList<T>>::contains_key((collection_id, item_id));
+ if list_exists {
- // if !is_owner
- // {
- // let no_perm_mes = "You do not have permissions to modify this collection";
+ let mut list = <ApprovedList<T>>::get((collection_id, item_id));
+ let item_contains = list.contains(&approved.clone());
- // // check if item owner
- // if item.owner != sender
- // {
- // ensure!(<AdminList<T>>::contains_key(collection_id), no_perm_mes);
- // ensure!(<AdminList<T>>::get(collection_id).contains(&sender), no_perm_mes);
- // }
+ if !item_contains {
+ list.push(approved.clone());
+ }
+ } else {
- // ensure!(<ApprovedList<T>>::contains_key((collection_id, item_id)), no_perm_mes);
- // let list_itm = <ApprovedList<T>>::get((collection_id, item_id));
- // ensure!(list_itm.contains(&new_owner.clone()), no_perm_mes);
+ let mut itm = Vec::new();
+ itm.push(approved.clone());
+ <ApprovedList<T>>::insert((collection_id, item_id), itm);
+ }
- // }
+ Ok(())
+ }
+ #[weight = frame_support::weights::SimpleDispatchInfo::default()]
+ pub fn transfer_from(origin, collection_id: u64, item_id: u64, new_owner: T::AccountId) -> DispatchResult {
- let no_perm_mes = "You do not have permissions to modify this collection";
- ensure!(<ApprovedList<T>>::contains_key((collection_id, item_id)), no_perm_mes);
- let list_itm = <ApprovedList<T>>::get((collection_id, item_id));
- ensure!(list_itm.contains(&new_owner.clone()), no_perm_mes);
+ let no_perm_mes = "You do not have permissions to modify this collection";
+ ensure!(<ApprovedList<T>>::contains_key((collection_id, item_id)), no_perm_mes);
+ let list_itm = <ApprovedList<T>>::get((collection_id, item_id));
+ ensure!(list_itm.contains(&new_owner.clone()), no_perm_mes);
- Self::transfer(origin, collection_id, item_id, new_owner);
+ Self::transfer(origin, collection_id, item_id, new_owner)?;
- Ok(())
- }
- }
-}
\ No newline at end of file
+ Ok(())
+ }
+ }
+}
pallets/nft/src/mock.rsdiffbeforeafterboth--- a/pallets/nft/src/mock.rs
+++ b/pallets/nft/src/mock.rs
@@ -1,15 +1,17 @@
// Creating mock runtime here
use crate::{Module, Trait};
+use frame_support::{impl_outer_origin, parameter_types, weights::Weight};
+use frame_system as system;
use sp_core::H256;
-use frame_support::{impl_outer_origin, parameter_types, weights::Weight};
use sp_runtime::{
- traits::{BlakeTwo256, IdentityLookup}, testing::Header, Perbill,
+ testing::Header,
+ traits::{BlakeTwo256, IdentityLookup},
+ Perbill,
};
-use frame_system as system;
impl_outer_origin! {
- pub enum Origin for Test {}
+ pub enum Origin for Test {}
}
// For testing the pallet, we construct most of a mock runtime. This means
@@ -18,39 +20,42 @@
#[derive(Clone, Eq, PartialEq)]
pub struct Test;
parameter_types! {
- pub const BlockHashCount: u64 = 250;
- pub const MaximumBlockWeight: Weight = 1024;
- pub const MaximumBlockLength: u32 = 2 * 1024;
- pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
+ pub const BlockHashCount: u64 = 250;
+ pub const MaximumBlockWeight: Weight = 1024;
+ pub const MaximumBlockLength: u32 = 2 * 1024;
+ pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
}
impl system::Trait for Test {
- type Origin = Origin;
- type Call = ();
- type Index = u64;
- type BlockNumber = u64;
- type Hash = H256;
- type Hashing = BlakeTwo256;
- type AccountId = u64;
- type Lookup = IdentityLookup<Self::AccountId>;
- type Header = Header;
- type Event = ();
- type BlockHashCount = BlockHashCount;
- type MaximumBlockWeight = MaximumBlockWeight;
- type MaximumBlockLength = MaximumBlockLength;
- type AvailableBlockRatio = AvailableBlockRatio;
- type Version = ();
- type ModuleToIndex = ();
- type AccountData = ();
- type OnNewAccount = ();
- type OnKilledAccount = ();
+ type Origin = Origin;
+ type Call = ();
+ type Index = u64;
+ type BlockNumber = u64;
+ type Hash = H256;
+ type Hashing = BlakeTwo256;
+ type AccountId = u64;
+ type Lookup = IdentityLookup<Self::AccountId>;
+ type Header = Header;
+ type Event = ();
+ type BlockHashCount = BlockHashCount;
+ type MaximumBlockWeight = MaximumBlockWeight;
+ type MaximumBlockLength = MaximumBlockLength;
+ type AvailableBlockRatio = AvailableBlockRatio;
+ type Version = ();
+ type ModuleToIndex = ();
+ type AccountData = ();
+ type OnNewAccount = ();
+ type OnKilledAccount = ();
}
impl Trait for Test {
- type Event = ();
+ type Event = ();
}
pub type TemplateModule = Module<Test>;
// This function basically just builds a genesis storage key/value store according to
// our desired mockup.
pub fn new_test_ext() -> sp_io::TestExternalities {
- system::GenesisConfig::default().build_storage::<Test>().unwrap().into()
+ system::GenesisConfig::default()
+ .build_storage::<Test>()
+ .unwrap()
+ .into()
}
pallets/nft/src/tests.rsdiffbeforeafterboth1// Tests to be written here2use crate::{ mock::*};3use frame_support::{assert_ok, assert_noop};45#[test]6fn create_collection_test() {7 new_test_ext().execute_with(|| {8 let size = 1024;9 let origin1 = Origin::signed(1);10 assert_ok!(TemplateModule::create_collection(origin1.clone(), size));11 assert_eq!(TemplateModule::collection(1).owner, 1);12 });13}1415#[test]16fn change_collection_owner() {17 new_test_ext().execute_with(|| {18 let size = 1024;19 let origin1 = Origin::signed(1);2021 assert_ok!(TemplateModule::create_collection(origin1.clone(), size));22 assert_ok!(TemplateModule::change_collection_owner(origin1.clone(), 1, 2));23 assert_eq!(TemplateModule::collection(1).owner, 2);24 });25}2627#[test]28fn destroy_collection() {29 new_test_ext().execute_with(|| {30 let size = 1024;31 let origin1 = Origin::signed(1);3233 assert_ok!(TemplateModule::create_collection(origin1.clone(), size));34 assert_ok!(TemplateModule::destroy_collection(origin1.clone(), 1));35 });36}3738#[test]39fn create_item() {40 new_test_ext().execute_with(|| {41 let size = 1024;42 let origin1 = Origin::signed(1);43 let origin2 = Origin::signed(2);4445 assert_ok!(TemplateModule::create_collection(origin1.clone(), size));46 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));47 assert_ok!(TemplateModule::create_item(origin2.clone(), 1, [1,1,1].to_vec()));4849 // check balance (collection with id = 1, user id = 2)50 assert_eq!(TemplateModule::balance_count((1, 2)), 1);51 });52}5354#[test]55fn burn_item() {56 new_test_ext().execute_with(|| {57 let size = 1024;58 let origin1 = Origin::signed(1);59 let origin2 = Origin::signed(2);6061 assert_ok!(TemplateModule::create_collection(origin1.clone(), size));62 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));63 assert_ok!(TemplateModule::create_item(origin2.clone(), 1, [1,1,1].to_vec()));6465 // check balance (collection with id = 1, user id = 2)66 assert_eq!(TemplateModule::balance_count((1, 2)), 1);6768 // burn item69 assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1));70 assert_noop!(TemplateModule::burn_item(origin1.clone(), 1, 1), "Item does not exists");7172 assert_eq!(TemplateModule::balance_count((1, 1)), 0);73 });74}757677#[test]78fn add_collection_admin() {79 new_test_ext().execute_with(|| {80 let size = 1024;81 let origin1 = Origin::signed(1);82 let origin2 = Origin::signed(2);83 let origin3 = Origin::signed(3);8485 assert_ok!(TemplateModule::create_collection(origin1.clone(), size));86 assert_ok!(TemplateModule::create_collection(origin2.clone(), size));87 assert_ok!(TemplateModule::create_collection(origin3.clone(), size));8889 assert_eq!(TemplateModule::collection(1).owner, 1);90 assert_eq!(TemplateModule::collection(2).owner, 2);91 assert_eq!(TemplateModule::collection(3).owner, 3);9293 // collection admin94 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));95 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 3));9697 assert_eq!(TemplateModule::admin_list_collection(1).contains(&2), true);98 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), true);99 });100}101102#[test]103fn remove_collection_admin() {104 new_test_ext().execute_with(|| {105 let size = 1024;106 let origin1 = Origin::signed(1);107 let origin2 = Origin::signed(2);108 let origin3 = Origin::signed(3);109110 assert_ok!(TemplateModule::create_collection(origin1.clone(), size));111 assert_ok!(TemplateModule::create_collection(origin2.clone(), size));112 assert_ok!(TemplateModule::create_collection(origin3.clone(), size));113114 assert_eq!(TemplateModule::collection(1).owner, 1);115 assert_eq!(TemplateModule::collection(2).owner, 2);116 assert_eq!(TemplateModule::collection(3).owner, 3);117118 // collection admin119 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));120 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 3));121122 assert_eq!(TemplateModule::admin_list_collection(1).contains(&2), true);123 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), true);124125 // remove admin126 assert_ok!(TemplateModule::remove_collection_admin(origin2.clone(), 1, 3));127 assert_eq!(TemplateModule::admin_list_collection(1).contains(&3), false);128 });129}130131#[test]132fn balance_of() {133 new_test_ext().execute_with(|| {134 let size = 1024;135 let origin1 = Origin::signed(1);136 let origin2 = Origin::signed(2);137 let origin3 = Origin::signed(3);138139 assert_ok!(TemplateModule::create_collection(origin1.clone(), size));140 assert_ok!(TemplateModule::create_collection(origin2.clone(), size));141 assert_ok!(TemplateModule::create_collection(origin3.clone(), size));142143 assert_eq!(TemplateModule::collection(1).owner, 1);144 assert_eq!(TemplateModule::collection(2).owner, 2);145 assert_eq!(TemplateModule::collection(3).owner, 3);146147 // check balance before148 assert_eq!(TemplateModule::balance_count((1, 1)), 0);149150 // create item151 assert_ok!(TemplateModule::create_item(origin1.clone(), 1, [1,1,1].to_vec()));152 153 // check balance (collection with id = 1, user id = 2)154 assert_eq!(TemplateModule::balance_count((1, 1)), 1);155 assert_eq!(TemplateModule::item_id((1,1)).owner, 1);156 });157}158159#[test]160fn transfer() {161 new_test_ext().execute_with(|| {162 let size = 1024;163 let origin1 = Origin::signed(1);164 let origin2 = Origin::signed(2);165 let origin3 = Origin::signed(3);166167 assert_ok!(TemplateModule::create_collection(origin1.clone(), size));168 assert_ok!(TemplateModule::create_collection(origin2.clone(), size));169 assert_ok!(TemplateModule::create_collection(origin3.clone(), size));170171 assert_eq!(TemplateModule::collection(1).owner, 1);172 assert_eq!(TemplateModule::collection(2).owner, 2);173 assert_eq!(TemplateModule::collection(3).owner, 3);174175 // create item176 assert_ok!(TemplateModule::create_item(origin1.clone(), 1, [1,1,1].to_vec()));177178 // transfer179 assert_ok!(TemplateModule::transfer(origin1.clone(), 1, 1, 2));180 assert_eq!(TemplateModule::item_id((1,1)).owner, 2);181182 // balance_of check183 assert_eq!(TemplateModule::balance_count((1, 1)), 0);184 assert_eq!(TemplateModule::balance_count((1, 2)), 1);185 });186}187188#[test]189fn approve() {190 new_test_ext().execute_with(|| {191 let size = 1024;192 let origin1 = Origin::signed(1);193 let origin2 = Origin::signed(2);194 let origin3 = Origin::signed(3);195196 assert_ok!(TemplateModule::create_collection(origin1.clone(), size));197 assert_ok!(TemplateModule::create_collection(origin2.clone(), size));198 assert_ok!(TemplateModule::create_collection(origin3.clone(), size));199200 assert_eq!(TemplateModule::collection(1).owner, 1);201 assert_eq!(TemplateModule::collection(2).owner, 2);202 assert_eq!(TemplateModule::collection(3).owner, 3);203204 // create item205 assert_ok!(TemplateModule::create_item(origin1.clone(), 1, [1,1,1].to_vec()));206207 // approve208 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));209 assert_eq!(TemplateModule::approved((1,1)).contains(&2), true);210211 });212}213214#[test]215fn get_approved() {216 new_test_ext().execute_with(|| {217 let size = 1024;218 let origin1 = Origin::signed(1);219 let origin2 = Origin::signed(2);220 let origin3 = Origin::signed(3);221222 assert_ok!(TemplateModule::create_collection(origin1.clone(), size));223 assert_ok!(TemplateModule::create_collection(origin2.clone(), size));224 assert_ok!(TemplateModule::create_collection(origin3.clone(), size));225226 assert_eq!(TemplateModule::collection(1).owner, 1);227 assert_eq!(TemplateModule::collection(2).owner, 2);228 assert_eq!(TemplateModule::collection(3).owner, 3);229230 // create item231 assert_ok!(TemplateModule::create_item(origin1.clone(), 1, [1,1,1].to_vec()));232233 // approve234 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));235 assert_eq!(TemplateModule::approved((1,1)).contains(&2), true);236237 });238}239240#[test]241fn transfer_from() {242 new_test_ext().execute_with(|| {243 let size = 1024;244 let origin1 = Origin::signed(1);245 let origin2 = Origin::signed(2);246 let origin3 = Origin::signed(3);247248 assert_ok!(TemplateModule::create_collection(origin1.clone(), size));249 assert_ok!(TemplateModule::create_collection(origin2.clone(), size));250 assert_ok!(TemplateModule::create_collection(origin3.clone(), size));251252 assert_eq!(TemplateModule::collection(1).owner, 1);253 assert_eq!(TemplateModule::collection(2).owner, 2);254 assert_eq!(TemplateModule::collection(3).owner, 3);255256 // create item257 assert_ok!(TemplateModule::create_item(origin1.clone(), 1, [1,1,1].to_vec()));258259 // approve260 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));261 assert_ok!(TemplateModule::transfer_from(origin1.clone(), 1, 1, 2));262263 });264}