From ec9052988b691a86756ad5c68c05787796831e8a Mon Sep 17 00:00:00 2001 From: Trubnikov Sergey Date: Mon, 24 Oct 2022 21:43:48 +0000 Subject: [PATCH] feat: add eth methots for bulk properties --- --- a/pallets/common/src/erc.rs +++ b/pallets/common/src/erc.rs @@ -27,7 +27,7 @@ use sp_std::vec::Vec; use up_data_structs::{ AccessMode, CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property, - SponsoringRateLimit, SponsorshipState, + SponsoringRateLimit, SponsorshipState, PropertyKey, }; use alloc::format; @@ -97,6 +97,21 @@ .map_err(dispatch_to_evm::) } + /// Set collection properties. + /// + /// @param properties Vector of properties key/value pair. + #[weight(>::set_collection_properties(properties.len() as u32))] + fn set_collection_properties( + &mut self, + caller: caller, + properties: Vec<(string, bytes)>, + ) -> Result { + for (key, value) in properties.into_iter() { + self.set_collection_property(caller, key, value)?; + } + Ok(()) + } + /// Delete collection property. /// /// @param key Property key. @@ -123,12 +138,38 @@ .try_into() .map_err(|_| "key too large")?; - let props = >::get(self.id); + let props = CollectionProperties::::get(self.id); let prop = props.get(&key).ok_or("key not found")?; Ok(bytes(prop.to_vec())) } + /// Get collection properties. + /// + /// @param keys Properties keys. + /// @return Vector of properties key/value pairs. + fn collection_properties(&self, keys: Vec) -> Result> { + let mut keys_ = Vec::::with_capacity(keys.len()); + for key in keys { + keys_.push( + >::from(key) + .try_into() + .map_err(|_| Error::Revert("key too large".into()))?, + ) + } + let properties = Pallet::::filter_collection_properties(self.id, Some(keys_)) + .map_err(dispatch_to_evm::)?; + + let mut properties_ = Vec::<(string, bytes)>::with_capacity(properties.len()); + for p in properties { + let key = + string::from_utf8(p.key.into()).map_err(|e| Error::Revert(format!("{}", e)))?; + let value = bytes(p.value.to_vec()); + properties_.push((key, value)); + } + Ok(properties_) + } + /// Set the sponsor of the collection. /// /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor. --- a/pallets/fungible/src/stubs/UniqueFungible.sol +++ b/pallets/fungible/src/stubs/UniqueFungible.sol @@ -18,7 +18,7 @@ } /// @title A contract that allows you to work with collections. -/// @dev the ERC-165 identifier for this interface is 0x25d897dc +/// @dev the ERC-165 identifier for this interface is 0x5d354410 contract Collection is Dummy, ERC165 { /// Set collection property. /// @@ -33,6 +33,17 @@ dummy = 0; } + /// Set collection properties. + /// + /// @param properties Vector of properties key/value pair. + /// @dev EVM selector for this function is: 0x50b26b2a, + /// or in textual repr: setCollectionProperties((string,bytes)[]) + function setCollectionProperties(Tuple10[] memory properties) public { + require(false, stub_error); + properties; + dummy = 0; + } + /// Delete collection property. /// /// @param key Property key. @@ -59,6 +70,19 @@ return hex""; } + /// Get collection properties. + /// + /// @param keys Properties keys. + /// @return Vector of properties key/value pairs. + /// @dev EVM selector for this function is: 0x285fb8e6, + /// or in textual repr: collectionProperties(string[]) + function collectionProperties(string[] memory keys) public view returns (Tuple10[] memory) { + require(false, stub_error); + keys; + dummy; + return new Tuple10[](0); + } + /// Set the sponsor of the collection. /// /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor. @@ -397,6 +421,12 @@ } } +/// @dev anonymous struct +struct Tuple10 { + string field_0; + bytes field_1; +} + /// @dev the ERC-165 identifier for this interface is 0x032e5926 contract ERC20UniqueExtensions is Dummy, ERC165 { /// @dev EVM selector for this function is: 0x0ecd0ab0, --- a/pallets/nonfungible/src/stubs/UniqueNFT.sol +++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol @@ -91,7 +91,7 @@ } /// @title A contract that allows you to work with collections. -/// @dev the ERC-165 identifier for this interface is 0x25d897dc +/// @dev the ERC-165 identifier for this interface is 0x5d354410 contract Collection is Dummy, ERC165 { /// Set collection property. /// @@ -106,6 +106,17 @@ dummy = 0; } + /// Set collection properties. + /// + /// @param properties Vector of properties key/value pair. + /// @dev EVM selector for this function is: 0x50b26b2a, + /// or in textual repr: setCollectionProperties((string,bytes)[]) + function setCollectionProperties(Tuple19[] memory properties) public { + require(false, stub_error); + properties; + dummy = 0; + } + /// Delete collection property. /// /// @param key Property key. @@ -132,6 +143,19 @@ return hex""; } + /// Get collection properties. + /// + /// @param keys Properties keys. + /// @return Vector of properties key/value pairs. + /// @dev EVM selector for this function is: 0x285fb8e6, + /// or in textual repr: collectionProperties(string[]) + function collectionProperties(string[] memory keys) public view returns (Tuple19[] memory) { + require(false, stub_error); + keys; + dummy; + return new Tuple19[](0); + } + /// Set the sponsor of the collection. /// /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor. @@ -470,6 +494,12 @@ } } +/// @dev anonymous struct +struct Tuple19 { + string field_0; + bytes field_1; +} + /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension /// @dev See https://eips.ethereum.org/EIPS/eip-721 /// @dev the ERC-165 identifier for this interface is 0x5b5e139f --- a/pallets/refungible/src/stubs/UniqueRefungible.sol +++ b/pallets/refungible/src/stubs/UniqueRefungible.sol @@ -91,7 +91,7 @@ } /// @title A contract that allows you to work with collections. -/// @dev the ERC-165 identifier for this interface is 0x25d897dc +/// @dev the ERC-165 identifier for this interface is 0x5d354410 contract Collection is Dummy, ERC165 { /// Set collection property. /// @@ -106,6 +106,17 @@ dummy = 0; } + /// Set collection properties. + /// + /// @param properties Vector of properties key/value pair. + /// @dev EVM selector for this function is: 0x50b26b2a, + /// or in textual repr: setCollectionProperties((string,bytes)[]) + function setCollectionProperties(Tuple19[] memory properties) public { + require(false, stub_error); + properties; + dummy = 0; + } + /// Delete collection property. /// /// @param key Property key. @@ -132,6 +143,19 @@ return hex""; } + /// Get collection properties. + /// + /// @param keys Properties keys. + /// @return Vector of properties key/value pairs. + /// @dev EVM selector for this function is: 0x285fb8e6, + /// or in textual repr: collectionProperties(string[]) + function collectionProperties(string[] memory keys) public view returns (Tuple19[] memory) { + require(false, stub_error); + keys; + dummy; + return new Tuple19[](0); + } + /// Set the sponsor of the collection. /// /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor. @@ -470,6 +494,12 @@ } } +/// @dev anonymous struct +struct Tuple19 { + string field_0; + bytes field_1; +} + /// @dev the ERC-165 identifier for this interface is 0x5b5e139f contract ERC721Metadata is Dummy, ERC165 { // /// @notice A descriptive name for a collection of NFTs in this contract --- a/tests/src/eth/api/UniqueFungible.sol +++ b/tests/src/eth/api/UniqueFungible.sol @@ -13,7 +13,7 @@ } /// @title A contract that allows you to work with collections. -/// @dev the ERC-165 identifier for this interface is 0x25d897dc +/// @dev the ERC-165 identifier for this interface is 0x5d354410 interface Collection is Dummy, ERC165 { /// Set collection property. /// @@ -23,6 +23,13 @@ /// or in textual repr: setCollectionProperty(string,bytes) function setCollectionProperty(string memory key, bytes memory value) external; + /// Set collection properties. + /// + /// @param properties Vector of properties key/value pair. + /// @dev EVM selector for this function is: 0x50b26b2a, + /// or in textual repr: setCollectionProperties((string,bytes)[]) + function setCollectionProperties(Tuple10[] memory properties) external; + /// Delete collection property. /// /// @param key Property key. @@ -40,6 +47,14 @@ /// or in textual repr: collectionProperty(string) function collectionProperty(string memory key) external view returns (bytes memory); + /// Get collection properties. + /// + /// @param keys Properties keys. + /// @return Vector of properties key/value pairs. + /// @dev EVM selector for this function is: 0x285fb8e6, + /// or in textual repr: collectionProperties(string[]) + function collectionProperties(string[] memory keys) external view returns (Tuple10[] memory); + /// Set the sponsor of the collection. /// /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor. @@ -258,6 +273,12 @@ function setOwnerCross(Tuple6 memory newOwner) external; } +/// @dev anonymous struct +struct Tuple10 { + string field_0; + bytes field_1; +} + /// @dev the ERC-165 identifier for this interface is 0x032e5926 interface ERC20UniqueExtensions is Dummy, ERC165 { /// @dev EVM selector for this function is: 0x0ecd0ab0, --- a/tests/src/eth/api/UniqueNFT.sol +++ b/tests/src/eth/api/UniqueNFT.sol @@ -62,7 +62,7 @@ } /// @title A contract that allows you to work with collections. -/// @dev the ERC-165 identifier for this interface is 0x25d897dc +/// @dev the ERC-165 identifier for this interface is 0x5d354410 interface Collection is Dummy, ERC165 { /// Set collection property. /// @@ -72,6 +72,13 @@ /// or in textual repr: setCollectionProperty(string,bytes) function setCollectionProperty(string memory key, bytes memory value) external; + /// Set collection properties. + /// + /// @param properties Vector of properties key/value pair. + /// @dev EVM selector for this function is: 0x50b26b2a, + /// or in textual repr: setCollectionProperties((string,bytes)[]) + function setCollectionProperties(Tuple19[] memory properties) external; + /// Delete collection property. /// /// @param key Property key. @@ -89,6 +96,14 @@ /// or in textual repr: collectionProperty(string) function collectionProperty(string memory key) external view returns (bytes memory); + /// Get collection properties. + /// + /// @param keys Properties keys. + /// @return Vector of properties key/value pairs. + /// @dev EVM selector for this function is: 0x285fb8e6, + /// or in textual repr: collectionProperties(string[]) + function collectionProperties(string[] memory keys) external view returns (Tuple19[] memory); + /// Set the sponsor of the collection. /// /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor. @@ -307,6 +322,12 @@ function setOwnerCross(Tuple6 memory newOwner) external; } +/// @dev anonymous struct +struct Tuple19 { + string field_0; + bytes field_1; +} + /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension /// @dev See https://eips.ethereum.org/EIPS/eip-721 /// @dev the ERC-165 identifier for this interface is 0x5b5e139f --- a/tests/src/eth/api/UniqueRefungible.sol +++ b/tests/src/eth/api/UniqueRefungible.sol @@ -62,7 +62,7 @@ } /// @title A contract that allows you to work with collections. -/// @dev the ERC-165 identifier for this interface is 0x25d897dc +/// @dev the ERC-165 identifier for this interface is 0x5d354410 interface Collection is Dummy, ERC165 { /// Set collection property. /// @@ -72,6 +72,13 @@ /// or in textual repr: setCollectionProperty(string,bytes) function setCollectionProperty(string memory key, bytes memory value) external; + /// Set collection properties. + /// + /// @param properties Vector of properties key/value pair. + /// @dev EVM selector for this function is: 0x50b26b2a, + /// or in textual repr: setCollectionProperties((string,bytes)[]) + function setCollectionProperties(Tuple19[] memory properties) external; + /// Delete collection property. /// /// @param key Property key. @@ -89,6 +96,14 @@ /// or in textual repr: collectionProperty(string) function collectionProperty(string memory key) external view returns (bytes memory); + /// Get collection properties. + /// + /// @param keys Properties keys. + /// @return Vector of properties key/value pairs. + /// @dev EVM selector for this function is: 0x285fb8e6, + /// or in textual repr: collectionProperties(string[]) + function collectionProperties(string[] memory keys) external view returns (Tuple19[] memory); + /// Set the sponsor of the collection. /// /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor. @@ -307,6 +322,12 @@ function setOwnerCross(Tuple6 memory newOwner) external; } +/// @dev anonymous struct +struct Tuple19 { + string field_0; + bytes field_1; +} + /// @dev the ERC-165 identifier for this interface is 0x5b5e139f interface ERC721Metadata is Dummy, ERC165 { // /// @notice A descriptive name for a collection of NFTs in this contract --- a/tests/src/eth/collectionProperties.test.ts +++ b/tests/src/eth/collectionProperties.test.ts @@ -161,3 +161,31 @@ await checkERC721Metadata(helper, 'rft'); }); }); + +describe('EVM collection property', () => { + itEth('Set/read properties', async ({helper, privateKey}) => { + const alice = await privateKey('//Alice'); + const collection = await helper.nft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'}); + + const sender = await helper.eth.createAccountWithBalance(alice, 100n); + await collection.addAdmin(alice, {Ethereum: sender}); + + const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId); + const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', sender); + + const key1 = 'key1'; + const value1 = Buffer.from('value1'); + + const key2 = 'key2'; + const value2 = Buffer.from('value2'); + + const writeProperties = [ + [key1, '0x'+value1.toString('hex')], + [key2, '0x'+value2.toString('hex')], + ]; + + await contract.methods.setCollectionProperties(writeProperties).send(); + const readProperties = await contract.methods.collectionProperties([key1, key2]).call(); + expect(readProperties).to.be.like(writeProperties); + }); +}); --- a/tests/src/eth/fungibleAbi.json +++ b/tests/src/eth/fungibleAbi.json @@ -229,6 +229,25 @@ "type": "function" }, { + "inputs": [ + { "internalType": "string[]", "name": "keys", "type": "string[]" } + ], + "name": "collectionProperties", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "field_0", "type": "string" }, + { "internalType": "bytes", "name": "field_1", "type": "bytes" } + ], + "internalType": "struct Tuple10[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [{ "internalType": "string", "name": "key", "type": "string" }], "name": "collectionProperty", "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], @@ -463,6 +482,23 @@ }, { "inputs": [ + { + "components": [ + { "internalType": "string", "name": "field_0", "type": "string" }, + { "internalType": "bytes", "name": "field_1", "type": "bytes" } + ], + "internalType": "struct Tuple10[]", + "name": "properties", + "type": "tuple[]" + } + ], + "name": "setCollectionProperties", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "string", "name": "key", "type": "string" }, { "internalType": "bytes", "name": "value", "type": "bytes" } ], --- a/tests/src/eth/nonFungibleAbi.json +++ b/tests/src/eth/nonFungibleAbi.json @@ -259,6 +259,25 @@ "type": "function" }, { + "inputs": [ + { "internalType": "string[]", "name": "keys", "type": "string[]" } + ], + "name": "collectionProperties", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "field_0", "type": "string" }, + { "internalType": "bytes", "name": "field_1", "type": "bytes" } + ], + "internalType": "struct Tuple19[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [{ "internalType": "string", "name": "key", "type": "string" }], "name": "collectionProperty", "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], @@ -578,6 +597,23 @@ }, { "inputs": [ + { + "components": [ + { "internalType": "string", "name": "field_0", "type": "string" }, + { "internalType": "bytes", "name": "field_1", "type": "bytes" } + ], + "internalType": "struct Tuple19[]", + "name": "properties", + "type": "tuple[]" + } + ], + "name": "setCollectionProperties", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "string", "name": "key", "type": "string" }, { "internalType": "bytes", "name": "value", "type": "bytes" } ], --- a/tests/src/eth/reFungibleAbi.json +++ b/tests/src/eth/reFungibleAbi.json @@ -241,6 +241,25 @@ "type": "function" }, { + "inputs": [ + { "internalType": "string[]", "name": "keys", "type": "string[]" } + ], + "name": "collectionProperties", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "field_0", "type": "string" }, + { "internalType": "bytes", "name": "field_1", "type": "bytes" } + ], + "internalType": "struct Tuple19[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [{ "internalType": "string", "name": "key", "type": "string" }], "name": "collectionProperty", "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], @@ -560,6 +579,23 @@ }, { "inputs": [ + { + "components": [ + { "internalType": "string", "name": "field_0", "type": "string" }, + { "internalType": "bytes", "name": "field_1", "type": "bytes" } + ], + "internalType": "struct Tuple19[]", + "name": "properties", + "type": "tuple[]" + } + ], + "name": "setCollectionProperties", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "string", "name": "key", "type": "string" }, { "internalType": "bytes", "name": "value", "type": "bytes" } ], -- gitstuff