git.delta.rocks / unique-network / refs/commits / 4906885c14fb

difftreelog

Merge pull request #654 from UniqueNetwork/feature/solidity_methods_renaming

Yaroslav Bolyukin2022-10-18parents: #e26460b #8f23ca0.patch.diff
in: master
Feature/solidity methods renaming

21 files changed

modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -592,6 +592,7 @@
 	///
 	/// @dev Owner can be changed only by current owner
 	/// @param newOwner new owner account
+	#[solidity(rename_selector = "changeCollectionOwner")]
 	fn set_owner(&mut self, caller: caller, new_owner: address) -> Result<void> {
 		self.consume_store_writes(1)?;
 
modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
--- 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 0x3e1e8083
+/// @dev the ERC-165 identifier for this interface is 0x62e22290
 contract Collection is Dummy, ERC165 {
 	/// Set collection property.
 	///
@@ -296,9 +296,9 @@
 	///
 	/// @dev Owner can be changed only by current owner
 	/// @param newOwner new owner account
-	/// @dev EVM selector for this function is: 0x13af4035,
-	///  or in textual repr: setOwner(address)
-	function setOwner(address newOwner) public {
+	/// @dev EVM selector for this function is: 0x4f53e226,
+	///  or in textual repr: changeCollectionOwner(address)
+	function changeCollectionOwner(address newOwner) public {
 		require(false, stub_error);
 		newOwner;
 		dummy = 0;
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
--- 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 0x3e1e8083
+/// @dev the ERC-165 identifier for this interface is 0x62e22290
 contract Collection is Dummy, ERC165 {
 	/// Set collection property.
 	///
@@ -369,9 +369,9 @@
 	///
 	/// @dev Owner can be changed only by current owner
 	/// @param newOwner new owner account
-	/// @dev EVM selector for this function is: 0x13af4035,
-	///  or in textual repr: setOwner(address)
-	function setOwner(address newOwner) public {
+	/// @dev EVM selector for this function is: 0x4f53e226,
+	///  or in textual repr: changeCollectionOwner(address)
+	function changeCollectionOwner(address newOwner) public {
 		require(false, stub_error);
 		newOwner;
 		dummy = 0;
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
--- 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 0x3e1e8083
+/// @dev the ERC-165 identifier for this interface is 0x62e22290
 contract Collection is Dummy, ERC165 {
 	/// Set collection property.
 	///
@@ -369,9 +369,9 @@
 	///
 	/// @dev Owner can be changed only by current owner
 	/// @param newOwner new owner account
-	/// @dev EVM selector for this function is: 0x13af4035,
-	///  or in textual repr: setOwner(address)
-	function setOwner(address newOwner) public {
+	/// @dev EVM selector for this function is: 0x4f53e226,
+	///  or in textual repr: changeCollectionOwner(address)
+	function changeCollectionOwner(address newOwner) public {
 		require(false, stub_error);
 		newOwner;
 		dummy = 0;
modifiedpallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/unique/src/eth/mod.rsdiffbeforeafterboth
--- a/pallets/unique/src/eth/mod.rs
+++ b/pallets/unique/src/eth/mod.rs
@@ -184,6 +184,7 @@
 	/// @return address Address of the newly created collection
 	#[weight(<SelfWeightOf<T>>::create_collection())]
 	#[deprecated(note = "mathod was renamed to `create_nft_collection`, prefer it instead")]
+	#[solidity(hide)]
 	fn create_nonfungible_collection(
 		&mut self,
 		caller: caller,
modifiedpallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/unique/src/eth/stubs/CollectionHelpers.soldiffbeforeafterboth
--- a/pallets/unique/src/eth/stubs/CollectionHelpers.sol
+++ b/pallets/unique/src/eth/stubs/CollectionHelpers.sol
@@ -45,25 +45,21 @@
 		return 0x0000000000000000000000000000000000000000;
 	}
 
-	/// Create an NFT collection
-	/// @param name Name of the collection
-	/// @param description Informative description of the collection
-	/// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications
-	/// @return address Address of the newly created collection
-	/// @dev EVM selector for this function is: 0xe34a6844,
-	///  or in textual repr: createNonfungibleCollection(string,string,string)
-	function createNonfungibleCollection(
-		string memory name,
-		string memory description,
-		string memory tokenPrefix
-	) public payable returns (address) {
-		require(false, stub_error);
-		name;
-		description;
-		tokenPrefix;
-		dummy = 0;
-		return 0x0000000000000000000000000000000000000000;
-	}
+	// /// Create an NFT collection
+	// /// @param name Name of the collection
+	// /// @param description Informative description of the collection
+	// /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications
+	// /// @return address Address of the newly created collection
+	// /// @dev EVM selector for this function is: 0xe34a6844,
+	// ///  or in textual repr: createNonfungibleCollection(string,string,string)
+	// function createNonfungibleCollection(string memory name, string memory description, string memory tokenPrefix) public payable returns (address) {
+	// 	require(false, stub_error);
+	// 	name;
+	// 	description;
+	// 	tokenPrefix;
+	// 	dummy = 0;
+	// 	return 0x0000000000000000000000000000000000000000;
+	// }
 
 	/// @dev EVM selector for this function is: 0xab173450,
 	///  or in textual repr: createRFTCollection(string,string,string)
modifiedtests/src/eth/api/CollectionHelpers.soldiffbeforeafterboth
--- a/tests/src/eth/api/CollectionHelpers.sol
+++ b/tests/src/eth/api/CollectionHelpers.sol
@@ -33,18 +33,14 @@
 		string memory tokenPrefix
 	) external payable returns (address);
 
-	/// Create an NFT collection
-	/// @param name Name of the collection
-	/// @param description Informative description of the collection
-	/// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications
-	/// @return address Address of the newly created collection
-	/// @dev EVM selector for this function is: 0xe34a6844,
-	///  or in textual repr: createNonfungibleCollection(string,string,string)
-	function createNonfungibleCollection(
-		string memory name,
-		string memory description,
-		string memory tokenPrefix
-	) external payable returns (address);
+	// /// Create an NFT collection
+	// /// @param name Name of the collection
+	// /// @param description Informative description of the collection
+	// /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications
+	// /// @return address Address of the newly created collection
+	// /// @dev EVM selector for this function is: 0xe34a6844,
+	// ///  or in textual repr: createNonfungibleCollection(string,string,string)
+	// function createNonfungibleCollection(string memory name, string memory description, string memory tokenPrefix) external payable returns (address);
 
 	/// @dev EVM selector for this function is: 0xab173450,
 	///  or in textual repr: createRFTCollection(string,string,string)
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
--- 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 0x3e1e8083
+/// @dev the ERC-165 identifier for this interface is 0x62e22290
 interface Collection is Dummy, ERC165 {
 	/// Set collection property.
 	///
@@ -194,9 +194,9 @@
 	///
 	/// @dev Owner can be changed only by current owner
 	/// @param newOwner new owner account
-	/// @dev EVM selector for this function is: 0x13af4035,
-	///  or in textual repr: setOwner(address)
-	function setOwner(address newOwner) external;
+	/// @dev EVM selector for this function is: 0x4f53e226,
+	///  or in textual repr: changeCollectionOwner(address)
+	function changeCollectionOwner(address newOwner) external;
 }
 
 /// @dev the ERC-165 identifier for this interface is 0x63034ac5
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- 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 0x3e1e8083
+/// @dev the ERC-165 identifier for this interface is 0x62e22290
 interface Collection is Dummy, ERC165 {
 	/// Set collection property.
 	///
@@ -243,9 +243,9 @@
 	///
 	/// @dev Owner can be changed only by current owner
 	/// @param newOwner new owner account
-	/// @dev EVM selector for this function is: 0x13af4035,
-	///  or in textual repr: setOwner(address)
-	function setOwner(address newOwner) external;
+	/// @dev EVM selector for this function is: 0x4f53e226,
+	///  or in textual repr: changeCollectionOwner(address)
+	function changeCollectionOwner(address newOwner) external;
 }
 
 /// @dev anonymous struct
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
--- 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 0x3e1e8083
+/// @dev the ERC-165 identifier for this interface is 0x62e22290
 interface Collection is Dummy, ERC165 {
 	/// Set collection property.
 	///
@@ -243,9 +243,9 @@
 	///
 	/// @dev Owner can be changed only by current owner
 	/// @param newOwner new owner account
-	/// @dev EVM selector for this function is: 0x13af4035,
-	///  or in textual repr: setOwner(address)
-	function setOwner(address newOwner) external;
+	/// @dev EVM selector for this function is: 0x4f53e226,
+	///  or in textual repr: changeCollectionOwner(address)
+	function changeCollectionOwner(address newOwner) external;
 }
 
 /// @dev anonymous struct
modifiedtests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth
--- a/tests/src/eth/collectionAdmin.test.ts
+++ b/tests/src/eth/collectionAdmin.test.ts
@@ -282,7 +282,7 @@
     const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
     const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
 
-    await collectionEvm.methods.setOwner(newOwner).send();
+    await collectionEvm.methods.changeCollectionOwner(newOwner).send();
 
     expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;
     expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.true;
@@ -293,7 +293,7 @@
     const newOwner = await helper.eth.createAccountWithBalance(donor);
     const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
     const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
-    const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.setOwner(newOwner).send());
+    const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.changeCollectionOwner(newOwner).send());
     expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
     expect(cost > 0);
   });
@@ -304,7 +304,7 @@
     const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
     const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
 
-    await expect(collectionEvm.methods.setOwner(newOwner).send({from: newOwner})).to.be.rejected;
+    await expect(collectionEvm.methods.changeCollectionOwner(newOwner).send({from: newOwner})).to.be.rejected;
     expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.false;
   });
 });
modifiedtests/src/eth/collectionHelpersAbi.jsondiffbeforeafterboth
--- a/tests/src/eth/collectionHelpersAbi.json
+++ b/tests/src/eth/collectionHelpersAbi.json
@@ -42,17 +42,6 @@
       { "internalType": "string", "name": "description", "type": "string" },
       { "internalType": "string", "name": "tokenPrefix", "type": "string" }
     ],
