difftreelog
refactor! rewrite collections accessors
in: master
Squashed from multiple
4 files changed
node/src/chain_spec.rsdiffbeforeafterboth--- a/node/src/chain_spec.rs
+++ b/node/src/chain_spec.rs
@@ -179,9 +179,10 @@
.collect(),
}),
pallet_nft: Some(NftConfig {
- collection: vec![(
+ collection_id: vec![(
1,
- CollectionType {
+ Collection {
+ id: 1,
owner: get_account_id_from_seed::<sr25519::Public>("Alice"),
mode: CollectionMode::NFT,
access: AccessMode::Normal,
pallets/nft/src/lib.rsdiffbeforeafterboth125125126#[derive(Encode, Decode, Clone, PartialEq)]126#[derive(Encode, Decode, Clone, PartialEq)]127#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]127#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]128pub struct CollectionType<T: Config> {128pub struct Collection<T: Config> {129 pub id: CollectionId,129 pub owner: T::AccountId,130 pub owner: T::AccountId,130 pub mode: CollectionMode,131 pub mode: CollectionMode,131 pub access: AccessMode,132 pub access: AccessMode,426 pub AccountItemCount get(fn account_item_count): map hasher(twox_64_concat) T::AccountId => u32;427 pub AccountItemCount get(fn account_item_count): map hasher(twox_64_concat) T::AccountId => u32;427428428 // Basic collections429 // Basic collections429 pub Collection get(fn collection) config(): map hasher(identity) CollectionId => Option<CollectionType<T>> = None;430 pub CollectionById get(fn collection_id) config(): map hasher(identity) CollectionId => Option<Collection<T>> = None;430 pub AdminList get(fn admin_list_collection): map hasher(identity) CollectionId => Vec<T::AccountId>;431 pub AdminList get(fn admin_list_collection): map hasher(identity) CollectionId => Vec<T::AccountId>;431 pub WhiteList get(fn white_list): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => bool;432 pub WhiteList get(fn white_list): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => bool;432433464 add_extra_genesis {465 add_extra_genesis {465 build(|config: &GenesisConfig<T>| {466 build(|config: &GenesisConfig<T>| {466 // Modification of storage467 // Modification of storage467 for (_num, _c) in &config.collection {468 for (_num, _c) in &config.collection_id {468 <Module<T>>::init_collection(_c);469 <Module<T>>::init_collection(_c);469 }470 }470471615 };616 };616617617 // Create new collection618 // Create new collection618 let new_collection = CollectionType {619 let new_collection = Collection {620 id: next_id,619 owner: who.clone(),621 owner: who.clone(),620 name: collection_name,622 name: collection_name,621 mode: mode.clone(),623 mode: mode.clone(),634 };636 };635637636 // Add new collection to map638 // Add new collection to map637 <Collection<T>>::insert(next_id, new_collection);639 <CollectionById<T>>::insert(next_id, new_collection);638640639 // call event641 // call event640 Self::deposit_event(RawEvent::Created(next_id, mode.into(), who.clone()));642 Self::deposit_event(RawEvent::Created(next_id, mode.into(), who.clone()));655 pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {657 pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {656658657 let sender = ensure_signed(origin)?;659 let sender = ensure_signed(origin)?;658 Self::check_owner_permissions(collection_id, sender)?;660 let collection = Self::get_collection(collection_id)?;659660 let target_collection = <Collection<T>>::get(collection_id);661 Self::check_owner_permissions(&collection, sender)?;661 if !target_collection.limits.owner_can_destroy {662 if !collection.limits.owner_can_destroy {662 fail!(Error::<T>::NoPermission);663 fail!(Error::<T>::NoPermission);663 }664 }664665667 <Balance<T>>::remove_prefix(collection_id);668 <Balance<T>>::remove_prefix(collection_id);668 <ItemListIndex>::remove(collection_id);669 <ItemListIndex>::remove(collection_id);669 <AdminList<T>>::remove(collection_id);670 <AdminList<T>>::remove(collection_id);670 <Collection<T>>::remove(collection_id);671 <CollectionById<T>>::remove(collection_id);671 <WhiteList<T>>::remove_prefix(collection_id);672 <WhiteList<T>>::remove_prefix(collection_id);672673673 <NftItemList<T>>::remove_prefix(collection_id);674 <NftItemList<T>>::remove_prefix(collection_id);709 pub fn add_to_white_list(origin, collection_id: CollectionId, address: T::AccountId) -> DispatchResult{710 pub fn add_to_white_list(origin, collection_id: CollectionId, address: T::AccountId) -> DispatchResult{710711711 let sender = ensure_signed(origin)?;712 let sender = ensure_signed(origin)?;712 Self::check_owner_or_admin_permissions(collection_id, sender)?;713 let collection = Self::get_collection(collection_id)?;714 Self::check_owner_or_admin_permissions(&collection, sender)?;713715714 <WhiteList<T>>::insert(collection_id, address, true);716 <WhiteList<T>>::insert(collection_id, address, true);715 717 732 pub fn remove_from_white_list(origin, collection_id: CollectionId, address: T::AccountId) -> DispatchResult{734 pub fn remove_from_white_list(origin, collection_id: CollectionId, address: T::AccountId) -> DispatchResult{733735734 let sender = ensure_signed(origin)?;736 let sender = ensure_signed(origin)?;735 Self::check_owner_or_admin_permissions(collection_id, sender)?;737 let collection = Self::get_collection(collection_id)?;738 Self::check_owner_or_admin_permissions(&collection, sender)?;736739737 <WhiteList<T>>::remove(collection_id, address);740 <WhiteList<T>>::remove(collection_id, address);738741755 {758 {756 let sender = ensure_signed(origin)?;759 let sender = ensure_signed(origin)?;757760758 Self::check_owner_permissions(collection_id, sender)?;761 let mut target_collection = Self::get_collection(collection_id)?;759 let mut target_collection = <Collection<T>>::get(collection_id).unwrap();762 Self::check_owner_permissions(&target_collection, sender)?;760 target_collection.access = mode;763 target_collection.access = mode;761 <Collection<T>>::insert(collection_id, target_collection);764 Self::save_collection(target_collection);762765763 Ok(())766 Ok(())764 }767 }781 {784 {782 let sender = ensure_signed(origin)?;785 let sender = ensure_signed(origin)?;783786784 Self::check_owner_permissions(collection_id, sender)?;787 let mut target_collection = Self::get_collection(collection_id)?;785 let mut target_collection = <Collection<T>>::get(collection_id).unwrap();788 Self::check_owner_permissions(&target_collection, sender)?;786 target_collection.mint_mode = mint_permission;789 target_collection.mint_mode = mint_permission;787 <Collection<T>>::insert(collection_id, target_collection);790 Self::save_collection(target_collection);788791789 Ok(())792 Ok(())790 }793 }804 pub fn change_collection_owner(origin, collection_id: CollectionId, new_owner: T::AccountId) -> DispatchResult {807 pub fn change_collection_owner(origin, collection_id: CollectionId, new_owner: T::AccountId) -> DispatchResult {805808806 let sender = ensure_signed(origin)?;809 let sender = ensure_signed(origin)?;807 Self::check_owner_permissions(collection_id, sender)?;810 let mut target_collection = Self::get_collection(collection_id)?;808 let mut target_collection = <Collection<T>>::get(collection_id).unwrap();811 Self::check_owner_permissions(&target_collection, sender)?;809 target_collection.owner = new_owner;812 target_collection.owner = new_owner;810 <Collection<T>>::insert(collection_id, target_collection);813 Self::save_collection(target_collection);811814812 Ok(())815 Ok(())813 }816 }829 pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::AccountId) -> DispatchResult {832 pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::AccountId) -> DispatchResult {830833831 let sender = ensure_signed(origin)?;834 let sender = ensure_signed(origin)?;832 Self::check_owner_or_admin_permissions(collection_id, sender)?;835 let collection = Self::get_collection(collection_id)?;836 Self::check_owner_or_admin_permissions(&collection, sender)?;833 let mut admin_arr: Vec<T::AccountId> = Vec::new();837 let mut admin_arr: Vec<T::AccountId> = Vec::new();834838835 if <AdminList<T>>::contains_key(collection_id)839 if <AdminList<T>>::contains_key(collection_id)863 pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::AccountId) -> DispatchResult {867 pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::AccountId) -> DispatchResult {864868865 let sender = ensure_signed(origin)?;869 let sender = ensure_signed(origin)?;866 Self::check_owner_or_admin_permissions(collection_id, sender)?;870 let collection = Self::get_collection(collection_id)?;871 Self::check_owner_or_admin_permissions(&collection, sender)?;867 ensure!(<AdminList<T>>::contains_key(collection_id), Error::<T>::AdminNotFound);872 ensure!(<AdminList<T>>::contains_key(collection_id), Error::<T>::AdminNotFound);868873869 let mut admin_arr = <AdminList<T>>::get(collection_id);874 let mut admin_arr = <AdminList<T>>::get(collection_id);886 pub fn set_collection_sponsor(origin, collection_id: CollectionId, new_sponsor: T::AccountId) -> DispatchResult {891 pub fn set_collection_sponsor(origin, collection_id: CollectionId, new_sponsor: T::AccountId) -> DispatchResult {887892888 let sender = ensure_signed(origin)?;893 let sender = ensure_signed(origin)?;894 let mut target_collection = Self::get_collection(collection_id)?;895 Self::check_owner_permissions(&target_collection, sender)?;889896890 let mut target_collection = <Collection<T>>::get(collection_id).ok_or(Error::<T>::CollectionNotFound)?;891 ensure!(sender == target_collection.owner, Error::<T>::NoPermission);892893 target_collection.sponsor = new_sponsor;897 target_collection.sponsor = new_sponsor;894 target_collection.sponsor_confirmed = false;898 target_collection.sponsor_confirmed = false;895 <Collection<T>>::insert(collection_id, target_collection);899 Self::save_collection(target_collection);896900897 Ok(())901 Ok(())898 }902 }909913910 let sender = ensure_signed(origin)?;914 let sender = ensure_signed(origin)?;911915912 let mut target_collection = <Collection<T>>::get(collection_id).ok_or(Error::<T>::CollectionNotFound)?;916 let mut target_collection = Self::get_collection(collection_id)?;913 ensure!(sender == target_collection.sponsor, Error::<T>::ConfirmUnsetSponsorFail);917 ensure!(sender == target_collection.sponsor, Error::<T>::ConfirmUnsetSponsorFail);914918915 target_collection.sponsor_confirmed = true;919 target_collection.sponsor_confirmed = true;916 <Collection<T>>::insert(collection_id, target_collection);920 Self::save_collection(target_collection);917921918 Ok(())922 Ok(())919 }923 }932936933 let sender = ensure_signed(origin)?;937 let sender = ensure_signed(origin)?;934938935 let mut target_collection = <Collection<T>>::get(collection_id).ok_or(Error::<T>::CollectionNotFound)?;939 let mut target_collection = Self::get_collection(collection_id)?;936 ensure!(sender == target_collection.owner, Error::<T>::NoPermission);940 Self::check_owner_permissions(&target_collection, sender)?;937941938 target_collection.sponsor = T::AccountId::default();942 target_collection.sponsor = T::AccountId::default();939 target_collection.sponsor_confirmed = false;943 target_collection.sponsor_confirmed = false;940 <Collection<T>>::insert(collection_id, target_collection);944 Self::save_collection(target_collection);941945942 Ok(())946 Ok(())943 }947 }971975972 let sender = ensure_signed(origin)?;976 let sender = ensure_signed(origin)?;973977974 Self::collection_exists(collection_id)?;978 let target_collection = Self::get_collection(collection_id)?;975979976 let target_collection = <Collection<T>>::get(collection_id).unwrap();980 Self::can_create_items_in_collection(&target_collection, &sender, &owner)?;977978 Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;979 Self::validate_create_item_args(&target_collection, &data)?;981 Self::validate_create_item_args(&target_collection, &data)?;980 Self::create_item_no_validation(collection_id, owner, data)?;982 Self::create_item_no_validation(&target_collection, owner, data)?;981983982 Ok(())984 Ok(())983 }985 }1008 ensure!(items_data.len() > 0, Error::<T>::EmptyArgument);1010 ensure!(items_data.len() > 0, Error::<T>::EmptyArgument);1009 let sender = ensure_signed(origin)?;1011 let sender = ensure_signed(origin)?;101010121011 Self::collection_exists(collection_id)?;1013 let target_collection = Self::get_collection(collection_id)?;1012 let target_collection = <Collection<T>>::get(collection_id).unwrap();101310141014 Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;1015 Self::can_create_items_in_collection(&target_collection, &sender, &owner)?;101510161016 for data in &items_data {1017 for data in &items_data {1017 Self::validate_create_item_args(&target_collection, data)?;1018 Self::validate_create_item_args(&target_collection, data)?;1018 }1019 }1019 for data in &items_data {1020 for data in &items_data {1020 Self::create_item_no_validation(collection_id, owner.clone(), data.clone())?;1021 Self::create_item_no_validation(&target_collection, owner.clone(), data.clone())?;1021 }1022 }102210231023 Ok(())1024 Ok(())1040 pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {1041 pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {104110421042 let sender = ensure_signed(origin)?;1043 let sender = ensure_signed(origin)?;1043 Self::collection_exists(collection_id)?;104410441045 // Transfer permissions check1045 // Transfer permissions check1046 let target_collection = <Collection<T>>::get(collection_id).unwrap();1046 let target_collection = Self::get_collection(collection_id)?;1047 ensure!(1047 ensure!(1048 Self::is_item_owner(sender.clone(), collection_id, item_id) ||1048 Self::is_item_owner(sender.clone(), &target_collection, item_id) ||1049 (1049 (1050 target_collection.limits.owner_can_transfer &&1050 target_collection.limits.owner_can_transfer &&1051 Self::is_owner_or_admin_permissions(collection_id, sender.clone())1051 Self::is_owner_or_admin_permissions(&target_collection, sender.clone())1052 ),1052 ),1053 Error::<T>::NoPermission1053 Error::<T>::NoPermission1054 );1054 );105510551056 if target_collection.access == AccessMode::WhiteList {1056 if target_collection.access == AccessMode::WhiteList {1057 Self::check_white_list(collection_id, &sender)?;1057 Self::check_white_list(&target_collection, &sender)?;1058 }1058 }105910591060 match target_collection.mode1060 match target_collection.mode1061 {1061 {1062 CollectionMode::NFT => Self::burn_nft_item(collection_id, item_id)?,1062 CollectionMode::NFT => Self::burn_nft_item(&target_collection, item_id)?,1063 CollectionMode::Fungible(_) => Self::burn_fungible_item(&sender, collection_id, value)?,1063 CollectionMode::Fungible(_) => Self::burn_fungible_item(&sender, &target_collection, value)?,1064 CollectionMode::ReFungible => Self::burn_refungible_item(collection_id, item_id, &sender)?,1064 CollectionMode::ReFungible => Self::burn_refungible_item(&target_collection, item_id, &sender)?,1065 _ => ()1065 _ => ()1066 };1066 };106710671068 // call event1068 // call event1069 Self::deposit_event(RawEvent::ItemDestroyed(collection_id, item_id));1069 Self::deposit_event(RawEvent::ItemDestroyed(target_collection.id, item_id));107010701071 Ok(())1071 Ok(())1072 }1072 }1097 #[weight = <T as Config>::WeightInfo::transfer()]1097 #[weight = <T as Config>::WeightInfo::transfer()]1098 pub fn transfer(origin, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {1098 pub fn transfer(origin, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {1099 let sender = ensure_signed(origin)?;1099 let sender = ensure_signed(origin)?;1100 Self::transfer_internal(sender, recipient, collection_id, item_id, value)1100 let collection = Self::get_collection(collection_id)?;11011102 Self::transfer_internal(sender, recipient, &collection, item_id, value)1101 }1103 }110211041103 /// Set, change, or remove approved address to transfer the ownership of the NFT.1105 /// Set, change, or remove approved address to transfer the ownership of the NFT.1119 pub fn approve(origin, spender: T::AccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResult {1121 pub fn approve(origin, spender: T::AccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResult {112011221121 let sender = ensure_signed(origin)?;1123 let sender = ensure_signed(origin)?;1124 let target_collection = Self::get_collection(collection_id)?;112211251123 Self::collection_exists(collection_id)?;1126 Self::token_exists(&target_collection, item_id, &sender)?;1124 Self::token_exists(collection_id, item_id, &sender)?;112511271126 // Transfer permissions check1128 // Transfer permissions check1127 let target_collection = <Collection<T>>::get(collection_id).unwrap();1128 let allowance_limit = if (1129 let allowance_limit = if (1129 target_collection.limits.owner_can_transfer &&1130 target_collection.limits.owner_can_transfer &&1130 Self::is_owner_or_admin_permissions(1131 Self::is_owner_or_admin_permissions(1131 collection_id,1132 &target_collection,1132 sender.clone(),1133 sender.clone(),1133 )1134 )1134 ) {1135 ) {1135 None1136 None1136 } else if let Some(amount) = Self::owned_amount(1137 } else if let Some(amount) = Self::owned_amount(1137 sender.clone(),1138 sender.clone(),1138 collection_id,1139 &target_collection,1139 item_id,1140 item_id,1140 ) {1141 ) {1141 Some(amount)1142 Some(amount)1144 };1145 };114511461146 if target_collection.access == AccessMode::WhiteList {1147 if target_collection.access == AccessMode::WhiteList {1147 Self::check_white_list(collection_id, &sender)?;1148 Self::check_white_list(&target_collection, &sender)?;1148 Self::check_white_list(collection_id, &spender)?;1149 Self::check_white_list(&target_collection, &spender)?;1149 }1150 }115011511151 let allowance_exists = <Allowances<T>>::contains_key(collection_id, (item_id, &sender, &spender));1152 let allowance_exists = <Allowances<T>>::contains_key(collection_id, (item_id, &sender, &spender));1184 pub fn transfer_from(origin, from: T::AccountId, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResult {1185 pub fn transfer_from(origin, from: T::AccountId, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResult {118511861186 let sender = ensure_signed(origin)?;1187 let sender = ensure_signed(origin)?;1188 let target_collection = Self::get_collection(collection_id)?;11891187 let mut appoved_transfer = false;1190 let mut appoved_transfer = false;118811911189 // Check approval1192 // Check approval1194 appoved_transfer = true;1197 appoved_transfer = true;1195 }1198 }119611991197 let target_collection = <Collection<T>>::get(collection_id).unwrap();11981199 // Limits check1200 // Limits check1200 Self::is_correct_transfer(collection_id, &target_collection, &recipient)?;1201 Self::is_correct_transfer(&target_collection, &recipient)?;120112021202 // Transfer permissions check 1203 // Transfer permissions check 1203 ensure!(1204 ensure!(1204 appoved_transfer || 1205 appoved_transfer || 1205 (1206 (1206 target_collection.limits.owner_can_transfer &&1207 target_collection.limits.owner_can_transfer &&1207 Self::is_owner_or_admin_permissions(collection_id, sender.clone())1208 Self::is_owner_or_admin_permissions(&target_collection, sender.clone())1208 ),1209 ),1209 Error::<T>::NoPermission1210 Error::<T>::NoPermission1210 );1211 );121112121212 if target_collection.access == AccessMode::WhiteList {1213 if target_collection.access == AccessMode::WhiteList {1213 Self::check_white_list(collection_id, &sender)?;1214 Self::check_white_list(&target_collection, &sender)?;1214 Self::check_white_list(collection_id, &recipient)?;1215 Self::check_white_list(&target_collection, &recipient)?;1215 }1216 }121612171217 // Reduce approval by transferred amount or remove if remaining approval drops to 01218 // Reduce approval by transferred amount or remove if remaining approval drops to 0122412251225 match target_collection.mode1226 match target_collection.mode1226 {1227 {1227 CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, from, recipient)?,1228 CollectionMode::NFT => Self::transfer_nft(&target_collection, item_id, from, recipient)?,1228 CollectionMode::Fungible(_) => Self::transfer_fungible(collection_id, value, &from, &recipient)?,1229 CollectionMode::Fungible(_) => Self::transfer_fungible(&target_collection, value, &from, &recipient)?,1229 CollectionMode::ReFungible => Self::transfer_refungible(collection_id, item_id, value, from.clone(), recipient)?,1230 CollectionMode::ReFungible => Self::transfer_refungible(&target_collection, item_id, value, from.clone(), recipient)?,1230 _ => ()1231 _ => ()1231 };1232 };123212331269 ) -> DispatchResult {1270 ) -> DispatchResult {1270 let sender = ensure_signed(origin)?;1271 let sender = ensure_signed(origin)?;1271 1272 1272 Self::collection_exists(collection_id)?;1273 let target_collection = Self::get_collection(collection_id)?;1273 Self::token_exists(collection_id, item_id, &sender)?;1274 Self::token_exists(&target_collection, item_id, &sender)?;127412751275 ensure!(ChainLimit::get().custom_data_limit >= data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);1276 ensure!(ChainLimit::get().custom_data_limit >= data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);127612771277 // Modify permissions check1278 // Modify permissions check1278 let target_collection = <Collection<T>>::get(collection_id).unwrap();1279 ensure!(Self::is_item_owner(sender.clone(), &target_collection, item_id) ||1279 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||1280 Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1280 Self::is_owner_or_admin_permissions(&target_collection, sender.clone()),1281 Error::<T>::NoPermission);1281 Error::<T>::NoPermission);128212821283 match target_collection.mode1283 match target_collection.mode1284 {1284 {1285 CollectionMode::NFT => Self::set_nft_variable_data(collection_id, item_id, data)?,1285 CollectionMode::NFT => Self::set_nft_variable_data(&target_collection, item_id, data)?,1286 CollectionMode::ReFungible => Self::set_re_fungible_variable_data(collection_id, item_id, data)?,1286 CollectionMode::ReFungible => Self::set_re_fungible_variable_data(&target_collection, item_id, data)?,1287 CollectionMode::Fungible(_) => fail!(Error::<T>::CantStoreMetadataInFungibleTokens),1287 CollectionMode::Fungible(_) => fail!(Error::<T>::CantStoreMetadataInFungibleTokens),1288 _ => fail!(Error::<T>::UnexpectedCollectionType)1288 _ => fail!(Error::<T>::UnexpectedCollectionType)1289 };1289 };1312 version: SchemaVersion1312 version: SchemaVersion1313 ) -> DispatchResult {1313 ) -> DispatchResult {1314 let sender = ensure_signed(origin)?;1314 let sender = ensure_signed(origin)?;1315 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;1315 let mut target_collection = Self::get_collection(collection_id)?;1316 let mut target_collection = <Collection<T>>::get(collection_id).unwrap();1316 Self::check_owner_or_admin_permissions(&target_collection, sender.clone())?;1317 target_collection.schema_version = version;1317 target_collection.schema_version = version;1318 <Collection<T>>::insert(collection_id, target_collection);1318 Self::save_collection(target_collection);131913191320 Ok(())1320 Ok(())1321 }1321 }1339 schema: Vec<u8>1339 schema: Vec<u8>1340 ) -> DispatchResult {1340 ) -> DispatchResult {1341 let sender = ensure_signed(origin)?;1341 let sender = ensure_signed(origin)?;1342 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;1342 let mut target_collection = Self::get_collection(collection_id)?;1343 Self::check_owner_or_admin_permissions(&target_collection, sender.clone())?;134313441344 // check schema limit1345 // check schema limit1345 ensure!(schema.len() as u32 <= ChainLimit::get().offchain_schema_limit, "");1346 ensure!(schema.len() as u32 <= ChainLimit::get().offchain_schema_limit, "");134613471347 let mut target_collection = <Collection<T>>::get(collection_id).unwrap();1348 target_collection.offchain_schema = schema;1348 target_collection.offchain_schema = schema;1349 <Collection<T>>::insert(collection_id, target_collection);1349 Self::save_collection(target_collection);135013501351 Ok(())1351 Ok(())1352 }1352 }1370 schema: Vec<u8>1370 schema: Vec<u8>1371 ) -> DispatchResult {1371 ) -> DispatchResult {1372 let sender = ensure_signed(origin)?;1372 let sender = ensure_signed(origin)?;1373 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;1373 let mut target_collection = Self::get_collection(collection_id)?;1374 Self::check_owner_or_admin_permissions(&target_collection, sender.clone())?;137413751375 // check schema limit1376 // check schema limit1376 ensure!(schema.len() as u32 <= ChainLimit::get().const_on_chain_schema_limit, "");1377 ensure!(schema.len() as u32 <= ChainLimit::get().const_on_chain_schema_limit, "");137713781378 let mut target_collection = <Collection<T>>::get(collection_id).unwrap();1379 target_collection.const_on_chain_schema = schema;1379 target_collection.const_on_chain_schema = schema;1380 <Collection<T>>::insert(collection_id, target_collection);1380 Self::save_collection(target_collection);138113811382 Ok(())1382 Ok(())1383 }1383 }1401 schema: Vec<u8>1401 schema: Vec<u8>1402 ) -> DispatchResult {1402 ) -> DispatchResult {1403 let sender = ensure_signed(origin)?;1403 let sender = ensure_signed(origin)?;1404 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;1404 let mut target_collection = Self::get_collection(collection_id)?;1405 Self::check_owner_or_admin_permissions(&target_collection, sender.clone())?;140514061406 // check schema limit1407 // check schema limit1407 ensure!(schema.len() as u32 <= ChainLimit::get().variable_on_chain_schema_limit, "");1408 ensure!(schema.len() as u32 <= ChainLimit::get().variable_on_chain_schema_limit, "");140814091409 let mut target_collection = <Collection<T>>::get(collection_id).unwrap();1410 target_collection.variable_on_chain_schema = schema;1410 target_collection.variable_on_chain_schema = schema;1411 <Collection<T>>::insert(collection_id, target_collection);1411 Self::save_collection(target_collection);141214121413 Ok(())1413 Ok(())1414 }1414 }1577 new_limits: CollectionLimits<T::BlockNumber>,1577 new_limits: CollectionLimits<T::BlockNumber>,1578 ) -> DispatchResult {1578 ) -> DispatchResult {1579 let sender = ensure_signed(origin)?;1579 let sender = ensure_signed(origin)?;1580 Self::check_owner_permissions(collection_id, sender.clone())?;1580 let mut target_collection = Self::get_collection(collection_id)?;1581 let mut target_collection = <Collection<T>>::get(collection_id).unwrap();1581 Self::check_owner_permissions(&target_collection, sender.clone())?;1582 let old_limits = target_collection.limits;1582 let old_limits = target_collection.limits;1583 let chain_limits = ChainLimit::get();1583 let chain_limits = ChainLimit::get();158415841599 );1599 );160016001601 target_collection.limits = new_limits;1601 target_collection.limits = new_limits;1602 <Collection<T>>::insert(collection_id, target_collection);1602 Self::save_collection(target_collection);160316031604 Ok(())1604 Ok(())1605 } 1605 } 160816081609impl<T: Config> Module<T> {1609impl<T: Config> Module<T> {161016101611 pub fn transfer_internal(sender: T::AccountId, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {1611 pub fn transfer_internal(sender: T::AccountId, recipient: T::AccountId, target_collection: &Collection<T>, item_id: TokenId, value: u128) -> DispatchResult {16121613 let target_collection = <Collection<T>>::get(collection_id).unwrap();16141615 // Limits check1612 // Limits check1616 Self::is_correct_transfer(collection_id, &target_collection, &recipient)?;1613 Self::is_correct_transfer(target_collection, &recipient)?;161716141618 // Transfer permissions check1615 // Transfer permissions check1619 ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||1616 ensure!(Self::is_item_owner(sender.clone(), target_collection, item_id) ||1620 Self::is_owner_or_admin_permissions(collection_id, sender.clone()),1617 Self::is_owner_or_admin_permissions(target_collection, sender.clone()),1621 Error::<T>::NoPermission);1618 Error::<T>::NoPermission);162216191623 if target_collection.access == AccessMode::WhiteList {1620 if target_collection.access == AccessMode::WhiteList {1624 Self::check_white_list(collection_id, &sender)?;1621 Self::check_white_list(target_collection, &sender)?;1625 Self::check_white_list(collection_id, &recipient)?;1622 Self::check_white_list(target_collection, &recipient)?;1626 }1623 }162716241628 match target_collection.mode1625 match target_collection.mode1629 {1626 {1630 CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, sender.clone(), recipient.clone())?,1627 CollectionMode::NFT => Self::transfer_nft(target_collection, item_id, sender.clone(), recipient.clone())?,1631 CollectionMode::Fungible(_) => Self::transfer_fungible(collection_id, value, &sender, &recipient)?,1628 CollectionMode::Fungible(_) => Self::transfer_fungible(target_collection, value, &sender, &recipient)?,1632 CollectionMode::ReFungible => Self::transfer_refungible(collection_id, item_id, value, sender.clone(), recipient.clone())?,1629 CollectionMode::ReFungible => Self::transfer_refungible(target_collection, item_id, value, sender.clone(), recipient.clone())?,1633 _ => ()1630 _ => ()1634 };1631 };163516321636 Self::deposit_event(RawEvent::Transfer(collection_id, item_id, sender, recipient, value));1633 Self::deposit_event(RawEvent::Transfer(target_collection.id, item_id, sender, recipient, value));163716341638 Ok(())1635 Ok(())1639 }1636 }16401637164116381642 fn is_correct_transfer(collection_id: CollectionId, collection: &CollectionType<T>, recipient: &T::AccountId) -> DispatchResult {1639 fn is_correct_transfer(collection: &Collection<T>, recipient: &T::AccountId) -> DispatchResult {1640 let collection_id = collection.id;164316411644 // check token limit and account token limit1642 // check token limit and account token limit1645 let account_items: u32 = <AddressTokens<T>>::get(collection_id, recipient).len() as u32;1643 let account_items: u32 = <AddressTokens<T>>::get(collection_id, recipient).len() as u32;1648 Ok(())1646 Ok(())1649 }1647 }165016481651 fn can_create_items_in_collection(collection_id: CollectionId, collection: &CollectionType<T>, sender: &T::AccountId, owner: &T::AccountId) -> DispatchResult {1649 fn can_create_items_in_collection(collection: &Collection<T>, sender: &T::AccountId, owner: &T::AccountId) -> DispatchResult {1650 let collection_id = collection.id;165216511653 // check token limit and account token limit1652 // check token limit and account token limit1654 let total_items: u32 = ItemListIndex::get(collection_id);1653 let total_items: u32 = ItemListIndex::get(collection_id);1655 let account_items: u32 = <AddressTokens<T>>::get(collection_id, owner).len() as u32;1654 let account_items: u32 = <AddressTokens<T>>::get(collection_id, owner).len() as u32;1656 ensure!(collection.limits.token_limit > total_items, Error::<T>::CollectionTokenLimitExceeded);1655 ensure!(collection.limits.token_limit > total_items, Error::<T>::CollectionTokenLimitExceeded);1657 ensure!(collection.limits.account_token_ownership_limit > account_items, Error::<T>::AccountTokenLimitExceeded);1656 ensure!(collection.limits.account_token_ownership_limit > account_items, Error::<T>::AccountTokenLimitExceeded);165816571659 if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) {1658 if !Self::is_owner_or_admin_permissions(collection, sender.clone()) {1660 ensure!(collection.mint_mode == true, Error::<T>::PublicMintingNotAllowed);1659 ensure!(collection.mint_mode == true, Error::<T>::PublicMintingNotAllowed);1661 Self::check_white_list(collection_id, owner)?;1660 Self::check_white_list(collection, owner)?;1662 Self::check_white_list(collection_id, sender)?;1661 Self::check_white_list(collection, sender)?;1663 }1662 }166416631665 Ok(())1664 Ok(())1666 }1665 }166716661668 fn validate_create_item_args(target_collection: &CollectionType<T>, data: &CreateItemData) -> DispatchResult {1667 fn validate_create_item_args(target_collection: &Collection<T>, data: &CreateItemData) -> DispatchResult {1669 match target_collection.mode1668 match target_collection.mode1670 {1669 {1671 CollectionMode::NFT => {1670 CollectionMode::NFT => {1703 Ok(())1702 Ok(())1704 }1703 }170517041706 fn create_item_no_validation(collection_id: CollectionId, owner: T::AccountId, data: CreateItemData) -> DispatchResult {1705 fn create_item_no_validation(collection: &Collection<T>, owner: T::AccountId, data: CreateItemData) -> DispatchResult {1706 let collection_id = collection.id;17071707 match data1708 match data1708 {1709 {1713 variable_data: data.variable_data1714 variable_data: data.variable_data1714 };1715 };171517161716 Self::add_nft_item(collection_id, item)?;1717 Self::add_nft_item(collection, item)?;1717 },1718 },1718 CreateItemData::Fungible(data) => {1719 CreateItemData::Fungible(data) => {1719 Self::add_fungible_item(collection_id, &owner, data.value)?;1720 Self::add_fungible_item(collection, &owner, data.value)?;1720 },1721 },1721 CreateItemData::ReFungible(data) => {1722 CreateItemData::ReFungible(data) => {1722 let mut owner_list = Vec::new();1723 let mut owner_list = Vec::new();1728 variable_data: data.variable_data1729 variable_data: data.variable_data1729 };1730 };173017311731 Self::add_refungible_item(collection_id, item)?;1732 Self::add_refungible_item(collection, item)?;1732 }1733 }1733 };1734 };173417351738 Ok(())1739 Ok(())1739 }1740 }174017411741 fn add_fungible_item(collection_id: CollectionId, owner: &T::AccountId, value: u128) -> DispatchResult {1742 fn add_fungible_item(collection: &Collection<T>, owner: &T::AccountId, value: u128) -> DispatchResult {1743 let collection_id = collection.id;174217441743 // Does new owner already have an account?1745 // Does new owner already have an account?1744 let mut balance: u128 = 0;1746 let mut balance: u128 = 0;1761 Ok(())1763 Ok(())1762 }1764 }176317651764 fn add_refungible_item(collection_id: CollectionId, item: ReFungibleItemType<T::AccountId>) -> DispatchResult {1766 fn add_refungible_item(collection: &Collection<T>, item: ReFungibleItemType<T::AccountId>) -> DispatchResult {1767 let collection_id = collection.id;17681765 let current_index = <ItemListIndex>::get(collection_id)1769 let current_index = <ItemListIndex>::get(collection_id)1766 .checked_add(1)1770 .checked_add(1)1784 Ok(())1788 Ok(())1785 }1789 }178617901787 fn add_nft_item(collection_id: CollectionId, item: NftItemType<T::AccountId>) -> DispatchResult {1791 fn add_nft_item(collection: &Collection<T>, item: NftItemType<T::AccountId>) -> DispatchResult {1792 let collection_id = collection.id;17931788 let current_index = <ItemListIndex>::get(collection_id)1794 let current_index = <ItemListIndex>::get(collection_id)1789 .checked_add(1)1795 .checked_add(1)1805 }1811 }180618121807 fn burn_refungible_item(1813 fn burn_refungible_item(1808 collection_id: CollectionId,1814 collection: &Collection<T>,1809 item_id: TokenId,1815 item_id: TokenId,1810 owner: &T::AccountId,1816 owner: &T::AccountId,1811 ) -> DispatchResult {1817 ) -> DispatchResult {1818 let collection_id = collection.id;18191812 ensure!(1820 ensure!(1813 <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1821 <ReFungibleItemList<T>>::contains_key(collection_id, item_id),1814 Error::<T>::TokenNotFound1822 Error::<T>::TokenNotFound1849 Ok(())1857 Ok(())1850 }1858 }185118591852 fn burn_nft_item(collection_id: CollectionId, item_id: TokenId) -> DispatchResult {1860 fn burn_nft_item(collection: &Collection<T>, item_id: TokenId) -> DispatchResult {1861 let collection_id = collection.id;18621853 ensure!(1863 ensure!(1854 <NftItemList<T>>::contains_key(collection_id, item_id),1864 <NftItemList<T>>::contains_key(collection_id, item_id),1868 Ok(())1878 Ok(())1869 }1879 }187018801871 fn burn_fungible_item(owner: &T::AccountId, collection_id: CollectionId, value: u128) -> DispatchResult {1881 fn burn_fungible_item(owner: &T::AccountId, collection: &Collection<T>, value: u128) -> DispatchResult {1882 let collection_id = collection.id;18831872 ensure!(1884 ensure!(1873 <FungibleItemList<T>>::contains_key(collection_id, owner),1885 <FungibleItemList<T>>::contains_key(collection_id, owner),1893 Ok(())1905 Ok(())1894 }1906 }189519071896 fn collection_exists(collection_id: CollectionId) -> DispatchResult {1908 pub fn get_collection(collection_id: CollectionId) -> Result<Collection<T>, sp_runtime::DispatchError> {1897 ensure!(1909 Ok(<CollectionById<T>>::get(collection_id)1898 <Collection<T>>::contains_key(collection_id),1899 Error::<T>::CollectionNotFound1910 .ok_or(Error::<T>::CollectionNotFound)?)1900 );1901 Ok(())1902 }1911 }190319121904 fn check_owner_permissions(collection_id: CollectionId, subject: T::AccountId) -> DispatchResult {1913 fn save_collection(collection: Collection<T>) {1905 Self::collection_exists(collection_id)?;1914 <CollectionById<T>>::insert(collection.id, collection);1915 }190619161907 let target_collection = <Collection<T>>::get(collection_id).unwrap();1917 fn check_owner_permissions(target_collection: &Collection<T>, subject: T::AccountId) -> DispatchResult {1908 ensure!(1918 ensure!(1909 subject == target_collection.owner,1919 subject == target_collection.owner,1910 Error::<T>::NoPermission1920 Error::<T>::NoPermission1913 Ok(())1923 Ok(())1914 }1924 }191519251916 fn is_owner_or_admin_permissions(collection_id: CollectionId, subject: T::AccountId) -> bool {1926 fn is_owner_or_admin_permissions(collection: &Collection<T>, subject: T::AccountId) -> bool {1917 let target_collection = <Collection<T>>::get(collection_id).unwrap();1927 let mut result: bool = subject == collection.owner;1918 let mut result: bool = subject == target_collection.owner;1919 let exists = <AdminList<T>>::contains_key(collection_id);1928 let exists = <AdminList<T>>::contains_key(collection.id);192019291921 if !result & exists {1930 if !result & exists {1922 if <AdminList<T>>::get(collection_id).contains(&subject) {1931 if <AdminList<T>>::get(collection.id).contains(&subject) {1923 result = true1932 result = true1924 }1933 }1925 }1934 }1928 }1937 }192919381930 fn check_owner_or_admin_permissions(1939 fn check_owner_or_admin_permissions(1931 collection_id: CollectionId,1940 collection: &Collection<T>,1932 subject: T::AccountId,1941 subject: T::AccountId,1933 ) -> DispatchResult {1942 ) -> DispatchResult {1934 Self::collection_exists(collection_id)?;1943 let result = Self::is_owner_or_admin_permissions(collection, subject.clone());1935 let result = Self::is_owner_or_admin_permissions(collection_id, subject.clone());193619441937 ensure!(1945 ensure!(1938 result,1946 result,194319511944 fn owned_amount(1952 fn owned_amount(1945 subject: T::AccountId,1953 subject: T::AccountId,1946 collection_id: CollectionId,1954 target_collection: &Collection<T>,1947 item_id: TokenId,1955 item_id: TokenId,1948 ) -> Option<u128> {1956 ) -> Option<u128> {1949 let target_collection = <Collection<T>>::get(collection_id);1957 let collection_id = target_collection.id;195019581951 match target_collection.mode {1959 match target_collection.mode {1952 CollectionMode::NFT => {1960 CollectionMode::NFT => {1971 }1979 }1972 }1980 }197319811974 fn is_item_owner(subject: T::AccountId, collection_id: CollectionId, item_id: TokenId) -> bool {1982 fn is_item_owner(subject: T::AccountId, target_collection: &Collection<T>, item_id: TokenId) -> bool {1975 let target_collection = <Collection<T>>::get(collection_id).unwrap();1983 let collection_id = target_collection.id;197619841977 match target_collection.mode {1985 match target_collection.mode {1978 CollectionMode::NFT => {1986 CollectionMode::NFT => {1991 }1999 }1992 }2000 }199320011994 fn check_white_list(collection_id: CollectionId, address: &T::AccountId) -> DispatchResult {2002 fn check_white_list(collection: &Collection<T>, address: &T::AccountId) -> DispatchResult {2003 let collection_id = collection.id;20041995 let mes = Error::<T>::AddresNotInWhiteList;2005 let mes = Error::<T>::AddresNotInWhiteList;1996 ensure!(<WhiteList<T>>::contains_key(collection_id, address), mes);2006 ensure!(<WhiteList<T>>::contains_key(collection_id, address), mes);2001 /// Check if token exists. In case of Fungible, check if there is an entry for 2011 /// Check if token exists. In case of Fungible, check if there is an entry for 2002 /// the owner in fungible balances double map2012 /// the owner in fungible balances double map2003 fn token_exists(2013 fn token_exists(2004 collection_id: CollectionId,2014 target_collection: &Collection<T>,2005 item_id: TokenId,2015 item_id: TokenId,2006 owner: &T::AccountId2016 owner: &T::AccountId2007 ) -> DispatchResult {2017 ) -> DispatchResult {2008 let target_collection = <Collection<T>>::get(collection_id).unwrap();2018 let collection_id = target_collection.id;2009 let exists = match target_collection.mode2019 let exists = match target_collection.mode2010 {2020 {2011 CollectionMode::NFT => <NftItemList<T>>::contains_key(collection_id, item_id),2021 CollectionMode::NFT => <NftItemList<T>>::contains_key(collection_id, item_id),2019 }2029 }202020302021 fn transfer_fungible(2031 fn transfer_fungible(2022 collection_id: CollectionId,2032 collection: &Collection<T>,2023 value: u128,2033 value: u128,2024 owner: &T::AccountId,2034 owner: &T::AccountId,2025 recipient: &T::AccountId,2035 recipient: &T::AccountId,2026 ) -> DispatchResult {2036 ) -> DispatchResult {2027 Self::token_exists(collection_id, 0, owner)?;2037 let collection_id = collection.id;2038 Self::token_exists(&collection, 0, owner)?;202820392029 let mut balance = <FungibleItemList<T>>::get(collection_id, owner);2040 let mut balance = <FungibleItemList<T>>::get(collection_id, owner);2030 ensure!(balance.value >= value, Error::<T>::TokenValueTooLow);2041 ensure!(balance.value >= value, Error::<T>::TokenValueTooLow);203120422032 // Send balance to recipient (updates balanceOf of recipient)2043 // Send balance to recipient (updates balanceOf of recipient)2033 Self::add_fungible_item(collection_id, recipient, value)?;2044 Self::add_fungible_item(collection, recipient, value)?;203420452035 // update balanceOf of sender2046 // update balanceOf of sender2036 <Balance<T>>::insert(collection_id, (*owner).clone(), balance.value - value);2047 <Balance<T>>::insert(collection_id, (*owner).clone(), balance.value - value);2048 }2059 }204920602050 fn transfer_refungible(2061 fn transfer_refungible(2051 collection_id: CollectionId,2062 collection: &Collection<T>,2052 item_id: TokenId,2063 item_id: TokenId,2053 value: u128,2064 value: u128,2054 owner: T::AccountId,2065 owner: T::AccountId,2055 new_owner: T::AccountId,2066 new_owner: T::AccountId,2056 ) -> DispatchResult {2067 ) -> DispatchResult {2057 Self::token_exists(collection_id, item_id, &owner)?;2068 let collection_id = collection.id;2069 Self::token_exists(collection, item_id, &owner)?;205820702059 let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id);2071 let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id);2060 let item = full_item2072 let item = full_item2130 }2142 }213121432132 fn transfer_nft(2144 fn transfer_nft(2133 collection_id: CollectionId,2145 collection: &Collection<T>,2134 item_id: TokenId,2146 item_id: TokenId,2135 sender: T::AccountId,2147 sender: T::AccountId,2136 new_owner: T::AccountId,2148 new_owner: T::AccountId,2137 ) -> DispatchResult {2149 ) -> DispatchResult {2138 Self::token_exists(collection_id, item_id, &sender)?;2150 let collection_id = collection.id;2151 Self::token_exists(&collection, item_id, &sender)?;213921522140 let mut item = <NftItemList<T>>::get(collection_id, item_id);2153 let mut item = <NftItemList<T>>::get(collection_id, item_id);214121542167 }2180 }2168 2181 2169 fn set_re_fungible_variable_data(2182 fn set_re_fungible_variable_data(2170 collection_id: CollectionId,2183 collection: &Collection<T>,2171 item_id: TokenId,2184 item_id: TokenId,2172 data: Vec<u8>2185 data: Vec<u8>2173 ) -> DispatchResult {2186 ) -> DispatchResult {2187 let collection_id = collection.id;2174 let mut item = <ReFungibleItemList<T>>::get(collection_id, item_id);2188 let mut item = <ReFungibleItemList<T>>::get(collection_id, item_id);217521892176 item.variable_data = data;2190 item.variable_data = data;2181 }2195 }218221962183 fn set_nft_variable_data(2197 fn set_nft_variable_data(2184 collection_id: CollectionId,2198 collection: &Collection<T>,2185 item_id: TokenId,2199 item_id: TokenId,2186 data: Vec<u8>2200 data: Vec<u8>2187 ) -> DispatchResult {2201 ) -> DispatchResult {2202 let collection_id = collection.id;2188 let mut item = <NftItemList<T>>::get(collection_id, item_id);2203 let mut item = <NftItemList<T>>::get(collection_id, item_id);2189 2204 2190 item.variable_data = data;2205 item.variable_data = data;2194 Ok(())2209 Ok(())2195 }2210 }219622112197 fn init_collection(item: &CollectionType<T>) {2212 fn init_collection(item: &Collection<T>) {2198 // check params2213 // check params2199 assert!(2214 assert!(2200 item.decimal_points <= MAX_DECIMAL_POINTS,2215 item.decimal_points <= MAX_DECIMAL_POINTS,2274 }2289 }227522902276 fn add_token_index(collection_id: CollectionId, item_index: TokenId, owner: &T::AccountId) -> DispatchResult {2291 fn add_token_index(collection_id: CollectionId, item_index: TokenId, owner: &T::AccountId) -> DispatchResult {22772278 // add to account limit2292 // add to account limit2279 if <AccountItemCount<T>>::contains_key(owner) {2293 if <AccountItemCount<T>>::contains_key(owner) {22802294244924632450 // Determine who is paying transaction fee based on ecnomic model2464 // Determine who is paying transaction fee based on ecnomic model2451 // Parse call to extract collection ID and access collection sponsor2465 // Parse call to extract collection ID and access collection sponsor2452 let mut sponsor: T::AccountId = match IsSubType::<Call<T>>::is_sub_type(call) {2466 let mut sponsor: Option<T::AccountId> = (|| match IsSubType::<Call<T>>::is_sub_type(call) {2453 Some(Call::create_item(collection_id, _owner, _properties)) => {2467 Some(Call::create_item(collection_id, _owner, _properties)) => {2454 let collection = <Collection<T>>::get(collection_id).unwrap();2468 let collection = <CollectionById<T>>::get(collection_id)?;245524692456 // sponsor timeout2470 // sponsor timeout2457 let block_number = <system::Module<T>>::block_number() as T::BlockNumber;2471 let block_number = <system::Module<T>>::block_number() as T::BlockNumber;245824722459 let limit = collection.limits.sponsor_transfer_timeout;2473 let limit = collection.limits.sponsor_transfer_timeout;2460 let mut sponsored = true;2461 if <CreateItemBasket<T>>::contains_key((collection_id, &who)) {2474 if <CreateItemBasket<T>>::contains_key((collection_id, &who)) {2462 let last_tx_block = <CreateItemBasket<T>>::get((collection_id, &who));2475 let last_tx_block = <CreateItemBasket<T>>::get((collection_id, &who));2463 let limit_time = last_tx_block + limit.into();2476 let limit_time = last_tx_block + limit.into();2464 if block_number <= limit_time {2477 if block_number <= limit_time {2465 sponsored = false;2478 return None;2466 }2479 }2467 }2480 }2468 if sponsored {2481 <CreateItemBasket<T>>::insert((collection_id, who.clone()), block_number);2469 <CreateItemBasket<T>>::insert((collection_id, who.clone()), block_number);2470 }247124822472 // check free create limit2483 // check free create limit2473 if (collection.limits.sponsored_data_size >= (_properties.len() as u32)) &&2484 if (collection.limits.sponsored_data_size >= (_properties.len() as u32)) &&2474 (collection.sponsor_confirmed) &&2485 (collection.sponsor_confirmed)2475 (sponsored)2476 {2486 {2477 collection.sponsor2487 Some(collection.sponsor)2478 } else {2488 } else {2479 T::AccountId::default()2489 None2480 }2490 }2481 }2491 }2482 Some(Call::transfer(_new_owner, collection_id, item_id, _value)) => {2492 Some(Call::transfer(_new_owner, collection_id, item_id, _value)) => {2483 let collection = <Collection<T>>::get(collection_id).unwrap();2493 let collection = <CollectionById<T>>::get(collection_id)?;2484 2494 2485 let mut sponsor_transfer = false;2495 let mut sponsor_transfer = false;2486 if collection.sponsor_confirmed {2496 if collection.sponsor_confirmed {2568 }2578 }256925792570 if !sponsor_transfer {2580 if !sponsor_transfer {2571 T::AccountId::default()2581 None2572 } else {2582 } else {2573 collection.sponsor2583 Some(collection.sponsor)2574 }2584 }2575 }2585 }257625862577 Some(Call::set_variable_meta_data(collection_id, item_id, data)) => {2587 Some(Call::set_variable_meta_data(collection_id, item_id, data)) => {2578 let mut sponsor_metadata_changes = false;2588 let mut sponsor_metadata_changes = false;257925892580 let collection = <Collection<T>>::get(collection_id).unwrap();2590 let collection = <CollectionById<T>>::get(collection_id)?;258125912582 if2592 if2583 collection.sponsor_confirmed &&2593 collection.sponsor_confirmed &&2600 }2610 }260126112602 if !sponsor_metadata_changes {2612 if !sponsor_metadata_changes {2603 T::AccountId::default()2613 None2604 } else {2614 } else {2605 collection.sponsor2615 Some(collection.sponsor)2606 }2616 }2607 }2617 }260826182609 _ => T::AccountId::default(),2619 _ => None,2610 };2620 })();261126212622 match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {2623 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {26242625 let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());26262627 let owned_contract = <ContractOwner<T>>::contains_key(called_contract.clone())2628 && <ContractOwner<T>>::get(called_contract.clone()) == *who;2629 let white_list_enabled = <ContractWhiteListEnabled<T>>::contains_key(called_contract.clone()) && <ContractWhiteListEnabled<T>>::get(called_contract.clone());2630 2631 if !owned_contract && white_list_enabled {2632 if !<ContractWhiteList<T>>::contains_key(called_contract.clone(), who) {2633 return Err(InvalidTransaction::Call.into());2634 }2635 }2636 },2637 _ => {},2638 }26392612 // Sponsor smart contracts2640 // Sponsor smart contracts2613 sponsor = match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {2641 sponsor = sponsor.or_else(|| match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {261426422615 // On instantiation: set the contract owner2643 // On instantiation: set the contract owner2616 Some(pallet_contracts::Call::instantiate(_endowment, _gas_limit, code_hash, _data, salt)) => {2644 Some(pallet_contracts::Call::instantiate(_endowment, _gas_limit, code_hash, _data, salt)) => {2622 );2650 );2623 <ContractOwner<T>>::insert(new_contract_address.clone(), who.clone());2651 <ContractOwner<T>>::insert(new_contract_address.clone(), who.clone());262426522625 T::AccountId::default()2653 None2626 },2654 },262726552628 // When the contract is called, check if the sponsoring is enabled and pay fees from contract endowment if it is2656 // When the contract is called, check if the sponsoring is enabled and pay fees from contract endowment if it is2629 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {2657 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {263026582631 let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());2659 let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());263226602633 let owned_contract = <ContractOwner<T>>::contains_key(called_contract.clone())2634 && <ContractOwner<T>>::get(called_contract.clone()) == *who;2635 let white_list_enabled = <ContractWhiteListEnabled<T>>::contains_key(called_contract.clone()) && <ContractWhiteListEnabled<T>>::get(called_contract.clone());2636 2637 if !owned_contract && white_list_enabled {2638 if !<ContractWhiteList<T>>::contains_key(called_contract.clone(), who) {2639 return Err(InvalidTransaction::Call.into());2640 }2641 }26422643 let mut sponsor_transfer = false;2661 let mut sponsor_transfer = false;2644 if <ContractSponsoringRateLimit<T>>::contains_key(called_contract.clone()) {2662 if <ContractSponsoringRateLimit<T>>::contains_key(called_contract.clone()) {2645 let last_tx_block = <ContractSponsorBasket<T>>::get((&called_contract, &who));2663 let last_tx_block = <ContractSponsorBasket<T>>::get((&called_contract, &who));2655 sponsor_transfer = false;2673 sponsor_transfer = false;2656 }2674 }2657 2675 2658 2659 let mut sp = T::AccountId::default();2660 if sponsor_transfer {2676 if sponsor_transfer {2661 if <ContractSelfSponsoring<T>>::contains_key(called_contract.clone()) {2677 if <ContractSelfSponsoring<T>>::contains_key(called_contract.clone()) {2662 if <ContractSelfSponsoring<T>>::get(called_contract.clone()) {2678 if <ContractSelfSponsoring<T>>::get(called_contract.clone()) {2663 sp = called_contract;2679 return Some(called_contract);2664 }2680 }2665 }2681 }2666 }2682 }266726832668 sp2684 None2669 },2685 },267026862671 _ => sponsor,2687 _ => None,2672 };2688 });267326892674 let mut who_pays_fee: T::AccountId = sponsor.clone();2690 let who_pays_fee = sponsor.unwrap_or_else(|| who.clone());2675 if sponsor == T::AccountId::default() {2676 who_pays_fee = who.clone();2677 }267826912679 <<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::withdraw_fee(&who_pays_fee, call, info, fee, tip)2692 <<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::withdraw_fee(&who_pays_fee, call, info, fee, tip)2680 .map(|i| (fee, i))2693 .map(|i| (fee, i))runtime/src/chain_extension.rsdiffbeforeafterboth--- a/runtime/src/chain_extension.rs
+++ b/runtime/src/chain_extension.rs
@@ -60,7 +60,9 @@
}
let recipient = AccountId32::from(bytes_rec);
- match pallet_nft::Module::<Runtime>::transfer_internal(sender, recipient, input.collection_id, input.token_id, input.amount) {
+ let collection = pallet_nft::Module::<Runtime>::get_collection(input.collection_id)?;
+
+ match pallet_nft::Module::<Runtime>::transfer_internal(sender, recipient, &collection, input.token_id, input.amount) {
Ok(_) => Ok(RetVal::Converging(func_id)),
_ => Err(DispatchError::Other("Transfer error"))
}
runtime_types.jsondiffbeforeafterboth--- a/runtime_types.json
+++ b/runtime_types.json
@@ -31,7 +31,8 @@
"ConstData": "Vec<u8>",
"VariableData": "Vec<u8>"
},
- "CollectionType": {
+ "Collection": {
+ "Id": "CollectionId",
"Owner": "AccountId",
"Mode": "CollectionMode",
"Access": "AccessMode",