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

difftreelog

Fix unit test building

Greg Zaitsev2021-11-23parent: #76d8b56.patch.diff
in: master

8 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5097,6 +5097,7 @@
  "frame-system-rpc-runtime-api",
  "hex-literal",
  "nft-data-structs",
+ "orml-vesting",
  "pallet-aura",
  "pallet-balances",
  "pallet-common",
@@ -5120,7 +5121,6 @@
  "pallet-transaction-payment-rpc-runtime-api",
  "pallet-treasury",
  "pallet-unq-scheduler",
- "pallet-vesting",
  "pallet-xcm",
  "parachain-info",
  "parity-scale-codec",
@@ -5308,6 +5308,21 @@
 ]
 
 [[package]]
+name = "orml-vesting"
+version = "0.4.1-dev"
+source = "git+https://github.com/UniqueNetwork/open-runtime-module-library#d69f226e332ae29b7b33d53d2f06f309d2986ea0"
+dependencies = [
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
 name = "owning_ref"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -273,8 +273,8 @@
 		TotalCollectionsLimitExceeded,
 		/// variable_data exceeded data limit.
 		TokenVariableDataLimitExceeded,
-		/// Exceeded max admin amount
-		CollectionAdminAmountExceeded,
+		/// Exceeded max admin count
+		CollectionAdminCountExceeded,
 
 		/// Collection settings not allowing items transferring
 		TransferNotAllowed,
@@ -479,10 +479,10 @@
 		if admin {
 			let amount = amount
 				.checked_add(1)
-				.ok_or(<Error<T>>::CollectionAdminAmountExceeded)?;
+				.ok_or(<Error<T>>::CollectionAdminCountExceeded)?;
 			ensure!(
 				amount <= Self::collection_admins_limit(),
-				<Error<T>>::CollectionAdminAmountExceeded,
+				<Error<T>>::CollectionAdminCountExceeded,
 			);
 
 			// =========
modifiedpallets/fungible/src/common.rsdiffbeforeafterboth
--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -182,7 +182,7 @@
 		_token: TokenId,
 		_data: Vec<u8>,
 	) -> DispatchResultWithPostInfo {
-		fail!(<Error<T>>::FungibleItemsHaveData)
+		fail!(<Error<T>>::FungibleItemsDontHaveData)
 	}
 
 	fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -35,7 +35,7 @@
 		/// Not default id passed as TokenId argument
 		FungibleItemsHaveNoId,
 		/// Tried to set data for fungible item
-		FungibleItemsHaveData,
+		FungibleItemsDontHaveData,
 	}
 
 	#[pallet::config]
@@ -44,15 +44,15 @@
 	}
 
 	#[pallet::pallet]
-	#[pallet::generate_store(pub(super) trait Store)]
+	#[pallet::generate_store(pub trait Store)]
 	pub struct Pallet<T>(_);
 
 	#[pallet::storage]
-	pub(super) type TotalSupply<T: Config> =
+	pub type TotalSupply<T: Config> =
 		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u128, QueryKind = ValueQuery>;
 
 	#[pallet::storage]
-	pub(super) type Balance<T: Config> = StorageNMap<
+	pub type Balance<T: Config> = StorageNMap<
 		Key = (
 			Key<Twox64Concat, CollectionId>,
 			Key<Blake2_128Concat, T::CrossAccountId>,
@@ -62,7 +62,7 @@
 	>;
 
 	#[pallet::storage]
-	pub(super) type Allowance<T: Config> = StorageNMap<
+	pub type Allowance<T: Config> = StorageNMap<
 		Key = (
 			Key<Twox64Concat, CollectionId>,
 			Key<Blake2_128, T::CrossAccountId>,
modifiedpallets/nft/src/mock.rsdiffbeforeafterboth
--- a/pallets/nft/src/mock.rs
+++ b/pallets/nft/src/mock.rs
@@ -124,25 +124,35 @@
 #[derive(Encode, Decode, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, TypeInfo)]
 pub struct TestCrossAccountId(u64, sp_core::H160);
 impl CrossAccountId<u64> for TestCrossAccountId {
+	fn as_sub(&self) -> &u64 {
+		&self.0
+	}
+	fn as_eth(&self) -> &sp_core::H160 {
+		&self.1
+	}
 	fn from_sub(sub: u64) -> Self {
 		let mut eth = [0; 20];
 		eth[12..20].copy_from_slice(&sub.to_be_bytes());
 		Self(sub, sp_core::H160(eth))
 	}
-	fn as_sub(&self) -> &u64 {
-		&self.0
-	}
 	fn from_eth(eth: sp_core::H160) -> Self {
 		let mut sub_raw = [0; 8];
 		sub_raw.copy_from_slice(&eth.0[0..8]);
 		let sub = u64::from_be_bytes(sub_raw);
 		Self(sub, eth)
 	}
-	fn as_eth(&self) -> &sp_core::H160 {
-		&self.1
+	fn conv_eq(&self, other: &Self) -> bool {
+		self.as_sub() == other.as_sub()
+	}
+}
+
+impl Default for TestCrossAccountId {
+	fn default() -> Self {
+		Self::from_sub(0)
 	}
 }
 
+
 pub struct TestEtheremTransactionSender;
 impl pallet_ethereum::EthereumTransactionSender for TestEtheremTransactionSender {
 	fn submit_logs_transaction(
@@ -157,6 +167,27 @@
 	type EthereumTransactionSender = TestEtheremTransactionSender;
 }
 
+impl pallet_common::Config for Test {
+	type Event = ();
+	type EvmBackwardsAddressMapping = TestEvmBackwardsAddressMapping;
+	type EvmAddressMapping = TestEvmAddressMapping;
+	type CrossAccountId = TestCrossAccountId;
+
+	type Currency = Balances;
+	type CollectionCreationPrice = CollectionCreationPrice;
+	type TreasuryAccountId = TreasuryAccountId;
+}
+
+impl pallet_fungible::Config for Test {
+	type WeightInfo = ();
+}
+impl pallet_refungible::Config for Test {
+	type WeightInfo = ();
+}
+impl pallet_nonfungible::Config for Test {
+	type WeightInfo = ();
+}
+
 impl pallet_template::Config for Test {
 	type WeightInfo = ();
 }
modifiedpallets/nft/src/tests.rsdiffbeforeafterboth
--- a/pallets/nft/src/tests.rs
+++ b/pallets/nft/src/tests.rs
@@ -1,11 +1,14 @@
 // Tests to be written here
 use super::*;
 use crate::mock::*;
-use crate::{AccessMode, CollectionMode, CreateItemData};
+use crate::{AccessMode, CollectionMode};
 use nft_data_structs::{
-	CreateNftData, CreateFungibleData, CreateReFungibleData, CollectionId, TokenId,
-	MAX_DECIMAL_POINTS,
+	COLLECTION_NUMBER_LIMIT, Collection, CollectionId, CreateItemData, CreateFungibleData, 
+	CreateNftData, CreateReFungibleData, ExistenceRequirement, MAX_COLLECTION_DESCRIPTION_LENGTH, 
+	MAX_COLLECTION_NAME_LENGTH, MAX_DECIMAL_POINTS, MAX_TOKEN_PREFIX_LENGTH, COLLECTION_ADMINS_LIMIT, 
+	MetaUpdatePermission, Pays, PostDispatchInfo, TokenId, Weight, WithdrawReasons,
 };
+
 use frame_support::{assert_noop, assert_ok};
 use sp_std::convert::TryInto;
 
@@ -49,18 +52,18 @@
 	let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
 	let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
 	let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();
-	assert_eq!(TemplateModule::collection_id(id).unwrap().owner, owner);
+	assert_eq!(<pallet_common::CollectionById<Test>>::get(id).unwrap().owner, owner);
 	assert_eq!(
-		TemplateModule::collection_id(id).unwrap().name,
+		<pallet_common::CollectionById<Test>>::get(id).unwrap().name,
 		saved_col_name
 	);
-	assert_eq!(TemplateModule::collection_id(id).unwrap().mode, *mode);
+	assert_eq!(<pallet_common::CollectionById<Test>>::get(id).unwrap().mode, *mode);
 	assert_eq!(
-		TemplateModule::collection_id(id).unwrap().description,
+		<pallet_common::CollectionById<Test>>::get(id).unwrap().description,
 		saved_description
 	);
 	assert_eq!(
-		TemplateModule::collection_id(id).unwrap().token_prefix,
+		<pallet_common::CollectionById<Test>>::get(id).unwrap().token_prefix,
 		saved_prefix
 	);
 	id
@@ -91,7 +94,7 @@
 fn set_version_schema() {
 	new_test_ext().execute_with(|| {
 		let origin1 = Origin::signed(1);
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		assert_ok!(TemplateModule::set_schema_version(
 			origin1,
@@ -99,7 +102,7 @@
 			SchemaVersion::Unique
 		));
 		assert_eq!(
-			TemplateModule::collection_id(collection_id)
+			<pallet_common::CollectionById<Test>>::get(collection_id)
 				.unwrap()
 				.schema_version,
 			SchemaVersion::Unique
@@ -131,11 +134,12 @@
 #[test]
 fn create_nft_item() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let data = default_nft_data();
 		create_test_item(collection_id, &data.clone().into());
-		let item = TemplateModule::nft_item_id(collection_id, 1).unwrap();
+
+		let item = <pallet_nonfungible::TokenData<Test>>::get((collection_id, 1)).unwrap();
 		assert_eq!(item.const_data, data.const_data.into_inner());
 		assert_eq!(item.variable_data, data.variable_data.into_inner());
 	});
@@ -146,7 +150,7 @@
 #[test]
 fn create_nft_multiple_items() {
 	new_test_ext().execute_with(|| {
-		create_test_collection(&CollectionMode::NFT, 1);
+		create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
@@ -154,7 +158,7 @@
 
 		assert_ok!(TemplateModule::create_multiple_items(
 			origin1,
-			1,
+			CollectionId(1),
 			account(1),
 			items_data
 				.clone()
@@ -163,7 +167,7 @@
 				.collect()
 		));
 		for (index, data) in items_data.into_iter().enumerate() {
-			let item = TemplateModule::nft_item_id(1, (index + 1) as TokenId).unwrap();
+			let item = <pallet_nonfungible::TokenData<Test>>::get((CollectionId(1), TokenId((index + 1) as u32))).unwrap();
 			assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());
 			assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());
 		}
@@ -173,12 +177,12 @@
 #[test]
 fn create_refungible_item() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
+		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
 
 		let data = default_re_fungible_data();
 		create_test_item(collection_id, &data.clone().into());
-		let item = TemplateModule::refungible_item_id(collection_id, 1).unwrap();
-		let balance = TemplateModule::balance(collection_id, 1, account(1));
+		let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));
+		let balance = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));
 		assert_eq!(item.const_data, data.const_data.into_inner());
 		assert_eq!(item.variable_data, data.variable_data.into_inner());
 		assert_eq!(balance, 1023);
@@ -188,7 +192,7 @@
 #[test]
 fn create_multiple_refungible_items() {
 	new_test_ext().execute_with(|| {
-		create_test_collection(&CollectionMode::ReFungible, 1);
+		create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
@@ -200,7 +204,7 @@
 
 		assert_ok!(TemplateModule::create_multiple_items(
 			origin1,
-			1,
+			CollectionId(1),
 			account(1),
 			items_data
 				.clone()
@@ -209,8 +213,8 @@
 				.collect()
 		));
 		for (index, data) in items_data.into_iter().enumerate() {
-			let item = TemplateModule::refungible_item_id(1, (index + 1) as TokenId).unwrap();
-			let balance = TemplateModule::balance(1, 1, account(1));
+			let item = <pallet_nonfungible::TokenData<Test>>::get((CollectionId(1), TokenId((index + 1) as u32))).unwrap();
+			let balance = <pallet_refungible::Balance<Test>>::get((CollectionId(1), TokenId(1), account(1)));
 			assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());
 			assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());
 			assert_eq!(balance, 1023);
@@ -221,12 +225,12 @@
 #[test]
 fn create_fungible_item() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
+		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
 
 		let data = default_fungible_data();
 		create_test_item(collection_id, &data.into());
 
-		assert_eq!(TemplateModule::fungible_item_id(collection_id, 1).value, 5);
+		assert_eq!(<pallet_fungible::Balance<Test>>::get((collection_id, account(1))), 5);
 	});
 }
 
@@ -235,7 +239,7 @@
 //     new_test_ext().execute_with(|| {
 //         default_limits();
 
-//         create_test_collection(&CollectionMode::Fungible(3), 1);
+//         create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
 
 //         let origin1 = Origin::signed(1);
 
@@ -259,7 +263,7 @@
 #[test]
 fn transfer_fungible_item() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
+		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -267,39 +271,32 @@
 		let data = default_fungible_data();
 		create_test_item(collection_id, &data.into());
 
-		assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 5);
-		assert_eq!(TemplateModule::balance_count(1, 1), 5);
+		assert_eq!(<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))), 5);
 
 		// change owner scenario