-    "name": "createNonfungibleCollection",
-    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
-    "stateMutability": "payable",
-    "type": "function"
-  },
-  {
-    "inputs": [
-      { "internalType": "string", "name": "name", "type": "string" },
-      { "internalType": "string", "name": "description", "type": "string" },
-      { "internalType": "string", "name": "tokenPrefix", "type": "string" }
-    ],
     "name": "createRFTCollection",
     "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
     "stateMutability": "payable",
modifiedtests/src/eth/fungibleAbi.jsondiffbeforeafterboth
--- a/tests/src/eth/fungibleAbi.json
+++ b/tests/src/eth/fungibleAbi.json
@@ -116,6 +116,15 @@
     "type": "function"
   },
   {
+    "inputs": [
+      { "internalType": "address", "name": "newOwner", "type": "address" }
+    ],
+    "name": "changeCollectionOwner",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
     "inputs": [],
     "name": "collectionOwner",
     "outputs": [
@@ -329,15 +338,6 @@
       { "internalType": "address", "name": "sponsor", "type": "address" }
     ],
     "name": "setCollectionSponsor",
-    "outputs": [],
-    "stateMutability": "nonpayable",
-    "type": "function"
-  },
-  {
-    "inputs": [
-      { "internalType": "address", "name": "newOwner", "type": "address" }
-    ],
-    "name": "setOwner",
     "outputs": [],
     "stateMutability": "nonpayable",
     "type": "function"
modifiedtests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth
before · tests/src/eth/nonFungibleAbi.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      { "internalType": "address", "name": "newAdmin", "type": "address" }86    ],87    "name": "addCollectionAdmin",88    "outputs": [],89    "stateMutability": "nonpayable",90    "type": "function"91  },92  {93    "inputs": [94      { "internalType": "address", "name": "user", "type": "address" }95    ],96    "name": "addToCollectionAllowList",97    "outputs": [],98    "stateMutability": "nonpayable",99    "type": "function"100  },101  {102    "inputs": [103      { "internalType": "address", "name": "user", "type": "address" }104    ],105    "name": "allowed",106    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],107    "stateMutability": "view",108    "type": "function"109  },110  {111    "inputs": [112      { "internalType": "address", "name": "approved", "type": "address" },113      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }114    ],115    "name": "approve",116    "outputs": [],117    "stateMutability": "nonpayable",118    "type": "function"119  },120  {121    "inputs": [122      { "internalType": "address", "name": "owner", "type": "address" }123    ],124    "name": "balanceOf",125    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],126    "stateMutability": "view",127    "type": "function"128  },129  {130    "inputs": [131      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }132    ],133    "name": "burn",134    "outputs": [],135    "stateMutability": "nonpayable",136    "type": "function"137  },138  {139    "inputs": [140      { "internalType": "address", "name": "from", "type": "address" },141      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }142    ],143    "name": "burnFrom",144    "outputs": [],145    "stateMutability": "nonpayable",146    "type": "function"147  },148  {149    "inputs": [],150    "name": "collectionOwner",151    "outputs": [152      {153        "components": [154          { "internalType": "address", "name": "field_0", "type": "address" },155          { "internalType": "uint256", "name": "field_1", "type": "uint256" }156        ],157        "internalType": "struct Tuple17",158        "name": "",159        "type": "tuple"160      }161    ],162    "stateMutability": "view",163    "type": "function"164  },165  {166    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],167    "name": "collectionProperty",168    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],169    "stateMutability": "view",170    "type": "function"171  },172  {173    "inputs": [],174    "name": "collectionSponsor",175    "outputs": [176      {177        "components": [178          { "internalType": "address", "name": "field_0", "type": "address" },179          { "internalType": "uint256", "name": "field_1", "type": "uint256" }180        ],181        "internalType": "struct Tuple17",182        "name": "",183        "type": "tuple"184      }185    ],186    "stateMutability": "view",187    "type": "function"188  },189  {190    "inputs": [],191    "name": "confirmCollectionSponsorship",192    "outputs": [],193    "stateMutability": "nonpayable",194    "type": "function"195  },196  {197    "inputs": [],198    "name": "contractAddress",199    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],200    "stateMutability": "view",201    "type": "function"202  },203  {204    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],205    "name": "deleteCollectionProperty",206    "outputs": [],207    "stateMutability": "nonpayable",208    "type": "function"209  },210  {211    "inputs": [212      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },213      { "internalType": "string", "name": "key", "type": "string" }214    ],215    "name": "deleteProperty",216    "outputs": [],217    "stateMutability": "nonpayable",218    "type": "function"219  },220  {221    "inputs": [],222    "name": "finishMinting",223    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],224    "stateMutability": "nonpayable",225    "type": "function"226  },227  {228    "inputs": [229      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }230    ],231    "name": "getApproved",232    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],233    "stateMutability": "view",234    "type": "function"235  },236  {237    "inputs": [],238    "name": "hasCollectionPendingSponsor",239    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],240    "stateMutability": "view",241    "type": "function"242  },243  {244    "inputs": [245      { "internalType": "address", "name": "owner", "type": "address" },246      { "internalType": "address", "name": "operator", "type": "address" }247    ],248    "name": "isApprovedForAll",249    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],250    "stateMutability": "view",251    "type": "function"252  },253  {254    "inputs": [255      { "internalType": "address", "name": "user", "type": "address" }256    ],257    "name": "isOwnerOrAdmin",258    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],259    "stateMutability": "view",260    "type": "function"261  },262  {263    "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],264    "name": "mint",265    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],266    "stateMutability": "nonpayable",267    "type": "function"268  },269  {270    "inputs": [271      { "internalType": "address", "name": "to", "type": "address" },272      { "internalType": "uint256[]", "name": "tokenIds", "type": "uint256[]" }273    ],274    "name": "mintBulk",275    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],276    "stateMutability": "nonpayable",277    "type": "function"278  },279  {280    "inputs": [281      { "internalType": "address", "name": "to", "type": "address" },282      {283        "components": [284          { "internalType": "uint256", "name": "field_0", "type": "uint256" },285          { "internalType": "string", "name": "field_1", "type": "string" }286        ],287        "internalType": "struct Tuple6[]",288        "name": "tokens",289        "type": "tuple[]"290      }291    ],292    "name": "mintBulkWithTokenURI",293    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],294    "stateMutability": "nonpayable",295    "type": "function"296  },297  {298    "inputs": [299      { "internalType": "address", "name": "to", "type": "address" },300      { "internalType": "string", "name": "tokenUri", "type": "string" }301    ],302    "name": "mintWithTokenURI",303    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],304    "stateMutability": "nonpayable",305    "type": "function"306  },307  {308    "inputs": [],309    "name": "mintingFinished",310    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],311    "stateMutability": "view",312    "type": "function"313  },314  {315    "inputs": [],316    "name": "name",317    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],318    "stateMutability": "view",319    "type": "function"320  },321  {322    "inputs": [],323    "name": "nextTokenId",324    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],325    "stateMutability": "view",326    "type": "function"327  },328  {329    "inputs": [330      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }331    ],332    "name": "ownerOf",333    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],334    "stateMutability": "view",335    "type": "function"336  },337  {338    "inputs": [339      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },340      { "internalType": "string", "name": "key", "type": "string" }341    ],342    "name": "property",343    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],344    "stateMutability": "view",345    "type": "function"346  },347  {348    "inputs": [349      { "internalType": "address", "name": "admin", "type": "address" }350    ],351    "name": "removeCollectionAdmin",352    "outputs": [],353    "stateMutability": "nonpayable",354    "type": "function"355  },356  {357    "inputs": [],358    "name": "removeCollectionSponsor",359    "outputs": [],360    "stateMutability": "nonpayable",361    "type": "function"362  },363  {364    "inputs": [365      { "internalType": "address", "name": "user", "type": "address" }366    ],367    "name": "removeFromCollectionAllowList",368    "outputs": [],369    "stateMutability": "nonpayable",370    "type": "function"371  },372  {373    "inputs": [374      { "internalType": "address", "name": "from", "type": "address" },375      { "internalType": "address", "name": "to", "type": "address" },376      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }377    ],378    "name": "safeTransferFrom",379    "outputs": [],380    "stateMutability": "nonpayable",381    "type": "function"382  },383  {384    "inputs": [385      { "internalType": "address", "name": "from", "type": "address" },386      { "internalType": "address", "name": "to", "type": "address" },387      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },388      { "internalType": "bytes", "name": "data", "type": "bytes" }389    ],390    "name": "safeTransferFrom",391    "outputs": [],392    "stateMutability": "nonpayable",393    "type": "function"394  },395  {396    "inputs": [397      { "internalType": "address", "name": "operator", "type": "address" },398      { "internalType": "bool", "name": "approved", "type": "bool" }399    ],400    "name": "setApprovalForAll",401    "outputs": [],402    "stateMutability": "nonpayable",403    "type": "function"404  },405  {406    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],407    "name": "setCollectionAccess",408    "outputs": [],409    "stateMutability": "nonpayable",410    "type": "function"411  },412  {413    "inputs": [414      { "internalType": "string", "name": "limit", "type": "string" },415      { "internalType": "uint32", "name": "value", "type": "uint32" }416    ],417    "name": "setCollectionLimit",418    "outputs": [],419    "stateMutability": "nonpayable",420    "type": "function"421  },422  {423    "inputs": [424      { "internalType": "string", "name": "limit", "type": "string" },425      { "internalType": "bool", "name": "value", "type": "bool" }426    ],427    "name": "setCollectionLimit",428    "outputs": [],429    "stateMutability": "nonpayable",430    "type": "function"431  },432  {433    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],434    "name": "setCollectionMintMode",435    "outputs": [],436    "stateMutability": "nonpayable",437    "type": "function"438  },439  {440    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],441    "name": "setCollectionNesting",442    "outputs": [],443    "stateMutability": "nonpayable",444    "type": "function"445  },446  {447    "inputs": [448      { "internalType": "bool", "name": "enable", "type": "bool" },449      {450        "internalType": "address[]",451        "name": "collections",452        "type": "address[]"453      }454    ],455    "name": "setCollectionNesting",456    "outputs": [],457    "stateMutability": "nonpayable",458    "type": "function"459  },460  {461    "inputs": [462      { "internalType": "string", "name": "key", "type": "string" },463      { "internalType": "bytes", "name": "value", "type": "bytes" }464    ],465    "name": "setCollectionProperty",466    "outputs": [],467    "stateMutability": "nonpayable",468    "type": "function"469  },470  {471    "inputs": [472      { "internalType": "address", "name": "sponsor", "type": "address" }473    ],474    "name": "setCollectionSponsor",475    "outputs": [],476    "stateMutability": "nonpayable",477    "type": "function"478  },479  {480    "inputs": [481      { "internalType": "address", "name": "newOwner", "type": "address" }482    ],483    "name": "setOwner",484    "outputs": [],485    "stateMutability": "nonpayable",486    "type": "function"487  },488  {489    "inputs": [490      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },491      { "internalType": "string", "name": "key", "type": "string" },492      { "internalType": "bytes", "name": "value", "type": "bytes" }493    ],494    "name": "setProperty",495    "outputs": [],496    "stateMutability": "nonpayable",497    "type": "function"498  },499  {500    "inputs": [501      { "internalType": "string", "name": "key", "type": "string" },502      { "internalType": "bool", "name": "isMutable", "type": "bool" },503      { "internalType": "bool", "name": "collectionAdmin", "type": "bool" },504      { "internalType": "bool", "name": "tokenOwner", "type": "bool" }505    ],506    "name": "setTokenPropertyPermission",507    "outputs": [],508    "stateMutability": "nonpayable",509    "type": "function"510  },511  {512    "inputs": [513      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }514    ],515    "name": "supportsInterface",516    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],517    "stateMutability": "view",518    "type": "function"519  },520  {521    "inputs": [],522    "name": "symbol",523    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],524    "stateMutability": "view",525    "type": "function"526  },527  {528    "inputs": [529      { "internalType": "uint256", "name": "index", "type": "uint256" }530    ],531    "name": "tokenByIndex",532    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],533    "stateMutability": "view",534    "type": "function"535  },536  {537    "inputs": [538      { "internalType": "address", "name": "owner", "type": "address" },539      { "internalType": "uint256", "name": "index", "type": "uint256" }540    ],541    "name": "tokenOfOwnerByIndex",542    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],543    "stateMutability": "view",544    "type": "function"545  },546  {547    "inputs": [548      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }549    ],550    "name": "tokenURI",551    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],552    "stateMutability": "view",553    "type": "function"554  },555  {556    "inputs": [],557    "name": "totalSupply",558    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],559    "stateMutability": "view",560    "type": "function"561  },562  {563    "inputs": [564      { "internalType": "address", "name": "to", "type": "address" },565      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }566    ],567    "name": "transfer",568    "outputs": [],569    "stateMutability": "nonpayable",570    "type": "function"571  },572  {573    "inputs": [574      { "internalType": "address", "name": "from", "type": "address" },575      { "internalType": "address", "name": "to", "type": "address" },576      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }577    ],578    "name": "transferFrom",579    "outputs": [],580    "stateMutability": "nonpayable",581    "type": "function"582  },583  {584    "inputs": [],585    "name": "uniqueCollectionType",586    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],587    "stateMutability": "view",588    "type": "function"589  }590]
after · tests/src/eth/nonFungibleAbi.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      { "internalType": "address", "name": "newAdmin", "type": "address" }86    ],87    "name": "addCollectionAdmin",88    "outputs": [],89    "stateMutability": "nonpayable",90    "type": "function"91  },92  {93    "inputs": [94      { "internalType": "address", "name": "user", "type": "address" }95    ],96    "name": "addToCollectionAllowList",97    "outputs": [],98    "stateMutability": "nonpayable",99    "type": "function"100  },101  {102    "inputs": [103      { "internalType": "address", "name": "user", "type": "address" }104    ],105    "name": "allowed",106    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],107    "stateMutability": "view",108    "type": "function"109  },110  {111    "inputs": [112      { "internalType": "address", "name": "approved", "type": "address" },113      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }114    ],115    "name": "approve",116    "outputs": [],117    "stateMutability": "nonpayable",118    "type": "function"119  },120  {121    "inputs": [122      { "internalType": "address", "name": "owner", "type": "address" }123    ],124    "name": "balanceOf",125    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],126    "stateMutability": "view",127    "type": "function"128  },129  {130    "inputs": [131      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }132    ],133    "name": "burn",134    "outputs": [],135    "stateMutability": "nonpayable",136    "type": "function"137  },138  {139    "inputs": [140      { "internalType": "address", "name": "from", "type": "address" },141      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }142    ],143    "name": "burnFrom",144    "outputs": [],145    "stateMutability": "nonpayable",146    "type": "function"147  },148  {149    "inputs": [150      { "internalType": "address", "name": "newOwner", "type": "address" }151    ],152    "name": "changeCollectionOwner",153    "outputs": [],154    "stateMutability": "nonpayable",155    "type": "function"156  },157  {158    "inputs": [],159    "name": "collectionOwner",160    "outputs": [161      {162        "components": [163          { "internalType": "address", "name": "field_0", "type": "address" },164          { "internalType": "uint256", "name": "field_1", "type": "uint256" }165        ],166        "internalType": "struct Tuple17",167        "name": "",168        "type": "tuple"169      }170    ],171    "stateMutability": "view",172    "type": "function"173  },174  {175    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],176    "name": "collectionProperty",177    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],178    "stateMutability": "view",179    "type": "function"180  },181  {182    "inputs": [],183    "name": "collectionSponsor",184    "outputs": [185      {186        "components": [187          { "internalType": "address", "name": "field_0", "type": "address" },188          { "internalType": "uint256", "name": "field_1", "type": "uint256" }189        ],190        "internalType": "struct Tuple17",191        "name": "",192        "type": "tuple"193      }194    ],195    "stateMutability": "view",196    "type": "function"197  },198  {199    "inputs": [],200    "name": "confirmCollectionSponsorship",201    "outputs": [],202    "stateMutability": "nonpayable",203    "type": "function"204  },205  {206    "inputs": [],207    "name": "contractAddress",208    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],209    "stateMutability": "view",210    "type": "function"211  },212  {213    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],214    "name": "deleteCollectionProperty",215    "outputs": [],216    "stateMutability": "nonpayable",217    "type": "function"218  },219  {220    "inputs": [221      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },222      { "internalType": "string", "name": "key", "type": "string" }223    ],224    "name": "deleteProperty",225    "outputs": [],226    "stateMutability": "nonpayable",227    "type": "function"228  },229  {230    "inputs": [],231    "name": "finishMinting",232    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],233    "stateMutability": "nonpayable",234    "type": "function"235  },236  {237    "inputs": [238      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }239    ],240    "name": "getApproved",241    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],242    "stateMutability": "view",243    "type": "function"244  },245  {246    "inputs": [],247    "name": "hasCollectionPendingSponsor",248    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],249    "stateMutability": "view",250    "type": "function"251  },252  {253    "inputs": [254      { "internalType": "address", "name": "owner", "type": "address" },255      { "internalType": "address", "name": "operator", "type": "address" }256    ],257    "name": "isApprovedForAll",258    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],259    "stateMutability": "view",260    "type": "function"261  },262  {263    "inputs": [264      { "internalType": "address", "name": "user", "type": "address" }265    ],266    "name": "isOwnerOrAdmin",267    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],268    "stateMutability": "view",269    "type": "function"270  },271  {272    "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],273    "name": "mint",274    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],275    "stateMutability": "nonpayable",276    "type": "function"277  },278  {279    "inputs": [280      { "internalType": "address", "name": "to", "type": "address" },281      { "internalType": "uint256[]", "name": "tokenIds", "type": "uint256[]" }282    ],283    "name": "mintBulk",284    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],285    "stateMutability": "nonpayable",286    "type": "function"287  },288  {289    "inputs": [290      { "internalType": "address", "name": "to", "type": "address" },291      {292        "components": [293          { "internalType": "uint256", "name": "field_0", "type": "uint256" },294          { "internalType": "string", "name": "field_1", "type": "string" }295        ],296        "internalType": "struct Tuple6[]",297        "name": "tokens",298        "type": "tuple[]"299      }300    ],301    "name": "mintBulkWithTokenURI",302    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],303    "stateMutability": "nonpayable",304    "type": "function"305  },306  {307    "inputs": [308      { "internalType": "address", "name": "to", "type": "address" },309      { "internalType": "string", "name": "tokenUri", "type": "string" }310    ],311    "name": "mintWithTokenURI",312    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],313    "stateMutability": "nonpayable",314    "type": "function"315  },316  {317    "inputs": [],318    "name": "mintingFinished",319    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],320    "stateMutability": "view",321    "type": "function"322  },323  {324    "inputs": [],325    "name": "name",326    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],327    "stateMutability": "view",328    "type": "function"329  },330  {331    "inputs": [],332    "name": "nextTokenId",333    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],334    "stateMutability": "view",335    "type": "function"336  },337  {338    "inputs": [339      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }340    ],341    "name": "ownerOf",342    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],343    "stateMutability": "view",344    "type": "function"345  },346  {347    "inputs": [348      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },349      { "internalType": "string", "name": "key", "type": "string" }350    ],351    "name": "property",352    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],353    "stateMutability": "view",354    "type": "function"355  },356  {357    "inputs": [358      { "internalType": "address", "name": "admin", "type": "address" }359    ],360    "name": "removeCollectionAdmin",361    "outputs": [],362    "stateMutability": "nonpayable",363    "type": "function"364  },365  {366    "inputs": [],367    "name": "removeCollectionSponsor",368    "outputs": [],369    "stateMutability": "nonpayable",370    "type": "function"371  },372  {373    "inputs": [374      { "internalType": "address", "name": "user", "type": "address" }375    ],376    "name": "removeFromCollectionAllowList",377    "outputs": [],378    "stateMutability": "nonpayable",379    "type": "function"380  },381  {382    "inputs": [383      { "internalType": "address", "name": "from", "type": "address" },384      { "internalType": "address", "name": "to", "type": "address" },385      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }386    ],387    "name": "safeTransferFrom",388    "outputs": [],389    "stateMutability": "nonpayable",390    "type": "function"391  },392  {393    "inputs": [394      { "internalType": "address", "name": "from", "type": "address" },395      { "internalType": "address", "name": "to", "type": "address" },396      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },397      { "internalType": "bytes", "name": "data", "type": "bytes" }398    ],399    "name": "safeTransferFrom",400    "outputs": [],401    "stateMutability": "nonpayable",402    "type": "function"403  },404  {405    "inputs": [406      { "internalType": "address", "name": "operator", "type": "address" },407      { "internalType": "bool", "name": "approved", "type": "bool" }408    ],409    "name": "setApprovalForAll",410    "outputs": [],411    "stateMutability": "nonpayable",412    "type": "function"413  },414  {415    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],416    "name": "setCollectionAccess",417    "outputs": [],418    "stateMutability": "nonpayable",419    "type": "function"420  },421  {422    "inputs": [423      { "internalType": "string", "name": "limit", "type": "string" },424      { "internalType": "uint32", "name": "value", "type": "uint32" }425    ],426    "name": "setCollectionLimit",427    "outputs": [],428    "stateMutability": "nonpayable",429    "type": "function"430  },431  {432    "inputs": [433      { "internalType": "string", "name": "limit", "type": "string" },434      { "internalType": "bool", "name": "value", "type": "bool" }435    ],436    "name": "setCollectionLimit",437    "outputs": [],438    "stateMutability": "nonpayable",439    "type": "function"440  },441  {442    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],443    "name": "setCollectionMintMode",444    "outputs": [],445    "stateMutability": "nonpayable",446    "type": "function"447  },448  {449    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],450    "name": "setCollectionNesting",451    "outputs": [],452    "stateMutability": "nonpayable",453    "type": "function"454  },455  {456    "inputs": [457      { "internalType": "bool", "name": "enable", "type": "bool" },458      {459        "internalType": "address[]",460        "name": "collections",461        "type": "address[]"462      }463    ],464    "name": "setCollectionNesting",465    "outputs": [],466    "stateMutability": "nonpayable",467    "type": "function"468  },469  {470    "inputs": [471      { "internalType": "string", "name": "key", "type": "string" },472      { "internalType": "bytes", "name": "value", "type": "bytes" }473    ],474    "name": "setCollectionProperty",475    "outputs": [],476    "stateMutability": "nonpayable",477    "type": "function"478  },479  {480    "inputs": [481      { "internalType": "address", "name": "sponsor", "type": "address" }482    ],483    "name": "setCollectionSponsor",484    "outputs": [],485    "stateMutability": "nonpayable",486    "type": "function"487  },488  {489    "inputs": [490      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },491      { "internalType": "string", "name": "key", "type": "string" },492      { "internalType": "bytes", "name": "value", "type": "bytes" }493    ],494    "name": "setProperty",495    "outputs": [],496    "stateMutability": "nonpayable",497    "type": "function"498  },499  {500    "inputs": [501      { "internalType": "string", "name": "key", "type": "string" },502      { "internalType": "bool", "name": "isMutable", "type": "bool" },503      { "internalType": "bool", "name": "collectionAdmin", "type": "bool" },504      { "internalType": "bool", "name": "tokenOwner", "type": "bool" }505    ],506    "name": "setTokenPropertyPermission",507    "outputs": [],508    "stateMutability": "nonpayable",509    "type": "function"510  },511  {512    "inputs": [513      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }514    ],515    "name": "supportsInterface",516    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],517    "stateMutability": "view",518    "type": "function"519  },520  {521    "inputs": [],522    "name": "symbol",523    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],524    "stateMutability": "view",525    "type": "function"526  },527  {528    "inputs": [529      { "internalType": "uint256", "name": "index", "type": "uint256" }530    ],531    "name": "tokenByIndex",532    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],533    "stateMutability": "view",534    "type": "function"535  },536  {537    "inputs": [538      { "internalType": "address", "name": "owner", "type": "address" },539      { "internalType": "uint256", "name": "index", "type": "uint256" }540    ],541    "name": "tokenOfOwnerByIndex",542    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],543    "stateMutability": "view",544    "type": "function"545  },546  {547    "inputs": [548      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }549    ],550    "name": "tokenURI",551    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],552    "stateMutability": "view",553    "type": "function"554  },555  {556    "inputs": [],557    "name": "totalSupply",558    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],559    "stateMutability": "view",560    "type": "function"561  },562  {563    "inputs": [564      { "internalType": "address", "name": "to", "type": "address" },565      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }566    ],567    "name": "transfer",568    "outputs": [],569    "stateMutability": "nonpayable",570    "type": "function"571  },572  {573    "inputs": [574      { "internalType": "address", "name": "from", "type": "address" },575      { "internalType": "address", "name": "to", "type": "address" },576      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }577    ],578    "name": "transferFrom",579    "outputs": [],580    "stateMutability": "nonpayable",581    "type": "function"582  },583  {584    "inputs": [],585    "name": "uniqueCollectionType",586    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],587    "stateMutability": "view",588    "type": "function"589  }590]
modifiedtests/src/eth/reFungibleAbi.jsondiffbeforeafterboth
--- a/tests/src/eth/reFungibleAbi.json
+++ b/tests/src/eth/reFungibleAbi.json
@@ -146,6 +146,15 @@
     "type": "function"
   },
   {
+    "inputs": [
+      { "internalType": "address", "name": "newOwner", "type": "address" }
+    ],
+    "name": "changeCollectionOwner",
+    "outputs": [],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
     "inputs": [],
     "name": "collectionOwner",
     "outputs": [
@@ -472,15 +481,6 @@
       { "internalType": "address", "name": "sponsor", "type": "address" }
     ],
     "name": "setCollectionSponsor",
-    "outputs": [],
-    "stateMutability": "nonpayable",
-    "type": "function"
-  },
-  {
-    "inputs": [
-      { "internalType": "address", "name": "newOwner", "type": "address" }
-    ],
-    "name": "setOwner",
     "outputs": [],
     "stateMutability": "nonpayable",
     "type": "function"