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

difftreelog

feat make collection ERC721 compatible

Yaroslav Bolyukin2022-10-13parent: #8ad09da.patch.diff
in: master

4 files changed

modifiedpallets/unique/src/eth/mod.rsdiffbeforeafterboth
--- a/pallets/unique/src/eth/mod.rs
+++ b/pallets/unique/src/eth/mod.rs
@@ -27,6 +27,7 @@
 		CollectionHelpersEvents,
 		static_property::{key, value as property_value},
 	},
+	Pallet as PalletCommon,
 };
 use pallet_evm_coder_substrate::{dispatch_to_evm, SubstrateRecorder, WithRecorder};
 use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};
@@ -340,6 +341,83 @@
 		)
 	}
 
+	#[solidity(rename_selector = "makeCollectionERC721MetadataCompatible")]
+	fn make_collection_metadata_compatible(
+		&mut self,
+		caller: caller,
+		collection: address,
+		base_uri: string,
+	) -> Result<()> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		let collection =
+			pallet_common::eth::map_eth_to_id(&collection).ok_or("not a collection address")?;
+		let mut collection =
+			<crate::CollectionHandle<T>>::new(collection).ok_or("collection not found")?;
+
+		if !matches!(
+			collection.mode,
+			CollectionMode::NFT | CollectionMode::ReFungible
+		) {
+			return Err("target collection should be either NFT or Refungible".into());
+		}
+
+		self.recorder().consume_sstore()?;
+		collection
+			.check_is_owner_or_admin(&caller)
+			.map_err(dispatch_to_evm::<T>)?;
+
+		if collection.flags.erc721metadata {
+			return Err("target collection is already Erc721Metadata compatible".into());
+		}
+		collection.flags.erc721metadata = true;
+
+		let all_permissions = <pallet_common::CollectionPropertyPermissions<T>>::get(collection.id);
+		if all_permissions.get(&key::url()).is_none() {
+			self.recorder().consume_sstore()?;
+			<PalletCommon<T>>::set_property_permission(&collection, &caller, default_url_pkp())
+				.map_err(dispatch_to_evm::<T>)?;
+		}
+		if all_permissions.get(&key::suffix()).is_none() {
+			self.recorder().consume_sstore()?;
+			<PalletCommon<T>>::set_property_permission(&collection, &caller, default_suffix_pkp())
+				.map_err(dispatch_to_evm::<T>)?;
+		}
+
+		let all_properties = <pallet_common::CollectionProperties<T>>::get(collection.id);
+		let mut new_properties = vec![];
+		if all_properties.get(&key::schema_name()).is_none() {
+			self.recorder().consume_sstore()?;
+			new_properties.push(up_data_structs::Property {
+				key: key::schema_name(),
+				value: property_value::erc721(),
+			});
+			new_properties.push(up_data_structs::Property {
+				key: key::schema_version(),
+				value: property_value::schema_version(),
+			});
+		}
+		if all_properties.get(&key::base_uri()).is_none() && !base_uri.is_empty() {
+			new_properties.push(up_data_structs::Property {
+				key: key::base_uri(),
+				value: base_uri
+					.into_bytes()
+					.try_into()
+					.map_err(|_| "base uri is too large")?,
+			});
+		}
+
+		if !new_properties.is_empty() {
+			self.recorder().consume_sstore()?;
+			<PalletCommon<T>>::set_collection_properties(&collection, &caller, new_properties)
+				.map_err(dispatch_to_evm::<T>)?;
+		}
+
+		self.recorder().consume_sstore()?;
+		collection.save().map_err(dispatch_to_evm::<T>)?;
+
+		Ok(())
+	}
+
 	/// Check if a collection exists
 	/// @param collectionAddress Address of the collection in question
 	/// @return bool Does the collection exist?