-		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 5));
-		assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 0);
-		assert_eq!(TemplateModule::balance_count(1, 1), 0);
-		assert_eq!(TemplateModule::balance_count(1, 2), 5);
+		assert_ok!(TemplateModule::transfer(origin1, account(2), CollectionId(1), TokenId(1), 5));
+		assert_eq!(<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))), 0);
 
 		// split item scenario
 		assert_ok!(TemplateModule::transfer(
 			origin2.clone(),
 			account(3),
-			1,
-			1,
+			CollectionId(1),
+			TokenId(1),
 			3
 		));
-		assert_eq!(TemplateModule::balance_count(1, 2), 2);
-		assert_eq!(TemplateModule::balance_count(1, 3), 3);
 
 		// split item and new owner has account scenario
-		assert_ok!(TemplateModule::transfer(origin2, account(3), 1, 1, 1));
-		assert_eq!(TemplateModule::fungible_item_id(1, 2).value, 1);
-		assert_eq!(TemplateModule::fungible_item_id(1, 3).value, 4);
-		assert_eq!(TemplateModule::balance_count(1, 2), 1);
-		assert_eq!(TemplateModule::balance_count(1, 3), 4);
+		assert_ok!(TemplateModule::transfer(origin2, account(3), CollectionId(1), TokenId(1), 1));
+		assert_eq!(<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(2))), 1);
+		assert_eq!(<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(3))), 4);
 	});
 }
 
 #[test]
 fn transfer_refungible_item() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
+		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
 
 		let data = default_re_fungible_data();
 		create_test_item(collection_id, &data.clone().into());
@@ -307,86 +304,87 @@
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
 		{
-			let item = TemplateModule::refungible_item_id(collection_id, 1).unwrap();
-			let balance = TemplateModule::balance(collection_id, 1, account(1));
+			let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));
+			let balance = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));
 			assert_eq!(item.const_data, data.const_data.into_inner());
 			assert_eq!(item.variable_data, data.variable_data.into_inner());
 			assert_eq!(balance, 1023);
 		}
-		assert_eq!(TemplateModule::balance_count(1, 1), 1023);
-		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+		
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 1023);
+		assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
 
 		// change owner scenario
-		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1023));
+		assert_ok!(TemplateModule::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1023));
 
-		let balance2 = TemplateModule::balance(collection_id, 1, account(2));
+		let balance2 = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2)));
 		assert_eq!(balance2, 1023);
-		assert_eq!(TemplateModule::balance_count(1, 1), 0);
-		assert_eq!(TemplateModule::balance_count(1, 2), 1023);
-		// assert_eq!(TemplateModule::address_tokens(1, 1), []);
-		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 0);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))), 1023);
+		assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), false);
+		assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))), true);
 
 		// split item scenario
 		assert_ok!(TemplateModule::transfer(
 			origin2.clone(),
 			account(3),
-			1,
-			1,
+			CollectionId(1),
+			TokenId(1),
 			500
 		));
 		{
-			let item = TemplateModule::refungible_item_id(1, 1).unwrap();
-			let balance2 = TemplateModule::balance(collection_id, 1, account(2));
-			let balance3 = TemplateModule::balance(collection_id, 1, account(3));
+			let item = <pallet_refungible::TokenData<Test>>::get((CollectionId(1), TokenId(1)));
+			let balance2 = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2)));
+			let balance3 = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3)));
 			assert_eq!(balance2, 523);
 			assert_eq!(balance3, 500);
 		}
-		assert_eq!(TemplateModule::balance_count(1, 2), 523);
-		assert_eq!(TemplateModule::balance_count(1, 3), 500);
-		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
-		assert_eq!(TemplateModule::address_tokens(1, 3), [1]);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))), 523);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))), 500);
+		assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))), true);
+		assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))), true);
 
 		// split item and new owner has account scenario
-		assert_ok!(TemplateModule::transfer(origin2, account(3), 1, 1, 200));
+		assert_ok!(TemplateModule::transfer(origin2, account(3), CollectionId(1), TokenId(1), 200));
 		{
-			let item = TemplateModule::refungible_item_id(1, 1).unwrap();
-			let balance2 = TemplateModule::balance(collection_id, 1, account(2));
-			let balance3 = TemplateModule::balance(collection_id, 1, account(3));
+			let item = <pallet_refungible::TokenData<Test>>::get((CollectionId(1), TokenId(1)));
+			let balance2 = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2)));
+			let balance3 = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3)));
 			assert_eq!(balance2, 323);
 			assert_eq!(balance3, 700);
 		}
-		assert_eq!(TemplateModule::balance_count(1, 2), 323);
-		assert_eq!(TemplateModule::balance_count(1, 3), 700);
-		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
-		assert_eq!(TemplateModule::address_tokens(1, 3), [1]);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))), 323);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))), 700);
+		assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))), true);
+		assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))), true);
 	});
 }
 
 #[test]
 fn transfer_nft_item() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let data = default_nft_data();
 		create_test_item(collection_id, &data.into());
-		assert_eq!(TemplateModule::balance_count(1, 1), 1);
-		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
+		assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
+
 
 		let origin1 = Origin::signed(1);
 		// default scenario
-		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1000));
-		assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(2));
-		assert_eq!(TemplateModule::balance_count(1, 1), 0);
-		assert_eq!(TemplateModule::balance_count(1, 2), 1);
-		// assert_eq!(TemplateModule::address_tokens(1, 1), []);
-		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
+		assert_ok!(TemplateModule::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1000));
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 0);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))), 1);
+		assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), false);
+		assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))), true);
 	});
 }
 
 #[test]
 fn nft_approve_and_transfer_from() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let data = default_nft_data();
 		create_test_item(collection_id, &data.into());
@@ -394,36 +392,35 @@
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
 
-		assert_eq!(TemplateModule::balance_count(1, 1), 1);
-		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
+		assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
 
 		// neg transfer
 		assert_noop!(
-			TemplateModule::transfer_from(origin2.clone(), account(1), account(2), 1, 1, 1),
-			Error::<Test>::NoPermission
+			TemplateModule::transfer_from(origin2.clone(), account(1), account(2), CollectionId(1), TokenId(1), 1),
+			CommonError::<Test>::NoPermission
 		);
 
 		// do approve
-		assert_ok!(TemplateModule::approve(origin1, account(2), 1, 1, 5));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);
-		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);
+		assert_ok!(TemplateModule::approve(origin1, account(2), CollectionId(1), TokenId(1), 5));
+		assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(2));
 
 		assert_ok!(TemplateModule::transfer_from(
 			origin2,
 			account(1),
 			account(3),
-			1,
-			1,
+			CollectionId(1),
+			TokenId(1),
 			1
 		));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);
+		assert!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none());
 	});
 }
 
 #[test]
 fn nft_approve_and_transfer_from_allow_list() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -432,35 +429,35 @@
 		create_test_item(collection_id, &data.clone().into());
 
 		assert_eq!(
-			&TemplateModule::nft_item_id(1, 1).unwrap().const_data,
+			&<pallet_nonfungible::TokenData<Test>>::get((collection_id, TokenId(1))).unwrap().const_data,
 			&data.const_data.into_inner()
 		);
-		assert_eq!(TemplateModule::balance_count(1, 1), 1);
-		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
+		assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
 
 		assert_ok!(TemplateModule::set_mint_permission(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			true
 		));
 		assert_ok!(TemplateModule::set_public_access_mode(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			AccessMode::AllowList
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			account(1)
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			account(2)
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			account(3)
 		));
 
@@ -468,30 +465,30 @@
 		assert_ok!(TemplateModule::approve(
 			origin1.clone(),
 			account(2),
-			1,
-			1,
+			CollectionId(1),
+			TokenId(1),
 			5
 		));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);
-		assert_ok!(TemplateModule::approve(origin1, account(3), 1, 1, 5));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);
+		assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(2));
+		assert_ok!(TemplateModule::approve(origin1, account(3), CollectionId(1), TokenId(1), 5));
+		assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(3));
 
 		assert_ok!(TemplateModule::transfer_from(
 			origin2,
 			account(1),
 			account(3),
-			1,
-			1,
+			CollectionId(1),
+			TokenId(1),
 			1
 		));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);
+		assert!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none());
 	});
 }
 
 #[test]
 fn refungible_approve_and_transfer_from() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
+		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -499,92 +496,89 @@
 		let data = default_re_fungible_data();
 		create_test_item(collection_id, &data.into());
 
-		assert_eq!(TemplateModule::balance_count(1, 1), 1023);
-		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 1023);
+		assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
 
 		assert_ok!(TemplateModule::set_mint_permission(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			true
 		));
 		assert_ok!(TemplateModule::set_public_access_mode(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			AccessMode::AllowList
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			account(1)
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			account(2)
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			account(3)
 		));
 
 		// do approve
-		assert_ok!(TemplateModule::approve(origin1, account(2), 1, 1, 1023));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1023);
+		assert_ok!(TemplateModule::approve(origin1, account(2), CollectionId(1), TokenId(1), 1023));
+		assert_eq!(<pallet_refungible::Allowance<Test>>::get((CollectionId(1), TokenId(1), account(1), account(2))), 1023);
 
 		assert_ok!(TemplateModule::transfer_from(
 			origin2,
 			account(1),
 			account(3),
-			1,
-			1,
+			CollectionId(1),
+			TokenId(1),
 			100
 		));
-		assert_eq!(TemplateModule::balance_count(1, 1), 923);
-		assert_eq!(TemplateModule::balance_count(1, 3), 100);
-		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
-		assert_eq!(TemplateModule::address_tokens(1, 3), [1]);
-
-		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 923);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 923);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))), 100);
+		assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
+		assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(3))), true);
+		assert_eq!(<pallet_refungible::Allowance<Test>>::get((CollectionId(1), TokenId(1), account(1), account(2))), 923);
 	});
 }
 
 #[test]
 fn fungible_approve_and_transfer_from() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
+		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
 
 		let data = default_fungible_data();
 		create_test_item(collection_id, &data.into());
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
-
-		assert_eq!(TemplateModule::balance_count(1, 1), 5);
 
 		assert_ok!(TemplateModule::set_mint_permission(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			true
 		));
 		assert_ok!(TemplateModule::set_public_access_mode(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			AccessMode::AllowList
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			account(1)
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			account(2)
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			account(3)
 		));
 
@@ -592,31 +586,29 @@
 		assert_ok!(TemplateModule::approve(
 			origin1.clone(),
 			account(2),
-			1,
-			1,
+			CollectionId(1),
+			TokenId(1),
 			5
 		));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);
-		assert_ok!(TemplateModule::approve(origin1, account(3), 1, 1, 5));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);
-		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);
+		assert_eq!(<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))), 5);
+		assert_ok!(TemplateModule::approve(origin1, account(3), CollectionId(1), TokenId(1), 5));
+		assert_eq!(<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))), 5);
+		assert_eq!(<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(3))), 5);
 
 		assert_ok!(TemplateModule::transfer_from(
 			origin2.clone(),
 			account(1),
 			account(3),
-			1,
-			1,
+			CollectionId(1),
+			TokenId(1),
 			4
 		));
