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
before · pallets/nft/src/eth/stubs/UniqueNFT.sol
1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56// Common stubs holder7contract Dummy {8	uint8 dummy;9	string stub_error = "this contract is implemented in native";10}1112// Inline13contract ERC721Events {14	event Transfer(15		address indexed from,16		address indexed to,17		uint256 indexed tokenId18	);19	event Approval(20		address indexed owner,21		address indexed approved,22		uint256 indexed tokenId23	);24	event ApprovalForAll(25		address indexed owner,26		address indexed operator,27		bool approved28	);29}3031// Inline32contract ERC721MintableEvents {33	event MintingFinished();34}3536// Inline37contract InlineNameSymbol is Dummy {38	function name() public view returns (string memory) {39		require(false, stub_error);40		dummy;41		return "";42	}4344	function symbol() public view returns (string memory) {45		require(false, stub_error);46		dummy;47		return "";48	}49}5051// Inline52contract InlineTotalSupply is Dummy {53	function totalSupply() public view returns (uint256) {54		require(false, stub_error);55		dummy;56		return 0;57	}58}5960contract ERC165 is Dummy {61	function supportsInterface(uint32 interfaceId) public view returns (bool) {62		require(false, stub_error);63		interfaceId;64		dummy;65		return false;66	}67}6869contract ERC721 is Dummy, ERC165, ERC721Events {70	function balanceOf(address owner) public view returns (uint256) {71		require(false, stub_error);72		owner;73		dummy;74		return 0;75	}7677	function ownerOf(uint256 tokenId) public view returns (address) {78		require(false, stub_error);79		tokenId;80		dummy;81		return 0x0000000000000000000000000000000000000000;82	}8384	function safeTransferFromWithData(85		address from,86		address to,87		uint256 tokenId,88		bytes memory data89	) public {90		require(false, stub_error);91		from;92		to;93		tokenId;94		data;95		dummy = 0;96	}9798	function safeTransferFrom(99		address from,100		address to,101		uint256 tokenId102	) public {103		require(false, stub_error);104		from;105		to;106		tokenId;107		dummy = 0;108	}109110	function transferFrom(111		address from,112		address to,113		uint256 tokenId114	) public {115		require(false, stub_error);116		from;117		to;118		tokenId;119		dummy = 0;120	}121122	function approve(address approved, uint256 tokenId) public {123		require(false, stub_error);124		approved;125		tokenId;126		dummy = 0;127	}128129	function setApprovalForAll(address operator, bool approved) public {130		require(false, stub_error);131		operator;132		approved;133		dummy = 0;134	}135136	function getApproved(uint256 tokenId) public view returns (address) {137		require(false, stub_error);138		tokenId;139		dummy;140		return 0x0000000000000000000000000000000000000000;141	}142143	function isApprovedForAll(address owner, address operator)144		public145		view146		returns (address)147	{148		require(false, stub_error);149		owner;150		operator;151		dummy;152		return 0x0000000000000000000000000000000000000000;153	}154}155156contract ERC721Burnable is Dummy {157	function burn(uint256 tokenId) public {158		require(false, stub_error);159		tokenId;160		dummy = 0;161	}162}163164contract ERC721Enumerable is Dummy, InlineTotalSupply {165	function tokenByIndex(uint256 index) public view returns (uint256) {166		require(false, stub_error);167		index;168		dummy;169		return 0;170	}171172	function tokenOfOwnerByIndex(address owner, uint256 index)173		public174		view175		returns (uint256)176	{177		require(false, stub_error);178		owner;179		index;180		dummy;181		return 0;182	}183}184185contract ERC721Metadata is Dummy, InlineNameSymbol {186	function tokenURI(uint256 tokenId) public view returns (string memory) {187		require(false, stub_error);188		tokenId;189		dummy;190		return "";191	}192}193194contract ERC721Mintable is Dummy, ERC721MintableEvents {195	function mintingFinished() public view returns (bool) {196		require(false, stub_error);197		dummy;198		return false;199	}200201	function mint(address to, uint256 tokenId) public returns (bool) {202		require(false, stub_error);203		to;204		tokenId;205		dummy = 0;206		return false;207	}208209	function mintWithTokenURI(210		address to,211		uint256 tokenId,212		string memory tokenUri213	) public returns (bool) {214		require(false, stub_error);215		to;216		tokenId;217		tokenUri;218		dummy = 0;219		return false;220	}221222	function finishMinting() public returns (bool) {223		require(false, stub_error);224		dummy = 0;225		return false;226	}227}228229contract ERC721UniqueExtensions is Dummy {230	function transfer(address to, uint256 tokenId) public {231		require(false, stub_error);232		to;233		tokenId;234		dummy = 0;235	}236237	function nextTokenId() public view returns (uint256) {238		require(false, stub_error);239		dummy;240		return 0;241	}242}243244contract UniqueNFT is245	Dummy,246	ERC165,247	ERC721,248	ERC721Metadata,249	ERC721Enumerable,250	ERC721UniqueExtensions,251	ERC721Mintable,252	ERC721Burnable253{}
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
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/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
 interface Dummy {
 
@@ -119,6 +125,25 @@
 	function transfer(address to, uint256 tokenId) external;
 
 	function nextTokenId() external view returns (uint256);
+
+	// Selector: setVariableMetadata(uint256,bytes) d4eac26d
+	function setVariableMetadata(uint256 tokenId, bytes memory data) external;
+
+	// Selector: getVariableMetadata(uint256) e6c5ce6f
+	function getVariableMetadata(uint256 tokenId)
+		external
+		view
+		returns (bytes memory);
+
+	// Selector: mintBulk(address,uint256[]) 44a9945e
+	function mintBulk(address to, uint256[] memory tokenIds)
+		external
+		returns (bool);
+
+	// Selector: mintBulkWithTokenURI(address,(uint256,string)[]) 36543006
+	function mintBulkWithTokenURI(address to, Tuple0[] memory tokens)
+		external
+		returns (bool);
 }
 
 interface UniqueNFT is