modifiedpallets/unique/src/eth/stubs/CollectionHelpers.soldiffbeforeafterboth
before · pallets/unique/src/eth/stubs/CollectionHelpers.sol
1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7contract Dummy {8	uint8 dummy;9	string stub_error = "this contract is implemented in native";10}1112contract ERC165 is Dummy {13	function supportsInterface(bytes4 interfaceID) external view returns (bool) {14		require(false, stub_error);15		interfaceID;16		return true;17	}18}1920/// @dev inlined interface21contract CollectionHelpersEvents {22	event CollectionCreated(address indexed owner, address indexed collectionId);23}2425/// @title Contract, which allows users to operate with collections26/// @dev the ERC-165 identifier for this interface is 0xd14d122127contract CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {28	/// Create an NFT collection29	/// @param name Name of the collection30	/// @param description Informative description of the collection31	/// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications32	/// @return address Address of the newly created collection33	/// @dev EVM selector for this function is: 0x844af658,34	///  or in textual repr: createNFTCollection(string,string,string)35	function createNFTCollection(36		string memory name,37		string memory description,38		string memory tokenPrefix39	) public payable returns (address) {40		require(false, stub_error);41		name;42		description;43		tokenPrefix;44		dummy = 0;45		return 0x0000000000000000000000000000000000000000;46	}4748	/// Create an NFT collection49	/// @param name Name of the collection50	/// @param description Informative description of the collection51	/// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications52	/// @return address Address of the newly created collection53	/// @dev EVM selector for this function is: 0xe34a6844,54	///  or in textual repr: createNonfungibleCollection(string,string,string)55	function createNonfungibleCollection(56		string memory name,57		string memory description,58		string memory tokenPrefix59	) public payable returns (address) {60		require(false, stub_error);61		name;62		description;63		tokenPrefix;64		dummy = 0;65		return 0x0000000000000000000000000000000000000000;66	}6768	/// @dev EVM selector for this function is: 0xa9e7b5c0,69	///  or in textual repr: createERC721MetadataCompatibleNFTCollection(string,string,string,string)70	function createERC721MetadataCompatibleNFTCollection(71		string memory name,72		string memory description,73		string memory tokenPrefix,74		string memory baseUri75	) public payable returns (address) {76		require(false, stub_error);77		name;78		description;79		tokenPrefix;80		baseUri;81		dummy = 0;82		return 0x0000000000000000000000000000000000000000;83	}8485	/// @dev EVM selector for this function is: 0xab173450,86	///  or in textual repr: createRFTCollection(string,string,string)87	function createRFTCollection(88		string memory name,89		string memory description,90		string memory tokenPrefix91	) public payable returns (address) {92		require(false, stub_error);93		name;94		description;95		tokenPrefix;96		dummy = 0;97		return 0x0000000000000000000000000000000000000000;98	}99100	/// @dev EVM selector for this function is: 0xa5596388,101	///  or in textual repr: createERC721MetadataCompatibleRFTCollection(string,string,string,string)102	function createERC721MetadataCompatibleRFTCollection(103		string memory name,104		string memory description,105		string memory tokenPrefix,106		string memory baseUri107	) public payable returns (address) {108		require(false, stub_error);109		name;110		description;111		tokenPrefix;112		baseUri;113		dummy = 0;114		return 0x0000000000000000000000000000000000000000;115	}116117	/// Check if a collection exists118	/// @param collectionAddress Address of the collection in question119	/// @return bool Does the collection exist?120	/// @dev EVM selector for this function is: 0xc3de1494,121	///  or in textual repr: isCollectionExist(address)122	function isCollectionExist(address collectionAddress) public view returns (bool) {123		require(false, stub_error);124		collectionAddress;125		dummy;126		return false;127	}128129	/// @dev EVM selector for this function is: 0xd23a7ab1,130	///  or in textual repr: collectionCreationFee()131	function collectionCreationFee() public view returns (uint256) {132		require(false, stub_error);133		dummy;134		return 0;135	}136}
after · pallets/unique/src/eth/stubs/CollectionHelpers.sol
1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7contract Dummy {8	uint8 dummy;9	string stub_error = "this contract is implemented in native";10}1112contract ERC165 is Dummy {13	function supportsInterface(bytes4 interfaceID) external view returns (bool) {14		require(false, stub_error);15		interfaceID;16		return true;17	}18}1920/// @dev inlined interface21contract CollectionHelpersEvents {22	event CollectionCreated(address indexed owner, address indexed collectionId);23}2425/// @title Contract, which allows users to operate with collections26/// @dev the ERC-165 identifier for this interface is 0x542f507927contract CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {28	/// Create an NFT collection29	/// @param name Name of the collection30	/// @param description Informative description of the collection31	/// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications32	/// @return address Address of the newly created collection33	/// @dev EVM selector for this function is: 0x844af658,34	///  or in textual repr: createNFTCollection(string,string,string)35	function createNFTCollection(36		string memory name,37		string memory description,38		string memory tokenPrefix39	) public payable returns (address) {40		require(false, stub_error);41		name;42		description;43		tokenPrefix;44		dummy = 0;45		return 0x0000000000000000000000000000000000000000;46	}4748	/// Create an NFT collection49	/// @param name Name of the collection50	/// @param description Informative description of the collection51	/// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications52	/// @return address Address of the newly created collection53	/// @dev EVM selector for this function is: 0xe34a6844,54	///  or in textual repr: createNonfungibleCollection(string,string,string)55	function createNonfungibleCollection(56		string memory name,57		string memory description,58		string memory tokenPrefix59	) public payable returns (address) {60		require(false, stub_error);61		name;62		description;63		tokenPrefix;64		dummy = 0;65		return 0x0000000000000000000000000000000000000000;66	}6768	/// @dev EVM selector for this function is: 0xa9e7b5c0,69	///  or in textual repr: createERC721MetadataCompatibleNFTCollection(string,string,string,string)70	function createERC721MetadataCompatibleNFTCollection(71		string memory name,72		string memory description,73		string memory tokenPrefix,74		string memory baseUri75	) public payable returns (address) {76		require(false, stub_error);77		name;78		description;79		tokenPrefix;80		baseUri;81		dummy = 0;82		return 0x0000000000000000000000000000000000000000;83	}8485	/// @dev EVM selector for this function is: 0xab173450,86	///  or in textual repr: createRFTCollection(string,string,string)87	function createRFTCollection(88		string memory name,89		string memory description,90		string memory tokenPrefix91	) public payable returns (address) {92		require(false, stub_error);93		name;94		description;95		tokenPrefix;96		dummy = 0;97		return 0x0000000000000000000000000000000000000000;98	}99100	/// @dev EVM selector for this function is: 0xa5596388,101	///  or in textual repr: createERC721MetadataCompatibleRFTCollection(string,string,string,string)102	function createERC721MetadataCompatibleRFTCollection(103		string memory name,104		string memory description,105		string memory tokenPrefix,106		string memory baseUri107	) public payable returns (address) {108		require(false, stub_error);109		name;110		description;111		tokenPrefix;112		baseUri;113		dummy = 0;114		return 0x0000000000000000000000000000000000000000;115	}116117	/// @dev EVM selector for this function is: 0x85624258,118	///  or in textual repr: makeCollectionERC721MetadataCompatible(address,string)119	function makeCollectionERC721MetadataCompatible(address collection, string memory baseUri) public {120		require(false, stub_error);121		collection;122		baseUri;123		dummy = 0;124	}125126	/// Check if a collection exists127	/// @param collectionAddress Address of the collection in question128	/// @return bool Does the collection exist?129	/// @dev EVM selector for this function is: 0xc3de1494,130	///  or in textual repr: isCollectionExist(address)131	function isCollectionExist(address collectionAddress) public view returns (bool) {132		require(false, stub_error);133		collectionAddress;134		dummy;135		return false;136	}137138	/// @dev EVM selector for this function is: 0xd23a7ab1,139	///  or in textual repr: collectionCreationFee()140	function collectionCreationFee() public view returns (uint256) {141		require(false, stub_error);142		dummy;143		return 0;144	}145}
modifiedtests/src/eth/api/CollectionHelpers.soldiffbeforeafterboth
--- a/tests/src/eth/api/CollectionHelpers.sol
+++ b/tests/src/eth/api/CollectionHelpers.sol
@@ -18,7 +18,7 @@
 }
 
 /// @title Contract, which allows users to operate with collections