-		assert_eq!(TemplateModule::balance_count(1, 1), 1);
-		assert_eq!(TemplateModule::balance_count(1, 3), 4);
 
-		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);
+		assert_eq!(<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))), 1);
 
 		assert_noop!(
-			TemplateModule::transfer_from(origin2, account(1), account(3), 1, 1, 4),
-			Error::<Test>::NoPermission
+			TemplateModule::transfer_from(origin2, account(1), account(3), CollectionId(1), TokenId(1), 4),
+			CommonError::<Test>::NoPermission
 		);
 	});
 }
@@ -624,7 +616,7 @@
 #[test]
 fn change_collection_owner() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		assert_ok!(TemplateModule::change_collection_owner(
@@ -633,7 +625,7 @@
 			2
 		));
 		assert_eq!(
-			TemplateModule::collection_id(collection_id).unwrap().owner,
+			<pallet_common::CollectionById<Test>>::get(collection_id).unwrap().owner,
 			2
 		);
 	});
@@ -642,7 +634,7 @@
 #[test]
 fn destroy_collection() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		assert_ok!(TemplateModule::destroy_collection(origin1, collection_id));
@@ -652,7 +644,7 @@
 #[test]
 fn burn_nft_item() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		assert_ok!(TemplateModule::add_collection_admin(
@@ -665,28 +657,28 @@
 		create_test_item(collection_id, &data.into());
 
 		// check balance (collection with id = 1, user id = 1)
-		assert_eq!(TemplateModule::balance_count(1, 1), 1);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
 
 		// burn item
 		assert_ok!(TemplateModule::burn_item(
 			origin1.clone(),
 			collection_id,
-			1,
+			TokenId(1),
 			1
 		));
 		assert_noop!(
-			TemplateModule::burn_item(origin1, collection_id, 1, 1),
-			Error::<Test>::TokenNotFound
+			TemplateModule::burn_item(origin1, collection_id, TokenId(1), 1),
+			CommonError::<Test>::TokenNotFound
 		);
 
-		assert_eq!(TemplateModule::balance_count(1, 1), 0);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 0);
 	});
 }
 
 #[test]
 fn burn_fungible_item() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
+		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		assert_ok!(TemplateModule::add_collection_admin(
@@ -699,23 +691,23 @@
 		create_test_item(collection_id, &data.into());
 
 		// check balance (collection with id = 1, user id = 1)
-		assert_eq!(TemplateModule::balance_count(1, 1), 5);
+		assert_eq!(<pallet_fungible::Balance<Test>>::get((collection_id, account(1))), 5);
 
 		// burn item
-		assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5));
+		assert_ok!(TemplateModule::burn_item(origin1.clone(), CollectionId(1), TokenId(1), 5));
 		assert_noop!(
-			TemplateModule::burn_item(origin1, 1, 1, 5),
-			Error::<Test>::TokenValueNotEnough
+			TemplateModule::burn_item(origin1, CollectionId(1), TokenId(1), 5),
+			CommonError::<Test>::TokenValueNotEnough
 		);
 
-		assert_eq!(TemplateModule::balance_count(1, 1), 0);
+		assert_eq!(<pallet_fungible::Balance<Test>>::get((collection_id, account(1))), 0);
 	});
 }
 
 #[test]
 fn burn_refungible_item() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
+		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
 		let origin1 = Origin::signed(1);
 
 		assert_ok!(TemplateModule::set_mint_permission(
@@ -730,13 +722,13 @@
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			collection_id,
 			account(1)
 		));
 
 		assert_ok!(TemplateModule::add_collection_admin(
 			origin1.clone(),
-			1,
+			collection_id,
 			account(2)
 		));
 
@@ -744,25 +736,26 @@
 		create_test_item(collection_id, &data.into());
 
 		// check balance (collection with id = 1, user id = 2)
-		assert_eq!(TemplateModule::balance_count(1, 1), 1023);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 1023);
+		assert_eq!(<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))), 1023);
 
 		// burn item
-		assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 1023));
+		assert_ok!(TemplateModule::burn_item(origin1.clone(), collection_id, TokenId(1), 1023));
 		assert_noop!(
-			TemplateModule::burn_item(origin1, 1, 1, 1023),
-			Error::<Test>::TokenNotFound
+			TemplateModule::burn_item(origin1, collection_id, TokenId(1), 1023),
+			CommonError::<Test>::TokenNotFound
 		);
 
-		assert_eq!(TemplateModule::balance_count(1, 1), 0);
+		assert_eq!(<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))), 0);
 	});
 }
 
 #[test]
 fn add_collection_admin() {
 	new_test_ext().execute_with(|| {
-		let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);
-		create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);
-		create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);
+		let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));
+		create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(2));
+		create_test_collection_for_owner(&CollectionMode::NFT, 3, CollectionId(3));
 
 		let origin1 = Origin::signed(1);
 
@@ -778,17 +771,18 @@
 			account(3)
 		));
 
-		assert!(TemplateModule::admin_list_collection(collection1_id).contains(&account(2)),);
-		assert!(TemplateModule::admin_list_collection(collection1_id).contains(&account(3)),);
+		assert!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(1))));
+		assert!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(2))));
+		assert!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))));
 	});
 }
 
 #[test]
 fn remove_collection_admin() {
 	new_test_ext().execute_with(|| {
-		let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);
-		create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);
-		create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);
+		let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));
+		create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(2));
+		create_test_collection_for_owner(&CollectionMode::NFT, 3, CollectionId(3));
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -805,33 +799,31 @@
 			account(3)
 		));
 
-		assert!(TemplateModule::admin_list_collection(1).contains(&account(2)),);
-		assert!(TemplateModule::admin_list_collection(1).contains(&account(3)),);
+		assert!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(2))));
+		assert!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))));
 
 		// remove admin
 		assert_ok!(TemplateModule::remove_collection_admin(
 			origin2,
-			1,
+			CollectionId(1),
 			account(3)
 		));
-		assert!(!TemplateModule::admin_list_collection(1).contains(&account(3)),);
+		assert!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))));
+		assert_eq!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(2))), false);
 	});
 }
 
 #[test]
 fn balance_of() {
 	new_test_ext().execute_with(|| {
-		let nft_collection_id = create_test_collection(&CollectionMode::NFT, 1);
-		let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), 2);
-		let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible, 3);
+		let nft_collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
+		let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(2));
+		let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(3));
 
 		// check balance before
-		assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 0);
-		assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 0);
-		assert_eq!(
-			TemplateModule::balance_count(re_fungible_collection_id, 1),
-			0
-		);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))), 0);
+		assert_eq!(<pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))), 0);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))), 0);
 
 		let nft_data = default_nft_data();
 		create_test_item(nft_collection_id, &nft_data.into());
@@ -843,36 +835,19 @@
 		create_test_item(re_fungible_collection_id, &re_fungible_data.into());
 
 		// check balance (collection with id = 1, user id = 1)
-		assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 1);
-		assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 5);
-		assert_eq!(
-			TemplateModule::balance_count(re_fungible_collection_id, 1),
-			1023
-		);
-		assert_eq!(
-			TemplateModule::nft_item_id(nft_collection_id, 1)
-				.unwrap()
-				.owner,
-			account(1)
-		);
-		assert_eq!(
-			TemplateModule::fungible_item_id(fungible_collection_id, 1).value,
-			5
-		);
-		assert_eq!(
-			TemplateModule::refungible_item_id(re_fungible_collection_id, 1)
-				.unwrap()
-				.owner[0]
-				.owner,
-			account(1)
-		);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))), 1);
+		assert_eq!(<pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))), 5);
+		assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))), 1023);
+
+		assert_eq!(<pallet_nonfungible::Owned<Test>>::get((nft_collection_id, account(1), TokenId(1))), true);
+		assert_eq!(<pallet_refungible::Owned<Test>>::get((nft_collection_id, account(1), TokenId(1))), true);
 	});
 }
 
 #[test]
 fn approve() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let data = default_nft_data();
 		create_test_item(collection_id, &data.into());
@@ -880,15 +855,15 @@
 		let origin1 = Origin::signed(1);
 
 		// approve
-		assert_ok!(TemplateModule::approve(origin1, account(2), 1, 1, 1));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);
+		assert_ok!(TemplateModule::approve(origin1, account(2), CollectionId(1), TokenId(1), 1));
+		assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(2));
 	});
 }
 
 #[test]
 fn transfer_from() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
 
@@ -899,46 +874,46 @@
 		assert_ok!(TemplateModule::approve(
 			origin1.clone(),
 			account(2),
-			1,
-			1,
+			CollectionId(1),
+			TokenId(1),
 			1
 		));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);
+		assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(2));
 
 		assert_ok!(TemplateModule::set_mint_permission(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			true
 		));
 		assert_ok!(TemplateModule::set_public_access_mode(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			AccessMode::AllowList
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			account(1)
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			CollectionId(1),
 			account(2)
 		));
-		assert_ok!(TemplateModule::add_to_allow_list(origin1, 1, account(3)));
+		assert_ok!(TemplateModule::add_to_allow_list(origin1, CollectionId(1), account(3)));
 
 		assert_ok!(TemplateModule::transfer_from(
 			origin2,
 			account(1),
 			account(2),
-			1,
-			1,
+			CollectionId(1),
+			TokenId(1),
 			1
 		));
 
 		// after transfer
-		assert_eq!(TemplateModule::balance_count(1, 1), 0);
-		assert_eq!(TemplateModule::balance_count(1, 2), 1);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(1))), 0);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(2))), 1);
 	});
 }
 
@@ -950,7 +925,7 @@
 #[test]
 fn owner_can_add_address_to_allow_list() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		assert_ok!(TemplateModule::add_to_allow_list(
@@ -958,14 +933,14 @@
 			collection_id,
 			account(2)
 		));
-		assert!(TemplateModule::allow_list(collection_id, 2));
+		assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(2))));
 	});
 }
 
 #[test]
 fn admin_can_add_address_to_allow_list() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
 
@@ -979,19 +954,19 @@
 			collection_id,
 			account(3)
 		));
-		assert!(TemplateModule::allow_list(collection_id, 3));
+		assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(3))));
 	});
 }
 
 #[test]
 fn nonprivileged_user_cannot_add_address_to_allow_list() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin2 = Origin::signed(2);
 		assert_noop!(
 			TemplateModule::add_to_allow_list(origin2, collection_id, account(3)),
-			Error::<Test>::NoPermission
+			CommonError::<Test>::NoPermission
 		);
 	});
 }
@@ -1002,8 +977,8 @@
 		let origin1 = Origin::signed(1);
 
 		assert_noop!(
-			TemplateModule::add_to_allow_list(origin1, 1, account(2)),
-			Error::<Test>::CollectionNotFound
+			TemplateModule::add_to_allow_list(origin1, CollectionId(1), account(2)),
+			CommonError::<Test>::CollectionNotFound
 		);
 	});
 }
@@ -1011,7 +986,7 @@
 #[test]
 fn nobody_can_add_address_to_allow_list_of_deleted_collection() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		assert_ok!(TemplateModule::destroy_collection(
@@ -1020,7 +995,7 @@
 		));
 		assert_noop!(
 			TemplateModule::add_to_allow_list(origin1, collection_id, account(2)),
-			Error::<Test>::CollectionNotFound
+			CommonError::<Test>::CollectionNotFound
 		);
 	});
 }
@@ -1029,7 +1004,7 @@
 #[test]
 fn address_is_already_added_to_allow_list() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 		let origin1 = Origin::signed(1);
 
 		assert_ok!(TemplateModule::add_to_allow_list(
@@ -1042,14 +1017,14 @@
 			collection_id,
 			account(2)
 		));
-		assert!(TemplateModule::allow_list(collection_id, 2));
+		assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(2))));
 	});
 }
 
 #[test]
 fn owner_can_remove_address_from_allow_list() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		assert_ok!(TemplateModule::add_to_allow_list(
@@ -1062,14 +1037,14 @@
 			collection_id,
 			account(2)
 		));
