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

difftreelog

add `collectionHelperAddress` method to `ERC721` & `ERC20` interfaces.

PraetorP2022-11-24parent: #5aafe0c.patch.diff
in: master

14 files changed

modifiedpallets/fungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/fungible/src/erc.rs
+++ b/pallets/fungible/src/erc.rs
@@ -30,6 +30,7 @@
 use pallet_evm_coder_substrate::{call, dispatch_to_evm};
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
 use pallet_common::{CollectionHandle, erc::CollectionCall};
+use sp_core::Get;
 
 use crate::{
 	Allowance, Balance, Config, FungibleHandle, Pallet, SelfWeightOf, TotalSupply,
@@ -132,6 +133,11 @@
 
 		Ok(<Allowance<T>>::get((self.id, owner, spender)).into())
 	}
+
+	/// @notice Returns collection helper contract address
+	fn collection_helper_address(&self) -> Result<address> {
+		Ok(T::ContractAddress::get())
+	}
 }
 
 #[solidity_interface(name = ERC20Mintable)]
modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
--- a/pallets/fungible/src/stubs/UniqueFungible.sol
+++ b/pallets/fungible/src/stubs/UniqueFungible.sol
@@ -547,7 +547,7 @@
 	event Approval(address indexed owner, address indexed spender, uint256 value);
 }
 
-/// @dev the ERC-165 identifier for this interface is 0x942e8b22
+/// @dev the ERC-165 identifier for this interface is 0x8cb847c4
 contract ERC20 is Dummy, ERC165, ERC20Events {
 	/// @dev EVM selector for this function is: 0x06fdde03,
 	///  or in textual repr: name()
@@ -634,6 +634,15 @@
 		dummy;
 		return 0;
 	}
+
+	/// @notice Returns collection helper contract address
+	/// @dev EVM selector for this function is: 0x1896cce6,
+	///  or in textual repr: collectionHelperAddress()
+	function collectionHelperAddress() public view returns (address) {
+		require(false, stub_error);
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
 }
 
 contract UniqueFungible is Dummy, ERC165, ERC20, ERC20Mintable, ERC20UniqueExtensions, Collection {}
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -42,6 +42,7 @@
 use pallet_evm::{account::CrossAccountId, PrecompileHandle};
 use pallet_evm_coder_substrate::call;
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
+use sp_core::Get;
 
 use crate::{
 	AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData, TokensMinted,
@@ -489,6 +490,11 @@
 		// TODO: Not implemetable
 		Err("not implemented".into())
 	}
+	
+	/// @notice Returns collection helper contract address 
+	fn collection_helper_address(&self) -> Result<address> {
+		Ok(T::ContractAddress::get())
+	}
 }
 
 /// @title ERC721 Token that can be irreversibly burned (destroyed).
modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -920,7 +920,7 @@
 
 /// @title ERC-721 Non-Fungible Token Standard
 /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-/// @dev the ERC-165 identifier for this interface is 0x80ac58cd
+/// @dev the ERC-165 identifier for this interface is 0x983a942b
 contract ERC721 is Dummy, ERC165, ERC721Events {
 	/// @notice Count all NFTs assigned to an owner
 	/// @dev NFTs assigned to the zero address are considered invalid, and this
@@ -1050,6 +1050,15 @@
 		dummy;
 		return 0x0000000000000000000000000000000000000000;
 	}
+
+	/// @notice Returns collection helper contract address
+	/// @dev EVM selector for this function is: 0x1896cce6,
+	///  or in textual repr: collectionHelperAddress()
+	function collectionHelperAddress() public view returns (address) {
+		require(false, stub_error);
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
 }
 
 contract UniqueNFT is
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -38,7 +38,7 @@
 use pallet_evm::{account::CrossAccountId, PrecompileHandle};
 use pallet_evm_coder_substrate::{call, dispatch_to_evm};
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
-use sp_core::H160;
+use sp_core::{H160, Get};
 use sp_std::{collections::btree_map::BTreeMap, vec::Vec, vec};
 use up_data_structs::{
 	CollectionId, CollectionPropertiesVec, mapping::TokenAddressMapping, Property, PropertyKey,
@@ -482,6 +482,11 @@
 		// TODO: Not implemetable
 		Err("not implemented".into())
 	}
