git.delta.rocks / unique-network / refs/commits / 24bc802b4d0c

difftreelog

feat item creation from evm

Yaroslav Bolyukin2021-04-30parent: #2b03ee1.patch.diff
in: master

1 file changed

modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
11171117
1118 #[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 {
11211121
1122 let sender = ensure_signed(origin)?;1122 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
11231123
1124 let target_collection = Self::get_collection(collection_id)?;1124 let target_collection = Self::get_collection(collection_id)?;
11251125
1152 .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 {
11561156
1157 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)?;
11591160
1160 let target_collection = Self::get_collection(collection_id)?;1161 Self::create_multiple_items_internal(sender, &collection, owner, items_data)?;
11611162
1162 Self::can_create_items_in_collection(&target_collection, &sender, &owner, items_data.len() as u32)?;
1163
1164 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 }
1170
1171 Ok(())1163 Ok(())
1172 }1164 }
11731165
1795 Ok(())1787 Ok(())
1796 }1788 }
17971789
1790 pub fn approve_internal(
1791 sender: T::AccountId,
1792 spender: T::AccountId,
1793 collection: &CollectionHandle<T>,
1794 item_id: TokenId,
1795 amount: u128
1796 ) -> DispatchResult {
1797 Self::token_exists(&collection, item_id)?;
17981798
1799 // Transfer permissions check
1800 let bypasses_limits = collection.limits.owner_can_transfer &&
1801 Self::is_owner_or_admin_permissions(
1802 &collection,
1803 sender.clone(),
1804 );
1805
1806 let allowance_limit = if bypasses_limits {
1807 None
1808 } 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 };
1817
1818 if collection.access == AccessMode::WhiteList {
1819 Self::check_white_list(&collection, &sender)?;
1820 Self::check_white_list(&collection, &spender)?;
1821 }
1822
1823 let allowance: u128 = amount
1824 .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);
1830
1831 Self::deposit_event(RawEvent::Approved(collection.id, item_id, sender, spender, allowance));
1832 Ok(())
1833 }
1834
1835 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 approval
1844 let approval: u128 = <Allowances<T>>::get(collection.id, (item_id, &from, &sender));
1845
1846 // Limits check
1847 Self::is_correct_transfer(&collection, &recipient)?;
1848
1849 // Transfer permissions check
1850 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>::NoPermission
1857 );
1858
1859 if collection.access == AccessMode::WhiteList {
1860 Self::check_white_list(&collection, &sender)?;
1861 Self::check_white_list(&collection, &recipient)?;
1862 }
1863
1864 // Reduce approval by transferred amount or remove if remaining approval drops to 0
1865 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 }
1870
1871 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 };
1883
1884 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)?;
1891
1892 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 }
1898
1899 Ok(())
1900 }
1901
1799 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 }
18681971
1869 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 data
1871 {1974 {
1872 CreateItemData::NFT(data) => {1975 CreateItemData::NFT(data) => {
1898 Ok(())2001 Ok(())
1899 }2002 }
19002003
1901 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;
19032006
1904 // 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;
19062009
1907 // 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);
19122015
1913 // Update balance2016 // Update balance
1914 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);
19182021
1919 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 }
19222025
1923 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;
19252028
1926 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);
19442047
1945 // Update balance2048 // Update balance
1946 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);
19502053
1951 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 }
19542057
1955 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;
19572060
1958 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);
19672070
1968 // Update balance2071 // Update balance
1969 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);
19732076
1974 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(())