-		assert!(!TemplateModule::allow_list(collection_id, 2));
+		assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(2))));
 	});
 }
 
 #[test]
 fn admin_can_remove_address_from_allow_list() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
 
@@ -1089,14 +1064,14 @@
 			collection_id,
 			account(3)
 		));
-		assert!(!TemplateModule::allow_list(collection_id, 3));
+		assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(3))));
 	});
 }
 
 #[test]
 fn nonprivileged_user_cannot_remove_address_from_allow_list() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
 
@@ -1107,9 +1082,9 @@
 		));
 		assert_noop!(
 			TemplateModule::remove_from_allow_list(origin2, collection_id, account(2)),
-			Error::<Test>::NoPermission
+			CommonError::<Test>::NoPermission
 		);
-		assert!(TemplateModule::allow_list(collection_id, 2));
+		assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(2))));
 	});
 }
 
@@ -1119,8 +1094,8 @@
 		let origin1 = Origin::signed(1);
 
 		assert_noop!(
-			TemplateModule::remove_from_allow_list(origin1, 1, account(2)),
-			Error::<Test>::CollectionNotFound
+			TemplateModule::remove_from_allow_list(origin1, CollectionId(1), account(2)),
+			CommonError::<Test>::CollectionNotFound
 		);
 	});
 }
@@ -1128,7 +1103,7 @@
 #[test]
 fn nobody_can_remove_address_from_allow_list_of_deleted_collection() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
 
@@ -1140,9 +1115,9 @@
 		assert_ok!(TemplateModule::destroy_collection(origin1, collection_id));
 		assert_noop!(
 			TemplateModule::remove_from_allow_list(origin2, collection_id, account(2)),
-			Error::<Test>::CollectionNotFound
+			CommonError::<Test>::CollectionNotFound
 		);
-		assert!(!TemplateModule::allow_list(collection_id, 2));
+		assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(2))));
 	});
 }
 
@@ -1150,7 +1125,7 @@
 #[test]
 fn address_is_already_removed_from_allow_list() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 		let origin1 = Origin::signed(1);
 
 		assert_ok!(TemplateModule::add_to_allow_list(
@@ -1168,7 +1143,7 @@
 			collection_id,
 			account(2)
 		));
-		assert!(!TemplateModule::allow_list(collection_id, 2));
+		assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(2))));
 	});
 }
 
@@ -1176,7 +1151,7 @@
 #[test]
 fn allow_list_test_1() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
@@ -1195,8 +1170,8 @@
 		));
 
 		assert_noop!(
-			TemplateModule::transfer(origin1, account(3), 1, 1, 1),
-			Error::<Test>::AddresNotInAllowList
+			TemplateModule::transfer(origin1, account(3), CollectionId(1), TokenId(1), 1),
+			CommonError::<Test>::AddressNotInAllowlist
 		);
 	});
 }
@@ -1204,7 +1179,7 @@
 #[test]
 fn allow_list_test_2() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 		let origin1 = Origin::signed(1);
 
 		let data = default_nft_data();
@@ -1217,12 +1192,12 @@
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			collection_id,
 			account(1)
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			collection_id,
 			account(2)
 		));
 
@@ -1230,21 +1205,21 @@
 		assert_ok!(TemplateModule::approve(
 			origin1.clone(),
 			account(1),
-			1,
-			1,
+			collection_id,
+			TokenId(1),
 			1
 		));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);
+		assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(1));
 
 		assert_ok!(TemplateModule::remove_from_allow_list(
 			origin1.clone(),
-			1,
+			collection_id,
 			account(1)
 		));
 
 		assert_noop!(
-			TemplateModule::transfer_from(origin1, account(1), account(3), 1, 1, 1),
-			Error::<Test>::AddresNotInAllowList
+			TemplateModule::transfer_from(origin1, account(1), account(3), CollectionId(1), TokenId(1), 1),
+			CommonError::<Test>::AddressNotInAllowlist
 		);
 	});
 }
@@ -1253,7 +1228,7 @@
 #[test]
 fn allow_list_test_3() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
@@ -1267,13 +1242,13 @@
 		));
 		assert_ok!(TemplateModule::add_to_allow_list(
 			origin1.clone(),
-			1,
+			collection_id,
 			account(1)
 		));
 
 		assert_noop!(
-			TemplateModule::transfer(origin1, account(3), 1, 1, 1),
-			Error::<Test>::AddresNotInAllowList
+			TemplateModule::transfer(origin1, account(3), collection_id, TokenId(1), 1),
+			CommonError::<Test>::AddressNotInAllowlist
 		);
 	});
 }
@@ -1281,7 +1256,7 @@
 #[test]
 fn allow_list_test_4() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
@@ -1308,11 +1283,11 @@
 		assert_ok!(TemplateModule::approve(
 			origin1.clone(),
 			account(1),
-			1,
-			1,
+			collection_id,
+			TokenId(1),
 			1
 		));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);
+		assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(1));
 
 		assert_ok!(TemplateModule::remove_from_allow_list(
 			origin1.clone(),
@@ -1321,8 +1296,8 @@
 		));
 
 		assert_noop!(
-			TemplateModule::transfer_from(origin1, account(1), account(3), 1, 1, 1),
-			Error::<Test>::AddresNotInAllowList
+			TemplateModule::transfer_from(origin1, account(1), account(3), collection_id, TokenId(1), 1),
+			CommonError::<Test>::AddressNotInAllowlist
 		);
 	});
 }
@@ -1331,7 +1306,7 @@
 #[test]
 fn allow_list_test_5() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
@@ -1344,8 +1319,8 @@
 			AccessMode::AllowList
 		));
 		assert_noop!(
-			TemplateModule::burn_item(origin1.clone(), 1, 1, 5),
-			Error::<Test>::AddresNotInAllowList
+			TemplateModule::burn_item(origin1.clone(), CollectionId(1), TokenId(1), 5),
+			CommonError::<Test>::AddressNotInAllowlist
 		);
 	});
 }
@@ -1354,7 +1329,7 @@
 #[test]
 fn allow_list_test_6() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
@@ -1369,8 +1344,8 @@
 
 		// do approve
 		assert_noop!(
-			TemplateModule::approve(origin1, account(1), 1, 1, 5),
-			Error::<Test>::AddresNotInAllowList
+			TemplateModule::approve(origin1, account(1), CollectionId(1), TokenId(1), 5),
+			CommonError::<Test>::AddressNotInAllowlist
 		);
 	});
 }
@@ -1380,7 +1355,7 @@
 #[test]
 fn allow_list_test_7() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let data = default_nft_data();
 		create_test_item(collection_id, &data.into());
@@ -1403,14 +1378,14 @@
 			account(2)
 		));
 
-		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1));
+		assert_ok!(TemplateModule::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1));
 	});
 }
 
 #[test]
 fn allow_list_test_8() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let data = default_nft_data();
 		create_test_item(collection_id, &data.into());
@@ -1437,18 +1412,18 @@
 		assert_ok!(TemplateModule::approve(
 			origin1.clone(),
 			account(1),
-			1,
-			1,
+			CollectionId(1), 
+			TokenId(1),
 			5
 		));
-		assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 5);
+		assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(1));
 
 		assert_ok!(TemplateModule::transfer_from(
 			origin1,
 			account(1),
 			account(2),
-			1,
-			1,
+			CollectionId(1), 
+			TokenId(1),
 			1
 		));
 	});
@@ -1458,7 +1433,7 @@
 #[test]
 fn allow_list_test_9() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 		let origin1 = Origin::signed(1);
 
 		assert_ok!(TemplateModule::set_public_access_mode(
@@ -1481,7 +1456,7 @@
 #[test]
 fn allow_list_test_10() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -1516,7 +1491,7 @@
 #[test]
 fn allow_list_test_11() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -1538,8 +1513,8 @@
 		));
 
 		assert_noop!(
-			TemplateModule::create_item(origin2, 1, account(2), default_nft_data().into()),
-			Error::<Test>::PublicMintingNotAllowed
+			TemplateModule::create_item(origin2, CollectionId(1), account(2), default_nft_data().into()),
+			CommonError::<Test>::PublicMintingNotAllowed
 		);
 	});
 }
@@ -1548,7 +1523,7 @@
 #[test]
 fn allow_list_test_12() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -1565,8 +1540,8 @@
 		));
 
 		assert_noop!(
-			TemplateModule::create_item(origin2, 1, account(2), default_nft_data().into()),
-			Error::<Test>::PublicMintingNotAllowed
+			TemplateModule::create_item(origin2, CollectionId(1), account(2), default_nft_data().into()),
+			CommonError::<Test>::PublicMintingNotAllowed
 		);
 	});
 }
@@ -1575,7 +1550,7 @@
 #[test]
 fn allow_list_test_13() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
@@ -1599,7 +1574,7 @@
 #[test]
 fn allow_list_test_14() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -1623,7 +1598,7 @@
 
 		assert_ok!(TemplateModule::create_item(
 			origin2,
-			1,
+			collection_id,
 			account(2),
 			default_nft_data().into()
 		));
@@ -1634,7 +1609,7 @@
 #[test]
 fn allow_list_test_15() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -1651,8 +1626,8 @@
 		));
 
 		assert_noop!(
-			TemplateModule::create_item(origin2, 1, account(2), default_nft_data().into()),
-			Error::<Test>::AddresNotInAllowList
+			TemplateModule::create_item(origin2, collection_id, account(2), default_nft_data().into()),
+			CommonError::<Test>::AddressNotInAllowlist
 		);
 	});
 }
@@ -1661,7 +1636,7 @@
 #[test]
 fn allow_list_test_16() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -1684,7 +1659,7 @@
 
 		assert_ok!(TemplateModule::create_item(
 			origin2,
-			1,
+			collection_id,
 			account(2),
 			default_nft_data().into()
 		));
@@ -1695,7 +1670,7 @@
 #[test]
 fn total_number_collections_bound() {
 	new_test_ext().execute_with(|| {
-		create_test_collection(&CollectionMode::NFT, 1);
+		create_test_collection(&CollectionMode::NFT, CollectionId(1));
 	});
 }
 
@@ -1706,7 +1681,7 @@
 		let origin1 = Origin::signed(1);
 
 		for i in 0..COLLECTION_NUMBER_LIMIT {
-			create_test_collection(&CollectionMode::NFT, i + 1);
+			create_test_collection(&CollectionMode::NFT, CollectionId(i + 1));
 		}
 
 		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
@@ -1722,7 +1697,7 @@
 				token_prefix1,
 				CollectionMode::NFT
 			),
-			Error::<Test>::TotalCollectionsLimitExceeded
+			CommonError::<Test>::TotalCollectionsLimitExceeded
 		);
 	});
 }
@@ -1731,7 +1706,7 @@
 #[test]
 fn owned_tokens_bound() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let data = default_nft_data();
 		create_test_item(collection_id, &data.clone().into());
@@ -1743,19 +1718,19 @@
 #[test]
 fn owned_tokens_bound_neg() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
-		for _ in 0..ACCOUNT_TOKEN_OWNERSHIP_LIMIT {
+		for _ in 0..MAX_TOKEN_OWNERSHIP {
 			let data = default_nft_data();
 			create_test_item(collection_id, &data.clone().into());
 		}
 
 		let data = default_nft_data();
 		assert_noop!(
-			TemplateModule::create_item(origin1, 1, account(1), data.into()),
-			Error::<Test>::AccountTokenLimitExceeded
+			TemplateModule::create_item(origin1, CollectionId(1), account(1), data.into()),
+			CommonError::<Test>::AccountTokenLimitExceeded
 		);
 	});
 }
@@ -1764,7 +1739,7 @@
 #[test]
 fn collection_admins_bound() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
@@ -1785,7 +1760,7 @@
 #[test]
 fn collection_admins_bound_neg() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
