difftreelog
feat implement ERC721Burnable/Mintable interfaces
in: master
2 files changed
pallets/nft/src/eth/erc.rsdiffbeforeafterboth1use core::char::{decode_utf16, REPLACEMENT_CHARACTER};1use core::char::{decode_utf16, REPLACEMENT_CHARACTER};2use evm_coder::{ToLog, execution::Result, solidity, solidity_interface, types::*};2use evm_coder::{ToLog, execution::Result, solidity, solidity_interface, types::*};3use nft_data_structs::{CreateItemData, CreateNftData};3use core::convert::TryInto;4use core::convert::TryInto;4use alloc::format;5use alloc::format;5use crate::{Allowances, Module, Balance, CollectionHandle, CollectionMode, Config, NftItemList};6use crate::{7 Allowances, Module, Balance, CollectionHandle, CollectionMode, Config, NftItemList,8 ItemListIndex,9};6use frame_support::storage::StorageDoubleMap;10use frame_support::storage::{StorageMap, StorageDoubleMap};7use pallet_evm::AddressMapping;11use pallet_evm::AddressMapping;8use super::account::CrossAccountId;12use super::account::CrossAccountId;9use sp_std::vec::Vec;13use sp_std::{vec, vec::Vec};101411#[solidity_interface(name = "ERC165")]15#[solidity_interface(name = "ERC165")]12impl<T: Config> CollectionHandle<T> {16impl<T: Config> CollectionHandle<T> {178 }182 }179}183}184185#[solidity_interface(name = "ERC721Burnable")]186impl<T: Config> CollectionHandle<T> {187 fn burn(&mut self, caller: caller, token_id: uint256) -> Result<void> {188 let caller = T::CrossAccountId::from_eth(caller);189 let token_id = token_id.try_into().map_err(|_| "amount overflow")?;190191 <Module<T>>::burn_item_internal(&caller, &self, token_id, 1).map_err(|_| "burn error")?;192 Ok(())193 }194}195196#[derive(ToLog)]197pub enum ERC721MintableEvents {198 #[allow(dead_code)]199 MintingFinished {},200}201202#[solidity_interface(name = "ERC721Mintable", events(ERC721MintableEvents))]203impl<T: Config> CollectionHandle<T> {204 fn minting_finished(&self) -> Result<bool> {205 Ok(false)206 }207208 fn mint(&mut self, caller: caller, to: address, token_id: uint256) -> Result<bool> {209 let caller = T::CrossAccountId::from_eth(caller);210 let to = T::CrossAccountId::from_eth(to);211 let token_id: u32 = token_id.try_into().map_err(|_| "amount overflow")?;212 if <ItemListIndex>::get(self.id)213 .checked_add(1)214 .ok_or("item id overflow")?215 != token_id216 {217 return Err("item id should be next".into());218 }219220 <Module<T>>::create_item_internal(221 &caller,222 &self,223 &to,224 CreateItemData::NFT(CreateNftData {225 const_data: vec![],226 variable_data: vec![],227 }),228 )229 .map_err(|_| "mint error")?;230 Ok(true)231 }232233 #[solidity(rename_selector = "mintWithTokenURI")]234 fn mint_with_token_uri(235 &mut self,236 caller: caller,237 to: address,238 token_id: uint256,239 token_uri: string,240 ) -> Result<bool> {241 let caller = T::CrossAccountId::from_eth(caller);242 let to = T::CrossAccountId::from_eth(to);243 let token_id: u32 = token_id.try_into().map_err(|_| "amount overflow")?;244 if <ItemListIndex>::get(self.id)245 .checked_add(1)246 .ok_or("item id overflow")?247 != token_id248 {249 return Err("item id should be next".into());250 }251252 <Module<T>>::create_item_internal(253 &caller,254 &self,255 &to,256 CreateItemData::NFT(CreateNftData {257 const_data: token_uri.into(),258 variable_data: vec![],259 }),260 )261 .map_err(|_| "mint error")?;262 Ok(true)263 }264265 fn finish_minting(&mut self, _caller: caller) -> Result<bool> {266 Err("not implementable".into())267 }268}180269181#[solidity_interface(name = "ERC721UniqueExtensions")]270#[solidity_interface(name = "ERC721UniqueExtensions")]182impl<T: Config> CollectionHandle<T> {271impl<T: Config> CollectionHandle<T> {197 Ok(())286 Ok(())198 }287 }288289 fn next_token_id(&self) -> Result<uint256> {290 Ok(ItemListIndex::get(self.id)291 .checked_add(1)292 .ok_or("item id overflow")?293 .into())294 }199}295}200296201#[solidity_interface(297#[solidity_interface(205 ERC721,301 ERC721,206 ERC721Metadata,302 ERC721Metadata,207 ERC721Enumerable,303 ERC721Enumerable,208 ERC721UniqueExtensions304 ERC721UniqueExtensions,305 ERC721Mintable,306 ERC721Burnable,209 )307 )210)]308)]211impl<T: Config> CollectionHandle<T> {}309impl<T: Config> CollectionHandle<T> {}pallets/nft/src/lib.rsdiffbeforeafterboth1236 }1236 }1237}1237}123812381239impl<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>::AddressIsZero1249 );1249 );125012501251 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)?;12541255 Ok(())1256 }12571254 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);182118251826 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}233023392331sp_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 integration2334 fn eth_contract_code(account: H160) -> Option<Vec<u8>>;2343 fn eth_contract_code(account: H160) -> Option<Vec<u8>>;2335 }2344 }2336}2345}23372346