git.delta.rocks / unique-network / refs/commits / aa106c3319ad

difftreelog

feat implement ERC721Burnable/Mintable interfaces

Yaroslav Bolyukin2021-06-28parent: #eef8c23.patch.diff
in: master

2 files changed

modifiedpallets/nft/src/eth/erc.rsdiffbeforeafterboth
--- a/pallets/nft/src/eth/erc.rs
+++ b/pallets/nft/src/eth/erc.rs
@@ -1,12 +1,16 @@
 use core::char::{decode_utf16, REPLACEMENT_CHARACTER};
 use evm_coder::{ToLog, execution::Result, solidity, solidity_interface, types::*};
+use nft_data_structs::{CreateItemData, CreateNftData};
 use core::convert::TryInto;
 use alloc::format;
-use crate::{Allowances, Module, Balance, CollectionHandle, CollectionMode, Config, NftItemList};
-use frame_support::storage::StorageDoubleMap;
+use crate::{
+	Allowances, Module, Balance, CollectionHandle, CollectionMode, Config, NftItemList,
+	ItemListIndex,
+};
+use frame_support::storage::{StorageMap, StorageDoubleMap};
 use pallet_evm::AddressMapping;
 use super::account::CrossAccountId;
-use sp_std::vec::Vec;
+use sp_std::{vec, vec::Vec};
 
 #[solidity_interface(name = "ERC165")]
 impl<T: Config> CollectionHandle<T> {
@@ -178,6 +182,91 @@
 	}
 }
 
+#[solidity_interface(name = "ERC721Burnable")]
+impl<T: Config> CollectionHandle<T> {
+	fn burn(&mut self, caller: caller, token_id: uint256) -> Result<void> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let token_id = token_id.try_into().map_err(|_| "amount overflow")?;
+
+		<Module<T>>::burn_item_internal(&caller, &self, token_id, 1).map_err(|_| "burn error")?;
+		Ok(())
+	}
+}
+
+#[derive(ToLog)]
+pub enum ERC721MintableEvents {
+	#[allow(dead_code)]
+	MintingFinished {},
+}
+
+#[solidity_interface(name = "ERC721Mintable", events(ERC721MintableEvents))]
+impl<T: Config> CollectionHandle<T> {
+	fn minting_finished(&self) -> Result<bool> {
+		Ok(false)
+	}
+
+	fn mint(&mut self, caller: caller, to: address, token_id: uint256) -> Result<bool> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let to = T::CrossAccountId::from_eth(to);
+		let token_id: u32 = token_id.try_into().map_err(|_| "amount overflow")?;
+		if <ItemListIndex>::get(self.id)
+			.checked_add(1)
+			.ok_or("item id overflow")?
+			!= token_id
+		{
+			return Err("item id should be next".into());
+		}
+
+		<Module<T>>::create_item_internal(
+			&caller,
+			&self,
+			&to,
+			CreateItemData::NFT(CreateNftData {
+				const_data: vec![],
+				variable_data: vec![],
+			}),
+		)
+		.map_err(|_| "mint error")?;
+		Ok(true)
+	}
+
+	#[solidity(rename_selector = "mintWithTokenURI")]
+	fn mint_with_token_uri(
+		&mut self,
+		caller: caller,
+		to: address,
+		token_id: uint256,
+		token_uri: string,
+	) -> Result<bool> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let to = T::CrossAccountId::from_eth(to);
+		let token_id: u32 = token_id.try_into().map_err(|_| "amount overflow")?;
+		if <ItemListIndex>::get(self.id)
+			.checked_add(1)
+			.ok_or("item id overflow")?
+			!= token_id
+		{
+			return Err("item id should be next".into());
+		}
+
+		<Module<T>>::create_item_internal(
+			&caller,
+			&self,
+			&to,
+			CreateItemData::NFT(CreateNftData {
+				const_data: token_uri.into(),
+				variable_data: vec![],
+			}),
+		)
+		.map_err(|_| "mint error")?;
+		Ok(true)
+	}
+
+	fn finish_minting(&mut self, _caller: caller) -> Result<bool> {
+		Err("not implementable".into())
+	}
+}
+
 #[solidity_interface(name = "ERC721UniqueExtensions")]
 impl<T: Config> CollectionHandle<T> {
 	#[solidity(rename_selector = "transfer")]
@@ -196,6 +285,13 @@
 			.map_err(|_| "transfer error")?;
 		Ok(())
 	}