@@ -1793,16 +1768,16 @@
 			assert_ok!(TemplateModule::add_collection_admin(
 				origin1.clone(),
 				collection_id,
-				account(2 + i)
+				account((2 + i).into())
 			));
 		}
 		assert_noop!(
 			TemplateModule::add_collection_admin(
 				origin1,
 				collection_id,
-				account(3 + COLLECTION_ADMINS_LIMIT)
+				account((3 + COLLECTION_ADMINS_LIMIT).into())
 			),
-			Error::<Test>::CollectionAdminsLimitExceeded
+			CommonError::<Test>::CollectionAdminCountExceeded
 		);
 	});
 }
@@ -1811,7 +1786,7 @@
 #[test]
 fn set_const_on_chain_schema() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		assert_ok!(TemplateModule::set_const_on_chain_schema(
@@ -1821,13 +1796,13 @@
 		));
 
 		assert_eq!(
-			TemplateModule::collection_id(collection_id)
+			<pallet_common::CollectionById<Test>>::get(collection_id)
 				.unwrap()
 				.const_on_chain_schema,
 			b"test const on chain schema".to_vec()
 		);
 		assert_eq!(
-			TemplateModule::collection_id(collection_id)
+			<pallet_common::CollectionById<Test>>::get(collection_id)
 				.unwrap()
 				.variable_on_chain_schema,
 			b"".to_vec()
@@ -1838,7 +1813,7 @@
 #[test]
 fn set_variable_on_chain_schema() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		assert_ok!(TemplateModule::set_variable_on_chain_schema(
@@ -1848,13 +1823,13 @@
 		));
 
 		assert_eq!(
-			TemplateModule::collection_id(collection_id)
+			<pallet_common::CollectionById<Test>>::get(collection_id)
 				.unwrap()
 				.const_on_chain_schema,
 			b"".to_vec()
 		);
 		assert_eq!(
-			TemplateModule::collection_id(collection_id)
+			<pallet_common::CollectionById<Test>>::get(collection_id)
 				.unwrap()
 				.variable_on_chain_schema,
 			b"test variable on chain schema".to_vec()
@@ -1865,23 +1840,23 @@
 #[test]
 fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
 		let data = default_nft_data();
-		create_test_item(1, &data.into());
+		create_test_item(CollectionId(1), &data.into());
 
 		let variable_data = b"test data".to_vec();
 		assert_ok!(TemplateModule::set_variable_meta_data(
 			origin1,
 			collection_id,
-			1,
+			TokenId(1),
 			variable_data.clone()
 		));
 
 		assert_eq!(
-			TemplateModule::nft_item_id(collection_id, 1)
+			<pallet_nonfungible::TokenData<Test>>::get((collection_id, 1))
 				.unwrap()
 				.variable_data,
 			variable_data
@@ -1892,24 +1867,23 @@
 #[test]
 fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
+		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
 		let data = default_re_fungible_data();
-		create_test_item(1, &data.into());
+		create_test_item(collection_id, &data.into());
 
 		let variable_data = b"test data".to_vec();
 		assert_ok!(TemplateModule::set_variable_meta_data(
 			origin1,
 			collection_id,
-			1,
+			TokenId(1),
 			variable_data.clone()
 		));
 
 		assert_eq!(
-			TemplateModule::refungible_item_id(collection_id, 1)
-				.unwrap()
+			<pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)))
 				.variable_data,
 			variable_data
 		);
@@ -1919,17 +1893,17 @@
 #[test]
 fn set_variable_meta_data_on_fungible_token_fails() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
+		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
 		let data = default_fungible_data();
-		create_test_item(1, &data.into());
+		create_test_item(collection_id, &data.into());
 
 		let variable_data = b"test data".to_vec();
 		assert_noop!(
-			TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),
-			Error::<Test>::CantStoreMetadataInFungibleTokens
+			TemplateModule::set_variable_meta_data(origin1, collection_id, TokenId(1), variable_data),
+			<pallet_fungible::Error<Test>>::FungibleItemsDontHaveData
 		);
 	});
 }
@@ -1937,17 +1911,17 @@
 #[test]
 fn set_variable_meta_data_on_nft_token_fails_for_big_data() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
 		let data = default_nft_data();
-		create_test_item(1, &data.into());
+		create_test_item(collection_id, &data.into());
 
 		let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();
 		assert_noop!(
-			TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),
-			Error::<Test>::TokenVariableDataLimitExceeded
+			TemplateModule::set_variable_meta_data(origin1, collection_id, TokenId(1), variable_data),
+			CommonError::<Test>::TokenVariableDataLimitExceeded
 		);
 	});
 }
@@ -1955,17 +1929,17 @@
 #[test]
 fn set_variable_meta_data_on_re_fungible_token_fails_for_big_data() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
+		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
 		let data = default_re_fungible_data();
-		create_test_item(1, &data.into());
+		create_test_item(collection_id, &data.into());
 
 		let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();
 		assert_noop!(
-			TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),
-			Error::<Test>::TokenVariableDataLimitExceeded
+			TemplateModule::set_variable_meta_data(origin1, collection_id, TokenId(1), variable_data),
+			CommonError::<Test>::TokenVariableDataLimitExceeded
 		);
 	});
 }
@@ -1975,12 +1949,12 @@
 	new_test_ext().execute_with(|| {
 		//default_limits();
 
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
 		let data = default_nft_data();
-		create_test_item(1, &data.into());
+		create_test_item(collection_id, &data.into());
 
 		assert_ok!(TemplateModule::set_meta_update_permission_flag(
 			origin1.clone(),
@@ -1992,12 +1966,12 @@
 		assert_ok!(TemplateModule::set_variable_meta_data(
 			origin1,
 			collection_id,
-			1,
+			TokenId(1),
 			variable_data.clone()
 		));
 
 		assert_eq!(
-			TemplateModule::nft_item_id(collection_id, 1)
+			<pallet_nonfungible::TokenData<Test>>::get((collection_id, TokenId(1)))
 				.unwrap()
 				.variable_data,
 			variable_data
@@ -2008,7 +1982,7 @@
 #[test]
 fn set_variable_meta_data_on_nft_with_item_owner_permission_flag_neg() {
 	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);
+		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 
@@ -2024,7 +1998,7 @@
 		));
 
 		let data = default_nft_data();
-		create_test_item(1, &data.into());
+		create_test_item(collection_id, &data.into());
 
 		assert_ok!(TemplateModule::set_meta_update_permission_flag(
 			origin1.clone(),
@@ -2037,10 +2011,10 @@
 			TemplateModule::set_variable_meta_data(
 				origin1,
 				collection_id,
-				1,
+				TokenId(1),
 				variable_data.clone()
 			),
-			Error::<Test>::TokenVariableDataLimitExceeded
+			CommonError::<Test>::TokenVariableDataLimitExceeded
 		);
 	})
 }
@@ -2050,23 +2024,22 @@
 	new_test_ext().execute_with(|| {
 		let origin1 = Origin::signed(1);
 
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
-		assert_ok!(TemplateModule::set_transfers_enabled_flag(origin1, 1, true));
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
+		assert_ok!(TemplateModule::set_transfers_enabled_flag(origin1, collection_id, true));
 
 		let data = default_nft_data();
 		create_test_item(collection_id, &data.into());
-		assert_eq!(TemplateModule::balance_count(1, 1), 1);
-		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
+		assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
 
 		let origin1 = Origin::signed(1);
 
 		// default scenario
-		assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1000));
-		assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(2));
-		assert_eq!(TemplateModule::balance_count(1, 1), 0);
-		assert_eq!(TemplateModule::balance_count(1, 2), 1);
-
-		assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
+		assert_ok!(TemplateModule::transfer(origin1, account(2), collection_id, TokenId(1), 1000));
+		assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), false);
+		assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))), true);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 0);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))), 1);
 	});
 }
 
@@ -2075,7 +2048,7 @@
 	new_test_ext().execute_with(|| {
 		// default_limits();
 
-		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);
+		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -2098,7 +2071,7 @@
 		));
 
 		let data = default_nft_data();
-		create_test_item(1, &data.into());
+		create_test_item(collection_id, &data.into());
 
 		assert_ok!(TemplateModule::set_meta_update_permission_flag(
 			origin2.clone(),
@@ -2110,12 +2083,12 @@
 		assert_ok!(TemplateModule::set_variable_meta_data(
 			origin1,
 			collection_id,
-			1,
+			TokenId(1),
 			variable_data.clone()
 		));
 
 		assert_eq!(
-			TemplateModule::nft_item_id(collection_id, 1)
+			<pallet_nonfungible::TokenData<Test>>::get((collection_id, 1))
 				.unwrap()
 				.variable_data,
 			variable_data
@@ -2128,7 +2101,7 @@
 	new_test_ext().execute_with(|| {
 		// default_limits();
 
-		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);
+		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(1));
 
 		let origin1 = Origin::signed(1);
 		let origin2 = Origin::signed(2);
@@ -2145,7 +2118,7 @@
 		));
 
 		let data = default_nft_data();
-		create_test_item(1, &data.into());
+		create_test_item(collection_id, &data.into());
 
 		assert_ok!(TemplateModule::set_meta_update_permission_flag(
 			origin2.clone(),
@@ -2158,10 +2131,10 @@
 			TemplateModule::set_variable_meta_data(
 				origin1,
 				collection_id,
-				1,
+				TokenId(1),
 				variable_data.clone()
 			),
-			Error::<Test>::NoPermission
+			CommonError::<Test>::NoPermission
 		);
 	});
 }
@@ -2171,7 +2144,7 @@
 	new_test_ext().execute_with(|| {
 		// default_limits();
 
-		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);
+		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(1));
 
 		let origin2 = Origin::signed(2);
 
@@ -2186,7 +2159,7 @@
 				collection_id,
 				MetaUpdatePermission::Admin
 			),
-			Error::<Test>::MetadataFlagFrozen
+			CommonError::<Test>::MetadataFlagFrozen
 		);
 	});
 }
@@ -2196,11 +2169,11 @@
 	new_test_ext().execute_with(|| {
 		// default_limits();
 
-		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);
+		let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));
 		let origin1 = Origin::signed(1);
 
 		let data = default_nft_data();
-		create_test_item(1, &data.into());
+		create_test_item(collection_id, &data.into());
 
 		assert_ok!(TemplateModule::set_meta_update_permission_flag(
 			origin1.clone(),
@@ -2213,10 +2186,10 @@
 			TemplateModule::set_variable_meta_data(
 				origin1.clone(),
 				collection_id,
-				1,
+				TokenId(1),
 				variable_data.clone()
 			),
-			Error::<Test>::MetadataUpdateDenied
+			CommonError::<Test>::NoPermission
 		);
 	});
 }
