difftreelog
feat bulk mint/get/set metadata
in: master
5 files changed
pallets/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(
pallets/nft/src/eth/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/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
pallets/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>,
tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth1// 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{}1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56// Anonymous struct7struct Tuple0 {8 uint256 field_0;9 string field_1;10}1112// Common stubs holder13interface Dummy {1415}1617// Inline18interface ERC721Events {19 event Transfer(20 address indexed from,21 address indexed to,22 uint256 indexed tokenId23 );24 event Approval(25 address indexed owner,26 address indexed approved,27 uint256 indexed tokenId28 );29 event ApprovalForAll(30 address indexed owner,31 address indexed operator,32 bool approved33 );34}3536// Inline37interface ERC721MintableEvents {38 event MintingFinished();39}4041// Inline42interface InlineNameSymbol is Dummy {43 function name() external view returns (string memory);4445 function symbol() external view returns (string memory);46}4748// Inline49interface InlineTotalSupply is Dummy {50 function totalSupply() external view returns (uint256);51}5253interface ERC165 is Dummy {54 function supportsInterface(uint32 interfaceId) external view returns (bool);55}5657interface ERC721 is Dummy, ERC165, ERC721Events {58 function balanceOf(address owner) external view returns (uint256);5960 function ownerOf(uint256 tokenId) external view returns (address);6162 function safeTransferFromWithData(63 address from,64 address to,65 uint256 tokenId,66 bytes memory data67 ) external;6869 function safeTransferFrom(70 address from,71 address to,72 uint256 tokenId73 ) external;7475 function transferFrom(76 address from,77 address to,78 uint256 tokenId79 ) external;8081 function approve(address approved, uint256 tokenId) external;8283 function setApprovalForAll(address operator, bool approved) external;8485 function getApproved(uint256 tokenId) external view returns (address);8687 function isApprovedForAll(address owner, address operator)88 external89 view90 returns (address);91}9293interface ERC721Burnable is Dummy {94 function burn(uint256 tokenId) external;95}9697interface ERC721Enumerable is Dummy, InlineTotalSupply {98 function tokenByIndex(uint256 index) external view returns (uint256);99100 function tokenOfOwnerByIndex(address owner, uint256 index)101 external102 view103 returns (uint256);104}105106interface ERC721Metadata is Dummy, InlineNameSymbol {107 function tokenURI(uint256 tokenId) external view returns (string memory);108}109110interface ERC721Mintable is Dummy, ERC721MintableEvents {111 function mintingFinished() external view returns (bool);112113 function mint(address to, uint256 tokenId) external returns (bool);114115 function mintWithTokenURI(116 address to,117 uint256 tokenId,118 string memory tokenUri119 ) external returns (bool);120121 function finishMinting() external returns (bool);122}123124interface ERC721UniqueExtensions is Dummy {125 function transfer(address to, uint256 tokenId) external;126127 function nextTokenId() external view returns (uint256);128129 // Selector: setVariableMetadata(uint256,bytes) d4eac26d130 function setVariableMetadata(uint256 tokenId, bytes memory data) external;131132 // Selector: getVariableMetadata(uint256) e6c5ce6f133 function getVariableMetadata(uint256 tokenId)134 external135 view136 returns (bytes memory);137138 // Selector: mintBulk(address,uint256[]) 44a9945e139 function mintBulk(address to, uint256[] memory tokenIds)140 external141 returns (bool);142143 // Selector: mintBulkWithTokenURI(address,(uint256,string)[]) 36543006144 function mintBulkWithTokenURI(address to, Tuple0[] memory tokens)145 external146 returns (bool);147}148149interface UniqueNFT is150 Dummy,151 ERC165,152 ERC721,153 ERC721Metadata,154 ERC721Enumerable,155 ERC721UniqueExtensions,156 ERC721Mintable,157 ERC721Burnable158{}