+	
+	/// @notice Returns collection helper contract address
+	fn collection_helper_address(&self) -> Result<address> {
+		Ok(T::ContractAddress::get())
+	}
 }
 
 /// Returns amount of pieces of `token` that `owner` have
modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -919,7 +919,7 @@
 
 /// @title ERC-721 Non-Fungible Token Standard
 /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-/// @dev the ERC-165 identifier for this interface is 0x58800161
+/// @dev the ERC-165 identifier for this interface is 0x4016cd87
 contract ERC721 is Dummy, ERC165, ERC721Events {
 	/// @notice Count all RFTs assigned to an owner
 	/// @dev RFTs assigned to the zero address are considered invalid, and this
@@ -1047,6 +1047,15 @@
 		dummy;
 		return 0x0000000000000000000000000000000000000000;
 	}
+
+	/// @notice Returns collection helper contract address
+	/// @dev EVM selector for this function is: 0x1896cce6,
+	///  or in textual repr: collectionHelperAddress()
+	function collectionHelperAddress() public view returns (address) {
+		require(false, stub_error);
+		dummy;
+		return 0x0000000000000000000000000000000000000000;
+	}
 }
 
 contract UniqueRefungible is
modifiedtests/src/apiConsts.test.tsdiffbeforeafterboth
--- a/tests/src/apiConsts.test.ts
+++ b/tests/src/apiConsts.test.ts
@@ -117,4 +117,4 @@
 
 function checkConst<T>(constValue: any, expectedValue: T) {
   expect(constValue.toBigInt()).equal(expectedValue);
-}
+}
\ No newline at end of file
modifiedtests/src/eth/abi/fungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/fungible.json
+++ b/tests/src/eth/abi/fungible.json
@@ -201,6 +201,13 @@
   },
   {
     "inputs": [],
+    "name": "collectionHelperAddress",
+    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [],
     "name": "collectionOwner",
     "outputs": [
       {
modifiedtests/src/eth/abi/nonFungible.jsondiffbeforeafterboth
before · tests/src/eth/abi/nonFungible.json
1[2  {3    "anonymous": false,4    "inputs": [5      {6        "indexed": true,7        "internalType": "address",8        "name": "owner",9        "type": "address"10      },11      {12        "indexed": true,13        "internalType": "address",14        "name": "approved",15        "type": "address"16      },17      {18        "indexed": true,19        "internalType": "uint256",20        "name": "tokenId",21        "type": "uint256"22      }23    ],24    "name": "Approval",25    "type": "event"26  },27  {28    "anonymous": false,29    "inputs": [30      {31        "indexed": true,32        "internalType": "address",33        "name": "owner",34        "type": "address"35      },36      {37        "indexed": true,38        "internalType": "address",39        "name": "operator",40        "type": "address"41      },42      {43        "indexed": false,44        "internalType": "bool",45        "name": "approved",46        "type": "bool"47      }48    ],49    "name": "ApprovalForAll",50    "type": "event"51  },52  {53    "anonymous": false,54    "inputs": [],55    "name": "MintingFinished",56    "type": "event"57  },58  {59    "anonymous": false,60    "inputs": [61      {62        "indexed": true,63        "internalType": "address",64        "name": "from",65        "type": "address"66      },67      {68        "indexed": true,69        "internalType": "address",70        "name": "to",71        "type": "address"72      },73      {74        "indexed": true,75        "internalType": "uint256",76        "name": "tokenId",77        "type": "uint256"78      }79    ],80    "name": "Transfer",81    "type": "event"82  },83  {84    "inputs": [85      {86        "components": [87          { "internalType": "address", "name": "eth", "type": "address" },88          { "internalType": "uint256", "name": "sub", "type": "uint256" }89        ],90        "internalType": "struct EthCrossAccount",91        "name": "newAdmin",92        "type": "tuple"93      }94    ],95    "name": "addCollectionAdminCross",96    "outputs": [],97    "stateMutability": "nonpayable",98    "type": "function"99  },100  {101    "inputs": [102      {103        "components": [104          { "internalType": "address", "name": "eth", "type": "address" },105          { "internalType": "uint256", "name": "sub", "type": "uint256" }106        ],107        "internalType": "struct EthCrossAccount",108        "name": "user",109        "type": "tuple"110      }111    ],112    "name": "addToCollectionAllowListCross",113    "outputs": [],114    "stateMutability": "nonpayable",115    "type": "function"116  },117  {118    "inputs": [119      {120        "components": [121          { "internalType": "address", "name": "eth", "type": "address" },122          { "internalType": "uint256", "name": "sub", "type": "uint256" }123        ],124        "internalType": "struct EthCrossAccount",125        "name": "user",126        "type": "tuple"127      }128    ],129    "name": "allowlistedCross",130    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],131    "stateMutability": "view",132    "type": "function"133  },134  {135    "inputs": [136      { "internalType": "address", "name": "approved", "type": "address" },137      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }138    ],139    "name": "approve",140    "outputs": [],141    "stateMutability": "nonpayable",142    "type": "function"143  },144  {145    "inputs": [146      {147        "components": [148          { "internalType": "address", "name": "eth", "type": "address" },149          { "internalType": "uint256", "name": "sub", "type": "uint256" }150        ],151        "internalType": "struct EthCrossAccount",152        "name": "approved",153        "type": "tuple"154      },155      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }156    ],157    "name": "approveCross",158    "outputs": [],159    "stateMutability": "nonpayable",160    "type": "function"161  },162  {163    "inputs": [164      { "internalType": "address", "name": "owner", "type": "address" }165    ],166    "name": "balanceOf",167    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],168    "stateMutability": "view",169    "type": "function"170  },171  {172    "inputs": [173      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }174    ],175    "name": "burn",176    "outputs": [],177    "stateMutability": "nonpayable",178    "type": "function"179  },180  {181    "inputs": [182      {183        "components": [184          { "internalType": "address", "name": "eth", "type": "address" },185          { "internalType": "uint256", "name": "sub", "type": "uint256" }186        ],187        "internalType": "struct EthCrossAccount",188        "name": "from",189        "type": "tuple"190      },191      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }192    ],193    "name": "burnFromCross",194    "outputs": [],195    "stateMutability": "nonpayable",196    "type": "function"197  },198  {199    "inputs": [200      {201        "components": [202          { "internalType": "address", "name": "eth", "type": "address" },203          { "internalType": "uint256", "name": "sub", "type": "uint256" }204        ],205        "internalType": "struct EthCrossAccount",206        "name": "newOwner",207        "type": "tuple"208      }209    ],210    "name": "changeCollectionOwnerCross",211    "outputs": [],212    "stateMutability": "nonpayable",213    "type": "function"214  },215  {216    "inputs": [],217    "name": "collectionAdmins",218    "outputs": [219      {220        "components": [221          { "internalType": "address", "name": "eth", "type": "address" },222          { "internalType": "uint256", "name": "sub", "type": "uint256" }223        ],224        "internalType": "struct EthCrossAccount[]",225        "name": "",226        "type": "tuple[]"227      }228    ],229    "stateMutability": "view",230    "type": "function"231  },232  {233    "inputs": [],234    "name": "collectionOwner",235    "outputs": [236      {237        "components": [238          { "internalType": "address", "name": "eth", "type": "address" },239          { "internalType": "uint256", "name": "sub", "type": "uint256" }240        ],241        "internalType": "struct EthCrossAccount",242        "name": "",243        "type": "tuple"244      }245    ],246    "stateMutability": "view",247    "type": "function"248  },249  {250    "inputs": [251      { "internalType": "string[]", "name": "keys", "type": "string[]" }252    ],253    "name": "collectionProperties",254    "outputs": [255      {256        "components": [257          { "internalType": "string", "name": "key", "type": "string" },258          { "internalType": "bytes", "name": "value", "type": "bytes" }259        ],260        "internalType": "struct Property[]",261        "name": "",262        "type": "tuple[]"263      }264    ],265    "stateMutability": "view",266    "type": "function"267  },268  {269    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],270    "name": "collectionProperty",271    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],272    "stateMutability": "view",273    "type": "function"274  },275  {276    "inputs": [],277    "name": "collectionSponsor",278    "outputs": [279      {280        "components": [281          { "internalType": "address", "name": "field_0", "type": "address" },282          { "internalType": "uint256", "name": "field_1", "type": "uint256" }283        ],284        "internalType": "struct Tuple30",285        "name": "",286        "type": "tuple"287      }288    ],289    "stateMutability": "view",290    "type": "function"291  },292  {293    "inputs": [],294    "name": "confirmCollectionSponsorship",295    "outputs": [],296    "stateMutability": "nonpayable",297    "type": "function"298  },299  {300    "inputs": [],301    "name": "contractAddress",302    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],303    "stateMutability": "view",304    "type": "function"305  },306  {307    "inputs": [308      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }309    ],310    "name": "crossOwnerOf",311    "outputs": [312      {313        "components": [314          { "internalType": "address", "name": "eth", "type": "address" },315          { "internalType": "uint256", "name": "sub", "type": "uint256" }316        ],317        "internalType": "struct EthCrossAccount",318        "name": "",319        "type": "tuple"320      }321    ],322    "stateMutability": "view",323    "type": "function"324  },325  {326    "inputs": [327      { "internalType": "string[]", "name": "keys", "type": "string[]" }328    ],329    "name": "deleteCollectionProperties",330    "outputs": [],331    "stateMutability": "nonpayable",332    "type": "function"333  },334  {335    "inputs": [336      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },337      { "internalType": "string[]", "name": "keys", "type": "string[]" }338    ],339    "name": "deleteProperties",340    "outputs": [],341    "stateMutability": "nonpayable",342    "type": "function"343  },344  {345    "inputs": [],346    "name": "description",347    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],348    "stateMutability": "view",349    "type": "function"350  },351  {352    "inputs": [],353    "name": "finishMinting",354    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],355    "stateMutability": "nonpayable",356    "type": "function"357  },358  {359    "inputs": [360      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }361    ],362    "name": "getApproved",363    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],364    "stateMutability": "view",365    "type": "function"366  },367  {368    "inputs": [],369    "name": "hasCollectionPendingSponsor",370    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],371    "stateMutability": "view",372    "type": "function"373  },374  {375    "inputs": [376      { "internalType": "address", "name": "owner", "type": "address" },377      { "internalType": "address", "name": "operator", "type": "address" }378    ],379    "name": "isApprovedForAll",380    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],381    "stateMutability": "view",382    "type": "function"383  },384  {385    "inputs": [386      {387        "components": [388          { "internalType": "address", "name": "eth", "type": "address" },389          { "internalType": "uint256", "name": "sub", "type": "uint256" }390        ],391        "internalType": "struct EthCrossAccount",392        "name": "user",393        "type": "tuple"394      }395    ],396    "name": "isOwnerOrAdminCross",397    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],398    "stateMutability": "view",399    "type": "function"400  },401  {402    "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],403    "name": "mint",404    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],405    "stateMutability": "nonpayable",406    "type": "function"407  },408  {409    "inputs": [410      { "internalType": "address", "name": "to", "type": "address" },411      { "internalType": "string", "name": "tokenUri", "type": "string" }412    ],413    "name": "mintWithTokenURI",414    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],415    "stateMutability": "nonpayable",416    "type": "function"417  },418  {419    "inputs": [],420    "name": "mintingFinished",421    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],422    "stateMutability": "view",423    "type": "function"424  },425  {426    "inputs": [],427    "name": "name",428    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],429    "stateMutability": "view",430    "type": "function"431  },432  {433    "inputs": [],434    "name": "nextTokenId",435    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],436    "stateMutability": "view",437    "type": "function"438  },439  {440    "inputs": [441      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }442    ],443    "name": "ownerOf",444    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],445    "stateMutability": "view",446    "type": "function"447  },448  {449    "inputs": [450      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },451      { "internalType": "string[]", "name": "keys", "type": "string[]" }452    ],453    "name": "properties",454    "outputs": [455      {456        "components": [457          { "internalType": "string", "name": "key", "type": "string" },458          { "internalType": "bytes", "name": "value", "type": "bytes" }459        ],460        "internalType": "struct Property[]",461        "name": "",462        "type": "tuple[]"463      }464    ],465    "stateMutability": "view",466    "type": "function"467  },468  {469    "inputs": [470      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },471      { "internalType": "string", "name": "key", "type": "string" }472    ],473    "name": "property",474    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],475    "stateMutability": "view",476    "type": "function"477  },478  {479    "inputs": [480      {481        "components": [482          { "internalType": "address", "name": "eth", "type": "address" },483          { "internalType": "uint256", "name": "sub", "type": "uint256" }484        ],485        "internalType": "struct EthCrossAccount",486        "name": "admin",487        "type": "tuple"488      }489    ],490    "name": "removeCollectionAdminCross",491    "outputs": [],492    "stateMutability": "nonpayable",493    "type": "function"494  },495  {496    "inputs": [],497    "name": "removeCollectionSponsor",498    "outputs": [],499    "stateMutability": "nonpayable",500    "type": "function"501  },502  {503    "inputs": [504      {505        "components": [506          { "internalType": "address", "name": "eth", "type": "address" },507          { "internalType": "uint256", "name": "sub", "type": "uint256" }508        ],509        "internalType": "struct EthCrossAccount",510        "name": "user",511        "type": "tuple"512      }513    ],514    "name": "removeFromCollectionAllowListCross",515    "outputs": [],516    "stateMutability": "nonpayable",517    "type": "function"518  },519  {520    "inputs": [521      { "internalType": "address", "name": "from", "type": "address" },522      { "internalType": "address", "name": "to", "type": "address" },523      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }524    ],525    "name": "safeTransferFrom",526    "outputs": [],527    "stateMutability": "nonpayable",528    "type": "function"529  },530  {531    "inputs": [532      { "internalType": "address", "name": "from", "type": "address" },533      { "internalType": "address", "name": "to", "type": "address" },534      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },535      { "internalType": "bytes", "name": "data", "type": "bytes" }536    ],537    "name": "safeTransferFrom",538    "outputs": [],539    "stateMutability": "nonpayable",540    "type": "function"541  },542  {543    "inputs": [544      { "internalType": "address", "name": "operator", "type": "address" },545      { "internalType": "bool", "name": "approved", "type": "bool" }546    ],547    "name": "setApprovalForAll",548    "outputs": [],549    "stateMutability": "nonpayable",550    "type": "function"551  },552  {553    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],554    "name": "setCollectionAccess",555    "outputs": [],556    "stateMutability": "nonpayable",557    "type": "function"558  },559  {560    "inputs": [561      { "internalType": "string", "name": "limit", "type": "string" },562      { "internalType": "uint256", "name": "value", "type": "uint256" }563    ],564    "name": "setCollectionLimit",565    "outputs": [],566    "stateMutability": "nonpayable",567    "type": "function"568  },569  {570    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],571    "name": "setCollectionMintMode",572    "outputs": [],573    "stateMutability": "nonpayable",574    "type": "function"575  },576  {577    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],578    "name": "setCollectionNesting",579    "outputs": [],580    "stateMutability": "nonpayable",581    "type": "function"582  },583  {584    "inputs": [585      { "internalType": "bool", "name": "enable", "type": "bool" },586      {587        "internalType": "address[]",588        "name": "collections",589        "type": "address[]"590      }591    ],592    "name": "setCollectionNesting",593    "outputs": [],594    "stateMutability": "nonpayable",595    "type": "function"596  },597  {598    "inputs": [599      {600        "components": [601          { "internalType": "string", "name": "key", "type": "string" },602          { "internalType": "bytes", "name": "value", "type": "bytes" }603        ],604        "internalType": "struct Property[]",605        "name": "properties",606        "type": "tuple[]"607      }608    ],609    "name": "setCollectionProperties",610    "outputs": [],611    "stateMutability": "nonpayable",612    "type": "function"613  },614  {615    "inputs": [616      {617        "components": [618          { "internalType": "address", "name": "eth", "type": "address" },619          { "internalType": "uint256", "name": "sub", "type": "uint256" }620        ],621        "internalType": "struct EthCrossAccount",622        "name": "sponsor",623        "type": "tuple"624      }625    ],626    "name": "setCollectionSponsorCross",627    "outputs": [],628    "stateMutability": "nonpayable",629    "type": "function"630  },631  {632    "inputs": [633      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },634      {635        "components": [636          { "internalType": "string", "name": "key", "type": "string" },637          { "internalType": "bytes", "name": "value", "type": "bytes" }638        ],639        "internalType": "struct Property[]",640        "name": "properties",641        "type": "tuple[]"642      }643    ],644    "name": "setProperties",645    "outputs": [],646    "stateMutability": "nonpayable",647    "type": "function"648  },649  {650    "inputs": [651      { "internalType": "string", "name": "key", "type": "string" },652      { "internalType": "bool", "name": "isMutable", "type": "bool" },653      { "internalType": "bool", "name": "collectionAdmin", "type": "bool" },654      { "internalType": "bool", "name": "tokenOwner", "type": "bool" }655    ],656    "name": "setTokenPropertyPermission",657    "outputs": [],658    "stateMutability": "nonpayable",659    "type": "function"660  },661  {662    "inputs": [663      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }664    ],665    "name": "supportsInterface",666    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],667    "stateMutability": "view",668    "type": "function"669  },670  {671    "inputs": [],672    "name": "symbol",673    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],674    "stateMutability": "view",675    "type": "function"676  },677  {678    "inputs": [679      { "internalType": "uint256", "name": "index", "type": "uint256" }680    ],681    "name": "tokenByIndex",682    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],683    "stateMutability": "view",684    "type": "function"685  },686  {687    "inputs": [688      { "internalType": "address", "name": "owner", "type": "address" },689      { "internalType": "uint256", "name": "index", "type": "uint256" }690    ],691    "name": "tokenOfOwnerByIndex",692    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],693    "stateMutability": "view",694    "type": "function"695  },696  {697    "inputs": [698      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }699    ],700    "name": "tokenURI",701    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],702    "stateMutability": "view",703    "type": "function"704  },705  {706    "inputs": [],707    "name": "totalSupply",708    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],709    "stateMutability": "view",710    "type": "function"711  },712  {713    "inputs": [714      { "internalType": "address", "name": "to", "type": "address" },715      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }716    ],717    "name": "transfer",718    "outputs": [],719    "stateMutability": "nonpayable",720    "type": "function"721  },722  {723    "inputs": [724      {725        "components": [726          { "internalType": "address", "name": "eth", "type": "address" },727          { "internalType": "uint256", "name": "sub", "type": "uint256" }728        ],729        "internalType": "struct EthCrossAccount",730        "name": "to",731        "type": "tuple"732      },733      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }734    ],735    "name": "transferCross",736    "outputs": [],737    "stateMutability": "nonpayable",738    "type": "function"739  },740  {741    "inputs": [742      { "internalType": "address", "name": "from", "type": "address" },743      { "internalType": "address", "name": "to", "type": "address" },744      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }745    ],746    "name": "transferFrom",747    "outputs": [],748    "stateMutability": "nonpayable",749    "type": "function"750  },751  {752    "inputs": [753      {754        "components": [755          { "internalType": "address", "name": "eth", "type": "address" },756          { "internalType": "uint256", "name": "sub", "type": "uint256" }757        ],758        "internalType": "struct EthCrossAccount",759        "name": "from",760        "type": "tuple"761      },762      {763        "components": [764          { "internalType": "address", "name": "eth", "type": "address" },765          { "internalType": "uint256", "name": "sub", "type": "uint256" }766        ],767        "internalType": "struct EthCrossAccount",768        "name": "to",769        "type": "tuple"770      },771      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }772    ],773    "name": "transferFromCross",774    "outputs": [],775    "stateMutability": "nonpayable",776    "type": "function"777  },778  {779    "inputs": [],780    "name": "uniqueCollectionType",781    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],782    "stateMutability": "view",783    "type": "function"784  }785]
modifiedtests/src/eth/abi/reFungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -213,6 +213,13 @@
   },
   {
     "inputs": [],
+    "name": "collectionHelperAddress",
+    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [],
     "name": "collectionOwner",
     "outputs": [
       {
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -354,7 +354,7 @@
 	event Approval(address indexed owner, address indexed spender, uint256 value);
 }
 
-/// @dev the ERC-165 identifier for this interface is 0x942e8b22
+/// @dev the ERC-165 identifier for this interface is 0x8cb847c4
 interface ERC20 is Dummy, ERC165, ERC20Events {
 	/// @dev EVM selector for this function is: 0x06fdde03,
 	///  or in textual repr: name()
@@ -395,6 +395,11 @@
 	/// @dev EVM selector for this function is: 0xdd62ed3e,
 	///  or in textual repr: allowance(address,address)
 	function allowance(address owner, address spender) external view returns (uint256);
+
+	/// @notice Returns collection helper contract address
+	/// @dev EVM selector for this function is: 0x1896cce6,
+	///  or in textual repr: collectionHelperAddress()
+	function collectionHelperAddress() external view returns (address);
 }
 
 interface UniqueFungible is Dummy, ERC165, ERC20, ERC20Mintable, ERC20UniqueExtensions, Collection {}
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -605,7 +605,7 @@
 
 /// @title ERC-721 Non-Fungible Token Standard
 /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-/// @dev the ERC-165 identifier for this interface is 0x80ac58cd
+/// @dev the ERC-165 identifier for this interface is 0x983a942b
 interface ERC721 is Dummy, ERC165, ERC721Events {
 	/// @notice Count all NFTs assigned to an owner
 	/// @dev NFTs assigned to the zero address are considered invalid, and this
@@ -685,6 +685,11 @@
 	/// @dev EVM selector for this function is: 0xe985e9c5,
 	///  or in textual repr: isApprovedForAll(address,address)
 	function isApprovedForAll(address owner, address operator) external view returns (address);
+
+	/// @notice Returns collection helper contract address
+	/// @dev EVM selector for this function is: 0x1896cce6,
+	///  or in textual repr: collectionHelperAddress()
+	function collectionHelperAddress() external view returns (address);
 }
 
 interface UniqueNFT is
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -604,7 +604,7 @@
 
 /// @title ERC-721 Non-Fungible Token Standard
 /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-/// @dev the ERC-165 identifier for this interface is 0x58800161
+/// @dev the ERC-165 identifier for this interface is 0x4016cd87
 interface ERC721 is Dummy, ERC165, ERC721Events {
 	/// @notice Count all RFTs assigned to an owner
 	/// @dev RFTs assigned to the zero address are considered invalid, and this
@@ -682,6 +682,11 @@
 	/// @dev EVM selector for this function is: 0xe985e9c5,
 	///  or in textual repr: isApprovedForAll(address,address)
 	function isApprovedForAll(address owner, address operator) external view returns (address);
+
+	/// @notice Returns collection helper contract address
+	/// @dev EVM selector for this function is: 0x1896cce6,
+	///  or in textual repr: collectionHelperAddress()
+	function collectionHelperAddress() external view returns (address);
 }
 
 interface UniqueRefungible is
addedtests/src/eth/collectionHelperAddress.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/collectionHelperAddress.test.ts
@@ -0,0 +1,57 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+import {itEth, usingEthPlaygrounds, expect} from './util';
+import {IKeyringPair} from '@polkadot/types/types';
+
+const EVM_COLLECTION_HELPERS_ADDRESS = '0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f';
+
+describe('[eth]CollectionHelerpAddress test: ERC721 ', () => {
+  let donor: IKeyringPair;
+
+  before(async function() {
+    await usingEthPlaygrounds(async (helper, privateKey) => {
+      donor = await privateKey({filename: __filename});
+    });
+  });
+
+  itEth('NFT\\RFT', async ({helper}) => {
+    const owner =  await helper.eth.createAccountWithBalance(donor);
+    
+    const {collectionAddress: nftCollectionAddress} = await helper.eth.createNFTCollection(owner, 'Sponsor', 'absolutely anything', 'ROC');
+    const nftCollection = helper.ethNativeContract.collection(nftCollectionAddress, 'nft', owner);
+    
+    const {collectionAddress: rftCollectionAddress} = await helper.eth.createRFTCollection(owner, 'Sponsor', 'absolutely anything', 'ROC');
+    const rftCollection = helper.ethNativeContract.collection(rftCollectionAddress, 'rft', owner);
+    
+    expect((await nftCollection.methods.collectionHelperAddress().call())
+      .toString().toLowerCase()).to.be.equal(EVM_COLLECTION_HELPERS_ADDRESS);
+    
+    expect((await rftCollection.methods.collectionHelperAddress().call())
+      .toString().toLowerCase()).to.be.equal(EVM_COLLECTION_HELPERS_ADDRESS);
+  });
+  
+  itEth('FT', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor);
+
+    const {collectionAddress} = await helper.eth.createFungibleCollection(owner, 'Sponsor', 18, 'absolutely anything', 'ROC');
+    const collection = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
+    
+    expect((await collection.methods.collectionHelperAddress().call())
+      .toString().toLowerCase()).to.be.equal(EVM_COLLECTION_HELPERS_ADDRESS);
+  });
+ 
+});