git.delta.rocks / unique-network / refs/commits / 353c1c657ac7

difftreelog

refactor! rewrite collections accessors

Yaroslav Bolyukin2021-03-05parent: #a84a730.patch.diff
in: master
Squashed from multiple

4 files changed

modifiednode/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,
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
125125
126#[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;
427428
428 // Basic collections429 // Basic collections
429 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;
432433
464 add_extra_genesis {465 add_extra_genesis {
465 build(|config: &GenesisConfig<T>| {466 build(|config: &GenesisConfig<T>| {
466 // Modification of storage467 // Modification of storage
467 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 }
470471
615 };616 };
616617
617 // Create new collection618 // Create new collection
618 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 };
635637
636 // Add new collection to map638 // Add new collection to map
637 <Collection<T>>::insert(next_id, new_collection);639 <CollectionById<T>>::insert(next_id, new_collection);
638640
639 // call event641 // call event
640 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 {
656658
657 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)?;
659
660 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 }
664665
667 <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);
672673
673 <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{
710711
711 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)?;
713715
714 <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{
733735
734 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)?;
736739
737 <WhiteList<T>>::remove(collection_id, address);740 <WhiteList<T>>::remove(collection_id, address);
738741
755 {758 {
756 let sender = ensure_signed(origin)?;759 let sender = ensure_signed(origin)?;
757760
758 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);
762765
763 Ok(())766 Ok(())
764 }767 }
781 {784 {
782 let sender = ensure_signed(origin)?;785 let sender = ensure_signed(origin)?;
783786
784 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);
788791
789 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 {
805808
806 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);
811814
812 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 {
830833
831 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();
834838
835 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 {
864868
865 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);
868873
869 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 {
887892
888 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)?;
889896
890 let mut target_collection = <Collection<T>>::get(collection_id).ok_or(Error::<T>::CollectionNotFound)?;
891 ensure!(sender == target_collection.owner, Error::<T>::NoPermission);
892
893 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);
896900
897 Ok(())901 Ok(())
898 }902 }
909913
910 let sender = ensure_signed(origin)?;914 let sender = ensure_signed(origin)?;
911915
912 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);
914918
915 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);
917921
918 Ok(())922 Ok(())
919 }923 }
932936
933 let sender = ensure_signed(origin)?;937 let sender = ensure_signed(origin)?;
934938
935 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)?;
937941
938 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);
941945
942 Ok(())946 Ok(())
943 }947 }
971975
972 let sender = ensure_signed(origin)?;976 let sender = ensure_signed(origin)?;
973977
974 Self::collection_exists(collection_id)?;978 let target_collection = Self::get_collection(collection_id)?;
975979
976 let target_collection = <Collection<T>>::get(collection_id).unwrap();980 Self::can_create_items_in_collection(&target_collection, &sender, &owner)?;
977
978 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)?;
981983
982 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)?;
10101012
1011 Self::collection_exists(collection_id)?;1013 let target_collection = Self::get_collection(collection_id)?;
1012 let target_collection = <Collection<T>>::get(collection_id).unwrap();
10131014
1014 Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;1015 Self::can_create_items_in_collection(&target_collection, &sender, &owner)?;
10151016
1016 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 }
10221023
1023 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 {
10411042
1042 let sender = ensure_signed(origin)?;1043 let sender = ensure_signed(origin)?;
1043 Self::collection_exists(collection_id)?;
10441044
1045 // Transfer permissions check1045 // Transfer permissions check
1046 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>::NoPermission
1054 );1054 );
10551055
1056 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 }
10591059
1060 match target_collection.mode1060 match target_collection.mode
1061 {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 };
10671067
1068 // call event1068 // call event
1069 Self::deposit_event(RawEvent::ItemDestroyed(collection_id, item_id));1069 Self::deposit_event(RawEvent::ItemDestroyed(target_collection.id, item_id));
10701070
1071 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)?;
1101
1102 Self::transfer_internal(sender, recipient, &collection, item_id, value)
1101 }1103 }
11021104
1103 /// 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 {
11201122
1121 let sender = ensure_signed(origin)?;1123 let sender = ensure_signed(origin)?;
1124 let target_collection = Self::get_collection(collection_id)?;
11221125
1123 Self::collection_exists(collection_id)?;1126 Self::token_exists(&target_collection, item_id, &sender)?;
1124 Self::token_exists(collection_id, item_id, &sender)?;
11251127
1126 // Transfer permissions check1128 // Transfer permissions check
1127 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 None
1136 } 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 };
11451146
1146 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 }
11501151
1151 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 {
11851186
1186 let sender = ensure_signed(origin)?;1187 let sender = ensure_signed(origin)?;
1188 let target_collection = Self::get_collection(collection_id)?;
1189
1187 let mut appoved_transfer = false;1190 let mut appoved_transfer = false;
11881191
1189 // Check approval1192 // Check approval
1194 appoved_transfer = true;1197 appoved_transfer = true;
1195 }1198 }
11961199
1197 let target_collection = <Collection<T>>::get(collection_id).unwrap();
1198
1199 // Limits check1200 // Limits check
1200 Self::is_correct_transfer(collection_id, &target_collection, &recipient)?;1201 Self::is_correct_transfer(&target_collection, &recipient)?;
12011202
1202 // 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>::NoPermission
1210 );1211 );
12111212
1212 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 }
12161217
1217 // 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 0
12241225
1225 match target_collection.mode1226 match target_collection.mode
1226 {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 };
12321233
1269 ) -> 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)?;
12741275
1275 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);
12761277
1277 // Modify permissions check1278 // Modify permissions check
1278 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);
12821282
1283 match target_collection.mode1283 match target_collection.mode
1284 {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: SchemaVersion
1313 ) -> 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);
13191319
1320 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())?;
13431344
1344 // check schema limit1345 // check schema limit
1345 ensure!(schema.len() as u32 <= ChainLimit::get().offchain_schema_limit, "");1346 ensure!(schema.len() as u32 <= ChainLimit::get().offchain_schema_limit, "");
13461347
1347 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);
13501350
1351 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())?;
13741375
1375 // check schema limit1376 // check schema limit
1376 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, "");
13771378
1378 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);
13811381
1382 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())?;
14051406
1406 // check schema limit1407 // check schema limit
1407 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, "");
14081409
1409 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);
14121412
1413 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();
15841584
1599 );1599 );
16001600
1601 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);
16031603
1604 Ok(())1604 Ok(())
1605 } 1605 }
16081608
1609impl<T: Config> Module<T> {1609impl<T: Config> Module<T> {
16101610
1611 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 {
1612
1613 let target_collection = <Collection<T>>::get(collection_id).unwrap();
1614
1615 // Limits check1612 // Limits check
1616 Self::is_correct_transfer(collection_id, &target_collection, &recipient)?;1613 Self::is_correct_transfer(target_collection, &recipient)?;
16171614
1618 // Transfer permissions check1615 // Transfer permissions check
1619 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);
16221619
1623 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 }
16271624
1628 match target_collection.mode1625 match target_collection.mode
1629 {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 };
16351632
1636 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));
16371634
1638 Ok(())1635 Ok(())
1639 }1636 }
16401637
16411638
1642 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;
16431641
1644 // check token limit and account token limit1642 // check token limit and account token limit
1645 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 }
16501648
1651 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;
16521651
1653 // check token limit and account token limit1652 // check token limit and account token limit
1654 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);
16581657
1659 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 }
16641663
1665 Ok(())1664 Ok(())
1666 }1665 }
16671666
1668 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.mode
1670 {1669 {
1671 CollectionMode::NFT => {1670 CollectionMode::NFT => {
1703 Ok(())1702 Ok(())
1704 }1703 }
17051704
1706 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;
1707
1707 match data1708 match data
1708 {1709 {
1713 variable_data: data.variable_data1714 variable_data: data.variable_data
1714 };1715 };
17151716
1716 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_data
1729 };1730 };
17301731
1731 Self::add_refungible_item(collection_id, item)?;1732 Self::add_refungible_item(collection, item)?;
1732 }1733 }
1733 };1734 };
17341735
1738 Ok(())1739 Ok(())
1739 }1740 }
17401741
1741 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;
17421744
1743 // 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 }
17631765
1764 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;
1768
1765 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 }
17861790
1787 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;
1793
1788 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 }
18061812
1807 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;
1819
1812 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>::TokenNotFound
1849 Ok(())1857 Ok(())
1850 }1858 }
18511859
1852 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;
1862
1853 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 }
18701880
1871 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;
1883
1872 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 }
18951907
1896 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 }
19031912
1904 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 }
19061916
1907 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>::NoPermission
1913 Ok(())1923 Ok(())
1914 }1924 }
19151925
1916 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);
19201929
1921 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 = true
1924 }1933 }
1925 }1934 }
1928 }1937 }
19291938
1930 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());
19361944
1937 ensure!(1945 ensure!(
1938 result,1946 result,
19431951
1944 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;
19501958
1951 match target_collection.mode {1959 match target_collection.mode {
1952 CollectionMode::NFT => {1960 CollectionMode::NFT => {
1971 }1979 }
1972 }1980 }
19731981
1974 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;
19761984
1977 match target_collection.mode {1985 match target_collection.mode {
1978 CollectionMode::NFT => {1986 CollectionMode::NFT => {
1991 }1999 }
1992 }2000 }
19932001
1994 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;
2004
1995 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 map
2003 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::AccountId
2007 ) -> 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.mode
2010 {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 }
20202030
2021 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)?;
20282039
2029 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);
20312042
2032 // 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)?;
20342045
2035 // update balanceOf of sender2046 // update balanceOf of sender
2036 <Balance<T>>::insert(collection_id, (*owner).clone(), balance.value - value);2047 <Balance<T>>::insert(collection_id, (*owner).clone(), balance.value - value);
2048 }2059 }
20492060
2050 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)?;
20582070
2059 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_item
2130 }2142 }
21312143
2132 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)?;
21392152
2140 let mut item = <NftItemList<T>>::get(collection_id, item_id);2153 let mut item = <NftItemList<T>>::get(collection_id, item_id);
21412154
2167 }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);
21752189
2176 item.variable_data = data;2190 item.variable_data = data;
2181 }2195 }
21822196
2183 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 }
21962211
2197 fn init_collection(item: &CollectionType<T>) {2212 fn init_collection(item: &Collection<T>) {
2198 // check params2213 // check params
2199 assert!(2214 assert!(
2200 item.decimal_points <= MAX_DECIMAL_POINTS,2215 item.decimal_points <= MAX_DECIMAL_POINTS,
2274 }2289 }
22752290
2276 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 {
2277
2278 // add to account limit2292 // add to account limit
2279 if <AccountItemCount<T>>::contains_key(owner) {2293 if <AccountItemCount<T>>::contains_key(owner) {
22802294
24492463
2450 // Determine who is paying transaction fee based on ecnomic model2464 // Determine who is paying transaction fee based on ecnomic model
2451 // Parse call to extract collection ID and access collection sponsor2465 // Parse call to extract collection ID and access collection sponsor
2452 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)?;
24552469
2456 // sponsor timeout2470 // sponsor timeout
2457 let block_number = <system::Module<T>>::block_number() as T::BlockNumber;2471 let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
24582472
2459 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 }
24712482
2472 // check free create limit2483 // check free create limit
2473 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 None
2480 }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 }
25692579
2570 if !sponsor_transfer {2580 if !sponsor_transfer {
2571 T::AccountId::default()2581 None
2572 } else {2582 } else {
2573 collection.sponsor2583 Some(collection.sponsor)
2574 }2584 }
2575 }2585 }
25762586
2577 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;
25792589
2580 let collection = <Collection<T>>::get(collection_id).unwrap();2590 let collection = <CollectionById<T>>::get(collection_id)?;
25812591
2582 if2592 if
2583 collection.sponsor_confirmed &&2593 collection.sponsor_confirmed &&
2600 }2610 }
26012611
2602 if !sponsor_metadata_changes {2612 if !sponsor_metadata_changes {
2603 T::AccountId::default()2613 None
2604 } else {2614 } else {
2605 collection.sponsor2615 Some(collection.sponsor)
2606 }2616 }
2607 }2617 }
26082618
2609 _ => T::AccountId::default(),2619 _ => None,
2610 };2620 })();
26112621
2622 match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {
2623 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {
2624
2625 let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());
2626
2627 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 }
2639
2612 // Sponsor smart contracts2640 // Sponsor smart contracts
2613 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) {
26142642
2615 // On instantiation: set the contract owner2643 // On instantiation: set the contract owner
2616 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());
26242652
2625 T::AccountId::default()2653 None
2626 },2654 },
26272655
2628 // 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 is
2629 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {2657 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {
26302658
2631 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());
26322660
2633 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 }
2642
2643 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 }
26672683
2668 sp2684 None
2669 },2685 },
26702686
2671 _ => sponsor,2687 _ => None,
2672 };2688 });
26732689
2674 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 }
26782691
2679 <<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))
modifiedruntime/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"))
                 }
modifiedruntime_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",