-/// @dev the ERC-165 identifier for this interface is 0xd14d1221
+/// @dev the ERC-165 identifier for this interface is 0x542f5079
 interface CollectionHelpers is Dummy, ERC165, CollectionHelpersEvents {
 	/// Create an NFT collection
 	/// @param name Name of the collection
@@ -72,6 +72,10 @@
 		string memory baseUri
 	) external payable returns (address);
 
+	/// @dev EVM selector for this function is: 0x85624258,
+	///  or in textual repr: makeCollectionERC721MetadataCompatible(address,string)
+	function makeCollectionERC721MetadataCompatible(address collection, string memory baseUri) external;
+
 	/// Check if a collection exists
 	/// @param collectionAddress Address of the collection in question
 	/// @return bool Does the collection exist?
modifiedtests/src/eth/collectionHelpersAbi.jsondiffbeforeafterboth
--- a/tests/src/eth/collectionHelpersAbi.json
+++ b/tests/src/eth/collectionHelpersAbi.json
@@ -97,6 +97,16 @@
   },
   {
     "inputs": [
+      { "internalType": "address", "name": "collection", "type": "address" },
+      { "internalType": "string", "name": "baseUri", "type": "string" }
+    ],
+    "name": "makeCollectionERC721MetadataCompatible",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [
       { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }
     ],
     "name": "supportsInterface",