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

difftreelog

feat bulk mint/get/set metadata

Yaroslav Bolyukin2021-09-01parent: #742db63.patch.diff
in: master

5 files changed

modifiedpallets/nft/src/eth/erc.rsdiffbeforeafterboth
--- a/pallets/nft/src/eth/erc.rs
+++ b/pallets/nft/src/eth/erc.rs
@@ -8,6 +8,7 @@
 };
 use frame_support::storage::{StorageMap, StorageDoubleMap};
 use pallet_evm::AddressMapping;
+use pallet_evm_coder_substrate::dispatch_to_evm;
 use super::account::CrossAccountId;
 use sp_std::{vec, vec::Vec};
 
@@ -299,6 +300,90 @@
 			.ok_or("item id overflow")?
 			.into())
 	}
+
+	fn set_variable_metadata(
+		&mut self,
+		caller: caller,
+		token_id: uint256,
+		data: bytes,
+	) -> Result<void> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let token_id = token_id.try_into().map_err(|_| "token id overflow")?;
+
+		<Module<T>>::set_variable_meta_data_internal(&caller, self, token_id, data)
+			.map_err(dispatch_to_evm::<T>)?;
+		Ok(())
+	}
+
+	fn get_variable_metadata(&self, token_id: uint256) -> Result<bytes> {
+		let token_id = token_id.try_into().map_err(|_| "token id overflow")?;
+
+		<Module<T>>::get_variable_metadata(self, token_id).map_err(dispatch_to_evm::<T>)
+	}
+
+	fn mint_bulk(&mut self, caller: caller, to: address, token_ids: Vec<uint256>) -> Result<bool> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let to = T::CrossAccountId::from_eth(to);
+		let mut expected_index = <ItemListIndex>::get(self.id)
+			.checked_add(1)
+			.ok_or("item id overflow")?;
+
+		let total_tokens = token_ids.len();
+		for id in token_ids.into_iter() {
+			let id: u32 = id.try_into().map_err(|_| "token id overflow")?;
+			if id != expected_index {
+				return Err("item id should be next".into());
+			}
+			expected_index = expected_index.checked_add(1).ok_or("item id overflow")?;
+		}
+
+		let data = (0..total_tokens)
+			.map(|_| {
+				CreateItemData::NFT(CreateNftData {
+					const_data: vec![].try_into().unwrap(),
+					variable_data: vec![].try_into().unwrap(),
+				})
+			})
+			.collect();
+
+		<Module<T>>::create_multiple_items_internal(&caller, self, &to, data)
+			.map_err(dispatch_to_evm::<T>)?;
+		Ok(true)
+	}
+
+	#[solidity(rename_selector = "mintBulkWithTokenURI")]
+	fn mint_bulk_with_token_uri(
+		&mut self,
+		caller: caller,
+		to: address,
+		tokens: Vec<(uint256, string)>,
+	) -> Result<bool> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let to = T::CrossAccountId::from_eth(to);
+		let mut expected_index = <ItemListIndex>::get(self.id)
+			.checked_add(1)
+			.ok_or("item id overflow")?;
+
+		let mut data = Vec::with_capacity(tokens.len());
+		for (id, token_uri) in tokens {
+			let id: u32 = id.try_into().map_err(|_| "token id overflow")?;
+			if id != expected_index {
+				panic!("item id should be next ({}) but got {}", expected_index, id);
+			}
+			expected_index = expected_index.checked_add(1).ok_or("item id overflow")?;
+
+			data.push(CreateItemData::NFT(CreateNftData {
+				const_data: Vec::<u8>::from(token_uri)
+					.try_into()
+					.map_err(|_| "token uri is too long")?,
+				variable_data: vec![].try_into().unwrap(),
+			}));
+		}
+
+		<Module<T>>::create_multiple_items_internal(&caller, self, &to, data)
+			.map_err(dispatch_to_evm::<T>)?;
+		Ok(true)
+	}
 }
 
 #[solidity_interface(
modifiedpallets/nft/src/eth/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nft/src/eth/stubs/UniqueNFT.soldiffbeforeafterboth
--- a/pallets/nft/src/eth/stubs/UniqueNFT.sol
+++ b/pallets/nft/src/eth/stubs/UniqueNFT.sol
@@ -3,6 +3,12 @@
 
 pragma solidity >=0.8.0 <0.9.0;
 
+// Anonymous struct
+struct Tuple0 {
+	uint256 field_0;
+	string field_1;
+}
+
 // Common stubs holder
 contract Dummy {
 	uint8 dummy;
@@ -239,6 +245,50 @@
 		dummy;
 		return 0;
 	}