+
+	fn next_token_id(&self) -> Result<uint256> {
+		Ok(ItemListIndex::get(self.id)
+			.checked_add(1)
+			.ok_or("item id overflow")?
+			.into())
+	}
 }
 
 #[solidity_interface(
@@ -205,7 +301,9 @@
 		ERC721,
 		ERC721Metadata,
 		ERC721Enumerable,
-		ERC721UniqueExtensions
+		ERC721UniqueExtensions,
+		ERC721Mintable,
+		ERC721Burnable,
 	)
 )]
 impl<T: Config> CollectionHandle<T> {}
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
1236 }1236 }
1237}1237}
12381238
1239impl<T: Config> Module<T> {1239impl<T: Config> Module<T> {
1240 pub fn create_item_internal(1240 pub fn create_item_internal(
1241 sender: &T::CrossAccountId,1241 sender: &T::CrossAccountId,
1242 collection: &CollectionHandle<T>,1242 collection: &CollectionHandle<T>,
1243 owner: &T::CrossAccountId,1243 owner: &T::CrossAccountId,
1244 data: CreateItemData,1244 data: CreateItemData,
1245 ) -> DispatchResult {1245 ) -> DispatchResult {
1246 ensure!(1246 ensure!(
1247 owner != &T::CrossAccountId::from_eth(H160([0; 20])),1247 owner != &T::CrossAccountId::from_eth(H160([0; 20])),
1248 Error::<T>::AddressIsZero1248 Error::<T>::AddressIsZero
1249 );1249 );
12501250
1251 Self::can_create_items_in_collection(collection, sender, owner, 1)?;1251 Self::can_create_items_in_collection(collection, sender, owner, 1)?;
1252 Self::validate_create_item_args(collection, &data)?;1252 Self::validate_create_item_args(collection, &data)?;
1253 Self::create_item_no_validation(collection, owner, data)?;1253 Self::create_item_no_validation(collection, owner, data)?;
1254
1255 Ok(())
1256 }
1257
1254 pub fn transfer_internal(1258 pub fn transfer_internal(
1255 sender: &T::CrossAccountId,1259 sender: &T::CrossAccountId,
1819 <NftItemList<T>>::remove(collection_id, item_id);1823 <NftItemList<T>>::remove(collection_id, item_id);
1820 <VariableMetaDataBasket<T>>::remove(collection_id, item_id);1824 <VariableMetaDataBasket<T>>::remove(collection_id, item_id);
18211825
1826 collection.log(ERC721Events::Transfer {
1827 from: *item.owner.as_eth(),
1828 to: H160::default(),
1829 token_id: item_id.into(),
1830 })?;
1822 Self::deposit_event(RawEvent::ItemDestroyed(collection.id, item_id));1831 Self::deposit_event(RawEvent::ItemDestroyed(collection.id, item_id));
1823 Ok(())1832 Ok(())
1824 }1833 }
2328 }2337 }
2329}2338}
23302339
2331sp_api::decl_runtime_apis! {2340sp_api::decl_runtime_apis! {
2332 pub trait NftApi {2341 pub trait NftApi {
2333 /// Used for ethereum integration2342 /// Used for ethereum integration
2334 fn eth_contract_code(account: H160) -> Option<Vec<u8>>;2343 fn eth_contract_code(account: H160) -> Option<Vec<u8>>;
2335 }2344 }
2336}2345}
23372346