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

difftreelog

misk: Move TokenChanged event into ERC721 contracts

Trubnikov Sergey2023-02-02parent: #3563d09.patch.diff
in: master

16 files changed

modifiedpallets/common/src/erc.rsdiffbeforeafterboth
26};26};
27use pallet_evm_coder_substrate::dispatch_to_evm;27use pallet_evm_coder_substrate::dispatch_to_evm;
28use sp_std::{vec, vec::Vec};28use sp_std::{vec, vec::Vec};
29use sp_core::U256;
30use up_data_structs::{29use up_data_structs::{
31 CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property, SponsoringRateLimit,30 CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property, SponsoringRateLimit,
32 SponsorshipState,31 SponsorshipState,
67 collection_id: Address,66 collection_id: Address,
68 },67 },
69
70 /// The token has been changed.
71 TokenChanged {
72 /// Collection ID.
73 #[indexed]
74 collection_id: Address,
75 /// Token ID.
76 token_id: U256,
77 },
78}68}
7969
80/// Does not always represent a full collection, for RFT it is either70/// Does not always represent a full collection, for RFT it is either
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
1250 mut stored_properties: Properties,1250 mut stored_properties: Properties,
1251 is_token_owner: impl Fn() -> Result<bool, DispatchError>,1251 is_token_owner: impl Fn() -> Result<bool, DispatchError>,
1252 set_token_properties: impl FnOnce(Properties),1252 set_token_properties: impl FnOnce(Properties),
1253 log: evm_coder::ethereum::Log,
1253 ) -> DispatchResult {1254 ) -> DispatchResult {
1254 let is_collection_admin = collection.is_owner_or_admin(sender);1255 let is_collection_admin = collection.is_owner_or_admin(sender);
1255 let permissions = Self::property_permissions(collection.id);1256 let permissions = Self::property_permissions(collection.id);
1304 }1305 }
1305 }1306 }
13061307
1307 <PalletEvm<T>>::deposit_log(1308 <PalletEvm<T>>::deposit_log(log.clone());
1308 CollectionHelpersEvents::TokenChanged {
1309 collection_id: eth::collection_id_to_address(collection.id),
1310 token_id: token_id.into(),
1311 }
1312 .to_log(T::ContractAddress::get()),
1313 );
1314 }1309 }
13151310
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
50 TokenProperties, SelfWeightOf, weights::WeightInfo,50 TokenProperties, SelfWeightOf, weights::WeightInfo,
51};51};
52
53/// Nft events.
54#[derive(ToLog)]
55pub enum ERC721TokenEvent {
56 /// The token has been changed.
57 TokenChanged {
58 /// Collection ID.
59 #[indexed]
60 collection_id: Address,
61 /// Token ID.
62 token_id: U256,
63 },
64}
5265
53frontier_contract! {66frontier_contract! {
54 macro_rules! NonfungibleHandle_result {...}67 macro_rules! NonfungibleHandle_result {...}
55 impl<T: Config> Contract for NonfungibleHandle<T> {...}68 impl<T: Config> Contract for NonfungibleHandle<T> {...}
56}69}
5770
58/// @title A contract that allows to set and delete token properties and change token property permissions.71/// @title A contract that allows to set and delete token properties and change token property permissions.
59#[solidity_interface(name = TokenProperties, enum(derive(PreDispatch)), enum_attr(weight))]72#[solidity_interface(name = TokenProperties, events(ERC721TokenEvent), enum(derive(PreDispatch)), enum_attr(weight))]
60impl<T: Config> NonfungibleHandle<T> {73impl<T: Config> NonfungibleHandle<T> {
61 /// @notice Set permissions for token property.74 /// @notice Set permissions for token property.
62 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.75 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
112};112};
113use pallet_structure::{Pallet as PalletStructure, Error as StructureError};113use pallet_structure::{Pallet as PalletStructure, Error as StructureError};
114use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};114use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
115use sp_core::H160;115use sp_core::{Get, H160};
116use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};116use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};
117use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};117use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};
118use core::ops::Deref;118use core::ops::Deref;
622 stored_properties,622 stored_properties,
623 is_token_owner,623 is_token_owner,
624 |properties| <TokenProperties<T>>::set((collection.id, token_id), properties),624 |properties| <TokenProperties<T>>::set((collection.id, token_id), properties),
625 erc::ERC721TokenEvent::TokenChanged {
626 collection_id: collection_id_to_address(collection.id),
627 token_id: token_id.into(),
628 }
629 .to_log(T::ContractAddress::get()),
625 )630 )
626 }631 }
627632
modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
17 }17 }
18}18}
19
20/// @dev inlined interface
21contract ERC721TokenEvent {
22 event TokenChanged(address indexed collectionId, uint256 tokenId);
23}
1924
20/// @title A contract that allows to set and delete token properties and change token property permissions.25/// @title A contract that allows to set and delete token properties and change token property permissions.
21/// @dev the ERC-165 identifier for this interface is 0xde0695c226/// @dev the ERC-165 identifier for this interface is 0xde0695c2
22contract TokenProperties is Dummy, ERC165 {27contract TokenProperties is Dummy, ERC165, ERC721TokenEvent {
23 // /// @notice Set permissions for token property.28 // /// @notice Set permissions for token property.
24 // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.29 // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
25 // /// @param key Property key.30 // /// @param key Property key.
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
5959
60pub const ADDRESS_FOR_PARTIALLY_OWNED_TOKENS: H160 = H160::repeat_byte(0xff);60pub const ADDRESS_FOR_PARTIALLY_OWNED_TOKENS: H160 = H160::repeat_byte(0xff);
61
62/// Rft events.
63#[derive(ToLog)]
64pub enum ERC721TokenEvent {
65 /// The token has been changed.
66 TokenChanged {
67 /// Collection ID.
68 #[indexed]
69 collection_id: Address,
70 /// Token ID.
71 token_id: U256,
72 },
73}
6174
62/// @title A contract that allows to set and delete token properties and change token property permissions.75/// @title A contract that allows to set and delete token properties and change token property permissions.
63#[solidity_interface(name = TokenProperties, enum(derive(PreDispatch)), enum_attr(weight))]76#[solidity_interface(name = TokenProperties, events(ERC721TokenEvent), enum(derive(PreDispatch)), enum_attr(weight))]
64impl<T: Config> RefungibleHandle<T> {77impl<T: Config> RefungibleHandle<T> {
65 /// @notice Set permissions for token property.78 /// @notice Set permissions for token property.
66 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.79 /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
100 Event as CommonEvent, Pallet as PalletCommon,100 Event as CommonEvent, Pallet as PalletCommon,
101};101};
102use pallet_structure::Pallet as PalletStructure;102use pallet_structure::Pallet as PalletStructure;
103use sp_core::H160;103use sp_core::{Get, H160};
104use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};104use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};
105use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};105use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};
106use up_data_structs::{106use up_data_structs::{
571 stored_properties,571 stored_properties,
572 is_token_owner,572 is_token_owner,
573 |properties| <TokenProperties<T>>::set((collection.id, token_id), properties),573 |properties| <TokenProperties<T>>::set((collection.id, token_id), properties),
574 erc::ERC721TokenEvent::TokenChanged {
575 collection_id: collection_id_to_address(collection.id),
576 token_id: token_id.into(),
577 }
578 .to_log(T::ContractAddress::get()),
574 )579 )
575 }580 }
576581
modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
17 }17 }
18}18}
19
20/// @dev inlined interface
21contract ERC721TokenEvent {
22 event TokenChanged(address indexed collectionId, uint256 tokenId);
23}
1924
20/// @title A contract that allows to set and delete token properties and change token property permissions.25/// @title A contract that allows to set and delete token properties and change token property permissions.
21/// @dev the ERC-165 identifier for this interface is 0xde0695c226/// @dev the ERC-165 identifier for this interface is 0xde0695c2
22contract TokenProperties is Dummy, ERC165 {27contract TokenProperties is Dummy, ERC165, ERC721TokenEvent {
23 // /// @notice Set permissions for token property.28 // /// @notice Set permissions for token property.
24 // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.29 // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
25 // /// @param key Property key.30 // /// @param key Property key.
modifiedpallets/unique/src/eth/stubs/CollectionHelpers.soldiffbeforeafterboth
22 event CollectionCreated(address indexed owner, address indexed collectionId);22 event CollectionCreated(address indexed owner, address indexed collectionId);
23 event CollectionDestroyed(address indexed collectionId);23 event CollectionDestroyed(address indexed collectionId);
24 event CollectionChanged(address indexed collectionId);24 event CollectionChanged(address indexed collectionId);
25 event TokenChanged(address indexed collectionId, uint256 tokenId);
26}25}
2726
28/// @title Contract, which allows users to operate with collections27/// @title Contract, which allows users to operate with collections
modifiedtests/src/eth/abi/collectionHelpers.jsondiffbeforeafterboth
44 "name": "CollectionDestroyed",44 "name": "CollectionDestroyed",
45 "type": "event"45 "type": "event"
46 },46 },
47 {
48 "anonymous": false,
49 "inputs": [
50 {
51 "indexed": true,
52 "internalType": "address",
53 "name": "collectionId",
54 "type": "address"
55 },
56 {
57 "indexed": false,
58 "internalType": "uint256",
59 "name": "tokenId",
60 "type": "uint256"
61 }
62 ],
63 "name": "TokenChanged",
64 "type": "event"
65 },
66 {47 {
67 "inputs": [48 "inputs": [
68 { "internalType": "uint32", "name": "collectionId", "type": "uint32" }49 { "internalType": "uint32", "name": "collectionId", "type": "uint32" }
modifiedtests/src/eth/abi/nonFungible.jsondiffbeforeafterboth
49 "name": "ApprovalForAll",49 "name": "ApprovalForAll",
50 "type": "event"50 "type": "event"
51 },51 },
52 {
53 "anonymous": false,
54 "inputs": [
55 {
56 "indexed": true,
57 "internalType": "address",
58 "name": "collectionId",
59 "type": "address"
60 },
61 {
62 "indexed": false,
63 "internalType": "uint256",
64 "name": "tokenId",
65 "type": "uint256"
66 }
67 ],
68 "name": "TokenChanged",
69 "type": "event"
70 },
52 {71 {
53 "anonymous": false,72 "anonymous": false,
54 "inputs": [73 "inputs": [
modifiedtests/src/eth/abi/reFungible.jsondiffbeforeafterboth
49 "name": "ApprovalForAll",49 "name": "ApprovalForAll",
50 "type": "event"50 "type": "event"
51 },51 },
52 {
53 "anonymous": false,
54 "inputs": [
55 {
56 "indexed": true,
57 "internalType": "address",
58 "name": "collectionId",
59 "type": "address"
60 },
61 {
62 "indexed": false,
63 "internalType": "uint256",
64 "name": "tokenId",
65 "type": "uint256"
66 }
67 ],
68 "name": "TokenChanged",
69 "type": "event"
70 },
52 {71 {
53 "anonymous": false,72 "anonymous": false,
54 "inputs": [73 "inputs": [
modifiedtests/src/eth/api/CollectionHelpers.soldiffbeforeafterboth
17 event CollectionCreated(address indexed owner, address indexed collectionId);17 event CollectionCreated(address indexed owner, address indexed collectionId);
18 event CollectionDestroyed(address indexed collectionId);18 event CollectionDestroyed(address indexed collectionId);
19 event CollectionChanged(address indexed collectionId);19 event CollectionChanged(address indexed collectionId);
20 event TokenChanged(address indexed collectionId, uint256 tokenId);
21}20}
2221
23/// @title Contract, which allows users to operate with collections22/// @title Contract, which allows users to operate with collections
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
12 function supportsInterface(bytes4 interfaceID) external view returns (bool);12 function supportsInterface(bytes4 interfaceID) external view returns (bool);
13}13}
14
15/// @dev inlined interface
16interface ERC721TokenEvent {
17 event TokenChanged(address indexed collectionId, uint256 tokenId);
18}
1419
15/// @title A contract that allows to set and delete token properties and change token property permissions.20/// @title A contract that allows to set and delete token properties and change token property permissions.
16/// @dev the ERC-165 identifier for this interface is 0xde0695c221/// @dev the ERC-165 identifier for this interface is 0xde0695c2
17interface TokenProperties is Dummy, ERC165 {22interface TokenProperties is Dummy, ERC165, ERC721TokenEvent {
18 // /// @notice Set permissions for token property.23 // /// @notice Set permissions for token property.
19 // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.24 // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
20 // /// @param key Property key.25 // /// @param key Property key.
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
12 function supportsInterface(bytes4 interfaceID) external view returns (bool);12 function supportsInterface(bytes4 interfaceID) external view returns (bool);
13}13}
14
15/// @dev inlined interface
16interface ERC721TokenEvent {
17 event TokenChanged(address indexed collectionId, uint256 tokenId);
18}
1419
15/// @title A contract that allows to set and delete token properties and change token property permissions.20/// @title A contract that allows to set and delete token properties and change token property permissions.
16/// @dev the ERC-165 identifier for this interface is 0xde0695c221/// @dev the ERC-165 identifier for this interface is 0xde0695c2
17interface TokenProperties is Dummy, ERC165 {22interface TokenProperties is Dummy, ERC165, ERC721TokenEvent {
18 // /// @notice Set permissions for token property.23 // /// @notice Set permissions for token property.
19 // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.24 // /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
20 // /// @param key Property key.25 // /// @param key Property key.
modifiedtests/src/eth/events.test.tsdiffbeforeafterboth
29 });29 });
30});30});
3131
32function clearEvents(ethEvents: NormalizedEvent[], subEvents: IEvent[]) {32function clearEvents(ethEvents: NormalizedEvent[] | null, subEvents: IEvent[]) {
33 if (ethEvents !== null) {
33 ethEvents.splice(0);34 ethEvents.splice(0);
35 }
34 subEvents.splice(0);36 subEvents.splice(0);
35}37}
3638
374 const owner = await helper.eth.createAccountWithBalance(donor);376 const owner = await helper.eth.createAccountWithBalance(donor);
375 const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');377 const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');
376 const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);378 const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);
377 const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);
378 const result = await collection.methods.mint(owner).send({from: owner});379 const result = await collection.methods.mint(owner).send({from: owner});
379 const tokenId = result.events.Transfer.returnValues.tokenId;380 const tokenId = result.events.Transfer.returnValues.tokenId;
380 await collection.methods.setTokenPropertyPermissions([381 await collection.methods.setTokenPropertyPermissions([
386 ]).send({from: owner});387 ]).send({from: owner});
387388
388
389 const ethEvents: any = [];
390 collectionHelper.events.allEvents((_: any, event: any) => {
391 ethEvents.push(event);
392 });
393 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['TokenPropertySet', 'TokenPropertyDeleted']}]);389 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['TokenPropertySet', 'TokenPropertyDeleted']}]);
394 {390 {
395 await collection.methods.setProperties(tokenId, [{key: 'A', value: [1,2,3]}]).send({from: owner});391 const result = await collection.methods.setProperties(tokenId, [{key: 'A', value: [1,2,3]}]).send({from: owner});
396 await helper.wait.newBlocks(1);392 await helper.wait.newBlocks(1);
397 expect(ethEvents).to.containSubset([393 expect(result.events.TokenChanged).to.be.like({
398 {
399 event: 'TokenChanged',394 event: 'TokenChanged',
400 returnValues: {395 returnValues: {
401 collectionId: collectionAddress,396 collectionId: collectionAddress,
397 tokenId: tokenId,
402 },398 },
403 },399 });
404 ]);
405 expect(subEvents).to.containSubset([{method: 'TokenPropertySet'}]);400 expect(subEvents).to.containSubset([{method: 'TokenPropertySet'}]);
406 clearEvents(ethEvents, subEvents);401 clearEvents(null, subEvents);
407 }402 }
408 {403 {
409 await collection.methods.deleteProperties(tokenId, ['A']).send({from: owner});404 const result = await collection.methods.deleteProperties(tokenId, ['A']).send({from: owner});
410 await helper.wait.newBlocks(1);405 await helper.wait.newBlocks(1);
411 expect(ethEvents).to.containSubset([406 expect(result.events.TokenChanged).to.be.like({
412 {
413 event: 'TokenChanged',407 event: 'TokenChanged',
414 returnValues: {408 returnValues: {
415 collectionId: collectionAddress,409 collectionId: collectionAddress,
410 tokenId: tokenId,
416 },411 },
417 },412 });
418 ]);
419 expect(subEvents).to.containSubset([{method: 'TokenPropertyDeleted'}]);413 expect(subEvents).to.containSubset([{method: 'TokenPropertyDeleted'}]);
420 }414 }
421 unsubscribe();415 unsubscribe();