+
+	// Selector: setVariableMetadata(uint256,bytes) d4eac26d
+	function setVariableMetadata(uint256 tokenId, bytes memory data) public {
+		require(false, stub_error);
+		tokenId;
+		data;
+		dummy = 0;
+	}
+
+	// Selector: getVariableMetadata(uint256) e6c5ce6f
+	function getVariableMetadata(uint256 tokenId)
+		public
+		view
+		returns (bytes memory)
+	{
+		require(false, stub_error);
+		tokenId;
+		dummy;
+		return hex"";
+	}
+
+	// Selector: mintBulk(address,uint256[]) 44a9945e
+	function mintBulk(address to, uint256[] memory tokenIds)
+		public
+		returns (bool)
+	{
+		require(false, stub_error);
+		to;
+		tokenIds;
+		dummy = 0;
+		return false;
+	}
+
+	// Selector: mintBulkWithTokenURI(address,(uint256,string)[]) 36543006
+	function mintBulkWithTokenURI(address to, Tuple0[] memory tokens)
+		public
+		returns (bool)
+	{
+		require(false, stub_error);
+		to;
+		tokens;
+		dummy = 0;
+		return false;
+	}
 }
 
 contract UniqueNFT is
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -1501,6 +1501,14 @@
 		Ok(())
 	}
 
+	pub fn get_variable_metadata(collection: &CollectionHandle<T>, item_id: TokenId) -> Result<Vec<u8>, DispatchError> {
+		Ok(match collection.mode {
+			CollectionMode::NFT => <NftItemList<T>>::get(collection.id, item_id).ok_or(Error::<T>::TokenNotFound)?.variable_data,
+			CollectionMode::ReFungible => <ReFungibleItemList<T>>::get(collection.id, item_id).ok_or(Error::<T>::TokenNotFound)?.variable_data,
+			_ => fail!(Error::<T>::UnexpectedCollectionType),
+		})
+	}
+
 	pub fn create_multiple_items_internal(
 		sender: &T::CrossAccountId,
 		collection: &CollectionHandle<T>,
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
before · tests/src/eth/api/UniqueNFT.sol
1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56// Common stubs holder7interface Dummy {89}1011// Inline12interface ERC721Events {13	event Transfer(14		address indexed from,15		address indexed to,16		uint256 indexed tokenId17	);18	event Approval(19		address indexed owner,20		address indexed approved,21		uint256 indexed tokenId22	);23	event ApprovalForAll(24		address indexed owner,25		address indexed operator,26		bool approved27	);28}2930// Inline31interface ERC721MintableEvents {32	event MintingFinished();33}3435// Inline36interface InlineNameSymbol is Dummy {37	function name() external view returns (string memory);3839	function symbol() external view returns (string memory);40}4142// Inline43interface InlineTotalSupply is Dummy {44	function totalSupply() external view returns (uint256);45}4647interface ERC165 is Dummy {48	function supportsInterface(uint32 interfaceId) external view returns (bool);49}5051interface ERC721 is Dummy, ERC165, ERC721Events {52	function balanceOf(address owner) external view returns (uint256);5354	function ownerOf(uint256 tokenId) external view returns (address);5556	function safeTransferFromWithData(57		address from,58		address to,59		uint256 tokenId,60		bytes memory data61	) external;6263	function safeTransferFrom(64		address from,65		address to,66		uint256 tokenId67	) external;6869	function transferFrom(70		address from,71		address to,72		uint256 tokenId73	) external;7475	function approve(address approved, uint256 tokenId) external;7677	function setApprovalForAll(address operator, bool approved) external;7879	function getApproved(uint256 tokenId) external view returns (address);8081	function isApprovedForAll(address owner, address operator)82		external83		view84		returns (address);85}8687interface ERC721Burnable is Dummy {88	function burn(uint256 tokenId) external;89}9091interface ERC721Enumerable is Dummy, InlineTotalSupply {92	function tokenByIndex(uint256 index) external view returns (uint256);9394	function tokenOfOwnerByIndex(address owner, uint256 index)95		external96		view97		returns (uint256);98}99100interface ERC721Metadata is Dummy, InlineNameSymbol {101	function tokenURI(uint256 tokenId) external view returns (string memory);102}103104interface ERC721Mintable is Dummy, ERC721MintableEvents {105	function mintingFinished() external view returns (bool);106107	function mint(address to, uint256 tokenId) external returns (bool);108109	function mintWithTokenURI(110		address to,111		uint256 tokenId,112		string memory tokenUri113	) external returns (bool);114115	function finishMinting() external returns (bool);116}117118interface ERC721UniqueExtensions is Dummy {119	function transfer(address to, uint256 tokenId) external;120121	function nextTokenId() external view returns (uint256);122}123124interface UniqueNFT is125	Dummy,126	ERC165,127	ERC721,128	ERC721Metadata,129	ERC721Enumerable,130	ERC721UniqueExtensions,131	ERC721Mintable,132	ERC721Burnable133{}