@@ -2226,27 +2199,26 @@
 	new_test_ext().execute_with(|| {
 		let origin1 = Origin::signed(1);
 
-		let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
 		assert_ok!(TemplateModule::set_transfers_enabled_flag(
-			origin1, 1, false
+			origin1, collection_id, false
 		));
 
 		let data = default_nft_data();
 		create_test_item(collection_id, &data.into());
-		assert_eq!(TemplateModule::balance_count(1, 1), 1);
-		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
+		assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
 
 		let origin1 = Origin::signed(1);
 
 		// default scenario
 		assert_noop!(
-			TemplateModule::transfer(origin1, account(2), 1, 1, 1000),
-			Error::<Test>::TransferNotAllowed
+			TemplateModule::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1000),
+			CommonError::<Test>::TransferNotAllowed
 		);
-		assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(1));
-		assert_eq!(TemplateModule::balance_count(1, 1), 1);
-		assert_eq!(TemplateModule::balance_count(1, 2), 0);
-
-		assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
+		assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))), 0);
+		assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
+		assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))), false);
 	});
 }
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
before · pallets/nonfungible/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23use erc::ERC721Events;4use frame_support::{BoundedVec, ensure};5use nft_data_structs::{6	AccessMode, CUSTOM_DATA_LIMIT, Collection, CollectionId, CustomDataLimit, TokenId,7};8use pallet_common::{9	Error as CommonError, Pallet as PalletCommon, Event as CommonEvent, account::CrossAccountId,10};11use sp_core::H160;12use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};13use sp_std::{vec::Vec, vec};14use core::ops::Deref;15use sp_std::collections::btree_map::BTreeMap;16use codec::{Encode, Decode};17use scale_info::TypeInfo;1819pub use pallet::*;20#[cfg(feature = "runtime-benchmarks")]21pub mod benchmarking;22pub mod common;23pub mod erc;24pub mod weights;2526pub struct CreateItemData<T: Config> {27	pub const_data: BoundedVec<u8, CustomDataLimit>,28	pub variable_data: BoundedVec<u8, CustomDataLimit>,29	pub owner: T::CrossAccountId,30}31pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;3233#[derive(Encode, Decode, TypeInfo)]34pub struct ItemData<T: Config> {35	pub const_data: Vec<u8>,36	pub variable_data: Vec<u8>,37	pub owner: T::CrossAccountId,38}3940#[frame_support::pallet]41pub mod pallet {42	use super::*;43	use frame_support::{Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key};44	use nft_data_structs::{CollectionId, TokenId};45	use super::weights::WeightInfo;4647	#[pallet::error]48	pub enum Error<T> {49		/// Not Nonfungible item data used to mint in Nonfungible collection.50		NotNonfungibleDataUsedToMintFungibleCollectionToken,51		/// Used amount > 1 with NFT52		NonfungibleItemsHaveNoAmount,53	}5455	#[pallet::config]56	pub trait Config: frame_system::Config + pallet_common::Config {57		type WeightInfo: WeightInfo;58	}5960	#[pallet::pallet]61	#[pallet::generate_store(pub(super) trait Store)]62	pub struct Pallet<T>(_);6364	#[pallet::storage]65	pub(super) type TokensMinted<T: Config> =66		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;67	#[pallet::storage]68	pub(super) type TokensBurnt<T: Config> =69		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;7071	#[pallet::storage]72	pub(super) type TokenData<T: Config> = StorageNMap<73		Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),74		Value = ItemData<T>,75		QueryKind = OptionQuery,76	>;7778	/// Used to enumerate tokens owned by account79	#[pallet::storage]80	pub(super) type Owned<T: Config> = StorageNMap<81		Key = (82			Key<Twox64Concat, CollectionId>,83			Key<Blake2_128Concat, T::CrossAccountId>,84			Key<Twox64Concat, TokenId>,85		),86		Value = bool,87		QueryKind = ValueQuery,88	>;8990	#[pallet::storage]91	pub(super) type AccountBalance<T: Config> = StorageNMap<92		Key = (93			Key<Twox64Concat, CollectionId>,94			Key<Blake2_128Concat, T::CrossAccountId>,95		),96		Value = u32,97		QueryKind = ValueQuery,98	>;99100	#[pallet::storage]101	pub(super) type Allowance<T: Config> = StorageNMap<102		Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),103		Value = T::CrossAccountId,104		QueryKind = OptionQuery,105	>;106}107108pub struct NonfungibleHandle<T: Config>(pallet_common::CollectionHandle<T>);109impl<T: Config> NonfungibleHandle<T> {110	pub fn cast(inner: pallet_common::CollectionHandle<T>) -> Self {111		Self(inner)112	}113	pub fn into_inner(self) -> pallet_common::CollectionHandle<T> {114		self.0115	}116}117impl<T: Config> Deref for NonfungibleHandle<T> {118	type Target = pallet_common::CollectionHandle<T>;119120	fn deref(&self) -> &Self::Target {121		&self.0122	}123}124125impl<T: Config> Pallet<T> {126	pub fn total_supply(collection: &NonfungibleHandle<T>) -> u32 {127		<TokensMinted<T>>::get(collection.id) - <TokensBurnt<T>>::get(collection.id)128	}129	pub fn token_exists(collection: &NonfungibleHandle<T>, token: TokenId) -> bool {130		<TokenData<T>>::contains_key((collection.id, token))131	}132}133134// unchecked calls skips any permission checks135impl<T: Config> Pallet<T> {136	pub fn init_collection(data: Collection<T>) -> Result<CollectionId, DispatchError> {137		PalletCommon::init_collection(data)138	}139	pub fn destroy_collection(140		collection: NonfungibleHandle<T>,141		sender: &T::CrossAccountId,142	) -> DispatchResult {143		let id = collection.id;144145		// =========146147		PalletCommon::destroy_collection(collection.0, sender)?;148149		<TokenData<T>>::remove_prefix((id,), None);150		<Owned<T>>::remove_prefix((id,), None);151		<TokensMinted<T>>::remove(id);152		<TokensBurnt<T>>::remove(id);153		<Allowance<T>>::remove_prefix((id,), None);154		<AccountBalance<T>>::remove_prefix((id,), None);155		Ok(())156	}157158	pub fn burn(159		collection: &NonfungibleHandle<T>,160		sender: &T::CrossAccountId,161		token: TokenId,162	) -> DispatchResult {163		let token_data = <TokenData<T>>::get((collection.id, token))164			.ok_or_else(|| <CommonError<T>>::TokenNotFound)?;165		ensure!(166			&token_data.owner == sender167				|| (collection.limits.owner_can_transfer()168					&& collection.is_owner_or_admin(sender)?),169			<CommonError<T>>::NoPermission170		);171172		if collection.access == AccessMode::AllowList {173			collection.check_allowlist(sender)?;174		}175176		let burnt = <TokensBurnt<T>>::get(collection.id)177			.checked_add(1)178			.ok_or(ArithmeticError::Overflow)?;179180		// =========181182		<Owned<T>>::remove((collection.id, &token_data.owner, token));183		<TokensBurnt<T>>::insert(collection.id, burnt);184		<TokenData<T>>::remove((collection.id, token));185		let old_spender = <Allowance<T>>::take((collection.id, token));186187		if let Some(old_spender) = old_spender {188			<PalletCommon<T>>::deposit_event(CommonEvent::Approved(189				collection.id,190				token,191				sender.clone(),192				old_spender.clone(),193				0,194			));195		}196197		collection.log_infallible(ERC721Events::Transfer {198			from: *token_data.owner.as_eth(),199			to: H160::default(),200			token_id: token.into(),201		});202		<PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(203			collection.id,204			token,205			token_data.owner,206			1,207		));208		return Ok(());209	}210211	pub fn transfer(212		collection: &NonfungibleHandle<T>,213		from: &T::CrossAccountId,214		to: &T::CrossAccountId,215		token: TokenId,216	) -> DispatchResult {217		ensure!(218			collection.limits.transfers_enabled(),219			<CommonError<T>>::TransferNotAllowed220		);221222		let token_data = <TokenData<T>>::get((collection.id, token))223			.ok_or_else(|| <CommonError<T>>::TokenNotFound)?;224		ensure!(225			&token_data.owner == from226				|| (collection.limits.owner_can_transfer()227					&& collection.is_owner_or_admin(from)?),228			<CommonError<T>>::NoPermission229		);230231		if collection.access == AccessMode::AllowList {232			collection.check_allowlist(from)?;233			collection.check_allowlist(to)?;234		}235		<PalletCommon<T>>::ensure_correct_receiver(to)?;236237		let balance_from = <AccountBalance<T>>::get((collection.id, from))238			.checked_sub(1)239			.ok_or(<CommonError<T>>::TokenValueTooLow)?;240		let balance_to = if from != to {241			let balance_to = <AccountBalance<T>>::get((collection.id, to))242				.checked_add(1)243				.ok_or(ArithmeticError::Overflow)?;244245			ensure!(246				balance_to < collection.limits.account_token_ownership_limit(),247				<CommonError<T>>::AccountTokenLimitExceeded,248			);249250			Some(balance_to)251		} else {252			None253		};254255		collection.consume_sstores(4)?;256		collection.consume_log(3, 0)?;257258		// =========259260		<TokenData<T>>::insert(261			(collection.id, token),262			ItemData {263				owner: to.clone(),264				..token_data265			},266		);267268		if let Some(balance_to) = balance_to {269			// from != to270			if balance_from == 0 {271				<AccountBalance<T>>::remove((collection.id, from));272			} else {273				<AccountBalance<T>>::insert((collection.id, from), balance_from);274			}275			<AccountBalance<T>>::insert((collection.id, to), balance_to);276			<Owned<T>>::remove((collection.id, from, token));277			<Owned<T>>::insert((collection.id, to, token), true);278		}279		Self::set_allowance_unchecked(collection, from, token, None, true);280281		collection.log_infallible(ERC721Events::Transfer {282			from: *from.as_eth(),283			to: *to.as_eth(),284			token_id: token.into(),285		});286		<PalletCommon<T>>::deposit_event(CommonEvent::Transfer(287			collection.id,288			token,289			from.clone(),290			to.clone(),291			1,292		));293		Ok(())294	}295296	pub fn create_multiple_items(297		collection: &NonfungibleHandle<T>,298		sender: &T::CrossAccountId,299		data: Vec<CreateItemData<T>>,300	) -> DispatchResult {301		let unrestricted_minting = collection.is_owner_or_admin(sender)?;302		if !unrestricted_minting {303			ensure!(304				collection.mint_mode,305				<CommonError<T>>::PublicMintingNotAllowed306			);307			collection.check_allowlist(sender)?;308309			for item in data.iter() {310				collection.check_allowlist(&item.owner)?;311			}312		}313314		for data in data.iter() {315			<PalletCommon<T>>::ensure_correct_receiver(&data.owner)?;316			if !data.const_data.is_empty() {317				collection.consume_sstore()?;318			}319			if !data.variable_data.is_empty() {320				collection.consume_sstore()?;321			}322			collection.consume_sstore()?;323			collection.consume_log(3, 0)?;324		}325326		let first_token = <TokensMinted<T>>::get(collection.id);327		let tokens_minted = first_token328			.checked_add(data.len() as u32)329			.ok_or(ArithmeticError::Overflow)?;330		ensure!(331			tokens_minted <= collection.limits.token_limit(),332			<CommonError<T>>::CollectionTokenLimitExceeded333		);334		collection.consume_sstore()?;335336		let mut balances = BTreeMap::new();337		for data in &data {338			let balance = balances339				.entry(&data.owner)340				.or_insert_with(|| <AccountBalance<T>>::get((collection.id, &data.owner)));341			*balance = balance.checked_add(1).ok_or(ArithmeticError::Overflow)?;342343			ensure!(344				*balance <= collection.limits.account_token_ownership_limit(),345				<CommonError<T>>::AccountTokenLimitExceeded,346			);347		}348		collection.consume_sstores(balances.len())?;349350		// =========351352		<TokensMinted<T>>::insert(collection.id, tokens_minted);353		for (account, balance) in balances {354			<AccountBalance<T>>::insert((collection.id, account), balance);355		}356		for (i, data) in data.into_iter().enumerate() {357			let token = first_token + i as u32 + 1;358359			<TokenData<T>>::insert(360				(collection.id, token),361				ItemData {362					const_data: data.const_data.into(),363					variable_data: data.variable_data.into(),364					owner: data.owner.clone(),365				},366			);367			<Owned<T>>::insert((collection.id, &data.owner, token), true);368369			collection.log_infallible(ERC721Events::Transfer {370				from: H160::default(),371				to: *data.owner.as_eth(),372				token_id: token.into(),373			});374			<PalletCommon<T>>::deposit_event(CommonEvent::ItemCreated(375				collection.id,376				TokenId(token),377				data.owner.clone(),378				1,379			));380		}381		Ok(())382	}383384	pub fn set_allowance_unchecked(385		collection: &NonfungibleHandle<T>,386		sender: &T::CrossAccountId,387		token: TokenId,388		spender: Option<&T::CrossAccountId>,389		assume_implicit_eth: bool,390	) {391		if let Some(spender) = spender {392			let old_spender = <Allowance<T>>::get((collection.id, token));393			<Allowance<T>>::insert((collection.id, token), spender);394			// In ERC721 there is only one possible approved user of token, so we set395			// approved user to spender396			collection.log_infallible(ERC721Events::Approval {397				owner: *sender.as_eth(),398				approved: *spender.as_eth(),399				token_id: token.into(),400			});401			// In Unique chain, any token can have any amount of approved users, so we need to402			// set allowance of old owner to 0, and allowance of new owner to 1403			if old_spender.as_ref() != Some(spender) {404				if let Some(old_owner) = old_spender {405					<PalletCommon<T>>::deposit_event(CommonEvent::Approved(406						collection.id,407						token,408						sender.clone(),409						old_owner.clone(),410						0,411					));412				}413				<PalletCommon<T>>::deposit_event(CommonEvent::Approved(414					collection.id,415					token,416					sender.clone(),417					spender.clone(),418					1,419				));420			}421		} else {422			let old_spender = <Allowance<T>>::take((collection.id, token));423			if !assume_implicit_eth {424				// In ERC721 there is only one possible approved user of token, so we set425				// approved user to zero address426				collection.log_infallible(ERC721Events::Approval {427					owner: *sender.as_eth(),428					approved: H160::default(),429					token_id: token.into(),430				});431			}432			// In Unique chain, any token can have any amount of approved users, so we need to433			// set allowance of old owner to 0434			if let Some(old_spender) = old_spender {435				<PalletCommon<T>>::deposit_event(CommonEvent::Approved(436					collection.id,437					token,438					sender.clone(),439					old_spender.clone(),440					0,441				));442			}443		}444	}445446	pub fn set_allowance(447		collection: &NonfungibleHandle<T>,448		sender: &T::CrossAccountId,449		token: TokenId,450		spender: Option<&T::CrossAccountId>,451	) -> DispatchResult {452		if collection.access == AccessMode::AllowList {453			collection.check_allowlist(&sender)?;454			if let Some(spender) = spender {455				collection.check_allowlist(&spender)?;456			}457		}458459		if let Some(spender) = spender {460			<PalletCommon<T>>::ensure_correct_receiver(spender)?;461		}462		let token_data =463			<TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;464		if &token_data.owner != sender {465			ensure!(466				collection.ignores_owned_amount(sender)?,467				<CommonError<T>>::CantApproveMoreThanOwned468			);469		}470471		// =========472473		Self::set_allowance_unchecked(collection, sender, token, spender, false);474		Ok(())475	}476477	pub fn transfer_from(478		collection: &NonfungibleHandle<T>,479		spender: &T::CrossAccountId,480		from: &T::CrossAccountId,481		to: &T::CrossAccountId,482		token: TokenId,483	) -> DispatchResult {484		if spender.conv_eq(from) {485			return Self::transfer(collection, from, to, token);486		}487		if collection.access == AccessMode::AllowList {488			// `from`, `to` checked in [`transfer`]489			collection.check_allowlist(spender)?;490		}491492		if <Allowance<T>>::get((collection.id, token)).as_ref() != Some(spender) {493			ensure!(494				collection.ignores_allowance(spender)?,495				<CommonError<T>>::TokenValueNotEnough496			);497		}498499		// =========500501		Self::transfer(collection, &from, to, token)?;502		// Allowance is reset in [`transfer`]503		Ok(())504	}505506	pub fn burn_from(507		collection: &NonfungibleHandle<T>,508		spender: &T::CrossAccountId,509		from: &T::CrossAccountId,510		token: TokenId,511	) -> DispatchResult {512		if spender.conv_eq(from) {513			return Self::burn(collection, from, token);514		}515		if collection.access == AccessMode::AllowList {516			// `from` checked in [`burn`]517			collection.check_allowlist(spender)?;518		}519520		if <Allowance<T>>::get((collection.id, token)).as_ref() != Some(spender) {521			ensure!(522				collection.ignores_allowance(spender)?,523				<CommonError<T>>::TokenValueNotEnough524			);525		}526527		// =========528529		Self::burn(collection, &from, token)530	}531532	pub fn set_variable_metadata(533		collection: &NonfungibleHandle<T>,534		sender: &T::CrossAccountId,535		token: TokenId,536		data: Vec<u8>,537	) -> DispatchResult {538		ensure!(539			data.len() as u32 <= CUSTOM_DATA_LIMIT,540			<CommonError<T>>::TokenVariableDataLimitExceeded541		);542		let token_data =543			<TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;544		collection.check_can_update_meta(sender, &token_data.owner)?;545546		collection.consume_sstore()?;547548		// =========549550		<TokenData<T>>::insert(551			(collection.id, token),552			ItemData {553				variable_data: data,554				..token_data555			},556		);557		Ok(())558	}559560	/// Delegated to `create_multiple_items`561	pub fn create_item(562		collection: &NonfungibleHandle<T>,563		sender: &T::CrossAccountId,564		data: CreateItemData<T>,565	) -> DispatchResult {566		Self::create_multiple_items(collection, sender, vec![data])567	}568}
after · pallets/nonfungible/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23use erc::ERC721Events;4use frame_support::{BoundedVec, ensure};5use nft_data_structs::{6	AccessMode, CUSTOM_DATA_LIMIT, Collection, CollectionId, CustomDataLimit, TokenId,7};8use pallet_common::{9	Error as CommonError, Pallet as PalletCommon, Event as CommonEvent, account::CrossAccountId,10};11use sp_core::H160;12use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};13use sp_std::{vec::Vec, vec};14use core::ops::Deref;15use sp_std::collections::btree_map::BTreeMap;16use codec::{Encode, Decode};17use scale_info::TypeInfo;1819pub use pallet::*;20#[cfg(feature = "runtime-benchmarks")]21pub mod benchmarking;22pub mod common;23pub mod erc;24pub mod weights;2526pub struct CreateItemData<T: Config> {27	pub const_data: BoundedVec<u8, CustomDataLimit>,28	pub variable_data: BoundedVec<u8, CustomDataLimit>,29	pub owner: T::CrossAccountId,30}31pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;3233#[derive(Encode, Decode, TypeInfo)]34pub struct ItemData<T: Config> {35	pub const_data: Vec<u8>,36	pub variable_data: Vec<u8>,37	pub owner: T::CrossAccountId,38}3940#[frame_support::pallet]41pub mod pallet {42	use super::*;43	use frame_support::{Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key};44	use nft_data_structs::{CollectionId, TokenId};45	use super::weights::WeightInfo;4647	#[pallet::error]48	pub enum Error<T> {49		/// Not Nonfungible item data used to mint in Nonfungible collection.50		NotNonfungibleDataUsedToMintFungibleCollectionToken,51		/// Used amount > 1 with NFT52		NonfungibleItemsHaveNoAmount,53	}5455	#[pallet::config]56	pub trait Config: frame_system::Config + pallet_common::Config {57		type WeightInfo: WeightInfo;58	}5960	#[pallet::pallet]61	#[pallet::generate_store(pub trait Store)]62	pub struct Pallet<T>(_);6364	#[pallet::storage]65	pub type TokensMinted<T: Config> =66		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;67	#[pallet::storage]68	pub type TokensBurnt<T: Config> =69		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;7071	#[pallet::storage]72	pub type TokenData<T: Config> = StorageNMap<73		Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),74		Value = ItemData<T>,75		QueryKind = OptionQuery,76	>;7778	/// Used to enumerate tokens owned by account79	#[pallet::storage]80	pub type Owned<T: Config> = StorageNMap<81		Key = (82			Key<Twox64Concat, CollectionId>,83			Key<Blake2_128Concat, T::CrossAccountId>,84			Key<Twox64Concat, TokenId>,85		),86		Value = bool,87		QueryKind = ValueQuery,88	>;8990	#[pallet::storage]91	pub type AccountBalance<T: Config> = StorageNMap<92		Key = (93			Key<Twox64Concat, CollectionId>,94			Key<Blake2_128Concat, T::CrossAccountId>,95		),96		Value = u32,97		QueryKind = ValueQuery,98	>;99100	#[pallet::storage]101	pub type Allowance<T: Config> = StorageNMap<102		Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),103		Value = T::CrossAccountId,104		QueryKind = OptionQuery,105	>;106}107108pub struct NonfungibleHandle<T: Config>(pallet_common::CollectionHandle<T>);109impl<T: Config> NonfungibleHandle<T> {110	pub fn cast(inner: pallet_common::CollectionHandle<T>) -> Self {111		Self(inner)112	}113	pub fn into_inner(self) -> pallet_common::CollectionHandle<T> {114		self.0115	}116}117impl<T: Config> Deref for NonfungibleHandle<T> {118	type Target = pallet_common::CollectionHandle<T>;119120	fn deref(&self) -> &Self::Target {121		&self.0122	}123}124125impl<T: Config> Pallet<T> {126	pub fn total_supply(collection: &NonfungibleHandle<T>) -> u32 {127		<TokensMinted<T>>::get(collection.id) - <TokensBurnt<T>>::get(collection.id)128	}129	pub fn token_exists(collection: &NonfungibleHandle<T>, token: TokenId) -> bool {130		<TokenData<T>>::contains_key((collection.id, token))131	}132}133134// unchecked calls skips any permission checks135impl<T: Config> Pallet<T> {136	pub fn init_collection(data: Collection<T>) -> Result<CollectionId, DispatchError> {137		PalletCommon::init_collection(data)138	}139	pub fn destroy_collection(140		collection: NonfungibleHandle<T>,141		sender: &T::CrossAccountId,142	) -> DispatchResult {143		let id = collection.id;144145		// =========146147		PalletCommon::destroy_collection(collection.0, sender)?;148149		<TokenData<T>>::remove_prefix((id,), None);150		<Owned<T>>::remove_prefix((id,), None);151		<TokensMinted<T>>::remove(id);152		<TokensBurnt<T>>::remove(id);153		<Allowance<T>>::remove_prefix((id,), None);154		<AccountBalance<T>>::remove_prefix((id,), None);155		Ok(())156	}157158	pub fn burn(159		collection: &NonfungibleHandle<T>,160		sender: &T::CrossAccountId,161		token: TokenId,162	) -> DispatchResult {163		let token_data = <TokenData<T>>::get((collection.id, token))164			.ok_or_else(|| <CommonError<T>>::TokenNotFound)?;165		ensure!(166			&token_data.owner == sender167				|| (collection.limits.owner_can_transfer()168					&& collection.is_owner_or_admin(sender)?),169			<CommonError<T>>::NoPermission170		);171172		if collection.access == AccessMode::AllowList {173			collection.check_allowlist(sender)?;174		}175176		let burnt = <TokensBurnt<T>>::get(collection.id)177			.checked_add(1)178			.ok_or(ArithmeticError::Overflow)?;179180		// =========181182		<Owned<T>>::remove((collection.id, &token_data.owner, token));183		<TokensBurnt<T>>::insert(collection.id, burnt);184		<TokenData<T>>::remove((collection.id, token));185		let old_spender = <Allowance<T>>::take((collection.id, token));186187		if let Some(old_spender) = old_spender {188			<PalletCommon<T>>::deposit_event(CommonEvent::Approved(189				collection.id,190				token,191				sender.clone(),192				old_spender.clone(),193				0,194			));195		}196197		collection.log_infallible(ERC721Events::Transfer {198			from: *token_data.owner.as_eth(),199			to: H160::default(),200			token_id: token.into(),201		});202		<PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(203			collection.id,204			token,205			token_data.owner,206			1,207		));208		return Ok(());209	}210211	pub fn transfer(212		collection: &NonfungibleHandle<T>,213		from: &T::CrossAccountId,214		to: &T::CrossAccountId,215		token: TokenId,216	) -> DispatchResult {217		ensure!(218			collection.limits.transfers_enabled(),219			<CommonError<T>>::TransferNotAllowed220		);221222		let token_data = <TokenData<T>>::get((collection.id, token))223			.ok_or_else(|| <CommonError<T>>::TokenNotFound)?;224		ensure!(225			&token_data.owner == from226				|| (collection.limits.owner_can_transfer()227					&& collection.is_owner_or_admin(from)?),228			<CommonError<T>>::NoPermission229		);230231		if collection.access == AccessMode::AllowList {232			collection.check_allowlist(from)?;233			collection.check_allowlist(to)?;234		}235		<PalletCommon<T>>::ensure_correct_receiver(to)?;236237		let balance_from = <AccountBalance<T>>::get((collection.id, from))238			.checked_sub(1)239			.ok_or(<CommonError<T>>::TokenValueTooLow)?;240		let balance_to = if from != to {241			let balance_to = <AccountBalance<T>>::get((collection.id, to))242				.checked_add(1)243				.ok_or(ArithmeticError::Overflow)?;244245			ensure!(246				balance_to < collection.limits.account_token_ownership_limit(),247				<CommonError<T>>::AccountTokenLimitExceeded,248			);249250			Some(balance_to)251		} else {252			None253		};254255		collection.consume_sstores(4)?;256		collection.consume_log(3, 0)?;257258		// =========259260		<TokenData<T>>::insert(261			(collection.id, token),262			ItemData {263				owner: to.clone(),264				..token_data265			},266		);267268		if let Some(balance_to) = balance_to {269			// from != to270			if balance_from == 0 {271				<AccountBalance<T>>::remove((collection.id, from));272			} else {273				<AccountBalance<T>>::insert((collection.id, from), balance_from);274			}275			<AccountBalance<T>>::insert((collection.id, to), balance_to);276			<Owned<T>>::remove((collection.id, from, token));277			<Owned<T>>::insert((collection.id, to, token), true);278		}279		Self::set_allowance_unchecked(collection, from, token, None, true);280281		collection.log_infallible(ERC721Events::Transfer {282			from: *from.as_eth(),283			to: *to.as_eth(),284			token_id: token.into(),285		});286		<PalletCommon<T>>::deposit_event(CommonEvent::Transfer(287			collection.id,288			token,289			from.clone(),290			to.clone(),291			1,292		));293		Ok(())294	}295296	pub fn create_multiple_items(297		collection: &NonfungibleHandle<T>,298		sender: &T::CrossAccountId,299		data: Vec<CreateItemData<T>>,300	) -> DispatchResult {301		let unrestricted_minting = collection.is_owner_or_admin(sender)?;302		if !unrestricted_minting {303			ensure!(304				collection.mint_mode,305				<CommonError<T>>::PublicMintingNotAllowed306			);307			collection.check_allowlist(sender)?;308309			for item in data.iter() {310				collection.check_allowlist(&item.owner)?;311			}312		}313314		for data in data.iter() {315			<PalletCommon<T>>::ensure_correct_receiver(&data.owner)?;316			if !data.const_data.is_empty() {317				collection.consume_sstore()?;318			}319			if !data.variable_data.is_empty() {320				collection.consume_sstore()?;321			}322			collection.consume_sstore()?;323			collection.consume_log(3, 0)?;324		}325326		let first_token = <TokensMinted<T>>::get(collection.id);327		let tokens_minted = first_token328			.checked_add(data.len() as u32)329			.ok_or(ArithmeticError::Overflow)?;330		ensure!(331			tokens_minted <= collection.limits.token_limit(),332			<CommonError<T>>::CollectionTokenLimitExceeded333		);334		collection.consume_sstore()?;335336		let mut balances = BTreeMap::new();337		for data in &data {338			let balance = balances339				.entry(&data.owner)340				.or_insert_with(|| <AccountBalance<T>>::get((collection.id, &data.owner)));341			*balance = balance.checked_add(1).ok_or(ArithmeticError::Overflow)?;342343			ensure!(344				*balance <= collection.limits.account_token_ownership_limit(),345				<CommonError<T>>::AccountTokenLimitExceeded,346			);347		}348		collection.consume_sstores(balances.len())?;349350		// =========351352		<TokensMinted<T>>::insert(collection.id, tokens_minted);353		for (account, balance) in balances {354			<AccountBalance<T>>::insert((collection.id, account), balance);355		}356		for (i, data) in data.into_iter().enumerate() {357			let token = first_token + i as u32 + 1;358359			<TokenData<T>>::insert(360				(collection.id, token),361				ItemData {362					const_data: data.const_data.into(),363					variable_data: data.variable_data.into(),364					owner: data.owner.clone(),365				},366			);367			<Owned<T>>::insert((collection.id, &data.owner, token), true);368369			collection.log_infallible(ERC721Events::Transfer {370				from: H160::default(),371				to: *data.owner.as_eth(),372				token_id: token.into(),373			});374			<PalletCommon<T>>::deposit_event(CommonEvent::ItemCreated(375				collection.id,376				TokenId(token),377				data.owner.clone(),378				1,379			));380		}381		Ok(())382	}383384	pub fn set_allowance_unchecked(385		collection: &NonfungibleHandle<T>,386		sender: &T::CrossAccountId,387		token: TokenId,388		spender: Option<&T::CrossAccountId>,389		assume_implicit_eth: bool,390	) {391		if let Some(spender) = spender {392			let old_spender = <Allowance<T>>::get((collection.id, token));393			<Allowance<T>>::insert((collection.id, token), spender);394			// In ERC721 there is only one possible approved user of token, so we set395			// approved user to spender396			collection.log_infallible(ERC721Events::Approval {397				owner: *sender.as_eth(),398				approved: *spender.as_eth(),399				token_id: token.into(),400			});401			// In Unique chain, any token can have any amount of approved users, so we need to402			// set allowance of old owner to 0, and allowance of new owner to 1403			if old_spender.as_ref() != Some(spender) {404				if let Some(old_owner) = old_spender {405					<PalletCommon<T>>::deposit_event(CommonEvent::Approved(406						collection.id,407						token,408						sender.clone(),409						old_owner.clone(),410						0,411					));412				}413				<PalletCommon<T>>::deposit_event(CommonEvent::Approved(414					collection.id,415					token,416					sender.clone(),417					spender.clone(),418					1,419				));420			}421		} else {422			let old_spender = <Allowance<T>>::take((collection.id, token));423			if !assume_implicit_eth {424				// In ERC721 there is only one possible approved user of token, so we set425				// approved user to zero address426				collection.log_infallible(ERC721Events::Approval {427					owner: *sender.as_eth(),428					approved: H160::default(),429					token_id: token.into(),430				});431			}432			// In Unique chain, any token can have any amount of approved users, so we need to433			// set allowance of old owner to 0434			if let Some(old_spender) = old_spender {435				<PalletCommon<T>>::deposit_event(CommonEvent::Approved(436					collection.id,437					token,438					sender.clone(),439					old_spender.clone(),440					0,441				));442			}443		}444	}445446	pub fn set_allowance(447		collection: &NonfungibleHandle<T>,448		sender: &T::CrossAccountId,449		token: TokenId,450		spender: Option<&T::CrossAccountId>,451	) -> DispatchResult {452		if collection.access == AccessMode::AllowList {453			collection.check_allowlist(&sender)?;454			if let Some(spender) = spender {455				collection.check_allowlist(&spender)?;456			}457		}458459		if let Some(spender) = spender {460			<PalletCommon<T>>::ensure_correct_receiver(spender)?;461		}462		let token_data =463			<TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;464		if &token_data.owner != sender {465			ensure!(466				collection.ignores_owned_amount(sender)?,467				<CommonError<T>>::CantApproveMoreThanOwned468			);469		}470471		// =========472473		Self::set_allowance_unchecked(collection, sender, token, spender, false);474		Ok(())475	}476477	pub fn transfer_from(478		collection: &NonfungibleHandle<T>,479		spender: &T::CrossAccountId,480		from: &T::CrossAccountId,481		to: &T::CrossAccountId,482		token: TokenId,483	) -> DispatchResult {484		if spender.conv_eq(from) {485			return Self::transfer(collection, from, to, token);486		}487		if collection.access == AccessMode::AllowList {488			// `from`, `to` checked in [`transfer`]489			collection.check_allowlist(spender)?;490		}491492		if <Allowance<T>>::get((collection.id, token)).as_ref() != Some(spender) {493			ensure!(494				collection.ignores_allowance(spender)?,495				<CommonError<T>>::TokenValueNotEnough496			);497		}498499		// =========500501		Self::transfer(collection, &from, to, token)?;502		// Allowance is reset in [`transfer`]503		Ok(())504	}505506	pub fn burn_from(507		collection: &NonfungibleHandle<T>,508		spender: &T::CrossAccountId,509		from: &T::CrossAccountId,510		token: TokenId,511	) -> DispatchResult {512		if spender.conv_eq(from) {513			return Self::burn(collection, from, token);514		}515		if collection.access == AccessMode::AllowList {516			// `from` checked in [`burn`]517			collection.check_allowlist(spender)?;518		}519520		if <Allowance<T>>::get((collection.id, token)).as_ref() != Some(spender) {521			ensure!(522				collection.ignores_allowance(spender)?,523				<CommonError<T>>::TokenValueNotEnough524			);525		}526527		// =========528529		Self::burn(collection, &from, token)530	}531532	pub fn set_variable_metadata(533		collection: &NonfungibleHandle<T>,534		sender: &T::CrossAccountId,535		token: TokenId,536		data: Vec<u8>,537	) -> DispatchResult {538		ensure!(539			data.len() as u32 <= CUSTOM_DATA_LIMIT,540			<CommonError<T>>::TokenVariableDataLimitExceeded541		);542		let token_data =543			<TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;544		collection.check_can_update_meta(sender, &token_data.owner)?;545546		collection.consume_sstore()?;547548		// =========549550		<TokenData<T>>::insert(551			(collection.id, token),552			ItemData {553				variable_data: data,554				..token_data555			},556		);557		Ok(())558	}559560	/// Delegated to `create_multiple_items`561	pub fn create_item(562		collection: &NonfungibleHandle<T>,563		sender: &T::CrossAccountId,564		data: CreateItemData<T>,565	) -> DispatchResult {566		Self::create_multiple_items(collection, sender, vec![data])567	}568}
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -54,25 +54,25 @@
 	}
 
 	#[pallet::pallet]
