difftreelog
feat add delete properties
in: master
17 files changed
pallets/common/src/erc.rsdiffbeforeafterboth117 /// @param key Property key.117 /// @param key Property key.118 #[weight(<SelfWeightOf<T>>::delete_collection_properties(1))]118 #[weight(<SelfWeightOf<T>>::delete_collection_properties(1))]119 fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {119 fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {120 self.consume_store_reads_and_writes(1, 1)?;121122 let caller = T::CrossAccountId::from_eth(caller);120 let caller = T::CrossAccountId::from_eth(caller);123 let key = <Vec<u8>>::from(key)121 let key = <Vec<u8>>::from(key)127 <Pallet<T>>::delete_collection_property(self, &caller, key).map_err(dispatch_to_evm::<T>)125 <Pallet<T>>::delete_collection_property(self, &caller, key).map_err(dispatch_to_evm::<T>)128 }126 }127128 /// Delete collection properties.129 ///130 /// @param keys Properties keys.131 #[weight(<SelfWeightOf<T>>::delete_collection_properties(keys.len() as u32))]132 fn delete_collection_properties(&mut self, caller: caller, keys: Vec<string>) -> Result<()> {133 let caller = T::CrossAccountId::from_eth(caller);134 let keys = keys135 .into_iter()136 .map(|key| {137 <Vec<u8>>::from(key)138 .try_into()139 .map_err(|_| Error::Revert("key too large".into()))140 })141 .collect::<Result<Vec<_>>>()?;142143 <Pallet<T>>::delete_collection_properties(self, &caller, keys).map_err(dispatch_to_evm::<T>)144 }129145130 /// Get collection property.146 /// Get collection property.131 ///147 ///146162147 /// Get collection properties.163 /// Get collection properties.148 ///164 ///149 /// @param keys Properties keys.165 /// @param keys Properties keys. Empty keys for all propertyes.150 /// @return Vector of properties key/value pairs.166 /// @return Vector of properties key/value pairs.151 fn collection_properties(&self, keys: Vec<string>) -> Result<Vec<(string, bytes)>> {167 fn collection_properties(&self, keys: Vec<string>) -> Result<Vec<(string, bytes)>> {152 let mut keys_ = Vec::<PropertyKey>::with_capacity(keys.len());168 let keys = keys153 for key in keys {154 keys_.push(169 .into_iter()170 .map(|key| {155 <Vec<u8>>::from(key)171 <Vec<u8>>::from(key)156 .try_into()172 .try_into()157 .map_err(|_| Error::Revert("key too large".into()))?,173 .map_err(|_| Error::Revert("key too large".into()))158 )174 })159 }175 .collect::<Result<Vec<_>>>()?;176160 let properties = Pallet::<T>::filter_collection_properties(self.id, Some(keys_))177 let properties = Pallet::<T>::filter_collection_properties(178 self.id,179 if keys.is_empty() { None } else { Some(keys) },180 )161 .map_err(dispatch_to_evm::<T>)?;181 .map_err(dispatch_to_evm::<T>)?;162182163 let mut properties_ = Vec::<(string, bytes)>::with_capacity(properties.len());183 let properties = properties184 .into_iter()164 for p in properties {185 .map(|p| {165 let key =186 let key =166 string::from_utf8(p.key.into()).map_err(|e| Error::Revert(format!("{}", e)))?;187 string::from_utf8(p.key.into()).map_err(|e| Error::Revert(format!("{}", e)))?;167 let value = bytes(p.value.to_vec());188 let value = bytes(p.value.to_vec());168 properties_.push((key, value));189 Ok((key, value))169 }190 })191 .collect::<Result<Vec<_>>>()?;170 Ok(properties_)192 Ok(properties)171 }193 }172194173 /// Set the sponsor of the collection.195 /// Set the sponsor of the collection.pallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth18}18}191920/// @title A contract that allows you to work with collections.20/// @title A contract that allows you to work with collections.21/// @dev the ERC-165 identifier for this interface is 0x5d35441021/// @dev the ERC-165 identifier for this interface is 0xb3152af322contract Collection is Dummy, ERC165 {22contract Collection is Dummy, ERC165 {23 /// Set collection property.23 /// Set collection property.24 ///24 ///55 dummy = 0;55 dummy = 0;56 }56 }5758 /// Delete collection properties.59 ///60 /// @param keys Properties keys.61 /// @dev EVM selector for this function is: 0xee206ee3,62 /// or in textual repr: deleteCollectionProperties(string[])63 function deleteCollectionProperties(string[] memory keys) public {64 require(false, stub_error);65 keys;66 dummy = 0;67 }576858 /// Get collection property.69 /// Get collection property.59 ///70 ///728373 /// Get collection properties.84 /// Get collection properties.74 ///85 ///75 /// @param keys Properties keys.86 /// @param keys Properties keys. Empty keys for all propertyes.76 /// @return Vector of properties key/value pairs.87 /// @return Vector of properties key/value pairs.77 /// @dev EVM selector for this function is: 0x285fb8e6,88 /// @dev EVM selector for this function is: 0x285fb8e6,78 /// or in textual repr: collectionProperties(string[])89 /// or in textual repr: collectionProperties(string[])pallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth91}91}929293/// @title A contract that allows you to work with collections.93/// @title A contract that allows you to work with collections.94/// @dev the ERC-165 identifier for this interface is 0x5d35441094/// @dev the ERC-165 identifier for this interface is 0xb3152af395contract Collection is Dummy, ERC165 {95contract Collection is Dummy, ERC165 {96 /// Set collection property.96 /// Set collection property.97 ///97 ///128 dummy = 0;128 dummy = 0;129 }129 }130131 /// Delete collection properties.132 ///133 /// @param keys Properties keys.134 /// @dev EVM selector for this function is: 0xee206ee3,135 /// or in textual repr: deleteCollectionProperties(string[])136 function deleteCollectionProperties(string[] memory keys) public {137 require(false, stub_error);138 keys;139 dummy = 0;140 }130141131 /// Get collection property.142 /// Get collection property.132 ///143 ///145156146 /// Get collection properties.157 /// Get collection properties.147 ///158 ///148 /// @param keys Properties keys.159 /// @param keys Properties keys. Empty keys for all propertyes.149 /// @return Vector of properties key/value pairs.160 /// @return Vector of properties key/value pairs.150 /// @dev EVM selector for this function is: 0x285fb8e6,161 /// @dev EVM selector for this function is: 0x285fb8e6,151 /// or in textual repr: collectionProperties(string[])162 /// or in textual repr: collectionProperties(string[])pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth91}91}929293/// @title A contract that allows you to work with collections.93/// @title A contract that allows you to work with collections.94/// @dev the ERC-165 identifier for this interface is 0x5d35441094/// @dev the ERC-165 identifier for this interface is 0xb3152af395contract Collection is Dummy, ERC165 {95contract Collection is Dummy, ERC165 {96 /// Set collection property.96 /// Set collection property.97 ///97 ///128 dummy = 0;128 dummy = 0;129 }129 }130131 /// Delete collection properties.132 ///133 /// @param keys Properties keys.134 /// @dev EVM selector for this function is: 0xee206ee3,135 /// or in textual repr: deleteCollectionProperties(string[])136 function deleteCollectionProperties(string[] memory keys) public {137 require(false, stub_error);138 keys;139 dummy = 0;140 }130141131 /// Get collection property.142 /// Get collection property.132 ///143 ///145156146 /// Get collection properties.157 /// Get collection properties.147 ///158 ///148 /// @param keys Properties keys.159 /// @param keys Properties keys. Empty keys for all propertyes.149 /// @return Vector of properties key/value pairs.160 /// @return Vector of properties key/value pairs.150 /// @dev EVM selector for this function is: 0x285fb8e6,161 /// @dev EVM selector for this function is: 0x285fb8e6,151 /// or in textual repr: collectionProperties(string[])162 /// or in textual repr: collectionProperties(string[])tests/src/eth/api/UniqueFungible.soldiffbeforeafterboth13}13}141415/// @title A contract that allows you to work with collections.15/// @title A contract that allows you to work with collections.16/// @dev the ERC-165 identifier for this interface is 0x5d35441016/// @dev the ERC-165 identifier for this interface is 0xb3152af317interface Collection is Dummy, ERC165 {17interface Collection is Dummy, ERC165 {18 /// Set collection property.18 /// Set collection property.19 ///19 ///37 /// or in textual repr: deleteCollectionProperty(string)37 /// or in textual repr: deleteCollectionProperty(string)38 function deleteCollectionProperty(string memory key) external;38 function deleteCollectionProperty(string memory key) external;3940 /// Delete collection properties.41 ///42 /// @param keys Properties keys.43 /// @dev EVM selector for this function is: 0xee206ee3,44 /// or in textual repr: deleteCollectionProperties(string[])45 function deleteCollectionProperties(string[] memory keys) external;394640 /// Get collection property.47 /// Get collection property.41 ///48 ///495650 /// Get collection properties.57 /// Get collection properties.51 ///58 ///52 /// @param keys Properties keys.59 /// @param keys Properties keys. Empty keys for all propertyes.53 /// @return Vector of properties key/value pairs.60 /// @return Vector of properties key/value pairs.54 /// @dev EVM selector for this function is: 0x285fb8e6,61 /// @dev EVM selector for this function is: 0x285fb8e6,55 /// or in textual repr: collectionProperties(string[])62 /// or in textual repr: collectionProperties(string[])tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth62}62}636364/// @title A contract that allows you to work with collections.64/// @title A contract that allows you to work with collections.65/// @dev the ERC-165 identifier for this interface is 0x5d35441065/// @dev the ERC-165 identifier for this interface is 0xb3152af366interface Collection is Dummy, ERC165 {66interface Collection is Dummy, ERC165 {67 /// Set collection property.67 /// Set collection property.68 ///68 ///86 /// or in textual repr: deleteCollectionProperty(string)86 /// or in textual repr: deleteCollectionProperty(string)87 function deleteCollectionProperty(string memory key) external;87 function deleteCollectionProperty(string memory key) external;8889 /// Delete collection properties.90 ///91 /// @param keys Properties keys.92 /// @dev EVM selector for this function is: 0xee206ee3,93 /// or in textual repr: deleteCollectionProperties(string[])94 function deleteCollectionProperties(string[] memory keys) external;889589 /// Get collection property.96 /// Get collection property.90 ///97 ///9810599 /// Get collection properties.106 /// Get collection properties.100 ///107 ///101 /// @param keys Properties keys.108 /// @param keys Properties keys. Empty keys for all propertyes.102 /// @return Vector of properties key/value pairs.109 /// @return Vector of properties key/value pairs.103 /// @dev EVM selector for this function is: 0x285fb8e6,110 /// @dev EVM selector for this function is: 0x285fb8e6,104 /// or in textual repr: collectionProperties(string[])111 /// or in textual repr: collectionProperties(string[])tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth62}62}636364/// @title A contract that allows you to work with collections.64/// @title A contract that allows you to work with collections.65/// @dev the ERC-165 identifier for this interface is 0x5d35441065/// @dev the ERC-165 identifier for this interface is 0xb3152af366interface Collection is Dummy, ERC165 {66interface Collection is Dummy, ERC165 {67 /// Set collection property.67 /// Set collection property.68 ///68 ///86 /// or in textual repr: deleteCollectionProperty(string)86 /// or in textual repr: deleteCollectionProperty(string)87 function deleteCollectionProperty(string memory key) external;87 function deleteCollectionProperty(string memory key) external;8889 /// Delete collection properties.90 ///91 /// @param keys Properties keys.92 /// @dev EVM selector for this function is: 0xee206ee3,93 /// or in textual repr: deleteCollectionProperties(string[])94 function deleteCollectionProperties(string[] memory keys) external;889589 /// Get collection property.96 /// Get collection property.90 ///97 ///9810599 /// Get collection properties.106 /// Get collection properties.100 ///107 ///101 /// @param keys Properties keys.108 /// @param keys Properties keys. Empty keys for all propertyes.102 /// @return Vector of properties key/value pairs.109 /// @return Vector of properties key/value pairs.103 /// @dev EVM selector for this function is: 0x285fb8e6,110 /// @dev EVM selector for this function is: 0x285fb8e6,104 /// or in textual repr: collectionProperties(string[])111 /// or in textual repr: collectionProperties(string[])tests/src/eth/collectionProperties.test.tsdiffbeforeafterboth161617import {itEth, usingEthPlaygrounds, expect, EthUniqueHelper} from './util';17import {itEth, usingEthPlaygrounds, expect, EthUniqueHelper} from './util';18import {Pallets} from '../util';18import {Pallets} from '../util';19import {IProperty, ITokenPropertyPermission} from '../util/playgrounds/types';19import {IProperty, ITokenPropertyPermission, TCollectionMode} from '../util/playgrounds/types';20import {IKeyringPair} from '@polkadot/types/types';20import {IKeyringPair} from '@polkadot/types/types';212122describe('EVM collection properties', () => {22describe('EVM collection properties', () => {163});163});164164165describe('EVM collection property', () => {165describe('EVM collection property', () => {166 let alice: IKeyringPair;167168 before(() => {169 usingEthPlaygrounds(async (_helper, privateKey) => {170 alice = await privateKey('//Alice');171 });172 });173174 async function testSetReadProperties(helper: EthUniqueHelper, mode: TCollectionMode) {175 const collection = await helper[mode].mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'});176177 const sender = await helper.eth.createAccountWithBalance(alice, 100n);178 await collection.addAdmin(alice, {Ethereum: sender});179180 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);181 const contract = helper.ethNativeContract.collection(collectionAddress, mode, sender);182183 const keys = ['key0', 'key1'];184185 const writeProperties = [186 helper.ethProperty.property(keys[0], 'value0'),187 helper.ethProperty.property(keys[1], 'value1'),188 ];189190 await contract.methods.setCollectionProperties(writeProperties).send();191 const readProperties = await contract.methods.collectionProperties([keys[0], keys[1]]).call();192 expect(readProperties).to.be.like(writeProperties);193 }194195 itEth('Set/read properties ft', async ({helper}) => {196 await testSetReadProperties(helper, 'ft');197 });198 itEth('Set/read properties rft', async ({helper}) => {199 await testSetReadProperties(helper, 'rft');200 });201 itEth('Set/read properties nft', async ({helper}) => {202 await testSetReadProperties(helper, 'nft');203 });204166 itEth('Set/read properties', async ({helper, privateKey}) => {205 async function testDeleteProperties(helper: EthUniqueHelper, mode: TCollectionMode) {167 const alice = await privateKey('//Alice');168 const collection = await helper.nft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'});206 const collection = await helper[mode].mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'});169207170 const sender = await helper.eth.createAccountWithBalance(alice, 100n);208 const sender = await helper.eth.createAccountWithBalance(alice, 100n);171 await collection.addAdmin(alice, {Ethereum: sender});209 await collection.addAdmin(alice, {Ethereum: sender});172210173 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);211 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);174 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', sender);212 const contract = helper.ethNativeContract.collection(collectionAddress, mode, sender);175213176 const key1 = 'key1';214 const keys = ['key0', 'key1', 'key2', 'key3'];215216 {177 const value1 = Buffer.from('value1');217 const writeProperties = [178 218 helper.ethProperty.property(keys[0], 'value0'),179 const key2 = 'key2';219 helper.ethProperty.property(keys[1], 'value1'),220 helper.ethProperty.property(keys[2], 'value2'),221 helper.ethProperty.property(keys[3], 'value3'),222 ];223224 await contract.methods.setCollectionProperties(writeProperties).send();180 const value2 = Buffer.from('value2');225 const readProperties = await contract.methods.collectionProperties([keys[0], keys[1], keys[2], keys[3]]).call();181226 expect(readProperties).to.be.like(writeProperties);227 }228229 {182 const writeProperties = [230 const expectProperties = [183 [key1, '0x'+value1.toString('hex')],231 helper.ethProperty.property(keys[0], 'value0'),184 [key2, '0x'+value2.toString('hex')],232 helper.ethProperty.property(keys[1], 'value1'),185 ];233 ];186234187 await contract.methods.setCollectionProperties(writeProperties).send();235 await contract.methods.deleteCollectionProperties([keys[2], keys[3]]).send();188 const readProperties = await contract.methods.collectionProperties([key1, key2]).call();236 const readProperties = await contract.methods.collectionProperties([]).call();189 expect(readProperties).to.be.like(writeProperties);237 expect(readProperties).to.be.like(expectProperties);238 }190 });239 }240 241 itEth('Delete properties ft', async ({helper}) => {242 await testDeleteProperties(helper, 'ft');243 });244 itEth('Delete properties rft', async ({helper}) => {245 await testDeleteProperties(helper, 'rft');246 });247 itEth('Delete properties nft', async ({helper}) => {248 await testDeleteProperties(helper, 'nft');249 });250 191});251});192252tests/src/eth/fungibleAbi.jsondiffbeforeafterboth292 "stateMutability": "view",292 "stateMutability": "view",293 "type": "function"293 "type": "function"294 },294 },295 {296 "inputs": [297 { "internalType": "string[]", "name": "keys", "type": "string[]" }298 ],299 "name": "deleteCollectionProperties",300 "outputs": [],301 "stateMutability": "nonpayable",302 "type": "function"303 },295 {304 {296 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],305 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],297 "name": "deleteCollectionProperty",306 "name": "deleteCollectionProperty",tests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth315 "stateMutability": "view",315 "stateMutability": "view",316 "type": "function"316 "type": "function"317 },317 },318 {319 "inputs": [320 { "internalType": "string[]", "name": "keys", "type": "string[]" }321 ],322 "name": "deleteCollectionProperties",323 "outputs": [],324 "stateMutability": "nonpayable",325 "type": "function"326 },318 {327 {319 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],328 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],320 "name": "deleteCollectionProperty",329 "name": "deleteCollectionProperty",tests/src/eth/reFungibleAbi.jsondiffbeforeafterboth297 "stateMutability": "view",297 "stateMutability": "view",298 "type": "function"298 "type": "function"299 },299 },300 {301 "inputs": [302 { "internalType": "string[]", "name": "keys", "type": "string[]" }303 ],304 "name": "deleteCollectionProperties",305 "outputs": [],306 "stateMutability": "nonpayable",307 "type": "function"308 },300 {309 {301 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],310 "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],302 "name": "deleteCollectionProperty",311 "name": "deleteCollectionProperty",tests/src/eth/util/playgrounds/types.tsdiffbeforeafterboth20 readonly field_1: string | Uint8Array,20 readonly field_1: string | Uint8Array,21}21}2223export type EthProperty = string[];222425tests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth181819import {DevUniqueHelper} from '../../../util/playgrounds/unique.dev';19import {DevUniqueHelper} from '../../../util/playgrounds/unique.dev';202021import {ContractImports, CompiledContract, TEthCrossAccount, NormalizedEvent} from './types';21import {ContractImports, CompiledContract, TEthCrossAccount, NormalizedEvent, EthProperty} from './types';222223// Native contracts ABI23// Native contracts ABI24import collectionHelpersAbi from '../../collectionHelpersAbi.json';24import collectionHelpersAbi from '../../collectionHelpersAbi.json';28import refungibleTokenAbi from '../../reFungibleTokenAbi.json';28import refungibleTokenAbi from '../../reFungibleTokenAbi.json';29import contractHelpersAbi from './../contractHelpersAbi.json';29import contractHelpersAbi from './../contractHelpersAbi.json';30import {ICrossAccountId, TEthereumAccount} from '../../../util/playgrounds/types';30import {ICrossAccountId, TEthereumAccount} from '../../../util/playgrounds/types';31import {TCollectionMode} from '../../../util/playgrounds/types';313232class EthGroupBase {33class EthGroupBase {33 helper: EthUniqueHelper;34 helper: EthUniqueHelper;107 return new web3.eth.Contract(collectionHelpersAbi as any, '0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f', {from: caller, gas: this.helper.eth.DEFAULT_GAS});108 return new web3.eth.Contract(collectionHelpersAbi as any, '0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f', {from: caller, gas: this.helper.eth.DEFAULT_GAS});108 }109 }109110110 collection(address: string, mode: 'nft' | 'rft' | 'ft', caller?: string): Contract {111 collection(address: string, mode: TCollectionMode, caller?: string): Contract {111 const abi = {112 const abi = {112 'nft': nonFungibleAbi,113 'nft': nonFungibleAbi,113 'rft': refungibleAbi,114 'rft': refungibleAbi,338 }339 }339}340} 340341342export class EthPropertyGroup extends EthGroupBase {343 property(key: string, value: string): EthProperty {344 return [345 key, 346 '0x'+Buffer.from(value).toString('hex'),347 ];348 }349}341export type EthUniqueHelperConstructor = new (...args: any[]) => EthUniqueHelper;350export type EthUniqueHelperConstructor = new (...args: any[]) => EthUniqueHelper;342351343export class EthCrossAccountGroup extends EthGroupBase {352export class EthCrossAccountGroup extends EthGroupBase {369 ethNativeContract: NativeContractGroup;378 ethNativeContract: NativeContractGroup;370 ethContract: ContractGroup;379 ethContract: ContractGroup;371 ethCrossAccount: EthCrossAccountGroup;380 ethCrossAccount: EthCrossAccountGroup;381 ethProperty: EthPropertyGroup;372382373 constructor(logger: { log: (msg: any, level: any) => void, level: any }, options: {[key: string]: any} = {}) {383 constructor(logger: { log: (msg: any, level: any) => void, level: any }, options: {[key: string]: any} = {}) {374 options.helperBase = options.helperBase ?? EthUniqueHelper;384 options.helperBase = options.helperBase ?? EthUniqueHelper;379 this.ethCrossAccount = new EthCrossAccountGroup(this);389 this.ethCrossAccount = new EthCrossAccountGroup(this);380 this.ethNativeContract = new NativeContractGroup(this);390 this.ethNativeContract = new NativeContractGroup(this);381 this.ethContract = new ContractGroup(this);391 this.ethContract = new ContractGroup(this);392 this.ethProperty = new EthPropertyGroup(this);382 }393 }383394384 getWeb3(): Web3 {395 getWeb3(): Web3 {tests/src/util/playgrounds/types.tsdiffbeforeafterboth224export type TRelayNetworks = 'rococo' | 'westend';224export type TRelayNetworks = 'rococo' | 'westend';225export type TNetworks = TUniqueNetworks | TSiblingNetworkds | TRelayNetworks;225export type TNetworks = TUniqueNetworks | TSiblingNetworkds | TRelayNetworks;226export type TSigner = IKeyringPair; // | 'string'226export type TSigner = IKeyringPair; // | 'string'227export type TCollectionMode = 'nft' | 'rft' | 'ft';227228