difftreelog
Merge pull request #5 from usetech-llc/hotfix/collection_count_update
in: master
Hotfix/collection count update
4 files changed
README.mddiffbeforeafterboth208 "Description": "Vec<u16>",208 "Description": "Vec<u16>",209 "TokenPrefix": "Vec<u8>",209 "TokenPrefix": "Vec<u8>",210 "CustomDataSize": "u32",210 "CustomDataSize": "u32",211 "MintMode": "bool",211 "OffchainSchema": "Vec<u8>",212 "OffchainSchema": "Vec<u8>",212 "Sponsor": "AccountId",213 "Sponsor": "AccountId",213 "UnconfirmedSponsor": "AccountId"214 "UnconfirmedSponsor": "AccountId"pallets/nft/src/lib.rsdiffbeforeafterboth97 pub description: Vec<u16>, // 256 include null escape char97 pub description: Vec<u16>, // 256 include null escape char98 pub token_prefix: Vec<u8>, // 16 include null escape char98 pub token_prefix: Vec<u8>, // 16 include null escape char99 pub custom_data_size: u32,99 pub custom_data_size: u32,100 pub mint_mode: bool,100 pub offchain_schema: Vec<u8>,101 pub offchain_schema: Vec<u8>,101 pub sponsor: AccountId, // Who pays fees. If set to default address, the fees are applied to the transaction sender102 pub sponsor: AccountId, // Who pays fees. If set to default address, the fees are applied to the transaction sender102 pub unconfirmed_sponsor: AccountId, // Sponsor address that has not yet confirmed sponsorship103 pub unconfirmed_sponsor: AccountId, // Sponsor address that has not yet confirmed sponsorship179 pub FungibleItemList get(fn fungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => FungibleItemType<T::AccountId>;180 pub FungibleItemList get(fn fungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => FungibleItemType<T::AccountId>;180 pub ReFungibleItemList get(fn refungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => ReFungibleItemType<T::AccountId>;181 pub ReFungibleItemList get(fn refungible_item_id): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => ReFungibleItemType<T::AccountId>;181182 // Active vesting list183 // pub VestingList get(fn vesting): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => VestingItem<T::AccountId, T::Moment>;184182185 /// Index list183 /// Index list186 pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => Vec<u64>;184 pub AddressTokens get(fn address_tokens): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) T::AccountId => Vec<u64>;209207210 fn on_initialize(now: T::BlockNumber) -> Weight {208 fn on_initialize(now: T::BlockNumber) -> Weight {211209212 if ChainVersion::get() == 0210 if ChainVersion::get() < 2213 {211 {214 let value = NextCollectionID::get();212 let value = NextCollectionID::get();215 CreatedCollectionCount::put(value);213 CreatedCollectionCount::put(value);271 owner: who.clone(),269 owner: who.clone(),272 name: name,270 name: name,273 mode: mode.clone(),271 mode: mode.clone(),272 mint_mode: false,274 access: AccessMode::Normal,273 access: AccessMode::Normal,275 description: description,274 description: description,276 decimal_points: decimal_points,275 decimal_points: decimal_points,309 }308 }310309311 #[weight = 0]310 #[weight = 0]311 pub fn add_to_white_list(origin, collection_id: u64, address: T::AccountId) -> DispatchResult{312313 let sender = ensure_signed(origin)?;314 Self::check_owner_or_admin_permissions(collection_id, sender)?;315316 let mut white_list_collection: Vec<T::AccountId>;317 if <WhiteList<T>>::contains_key(collection_id) {318 white_list_collection = <WhiteList<T>>::get(collection_id);319 if !white_list_collection.contains(&address.clone())320 {321 white_list_collection.push(address.clone());322 }323 }324 else {325 white_list_collection = Vec::new();326 white_list_collection.push(address.clone());327 }328329 <WhiteList<T>>::insert(collection_id, white_list_collection);330 Ok(())331 }332333 #[weight = 0]334 pub fn remove_from_white_list(origin, collection_id: u64, address: T::AccountId) -> DispatchResult{335336 let sender = ensure_signed(origin)?;337 Self::check_owner_or_admin_permissions(collection_id, sender)?;338339 if <WhiteList<T>>::contains_key(collection_id) {340 let mut white_list_collection = <WhiteList<T>>::get(collection_id);341 if white_list_collection.contains(&address.clone())342 {343 white_list_collection.retain(|i| *i != address.clone());344 <WhiteList<T>>::insert(collection_id, white_list_collection);345 }346 }347348 Ok(())349 }350351 #[weight = 0]352 pub fn set_public_access_mode(origin, collection_id: u64, mode: AccessMode) -> DispatchResult353 {354 let sender = ensure_signed(origin)?;355356 Self::check_owner_permissions(collection_id, sender)?;357 let mut target_collection = <Collection<T>>::get(collection_id);358 target_collection.access = mode;359 <Collection<T>>::insert(collection_id, target_collection);360361 Ok(())362 }363364 #[weight = 0]365 pub fn set_mint_permission(origin, collection_id: u64, mint_permission: bool) -> DispatchResult366 {367 let sender = ensure_signed(origin)?;368369 Self::check_owner_permissions(collection_id, sender)?;370 let mut target_collection = <Collection<T>>::get(collection_id);371 target_collection.mint_mode = mint_permission;372 <Collection<T>>::insert(collection_id, target_collection);373374 Ok(())375 }376377 #[weight = 0]312 pub fn change_collection_owner(origin, collection_id: u64, new_owner: T::AccountId) -> DispatchResult {378 pub fn change_collection_owner(origin, collection_id: u64, new_owner: T::AccountId) -> DispatchResult {313379314 let sender = ensure_signed(origin)?;380 let sender = ensure_signed(origin)?;405 pub fn create_item(origin, collection_id: u64, properties: Vec<u8>, owner: T::AccountId) -> DispatchResult {471 pub fn create_item(origin, collection_id: u64, properties: Vec<u8>, owner: T::AccountId) -> DispatchResult {406472407 let sender = ensure_signed(origin)?;473 let sender = ensure_signed(origin)?;474 Self::collection_exists(collection_id)?;408 let target_collection = <Collection<T>>::get(collection_id);475 let target_collection = <Collection<T>>::get(collection_id);476409 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;477 if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) {478 if target_collection.mint_mode == false {479 panic!("Collection is not in mint mode");480 }481482 Self::check_white_list(collection_id, owner.clone())?;483 }410484411 match target_collection.mode485 match target_collection.mode412 {486 {469 pub fn burn_item(origin, collection_id: u64, item_id: u64) -> DispatchResult {543 pub fn burn_item(origin, collection_id: u64, item_id: u64) -> DispatchResult {470544471 let sender = ensure_signed(origin)?;545 let sender = ensure_signed(origin)?;546 Self::collection_exists(collection_id)?;472 let item_owner = Self::is_item_owner(sender.clone(), collection_id, item_id);547 let item_owner = Self::is_item_owner(sender.clone(), collection_id, item_id);473 if !item_owner548 if !item_owner474 {549 {475 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;550 if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) { 551 Self::check_white_list(collection_id, sender.clone())?;552 }476 }553 }477 let target_collection = <Collection<T>>::get(collection_id);554 let target_collection = <Collection<T>>::get(collection_id);478555495572496 let sender = ensure_signed(origin)?;573 let sender = ensure_signed(origin)?;574497 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id), "Only item owner can call transfer method");575 let item_owner = Self::is_item_owner(sender.clone(), collection_id, item_id);576 if !item_owner {577 Self::check_white_list(collection_id, sender.clone())?;578 Self::check_white_list(collection_id, recipient.clone())?;579 }498580499 let target_collection = <Collection<T>>::get(collection_id);581 let target_collection = <Collection<T>>::get(collection_id);500582501 // TODO: implement other modes502 match target_collection.mode583 match target_collection.mode503 {584 {504 CollectionMode::NFT(_) => Self::transfer_nft(collection_id, item_id, sender.clone(), recipient)?,585 CollectionMode::NFT(_) => Self::transfer_nft(collection_id, item_id, sender.clone(), recipient)?,518 // amount param stub599 // amount param stub519 let amount = 100000000;600 let amount = 100000000;520601521 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id), "Only item owner can call transfer method");602 let item_owner = Self::is_item_owner(sender.clone(), collection_id, item_id);603 if !item_owner {604 Self::check_white_list(collection_id, approved.clone())?;605 }522606523 let list_exists = <ApprovedList<T>>::contains_key(collection_id, (item_id, sender.clone()));607 let list_exists = <ApprovedList<T>>::contains_key(collection_id, (item_id, sender.clone()));524 if list_exists {608 if list_exists {547 let approved_list_exists = <ApprovedList<T>>::contains_key(collection_id, (item_id, from.clone()));631 let approved_list_exists = <ApprovedList<T>>::contains_key(collection_id, (item_id, from.clone()));548 if approved_list_exists632 if approved_list_exists549 {633 {634 Self::check_white_list(collection_id, from.clone())?;635 Self::check_white_list(collection_id, recipient.clone())?;636550 let list_itm = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()));637 let list_itm = <ApprovedList<T>>::get(collection_id, (item_id, from.clone()));551 let opt_item = list_itm.iter().find(|i| i.approved == sender.clone());638 let opt_item = list_itm.iter().find(|i| i.approved == sender.clone());559 }646 }560 else647 else561 {648 {562 Self::check_owner_or_admin_permissions(collection_id, sender)?;649 panic!("Only approved addresses can call this method");563 }650 }564651565 let target_collection = <Collection<T>>::get(collection_id);652 let target_collection = <Collection<T>>::get(collection_id);770 Ok(())853 Ok(())771 }854 }772855773 fn check_owner_or_admin_permissions(856 fn is_owner_or_admin_permissions(collection_id: u64, subject: T::AccountId) -> bool {774 collection_id: u64,775 subject: T::AccountId,776 ) -> DispatchResult {777 Self::collection_exists(collection_id)?;778857779 let target_collection = <Collection<T>>::get(collection_id);858 let target_collection = <Collection<T>>::get(collection_id);780 let is_owner = subject == target_collection.owner;859 let mut result: bool = subject == target_collection.owner;781782 let no_perm_mes = "You do not have permissions to modify this collection";783 let exists = <AdminList<T>>::contains_key(collection_id);860 let exists = <AdminList<T>>::contains_key(collection_id);784861785 if !is_owner {862 if !result & exists {786 ensure!(exists, no_perm_mes);787 ensure!(788 <AdminList<T>>::get(collection_id).contains(&subject),863 if <AdminList<T>>::get(collection_id).contains(&subject) {789 no_perm_mes864 result = true790 );865 }791 }866 }792 Ok(())867868 result793 }869 }870871 fn check_owner_or_admin_permissions(collection_id: u64, subject: T::AccountId) -> DispatchResult {872 873 Self::collection_exists(collection_id)?;874 let result = Self::is_owner_or_admin_permissions(collection_id, subject.clone());875876 if result == true {877 Ok(())878 } else {879 panic!("You do not have permissions to modify this collection")880 }881 }794882795 fn is_item_owner(subject: T::AccountId, collection_id: u64, item_id: u64) -> bool {883 fn is_item_owner(subject: T::AccountId, collection_id: u64, item_id: u64) -> bool {796 let target_collection = <Collection<T>>::get(collection_id);884 let target_collection = <Collection<T>>::get(collection_id);812 }900 }813 }901 }902903 fn check_white_list(collection_id: u64, address: T::AccountId) -> DispatchResult {904905 let mes = "Address is not in white list";906 if <WhiteList<T>>::contains_key(collection_id){907 let wl = <WhiteList<T>>::get(collection_id);908 if !wl.contains(&address.clone()) {909 panic!(mes);910 }911 }912 else {913 panic!(mes);914 }915 Ok(())916 }814917815 fn transfer_fungible(918 fn transfer_fungible(816 collection_id: u64,919 collection_id: u64,820 new_owner: T::AccountId,923 new_owner: T::AccountId,821 ) -> DispatchResult {924 ) -> DispatchResult {925926 ensure!(927 <FungibleItemList<T>>::contains_key(collection_id, item_id),928 "Item not exists"929 );930822 let full_item = <FungibleItemList<T>>::get(collection_id, item_id);931 let full_item = <FungibleItemList<T>>::get(collection_id, item_id);823 let amount = full_item.value;932 let amount = full_item.value;904 new_owner: T::AccountId,1013 new_owner: T::AccountId,905 ) -> DispatchResult {1014 ) -> DispatchResult {10151016 ensure!(1017 <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1018 "Item not exists"1019 );1020906 let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id);1021 let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id);907 let item = full_item1022 let item = full_item984 new_owner: T::AccountId,1099 new_owner: T::AccountId,985 ) -> DispatchResult {1100 ) -> DispatchResult {1101 1102 ensure!(1103 <NftItemList<T>>::contains_key(collection_id, item_id),1104 "Item not exists"1105 );1106986 let mut item = <NftItemList<T>>::get(collection_id, item_id);1107 let mut item = <NftItemList<T>>::get(collection_id, item_id);9871108pallets/nft/src/tests.rsdiffbeforeafterboth1// Tests to be written here1// Tests to be written here2use crate::mock::*;2use crate::mock::*;3use crate::{ApprovePermissions, CollectionMode, Ownership};3use crate::{ApprovePermissions, CollectionMode, AccessMode, Ownership};4use frame_support::{assert_noop, assert_ok};4use frame_support::{assert_noop, assert_ok};556#[test]6#[test]321 assert_eq!(TemplateModule::balance_count(1, 1), 1);321 assert_eq!(TemplateModule::balance_count(1, 1), 1);322 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);322 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);323323324 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));325 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));324 assert_noop!(326 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));325 TemplateModule::transfer_from(origin2.clone(), 1, 3, 1, 1, 1),327 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));326 "You do not have permissions to modify this collection"328 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));327 );328329329 // do approve330 // do approve390 assert_eq!(TemplateModule::balance_count(1, 1), 1000);391 assert_eq!(TemplateModule::balance_count(1, 1), 1000);391 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);392 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);392393394 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));395 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));393 assert_noop!(396 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));394 TemplateModule::transfer_from(origin2.clone(), 1, 3, 1, 1, 1),397 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));395 "You do not have permissions to modify this collection"398 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));396 );397399398 // do approve400 // do approve461 assert_eq!(TemplateModule::balance_count(1, 1), 1000);463 assert_eq!(TemplateModule::balance_count(1, 1), 1000);462 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);464 assert_eq!(TemplateModule::address_tokens(1, 1), [1]);463465466 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));467 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));464 assert_noop!(468 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));465 TemplateModule::transfer_from(origin2.clone(), 1, 3, 1, 1, 1),469 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));466 "You do not have permissions to modify this collection"470 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));467 );468471469 // do approve472 // do approve573 let mode: CollectionMode = CollectionMode::NFT(2000);576 let mode: CollectionMode = CollectionMode::NFT(2000);574577575 let origin1 = Origin::signed(1);578 let origin1 = Origin::signed(1);576 let origin2 = Origin::signed(2);577 assert_ok!(TemplateModule::create_collection(579 assert_ok!(TemplateModule::create_collection(578 origin1.clone(),580 origin1.clone(),579 col_name1.clone(),581 col_name1.clone(),583 ));585 ));584 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));586 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));585 assert_ok!(TemplateModule::create_item(587 assert_ok!(TemplateModule::create_item(586 origin2.clone(),588 origin1.clone(),587 1,589 1,588 [1, 2, 3].to_vec(),590 [1, 2, 3].to_vec(),589 1591 1614 let mode: CollectionMode = CollectionMode::Fungible(3);616 let mode: CollectionMode = CollectionMode::Fungible(3);615617616 let origin1 = Origin::signed(1);618 let origin1 = Origin::signed(1);617 let origin2 = Origin::signed(2);618 assert_ok!(TemplateModule::create_collection(619 assert_ok!(TemplateModule::create_collection(619 origin1.clone(),620 origin1.clone(),620 col_name1.clone(),621 col_name1.clone(),624 ));625 ));625 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));626 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));626 assert_ok!(TemplateModule::create_item(627 assert_ok!(TemplateModule::create_item(627 origin2.clone(),628 origin1.clone(),628 1,629 1,629 [].to_vec(),630 [].to_vec(),630 1631 1662 mode663 mode663 ));664 ));665 666 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));667 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));668 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));669664 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));670 assert_ok!(TemplateModule::add_collection_admin(origin1.clone(), 1, 2));665 assert_ok!(TemplateModule::create_item(671 assert_ok!(TemplateModule::create_item(929 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));935 assert_ok!(TemplateModule::approve(origin1.clone(), 2, 1, 1));930 assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);936 assert_eq!(TemplateModule::approved(1, (1, 1))[0].approved, 2);937938 assert_ok!(TemplateModule::set_mint_permission(origin1.clone(), 1, true));939 assert_ok!(TemplateModule::set_public_access_mode(origin1.clone(), 1, AccessMode::WhiteList));940 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 1));941 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 2));942 assert_ok!(TemplateModule::add_to_white_list(origin1.clone(), 1, 3));943931 assert_ok!(TemplateModule::transfer_from(944 assert_ok!(TemplateModule::transfer_from(932 origin2.clone(),945 origin2.clone(),runtime/src/lib.rsdiffbeforeafterboth111 spec_name: create_runtime_str!("nft"),111 spec_name: create_runtime_str!("nft"),112 impl_name: create_runtime_str!("nft"),112 impl_name: create_runtime_str!("nft"),113 authoring_version: 1,113 authoring_version: 1,114 spec_version: 1,114 spec_version: 2,115 impl_version: 1,115 impl_version: 1,116 apis: RUNTIME_API_VERSIONS,116 apis: RUNTIME_API_VERSIONS,117 transaction_version: 1,117 transaction_version: 1,