difftreelog
feat item creation from evm
in: master
1 file changed
pallets/nft/src/lib.rsdiffbeforeafterboth111711171118 #[weight = <T as Config>::WeightInfo::create_item(data.len())]1118 #[weight = <T as Config>::WeightInfo::create_item(data.len())]1119 #[transactional]1119 #[transactional]1120 pub fn create_item(origin, collection_id: CollectionId, owner: T::AccountId, data: CreateItemData) -> DispatchResult {1120 pub fn create_item(origin, collection_id: CollectionId, owner: T::CrossAccountId, data: CreateItemData) -> DispatchResult {112111211122 let sender = ensure_signed(origin)?;1122 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);112311231124 let target_collection = Self::get_collection(collection_id)?;1124 let target_collection = Self::get_collection(collection_id)?;112511251152 .map(|data| { data.len() })1152 .map(|data| { data.len() })1153 .sum())]1153 .sum())]1154 #[transactional]1154 #[transactional]1155 pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::AccountId, items_data: Vec<CreateItemData>) -> DispatchResult {1155 pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::CrossAccountId, items_data: Vec<CreateItemData>) -> DispatchResult {115611561157 ensure!(items_data.len() > 0, Error::<T>::EmptyArgument);1157 ensure!(items_data.len() > 0, Error::<T>::EmptyArgument);1158 let sender = ensure_signed(origin)?;1158 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);1159 let collection = Self::get_collection(collection_id)?;115911601160 let target_collection = Self::get_collection(collection_id)?;1161 Self::create_multiple_items_internal(sender, &collection, owner, items_data)?;116111621162 Self::can_create_items_in_collection(&target_collection, &sender, &owner, items_data.len() as u32)?;11631164 for data in &items_data {1165 Self::validate_create_item_args(&target_collection, data)?;1166 }1167 for data in &items_data {1168 Self::create_item_no_validation(&target_collection, owner.clone(), data.clone())?;1169 }11701171 Ok(())1163 Ok(())1172 }1164 }117311651795 Ok(())1787 Ok(())1796 }1788 }179717891790 pub fn approve_internal(1791 sender: T::AccountId,1792 spender: T::AccountId,1793 collection: &CollectionHandle<T>,1794 item_id: TokenId,1795 amount: u1281796 ) -> DispatchResult {1797 Self::token_exists(&collection, item_id)?;179817981799 // Transfer permissions check1800 let bypasses_limits = collection.limits.owner_can_transfer &&1801 Self::is_owner_or_admin_permissions(1802 &collection,1803 sender.clone(),1804 );18051806 let allowance_limit = if bypasses_limits {1807 None1808 } else if let Some(amount) = Self::owned_amount(1809 sender.clone(),1810 &collection,1811 item_id,1812 ) {1813 Some(amount)1814 } else {1815 fail!(Error::<T>::NoPermission);1816 };18171818 if collection.access == AccessMode::WhiteList {1819 Self::check_white_list(&collection, &sender)?;1820 Self::check_white_list(&collection, &spender)?;1821 }18221823 let allowance: u128 = amount1824 .checked_add(<Allowances<T>>::get(collection.id, (item_id, &sender, &spender)))1825 .ok_or(Error::<T>::NumOverflow)?;1826 if let Some(limit) = allowance_limit {1827 ensure!(limit >= allowance, Error::<T>::TokenValueTooLow);1828 }1829 <Allowances<T>>::insert(collection.id, (item_id, sender.clone(), spender.clone()), allowance);18301831 Self::deposit_event(RawEvent::Approved(collection.id, item_id, sender, spender, allowance));1832 Ok(())1833 }18341835 pub fn transfer_from_internal(1836 sender: T::AccountId,1837 from: T::AccountId,1838 recipient: T::AccountId,1839 collection: &CollectionHandle<T>,1840 item_id: TokenId,1841 amount: u128,1842 ) -> DispatchResult {1843 // Check approval1844 let approval: u128 = <Allowances<T>>::get(collection.id, (item_id, &from, &sender));18451846 // Limits check1847 Self::is_correct_transfer(&collection, &recipient)?;18481849 // Transfer permissions check1850 ensure!(1851 approval >= amount || 1852 (1853 collection.limits.owner_can_transfer &&1854 Self::is_owner_or_admin_permissions(&collection, sender.clone())1855 ),1856 Error::<T>::NoPermission1857 );18581859 if collection.access == AccessMode::WhiteList {1860 Self::check_white_list(&collection, &sender)?;1861 Self::check_white_list(&collection, &recipient)?;1862 }18631864 // Reduce approval by transferred amount or remove if remaining approval drops to 01865 if approval.saturating_sub(amount) > 0 {1866 <Allowances<T>>::insert(collection.id, (item_id, &from, &sender), approval - amount);1867 } else {1868 <Allowances<T>>::remove(collection.id, (item_id, &from, &sender));1869 }18701871 match collection.mode {1872 CollectionMode::NFT => {1873 Self::transfer_nft(&collection, item_id, from.clone(), recipient.clone())?1874 }1875 CollectionMode::Fungible(_) => {1876 Self::transfer_fungible(&collection, amount, &from, &recipient)?1877 }1878 CollectionMode::ReFungible => {1879 Self::transfer_refungible(&collection, item_id, amount, from.clone(), recipient.clone())?1880 }1881 _ => ()1882 };18831884 pub fn create_multiple_items_internal(1885 sender: T::CrossAccountId,1886 collection: &CollectionHandle<T>,1887 owner: T::CrossAccountId,1888 items_data: Vec<CreateItemData>,1889 ) -> DispatchResult {1890 Self::can_create_items_in_collection(&collection, &sender, &owner, items_data.len() as u32)?;18911892 for data in &items_data {1893 Self::validate_create_item_args(&collection, data)?;1894 }1895 for data in &items_data {1896 Self::create_item_no_validation(&collection, owner.clone(), data.clone())?;1897 }18981899 Ok(())1900 }19011799 fn is_correct_transfer(collection: &CollectionHandle<T>, recipient: &T::AccountId) -> DispatchResult {1902 fn is_correct_transfer(collection: &CollectionHandle<T>, recipient: &T::AccountId) -> DispatchResult {1800 let collection_id = collection.id;1903 let collection_id = collection.id;1866 Ok(())1969 Ok(())1867 }1970 }186819711869 fn create_item_no_validation(collection: &CollectionHandle<T>, owner: T::AccountId, data: CreateItemData) -> DispatchResult {1972 fn create_item_no_validation(collection: &CollectionHandle<T>, owner: T::CrossAccountId, data: CreateItemData) -> DispatchResult {1870 match data1973 match data1871 {1974 {1872 CreateItemData::NFT(data) => {1975 CreateItemData::NFT(data) => {1898 Ok(())2001 Ok(())1899 }2002 }190020031901 fn add_fungible_item(collection: &CollectionHandle<T>, owner: &T::AccountId, value: u128) -> DispatchResult {2004 fn add_fungible_item(collection: &CollectionHandle<T>, owner: &T::CrossAccountId, value: u128) -> DispatchResult {1902 let collection_id = collection.id;2005 let collection_id = collection.id;190320061904 // Does new owner already have an account?2007 // Does new owner already have an account?1905 let balance: u128 = <FungibleItemList<T>>::get(collection_id, owner).value;2008 let balance: u128 = <FungibleItemList<T>>::get(collection_id, owner.as_sub()).value;190620091907 // Mint 2010 // Mint 1908 let item = FungibleItemType {2011 let item = FungibleItemType {1909 value: balance.checked_add(value).ok_or(Error::<T>::NumOverflow)?,2012 value: balance.checked_add(value).ok_or(Error::<T>::NumOverflow)?,1910 };2013 };1911 <FungibleItemList<T>>::insert(collection_id, (*owner).clone(), item);2014 <FungibleItemList<T>>::insert(collection_id, owner.as_sub(), item);191220151913 // Update balance2016 // Update balance1914 let new_balance = <Balance<T>>::get(collection_id, owner)2017 let new_balance = <Balance<T>>::get(collection_id, owner.as_sub())1915 .checked_add(value)2018 .checked_add(value)1916 .ok_or(Error::<T>::NumOverflow)?;2019 .ok_or(Error::<T>::NumOverflow)?;1917 <Balance<T>>::insert(collection_id, (*owner).clone(), new_balance);2020 <Balance<T>>::insert(collection_id, owner.as_sub(), new_balance);191820211919 Self::deposit_event(RawEvent::ItemCreated(collection_id, 0, owner.clone()));2022 Self::deposit_event(RawEvent::ItemCreated(collection_id, 0, owner.clone()));1920 Ok(())2023 Ok(())1921 }2024 }192220251923 fn add_refungible_item(collection: &CollectionHandle<T>, item: ReFungibleItemType<T::AccountId>) -> DispatchResult {2026 fn add_refungible_item(collection: &CollectionHandle<T>, item: ReFungibleItemType<T::CrossAccountId>) -> DispatchResult {1924 let collection_id = collection.id;2027 let collection_id = collection.id;192520281926 let current_index = <ItemListIndex>::get(collection_id)2029 let current_index = <ItemListIndex>::get(collection_id)1943 <ReFungibleItemList<T>>::insert(collection_id, current_index, itemcopy);2046 <ReFungibleItemList<T>>::insert(collection_id, current_index, itemcopy);194420471945 // Update balance2048 // Update balance1946 let new_balance = <Balance<T>>::get(collection_id, &owner)2049 let new_balance = <Balance<T>>::get(collection_id, owner.as_sub())1947 .checked_add(value)2050 .checked_add(value)1948 .ok_or(Error::<T>::NumOverflow)?;2051 .ok_or(Error::<T>::NumOverflow)?;1949 <Balance<T>>::insert(collection_id, owner.clone(), new_balance);2052 <Balance<T>>::insert(collection_id, owner.as_sub(), new_balance);195020531951 Self::deposit_event(RawEvent::ItemCreated(collection_id, current_index, owner));2054 Self::deposit_event(RawEvent::ItemCreated(collection_id, current_index, owner));1952 Ok(())2055 Ok(())1953 }2056 }195420571955 fn add_nft_item(collection: &CollectionHandle<T>, item: NftItemType<T::AccountId>) -> DispatchResult {2058 fn add_nft_item(collection: &CollectionHandle<T>, item: NftItemType<T::CrossAccountId>) -> DispatchResult {1956 let collection_id = collection.id;2059 let collection_id = collection.id;195720601958 let current_index = <ItemListIndex>::get(collection_id)2061 let current_index = <ItemListIndex>::get(collection_id)1966 <NftItemList<T>>::insert(collection_id, current_index, item);2069 <NftItemList<T>>::insert(collection_id, current_index, item);196720701968 // Update balance2071 // Update balance1969 let new_balance = <Balance<T>>::get(collection_id, item_owner.clone())2072 let new_balance = <Balance<T>>::get(collection_id, item_owner.as_sub())1970 .checked_add(1)2073 .checked_add(1)1971 .ok_or(Error::<T>::NumOverflow)?;2074 .ok_or(Error::<T>::NumOverflow)?;1972 <Balance<T>>::insert(collection_id, item_owner.clone(), new_balance);2075 <Balance<T>>::insert(collection_id, item_owner.as_sub(), new_balance);197320761974 Self::deposit_event(RawEvent::ItemCreated(collection_id, current_index, item_owner));2077 Self::deposit_event(RawEvent::ItemCreated(collection_id, current_index, item_owner));1975 Ok(())2078 Ok(())