difftreelog
feat support approve from evm
in: master
1 file changed
pallets/nft/src/lib.rsdiffbeforeafterboth1239 /// * item_id: ID of the item.1239 /// * item_id: ID of the item.1240 #[weight = <T as Config>::WeightInfo::approve()]1240 #[weight = <T as Config>::WeightInfo::approve()]1241 #[transactional]1241 #[transactional]1242 pub fn approve(origin, spender: T::AccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResult {1242 pub fn approve(origin, spender: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResult {124312431244 let sender = ensure_signed(origin)?;1244 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);1245 let target_collection = Self::get_collection(collection_id)?;1245 let collection = Self::get_collection(collection_id)?;124612461247 Self::token_exists(&target_collection, item_id)?;1247 Self::approve_internal(sender, spender, &collection, item_id, amount)?;124812481249 // Transfer permissions check1250 let bypasses_limits = target_collection.limits.owner_can_transfer &&1251 Self::is_owner_or_admin_permissions(1252 &target_collection,1253 sender.clone(),1254 );12551256 let allowance_limit = if bypasses_limits {1257 None1258 } else if let Some(amount) = Self::owned_amount(1259 sender.clone(),1260 &target_collection,1261 item_id,1262 ) {1263 Some(amount)1264 } else {1265 fail!(Error::<T>::NoPermission);1266 };12671268 if target_collection.access == AccessMode::WhiteList {1269 Self::check_white_list(&target_collection, &sender)?;1270 Self::check_white_list(&target_collection, &spender)?;1271 }12721273 let allowance: u128 = amount1274 .checked_add(<Allowances<T>>::get(collection_id, (item_id, &sender, &spender)))1275 .ok_or(Error::<T>::NumOverflow)?;1276 if let Some(limit) = allowance_limit {1277 ensure!(limit >= allowance, Error::<T>::TokenValueTooLow);1278 }1279 <Allowances<T>>::insert(collection_id, (item_id, sender.clone(), spender.clone()), allowance);12801281 Self::deposit_event(RawEvent::Approved(target_collection.id, item_id, sender, spender, allowance));1282 Ok(())1249 Ok(())1283 }1250 }1284 1251 1303 /// * value: Amount to transfer.1270 /// * value: Amount to transfer.1304 #[weight = <T as Config>::WeightInfo::transfer_from()]1271 #[weight = <T as Config>::WeightInfo::transfer_from()]1305 #[transactional]1272 #[transactional]1306 pub fn transfer_from(origin, from: T::AccountId, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResult {1273 pub fn transfer_from(origin, from: T::CrossAccountId, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResult {130712741308 let sender = ensure_signed(origin)?;1275 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);1309 let target_collection = Self::get_collection(collection_id)?;1276 let collection = Self::get_collection(collection_id)?;131012771311 // Check approval1278 Self::transfer_from_internal(sender, from, recipient, &collection, item_id, value)?;1312 let approval: u128 = <Allowances<T>>::get(collection_id, (item_id, &from, &sender));131312791314 // Limits check1315 Self::is_correct_transfer(&target_collection, &recipient)?;13161317 // Transfer permissions check 1318 ensure!(1319 approval >= value || 1320 (1321 target_collection.limits.owner_can_transfer &&1322 Self::is_owner_or_admin_permissions(&target_collection, sender.clone())1323 ),1324 Error::<T>::NoPermission1325 );13261327 if target_collection.access == AccessMode::WhiteList {1328 Self::check_white_list(&target_collection, &sender)?;1329 Self::check_white_list(&target_collection, &recipient)?;1330 }13311332 // Reduce approval by transferred amount or remove if remaining approval drops to 01333 if approval.saturating_sub(value) > 0 {1334 <Allowances<T>>::insert(collection_id, (item_id, &from, &sender), approval - value);1335 }1336 else {1337 <Allowances<T>>::remove(collection_id, (item_id, &from, &sender));1338 }13391340 match target_collection.mode1341 {1342 CollectionMode::NFT => Self::transfer_nft(&target_collection, item_id, from.clone(), recipient.clone())?,1343 CollectionMode::Fungible(_) => Self::transfer_fungible(&target_collection, value, &from, &recipient)?,1344 CollectionMode::ReFungible => Self::transfer_refungible(&target_collection, item_id, value, from.clone(), recipient.clone())?,1345 _ => ()1346 };13471348 Self::deposit_event(RawEvent::Transfer(target_collection.id, item_id, from, recipient, value));1349 Ok(())1280 Ok(())1350 }1281 }135112821767 }1698 }176816991769 pub fn approve_internal(1700 pub fn approve_internal(1770 sender: T::AccountId,1701 sender: T::CrossAccountId,1771 spender: T::AccountId,1702 spender: T::CrossAccountId,1772 collection: &CollectionHandle<T>,1703 collection: &CollectionHandle<T>,1773 item_id: TokenId,1704 item_id: TokenId,1774 amount: u1281705 amount: u1281800 }1731 }180117321802 let allowance: u128 = amount1733 let allowance: u128 = amount1803 .checked_add(<Allowances<T>>::get(collection.id, (item_id, &sender, &spender)))1734 .checked_add(<Allowances<T>>::get(collection.id, (item_id, sender.as_sub(), spender.as_sub())))1804 .ok_or(Error::<T>::NumOverflow)?;1735 .ok_or(Error::<T>::NumOverflow)?;1805 if let Some(limit) = allowance_limit {1736 if let Some(limit) = allowance_limit {1806 ensure!(limit >= allowance, Error::<T>::TokenValueTooLow);1737 ensure!(limit >= allowance, Error::<T>::TokenValueTooLow);1807 }1738 }1808 <Allowances<T>>::insert(collection.id, (item_id, sender.clone(), spender.clone()), allowance);1739 <Allowances<T>>::insert(collection.id, (item_id, sender.as_sub(), spender.as_sub()), allowance);1809174017411810 Self::deposit_event(RawEvent::Approved(collection.id, item_id, sender, spender, allowance));1742 Self::deposit_event(RawEvent::Approved(collection.id, item_id, sender, spender, allowance));1811 Ok(())1743 Ok(())1812 }1744 }181317451814 pub fn transfer_from_internal(1746 pub fn transfer_from_internal(1815 sender: T::AccountId,1747 sender: T::CrossAccountId,1816 from: T::AccountId,1748 from: T::CrossAccountId,1817 recipient: T::AccountId,1749 recipient: T::CrossAccountId,1818 collection: &CollectionHandle<T>,1750 collection: &CollectionHandle<T>,1819 item_id: TokenId,1751 item_id: TokenId,1820 amount: u128,1752 amount: u128,1821 ) -> DispatchResult {1753 ) -> DispatchResult {1822 // Check approval1754 // Check approval1823 let approval: u128 = <Allowances<T>>::get(collection.id, (item_id, &from, &sender));1755 let approval: u128 = <Allowances<T>>::get(collection.id, (item_id, from.as_sub(), sender.as_sub()));182417561825 // Limits check1757 // Limits check1826 Self::is_correct_transfer(&collection, &recipient)?;1758 Self::is_correct_transfer(&collection, &recipient)?;1841 }1773 }184217741843 // Reduce approval by transferred amount or remove if remaining approval drops to 01775 // Reduce approval by transferred amount or remove if remaining approval drops to 01844 if approval.saturating_sub(amount) > 0 {1776 let allowance = approval.saturating_sub(amount);1777 if allowance > 0 {1845 <Allowances<T>>::insert(collection.id, (item_id, &from, &sender), approval - amount);1778 <Allowances<T>>::insert(collection.id, (item_id, from.as_sub(), sender.as_sub()), allowance);1846 } else {1779 } else {1847 <Allowances<T>>::remove(collection.id, (item_id, &from, &sender));1780 <Allowances<T>>::remove(collection.id, (item_id, from.as_sub(), sender.as_sub()));1848 }1781 }184917821850 match collection.mode {1783 match collection.mode {1859 }1792 }1860 _ => ()1793 _ => ()1861 };1794 };17951796 Ok(())1797 }186217981863 pub fn create_multiple_items_internal(1799 pub fn create_multiple_items_internal(1864 sender: T::CrossAccountId,1800 sender: T::CrossAccountId,