-	#[pallet::generate_store(pub(super) trait Store)]
+	#[pallet::generate_store(pub trait Store)]
 	pub struct Pallet<T>(_);
 
 	#[pallet::storage]
-	pub(super) type TokensMinted<T: Config> =
+	pub type TokensMinted<T: Config> =
 		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;
 	#[pallet::storage]
-	pub(super) type TokensBurnt<T: Config> =
+	pub type TokensBurnt<T: Config> =
 		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;
 
 	#[pallet::storage]
-	pub(super) type TokenData<T: Config> = StorageNMap<
+	pub type TokenData<T: Config> = StorageNMap<
 		Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
 		Value = ItemData,
 		QueryKind = ValueQuery,
 	>;
 
 	#[pallet::storage]
-	pub(super) type TotalSupply<T: Config> = StorageNMap<
+	pub type TotalSupply<T: Config> = StorageNMap<
 		Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
 		Value = u128,
 		QueryKind = ValueQuery,
@@ -80,7 +80,7 @@
 
 	/// Used to enumerate tokens owned by account
 	#[pallet::storage]
-	pub(super) type Owned<T: Config> = StorageNMap<
+	pub type Owned<T: Config> = StorageNMap<
 		Key = (
 			Key<Twox64Concat, CollectionId>,
 			Key<Blake2_128Concat, T::CrossAccountId>,
@@ -91,7 +91,7 @@
 	>;
 
 	#[pallet::storage]
-	pub(super) type AccountBalance<T: Config> = StorageNMap<
+	pub type AccountBalance<T: Config> = StorageNMap<
 		Key = (
 			Key<Twox64Concat, CollectionId>,
 			// Owner
@@ -102,7 +102,7 @@
 	>;
 
 	#[pallet::storage]
-	pub(super) type Balance<T: Config> = StorageNMap<
+	pub type Balance<T: Config> = StorageNMap<
 		Key = (
 			Key<Twox64Concat, CollectionId>,
 			Key<Twox64Concat, TokenId>,
@@ -114,7 +114,7 @@
 	>;
 
 	#[pallet::storage]
-	pub(super) type Allowance<T: Config> = StorageNMap<
+	pub type Allowance<T: Config> = StorageNMap<
 		Key = (
 			Key<Twox64Concat, CollectionId>,
 			Key<Twox64Concat, TokenId>,