difftreelog
feat Add `collection_admins` method to eth collection.
in: master
19 files changed
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -580,7 +580,7 @@
/// Get collection owner.
///
- /// @return Tuble with sponsor address and his substrate mirror.
+ /// @return Tuple with sponsor address and his substrate mirror.
/// If address is canonical then substrate mirror is zero and vice versa.
fn collection_owner(&self) -> Result<(address, uint256)> {
Ok(convert_cross_account_to_tuple::<T>(
@@ -616,13 +616,16 @@
// .map_err(dispatch_to_evm::<T>)
// }
- // TODO: need implement AbiWriter for &Vec<T>
- // fn collection_admins(&self) -> Result<Vec<(address, uint256)>> {
- // let result = pallet_common::IsAdmin::<T>::iter_prefix((self.id,))
- // .map(|(admin, _)| pallet_common::eth::convert_cross_account_to_tuple::<T>(&admin))
- // .collect();
- // Ok(result)
- // }
+ /// Get collection administrators
+ ///
+ /// @return Vector of tuples with admins address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ fn collection_admins(&self) -> Result<Vec<(address, uint256)>> {
+ let result = crate::IsAdmin::<T>::iter_prefix((self.id,))
+ .map(|(admin, _)| crate::eth::convert_cross_account_to_tuple::<T>(&admin))
+ .collect();
+ Ok(result)
+ }
}
/// ### Note
pallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7contract Dummy {8 uint8 dummy;9 string stub_error = "this contract is implemented in native";10}1112contract ERC165 is Dummy {13 function supportsInterface(bytes4 interfaceID) external view returns (bool) {14 require(false, stub_error);15 interfaceID;16 return true;17 }18}1920/// @title A contract that allows you to work with collections.21/// @dev the ERC-165 identifier for this interface is 0x62e2229022contract Collection is Dummy, ERC165 {23 /// Set collection property.24 ///25 /// @param key Property key.26 /// @param value Propery value.27 /// @dev EVM selector for this function is: 0x2f073f66,28 /// or in textual repr: setCollectionProperty(string,bytes)29 function setCollectionProperty(string memory key, bytes memory value) public {30 require(false, stub_error);31 key;32 value;33 dummy = 0;34 }3536 /// Delete collection property.37 ///38 /// @param key Property key.39 /// @dev EVM selector for this function is: 0x7b7debce,40 /// or in textual repr: deleteCollectionProperty(string)41 function deleteCollectionProperty(string memory key) public {42 require(false, stub_error);43 key;44 dummy = 0;45 }4647 /// Get collection property.48 ///49 /// @dev Throws error if key not found.50 ///51 /// @param key Property key.52 /// @return bytes The property corresponding to the key.53 /// @dev EVM selector for this function is: 0xcf24fd6d,54 /// or in textual repr: collectionProperty(string)55 function collectionProperty(string memory key) public view returns (bytes memory) {56 require(false, stub_error);57 key;58 dummy;59 return hex"";60 }6162 /// Set the sponsor of the collection.63 ///64 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.65 ///66 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.67 /// @dev EVM selector for this function is: 0x7623402e,68 /// or in textual repr: setCollectionSponsor(address)69 function setCollectionSponsor(address sponsor) public {70 require(false, stub_error);71 sponsor;72 dummy = 0;73 }7475 /// Whether there is a pending sponsor.76 /// @dev EVM selector for this function is: 0x058ac185,77 /// or in textual repr: hasCollectionPendingSponsor()78 function hasCollectionPendingSponsor() public view returns (bool) {79 require(false, stub_error);80 dummy;81 return false;82 }8384 /// Collection sponsorship confirmation.85 ///86 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.87 /// @dev EVM selector for this function is: 0x3c50e97a,88 /// or in textual repr: confirmCollectionSponsorship()89 function confirmCollectionSponsorship() public {90 require(false, stub_error);91 dummy = 0;92 }9394 /// Remove collection sponsor.95 /// @dev EVM selector for this function is: 0x6e0326a3,96 /// or in textual repr: removeCollectionSponsor()97 function removeCollectionSponsor() public {98 require(false, stub_error);99 dummy = 0;100 }101102 /// Get current sponsor.103 ///104 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.105 /// @dev EVM selector for this function is: 0x6ec0a9f1,106 /// or in textual repr: collectionSponsor()107 function collectionSponsor() public view returns (Tuple6 memory) {108 require(false, stub_error);109 dummy;110 return Tuple6(0x0000000000000000000000000000000000000000, 0);111 }112113 /// Set limits for the collection.114 /// @dev Throws error if limit not found.115 /// @param limit Name of the limit. Valid names:116 /// "accountTokenOwnershipLimit",117 /// "sponsoredDataSize",118 /// "sponsoredDataRateLimit",119 /// "tokenLimit",120 /// "sponsorTransferTimeout",121 /// "sponsorApproveTimeout"122 /// @param value Value of the limit.123 /// @dev EVM selector for this function is: 0x6a3841db,124 /// or in textual repr: setCollectionLimit(string,uint32)125 function setCollectionLimit(string memory limit, uint32 value) public {126 require(false, stub_error);127 limit;128 value;129 dummy = 0;130 }131132 /// Set limits for the collection.133 /// @dev Throws error if limit not found.134 /// @param limit Name of the limit. Valid names:135 /// "ownerCanTransfer",136 /// "ownerCanDestroy",137 /// "transfersEnabled"138 /// @param value Value of the limit.139 /// @dev EVM selector for this function is: 0x993b7fba,140 /// or in textual repr: setCollectionLimit(string,bool)141 function setCollectionLimit(string memory limit, bool value) public {142 require(false, stub_error);143 limit;144 value;145 dummy = 0;146 }147148 /// Get contract address.149 /// @dev EVM selector for this function is: 0xf6b4dfb4,150 /// or in textual repr: contractAddress()151 function contractAddress() public view returns (address) {152 require(false, stub_error);153 dummy;154 return 0x0000000000000000000000000000000000000000;155 }156157 /// Add collection admin.158 /// @param newAdmin Address of the added administrator.159 /// @dev EVM selector for this function is: 0x92e462c7,160 /// or in textual repr: addCollectionAdmin(address)161 function addCollectionAdmin(address newAdmin) public {162 require(false, stub_error);163 newAdmin;164 dummy = 0;165 }166167 /// Remove collection admin.168 ///169 /// @param admin Address of the removed administrator.170 /// @dev EVM selector for this function is: 0xfafd7b42,171 /// or in textual repr: removeCollectionAdmin(address)172 function removeCollectionAdmin(address admin) public {173 require(false, stub_error);174 admin;175 dummy = 0;176 }177178 /// Toggle accessibility of collection nesting.179 ///180 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'181 /// @dev EVM selector for this function is: 0x112d4586,182 /// or in textual repr: setCollectionNesting(bool)183 function setCollectionNesting(bool enable) public {184 require(false, stub_error);185 enable;186 dummy = 0;187 }188189 /// Toggle accessibility of collection nesting.190 ///191 /// @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'192 /// @param collections Addresses of collections that will be available for nesting.193 /// @dev EVM selector for this function is: 0x64872396,194 /// or in textual repr: setCollectionNesting(bool,address[])195 function setCollectionNesting(bool enable, address[] memory collections) public {196 require(false, stub_error);197 enable;198 collections;199 dummy = 0;200 }201202 /// Set the collection access method.203 /// @param mode Access mode204 /// 0 for Normal205 /// 1 for AllowList206 /// @dev EVM selector for this function is: 0x41835d4c,207 /// or in textual repr: setCollectionAccess(uint8)208 function setCollectionAccess(uint8 mode) public {209 require(false, stub_error);210 mode;211 dummy = 0;212 }213214 /// Checks that user allowed to operate with collection.215 ///216 /// @param user User address to check.217 /// @dev EVM selector for this function is: 0xd63a8e11,218 /// or in textual repr: allowed(address)219 function allowed(address user) public view returns (bool) {220 require(false, stub_error);221 user;222 dummy;223 return false;224 }225226 /// Add the user to the allowed list.227 ///228 /// @param user Address of a trusted user.229 /// @dev EVM selector for this function is: 0x67844fe6,230 /// or in textual repr: addToCollectionAllowList(address)231 function addToCollectionAllowList(address user) public {232 require(false, stub_error);233 user;234 dummy = 0;235 }236237 /// Remove the user from the allowed list.238 ///239 /// @param user Address of a removed user.240 /// @dev EVM selector for this function is: 0x85c51acb,241 /// or in textual repr: removeFromCollectionAllowList(address)242 function removeFromCollectionAllowList(address user) public {243 require(false, stub_error);244 user;245 dummy = 0;246 }247248 /// Switch permission for minting.249 ///250 /// @param mode Enable if "true".251 /// @dev EVM selector for this function is: 0x00018e84,252 /// or in textual repr: setCollectionMintMode(bool)253 function setCollectionMintMode(bool mode) public {254 require(false, stub_error);255 mode;256 dummy = 0;257 }258259 /// Check that account is the owner or admin of the collection260 ///261 /// @param user account to verify262 /// @return "true" if account is the owner or admin263 /// @dev EVM selector for this function is: 0x9811b0c7,264 /// or in textual repr: isOwnerOrAdmin(address)265 function isOwnerOrAdmin(address user) public view returns (bool) {266 require(false, stub_error);267 user;268 dummy;269 return false;270 }271272 /// Returns collection type273 ///274 /// @return `Fungible` or `NFT` or `ReFungible`275 /// @dev EVM selector for this function is: 0xd34b55b8,276 /// or in textual repr: uniqueCollectionType()277 function uniqueCollectionType() public view returns (string memory) {278 require(false, stub_error);279 dummy;280 return "";281 }282283 /// Get collection owner.284 ///285 /// @return Tuble with sponsor address and his substrate mirror.286 /// If address is canonical then substrate mirror is zero and vice versa.287 /// @dev EVM selector for this function is: 0xdf727d3b,288 /// or in textual repr: collectionOwner()289 function collectionOwner() public view returns (Tuple6 memory) {290 require(false, stub_error);291 dummy;292 return Tuple6(0x0000000000000000000000000000000000000000, 0);293 }294295 /// Changes collection owner to another account296 ///297 /// @dev Owner can be changed only by current owner298 /// @param newOwner new owner account299 /// @dev EVM selector for this function is: 0x4f53e226,300 /// or in textual repr: changeCollectionOwner(address)301 function changeCollectionOwner(address newOwner) public {302 require(false, stub_error);303 newOwner;304 dummy = 0;305 }306}307308/// @dev the ERC-165 identifier for this interface is 0x63034ac5309contract ERC20UniqueExtensions is Dummy, ERC165 {310 /// Burn tokens from account311 /// @dev Function that burns an `amount` of the tokens of a given account,312 /// deducting from the sender's allowance for said account.313 /// @param from The account whose tokens will be burnt.314 /// @param amount The amount that will be burnt.315 /// @dev EVM selector for this function is: 0x79cc6790,316 /// or in textual repr: burnFrom(address,uint256)317 function burnFrom(address from, uint256 amount) public returns (bool) {318 require(false, stub_error);319 from;320 amount;321 dummy = 0;322 return false;323 }324325 /// Mint tokens for multiple accounts.326 /// @param amounts array of pairs of account address and amount327 /// @dev EVM selector for this function is: 0x1acf2d55,328 /// or in textual repr: mintBulk((address,uint256)[])329 function mintBulk(Tuple6[] memory amounts) public returns (bool) {330 require(false, stub_error);331 amounts;332 dummy = 0;333 return false;334 }335}336337/// @dev anonymous struct338struct Tuple6 {339 address field_0;340 uint256 field_1;341}342343/// @dev the ERC-165 identifier for this interface is 0x40c10f19344contract ERC20Mintable is Dummy, ERC165 {345 /// Mint tokens for `to` account.346 /// @param to account that will receive minted tokens347 /// @param amount amount of tokens to mint348 /// @dev EVM selector for this function is: 0x40c10f19,349 /// or in textual repr: mint(address,uint256)350 function mint(address to, uint256 amount) public returns (bool) {351 require(false, stub_error);352 to;353 amount;354 dummy = 0;355 return false;356 }357}358359/// @dev inlined interface360contract ERC20Events {361 event Transfer(address indexed from, address indexed to, uint256 value);362 event Approval(address indexed owner, address indexed spender, uint256 value);363}364365/// @dev the ERC-165 identifier for this interface is 0x942e8b22366contract ERC20 is Dummy, ERC165, ERC20Events {367 /// @dev EVM selector for this function is: 0x06fdde03,368 /// or in textual repr: name()369 function name() public view returns (string memory) {370 require(false, stub_error);371 dummy;372 return "";373 }374375 /// @dev EVM selector for this function is: 0x95d89b41,376 /// or in textual repr: symbol()377 function symbol() public view returns (string memory) {378 require(false, stub_error);379 dummy;380 return "";381 }382383 /// @dev EVM selector for this function is: 0x18160ddd,384 /// or in textual repr: totalSupply()385 function totalSupply() public view returns (uint256) {386 require(false, stub_error);387 dummy;388 return 0;389 }390391 /// @dev EVM selector for this function is: 0x313ce567,392 /// or in textual repr: decimals()393 function decimals() public view returns (uint8) {394 require(false, stub_error);395 dummy;396 return 0;397 }398399 /// @dev EVM selector for this function is: 0x70a08231,400 /// or in textual repr: balanceOf(address)401 function balanceOf(address owner) public view returns (uint256) {402 require(false, stub_error);403 owner;404 dummy;405 return 0;406 }407408 /// @dev EVM selector for this function is: 0xa9059cbb,409 /// or in textual repr: transfer(address,uint256)410 function transfer(address to, uint256 amount) public returns (bool) {411 require(false, stub_error);412 to;413 amount;414 dummy = 0;415 return false;416 }417418 /// @dev EVM selector for this function is: 0x23b872dd,419 /// or in textual repr: transferFrom(address,address,uint256)420 function transferFrom(421 address from,422 address to,423 uint256 amount424 ) public returns (bool) {425 require(false, stub_error);426 from;427 to;428 amount;429 dummy = 0;430 return false;431 }432433 /// @dev EVM selector for this function is: 0x095ea7b3,434 /// or in textual repr: approve(address,uint256)435 function approve(address spender, uint256 amount) public returns (bool) {436 require(false, stub_error);437 spender;438 amount;439 dummy = 0;440 return false;441 }442443 /// @dev EVM selector for this function is: 0xdd62ed3e,444 /// or in textual repr: allowance(address,address)445 function allowance(address owner, address spender) public view returns (uint256) {446 require(false, stub_error);447 owner;448 spender;449 dummy;450 return 0;451 }452}453454contract UniqueFungible is Dummy, ERC165, ERC20, ERC20Mintable, ERC20UniqueExtensions, Collection {}1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7contract Dummy {8 uint8 dummy;9 string stub_error = "this contract is implemented in native";10}1112contract ERC165 is Dummy {13 function supportsInterface(bytes4 interfaceID) external view returns (bool) {14 require(false, stub_error);15 interfaceID;16 return true;17 }18}1920/// @title A contract that allows you to work with collections.21/// @dev the ERC-165 identifier for this interface is 0x3af103fb22contract Collection is Dummy, ERC165 {23 /// Set collection property.24 ///25 /// @param key Property key.26 /// @param value Propery value.27 /// @dev EVM selector for this function is: 0x2f073f66,28 /// or in textual repr: setCollectionProperty(string,bytes)29 function setCollectionProperty(string memory key, bytes memory value) public {30 require(false, stub_error);31 key;32 value;33 dummy = 0;34 }3536 /// Delete collection property.37 ///38 /// @param key Property key.39 /// @dev EVM selector for this function is: 0x7b7debce,40 /// or in textual repr: deleteCollectionProperty(string)41 function deleteCollectionProperty(string memory key) public {42 require(false, stub_error);43 key;44 dummy = 0;45 }4647 /// Get collection property.48 ///49 /// @dev Throws error if key not found.50 ///51 /// @param key Property key.52 /// @return bytes The property corresponding to the key.53 /// @dev EVM selector for this function is: 0xcf24fd6d,54 /// or in textual repr: collectionProperty(string)55 function collectionProperty(string memory key) public view returns (bytes memory) {56 require(false, stub_error);57 key;58 dummy;59 return hex"";60 }6162 /// Set the sponsor of the collection.63 ///64 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.65 ///66 /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.67 /// @dev EVM selector for this function is: 0x7623402e,68 /// or in textual repr: setCollectionSponsor(address)69 function setCollectionSponsor(address sponsor) public {70 require(false, stub_error);71 sponsor;72 dummy = 0;73 }7475 /// Whether there is a pending sponsor.76 /// @dev EVM selector for this function is: 0x058ac185,77 /// or in textual repr: hasCollectionPendingSponsor()78 function hasCollectionPendingSponsor() public view returns (bool) {79 require(false, stub_error);80 dummy;81 return false;82 }8384 /// Collection sponsorship confirmation.85 ///86 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.87 /// @dev EVM selector for this function is: 0x3c50e97a,88 /// or in textual repr: confirmCollectionSponsorship()89 function confirmCollectionSponsorship() public {90 require(false, stub_error);91 dummy = 0;92 }9394 /// Remove collection sponsor.95 /// @dev EVM selector for this function is: 0x6e0326a3,96 /// or in textual repr: removeCollectionSponsor()97 function removeCollectionSponsor() public {98 require(false, stub_error);99 dummy = 0;100 }101102 /// Get current sponsor.103 ///104 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.105 /// @dev EVM selector for this function is: 0x6ec0a9f1,106 /// or in textual repr: collectionSponsor()107 function collectionSponsor() public view returns (Tuple6 memory) {108 require(false, stub_error);109 dummy;110 return Tuple6(0x0000000000000000000000000000000000000000, 0);111 }112113 /// Set limits for the collection.114 /// @dev Throws error if limit not found.115 /// @param limit Name of the limit. Valid names:116 /// "accountTokenOwnershipLimit",117 /// "sponsoredDataSize",118 /// "sponsoredDataRateLimit",119 /// "tokenLimit",120 /// "sponsorTransferTimeout",121 /// "sponsorApproveTimeout"122 /// @param value Value of the limit.123 /// @dev EVM selector for this function is: 0x6a3841db,124 /// or in textual repr: setCollectionLimit(string,uint32)125 function setCollectionLimit(string memory limit, uint32 value) public {126 require(false, stub_error);127 limit;128 value;129 dummy = 0;130 }131132 /// Set limits for the collection.133 /// @dev Throws error if limit not found.134 /// @param limit Name of the limit. Valid names:135 /// "ownerCanTransfer",136 /// "ownerCanDestroy",137 /// "transfersEnabled"138 /// @param value Value of the limit.139 /// @dev EVM selector for this function is: 0x993b7fba,140 /// or in textual repr: setCollectionLimit(string,bool)141 function setCollectionLimit(string memory limit, bool value) public {142 require(false, stub_error);143 limit;144 value;145 dummy = 0;146 }147148 /// Get contract address.149 /// @dev EVM selector for this function is: 0xf6b4dfb4,150 /// or in textual repr: contractAddress()151 function contractAddress() public view returns (address) {152 require(false, stub_error);153 dummy;154 return 0x0000000000000000000000000000000000000000;155 }156157 /// Add collection admin.158 /// @param newAdmin Address of the added administrator.159 /// @dev EVM selector for this function is: 0x92e462c7,160 /// or in textual repr: addCollectionAdmin(address)161 function addCollectionAdmin(address newAdmin) public {162 require(false, stub_error);163 newAdmin;164 dummy = 0;165 }166167 /// Remove collection admin.168 ///169 /// @param admin Address of the removed administrator.170 /// @dev EVM selector for this function is: 0xfafd7b42,171 /// or in textual repr: removeCollectionAdmin(address)172 function removeCollectionAdmin(address admin) public {173 require(false, stub_error);174 admin;175 dummy = 0;176 }177178 /// Toggle accessibility of collection nesting.179 ///180 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'181 /// @dev EVM selector for this function is: 0x112d4586,182 /// or in textual repr: setCollectionNesting(bool)183 function setCollectionNesting(bool enable) public {184 require(false, stub_error);185 enable;186 dummy = 0;187 }188189 /// Toggle accessibility of collection nesting.190 ///191 /// @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'192 /// @param collections Addresses of collections that will be available for nesting.193 /// @dev EVM selector for this function is: 0x64872396,194 /// or in textual repr: setCollectionNesting(bool,address[])195 function setCollectionNesting(bool enable, address[] memory collections) public {196 require(false, stub_error);197 enable;198 collections;199 dummy = 0;200 }201202 /// Set the collection access method.203 /// @param mode Access mode204 /// 0 for Normal205 /// 1 for AllowList206 /// @dev EVM selector for this function is: 0x41835d4c,207 /// or in textual repr: setCollectionAccess(uint8)208 function setCollectionAccess(uint8 mode) public {209 require(false, stub_error);210 mode;211 dummy = 0;212 }213214 /// Checks that user allowed to operate with collection.215 ///216 /// @param user User address to check.217 /// @dev EVM selector for this function is: 0xd63a8e11,218 /// or in textual repr: allowed(address)219 function allowed(address user) public view returns (bool) {220 require(false, stub_error);221 user;222 dummy;223 return false;224 }225226 /// Add the user to the allowed list.227 ///228 /// @param user Address of a trusted user.229 /// @dev EVM selector for this function is: 0x67844fe6,230 /// or in textual repr: addToCollectionAllowList(address)231 function addToCollectionAllowList(address user) public {232 require(false, stub_error);233 user;234 dummy = 0;235 }236237 /// Remove the user from the allowed list.238 ///239 /// @param user Address of a removed user.240 /// @dev EVM selector for this function is: 0x85c51acb,241 /// or in textual repr: removeFromCollectionAllowList(address)242 function removeFromCollectionAllowList(address user) public {243 require(false, stub_error);244 user;245 dummy = 0;246 }247248 /// Switch permission for minting.249 ///250 /// @param mode Enable if "true".251 /// @dev EVM selector for this function is: 0x00018e84,252 /// or in textual repr: setCollectionMintMode(bool)253 function setCollectionMintMode(bool mode) public {254 require(false, stub_error);255 mode;256 dummy = 0;257 }258259 /// Check that account is the owner or admin of the collection260 ///261 /// @param user account to verify262 /// @return "true" if account is the owner or admin263 /// @dev EVM selector for this function is: 0x9811b0c7,264 /// or in textual repr: isOwnerOrAdmin(address)265 function isOwnerOrAdmin(address user) public view returns (bool) {266 require(false, stub_error);267 user;268 dummy;269 return false;270 }271272 /// Returns collection type273 ///274 /// @return `Fungible` or `NFT` or `ReFungible`275 /// @dev EVM selector for this function is: 0xd34b55b8,276 /// or in textual repr: uniqueCollectionType()277 function uniqueCollectionType() public view returns (string memory) {278 require(false, stub_error);279 dummy;280 return "";281 }282283 /// Get collection owner.284 ///285 /// @return Tuple with sponsor address and his substrate mirror.286 /// If address is canonical then substrate mirror is zero and vice versa.287 /// @dev EVM selector for this function is: 0xdf727d3b,288 /// or in textual repr: collectionOwner()289 function collectionOwner() public view returns (Tuple6 memory) {290 require(false, stub_error);291 dummy;292 return Tuple6(0x0000000000000000000000000000000000000000, 0);293 }294295 /// Changes collection owner to another account296 ///297 /// @dev Owner can be changed only by current owner298 /// @param newOwner new owner account299 /// @dev EVM selector for this function is: 0x4f53e226,300 /// or in textual repr: changeCollectionOwner(address)301 function changeCollectionOwner(address newOwner) public {302 require(false, stub_error);303 newOwner;304 dummy = 0;305 }306307 /// Get collection administrators308 ///309 /// @return Vector of tuples with admins address and his substrate mirror.310 /// If address is canonical then substrate mirror is zero and vice versa.311 /// @dev EVM selector for this function is: 0x5813216b,312 /// or in textual repr: collectionAdmins()313 function collectionAdmins() public view returns (Tuple6[] memory) {314 require(false, stub_error);315 dummy;316 return new Tuple6[](0);317 }318}319320/// @dev the ERC-165 identifier for this interface is 0x63034ac5321contract ERC20UniqueExtensions is Dummy, ERC165 {322 /// Burn tokens from account323 /// @dev Function that burns an `amount` of the tokens of a given account,324 /// deducting from the sender's allowance for said account.325 /// @param from The account whose tokens will be burnt.326 /// @param amount The amount that will be burnt.327 /// @dev EVM selector for this function is: 0x79cc6790,328 /// or in textual repr: burnFrom(address,uint256)329 function burnFrom(address from, uint256 amount) public returns (bool) {330 require(false, stub_error);331 from;332 amount;333 dummy = 0;334 return false;335 }336337 /// Mint tokens for multiple accounts.338 /// @param amounts array of pairs of account address and amount339 /// @dev EVM selector for this function is: 0x1acf2d55,340 /// or in textual repr: mintBulk((address,uint256)[])341 function mintBulk(Tuple6[] memory amounts) public returns (bool) {342 require(false, stub_error);343 amounts;344 dummy = 0;345 return false;346 }347}348349/// @dev anonymous struct350struct Tuple6 {351 address field_0;352 uint256 field_1;353}354355/// @dev the ERC-165 identifier for this interface is 0x40c10f19356contract ERC20Mintable is Dummy, ERC165 {357 /// Mint tokens for `to` account.358 /// @param to account that will receive minted tokens359 /// @param amount amount of tokens to mint360 /// @dev EVM selector for this function is: 0x40c10f19,361 /// or in textual repr: mint(address,uint256)362 function mint(address to, uint256 amount) public returns (bool) {363 require(false, stub_error);364 to;365 amount;366 dummy = 0;367 return false;368 }369}370371/// @dev inlined interface372contract ERC20Events {373 event Transfer(address indexed from, address indexed to, uint256 value);374 event Approval(address indexed owner, address indexed spender, uint256 value);375}376377/// @dev the ERC-165 identifier for this interface is 0x942e8b22378contract ERC20 is Dummy, ERC165, ERC20Events {379 /// @dev EVM selector for this function is: 0x06fdde03,380 /// or in textual repr: name()381 function name() public view returns (string memory) {382 require(false, stub_error);383 dummy;384 return "";385 }386387 /// @dev EVM selector for this function is: 0x95d89b41,388 /// or in textual repr: symbol()389 function symbol() public view returns (string memory) {390 require(false, stub_error);391 dummy;392 return "";393 }394395 /// @dev EVM selector for this function is: 0x18160ddd,396 /// or in textual repr: totalSupply()397 function totalSupply() public view returns (uint256) {398 require(false, stub_error);399 dummy;400 return 0;401 }402403 /// @dev EVM selector for this function is: 0x313ce567,404 /// or in textual repr: decimals()405 function decimals() public view returns (uint8) {406 require(false, stub_error);407 dummy;408 return 0;409 }410411 /// @dev EVM selector for this function is: 0x70a08231,412 /// or in textual repr: balanceOf(address)413 function balanceOf(address owner) public view returns (uint256) {414 require(false, stub_error);415 owner;416 dummy;417 return 0;418 }419420 /// @dev EVM selector for this function is: 0xa9059cbb,421 /// or in textual repr: transfer(address,uint256)422 function transfer(address to, uint256 amount) public returns (bool) {423 require(false, stub_error);424 to;425 amount;426 dummy = 0;427 return false;428 }429430 /// @dev EVM selector for this function is: 0x23b872dd,431 /// or in textual repr: transferFrom(address,address,uint256)432 function transferFrom(433 address from,434 address to,435 uint256 amount436 ) public returns (bool) {437 require(false, stub_error);438 from;439 to;440 amount;441 dummy = 0;442 return false;443 }444445 /// @dev EVM selector for this function is: 0x095ea7b3,446 /// or in textual repr: approve(address,uint256)447 function approve(address spender, uint256 amount) public returns (bool) {448 require(false, stub_error);449 spender;450 amount;451 dummy = 0;452 return false;453 }454455 /// @dev EVM selector for this function is: 0xdd62ed3e,456 /// or in textual repr: allowance(address,address)457 function allowance(address owner, address spender) public view returns (uint256) {458 require(false, stub_error);459 owner;460 spender;461 dummy;462 return 0;463 }464}465466contract UniqueFungible is Dummy, ERC165, ERC20, ERC20Mintable, ERC20UniqueExtensions, Collection {}pallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/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 0x62e22290
+/// @dev the ERC-165 identifier for this interface is 0x3af103fb
contract Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -355,7 +355,7 @@
/// Get collection owner.
///
- /// @return Tuble with sponsor address and his substrate mirror.
+ /// @return Tuple with sponsor address and his substrate mirror.
/// If address is canonical then substrate mirror is zero and vice versa.
/// @dev EVM selector for this function is: 0xdf727d3b,
/// or in textual repr: collectionOwner()
@@ -376,6 +376,18 @@
newOwner;
dummy = 0;
}
+
+ /// Get collection administrators
+ ///
+ /// @return Vector of tuples with admins address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0x5813216b,
+ /// or in textual repr: collectionAdmins()
+ function collectionAdmins() public view returns (Tuple17[] memory) {
+ require(false, stub_error);
+ dummy;
+ return new Tuple17[](0);
+ }
}
/// @dev anonymous struct
pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/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 0x62e22290
+/// @dev the ERC-165 identifier for this interface is 0x3af103fb
contract Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -355,7 +355,7 @@
/// Get collection owner.
///
- /// @return Tuble with sponsor address and his substrate mirror.
+ /// @return Tuple with sponsor address and his substrate mirror.
/// If address is canonical then substrate mirror is zero and vice versa.
/// @dev EVM selector for this function is: 0xdf727d3b,
/// or in textual repr: collectionOwner()
@@ -376,6 +376,18 @@
newOwner;
dummy = 0;
}
+
+ /// Get collection administrators
+ ///
+ /// @return Vector of tuples with admins address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0x5813216b,
+ /// or in textual repr: collectionAdmins()
+ function collectionAdmins() public view returns (Tuple17[] memory) {
+ require(false, stub_error);
+ dummy;
+ return new Tuple17[](0);
+ }
}
/// @dev anonymous struct
pallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterbothbinary blob — no preview
pallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterbothbinary blob — no preview
tests/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 0x62e22290
+/// @dev the ERC-165 identifier for this interface is 0x3af103fb
interface Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -184,7 +184,7 @@
/// Get collection owner.
///
- /// @return Tuble with sponsor address and his substrate mirror.
+ /// @return Tuple with sponsor address and his substrate mirror.
/// If address is canonical then substrate mirror is zero and vice versa.
/// @dev EVM selector for this function is: 0xdf727d3b,
/// or in textual repr: collectionOwner()
@@ -197,6 +197,14 @@
/// @dev EVM selector for this function is: 0x4f53e226,
/// or in textual repr: changeCollectionOwner(address)
function changeCollectionOwner(address newOwner) external;
+
+ /// Get collection administrators
+ ///
+ /// @return Vector of tuples with admins address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0x5813216b,
+ /// or in textual repr: collectionAdmins()
+ function collectionAdmins() external view returns (Tuple6[] memory);
}
/// @dev the ERC-165 identifier for this interface is 0x63034ac5
tests/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 0x62e22290
+/// @dev the ERC-165 identifier for this interface is 0x3af103fb
interface Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -233,7 +233,7 @@
/// Get collection owner.
///
- /// @return Tuble with sponsor address and his substrate mirror.
+ /// @return Tuple with sponsor address and his substrate mirror.
/// If address is canonical then substrate mirror is zero and vice versa.
/// @dev EVM selector for this function is: 0xdf727d3b,
/// or in textual repr: collectionOwner()
@@ -246,6 +246,14 @@
/// @dev EVM selector for this function is: 0x4f53e226,
/// or in textual repr: changeCollectionOwner(address)
function changeCollectionOwner(address newOwner) external;
+
+ /// Get collection administrators
+ ///
+ /// @return Vector of tuples with admins address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0x5813216b,
+ /// or in textual repr: collectionAdmins()
+ function collectionAdmins() external view returns (Tuple17[] memory);
}
/// @dev anonymous struct
tests/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 0x62e22290
+/// @dev the ERC-165 identifier for this interface is 0x3af103fb
interface Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -233,7 +233,7 @@
/// Get collection owner.
///
- /// @return Tuble with sponsor address and his substrate mirror.
+ /// @return Tuple with sponsor address and his substrate mirror.
/// If address is canonical then substrate mirror is zero and vice versa.
/// @dev EVM selector for this function is: 0xdf727d3b,
/// or in textual repr: collectionOwner()
@@ -246,6 +246,14 @@
/// @dev EVM selector for this function is: 0x4f53e226,
/// or in textual repr: changeCollectionOwner(address)
function changeCollectionOwner(address newOwner) external;
+
+ /// Get collection administrators
+ ///
+ /// @return Vector of tuples with admins address and his substrate mirror.
+ /// If address is canonical then substrate mirror is zero and vice versa.
+ /// @dev EVM selector for this function is: 0x5813216b,
+ /// or in textual repr: collectionAdmins()
+ function collectionAdmins() external view returns (Tuple17[] memory);
}
/// @dev anonymous struct
tests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth--- a/tests/src/eth/collectionAdmin.test.ts
+++ b/tests/src/eth/collectionAdmin.test.ts
@@ -14,6 +14,7 @@
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
import {IKeyringPair} from '@polkadot/types/types';
+import {IEthCrossAccountId} from '../util/playgrounds/types';
import {usingEthPlaygrounds, itEth, expect, EthUniqueHelper} from './util';
async function recordEthFee(helper: EthUniqueHelper, userAddress: string, call: () => Promise<any>) {
@@ -68,11 +69,31 @@
const newAdmin = helper.eth.createAccount();
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+
expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false;
await collectionEvm.methods.addCollectionAdmin(newAdmin).send();
expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true;
});
+
+ itEth.skip('Check adminlist', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+
+ const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+
+ const admin1 = helper.eth.createAccount();
+ const [admin2] = await helper.arrange.createAccounts([10n], donor);
+ await collectionEvm.methods.addCollectionAdmin(admin1).send();
+ await collectionEvm.methods.addCollectionAdminSubstrate(admin2.addressRaw).send();
+ const adminListRpc = await helper.collection.getAdmins(collectionId);
+ let adminListEth = await collectionEvm.methods.collectionAdmins().call();
+ adminListEth = adminListEth.map((element: IEthCrossAccountId) => {
+ return helper.address.convertCrossAccountFromEthCrossAcoount(element);
+ });
+ expect(adminListRpc).to.be.like(adminListEth);
+ });
+
itEth('(!negative tests!) Add admin by ADMIN is not allowed', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
tests/src/eth/fungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/fungibleAbi.json
+++ b/tests/src/eth/fungibleAbi.json
@@ -126,6 +126,23 @@
},
{
"inputs": [],
+ "name": "collectionAdmins",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "field_0", "type": "address" },
+ { "internalType": "uint256", "name": "field_1", "type": "uint256" }
+ ],
+ "internalType": "struct Tuple6[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
"name": "collectionOwner",
"outputs": [
{
tests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/nonFungibleAbi.json
+++ b/tests/src/eth/nonFungibleAbi.json
@@ -156,6 +156,23 @@
},
{
"inputs": [],
+ "name": "collectionAdmins",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "field_0", "type": "address" },
+ { "internalType": "uint256", "name": "field_1", "type": "uint256" }
+ ],
+ "internalType": "struct Tuple17[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
"name": "collectionOwner",
"outputs": [
{
tests/src/eth/reFungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/reFungibleAbi.json
+++ b/tests/src/eth/reFungibleAbi.json
@@ -156,6 +156,23 @@
},
{
"inputs": [],
+ "name": "collectionAdmins",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "field_0", "type": "address" },
+ { "internalType": "uint256", "name": "field_1", "type": "uint256" }
+ ],
+ "internalType": "struct Tuple17[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
"name": "collectionOwner",
"outputs": [
{
tests/src/util/playgrounds/types.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/types.ts
+++ b/tests/src/util/playgrounds/types.ts
@@ -70,6 +70,13 @@
ethereum?: TEthereumAccount;
}
+export interface IEthCrossAccountId {
+ 0: TEthereumAccount;
+ 1: TSubstrateAccount;
+ field_0: TEthereumAccount;
+ field_1: TSubstrateAccount;
+}
+
export interface ICollectionLimits {
accountTokenOwnershipLimit?: number | null;
sponsoredDataSize?: number | null;
tests/src/util/playgrounds/unique.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -7,9 +7,11 @@
import {ApiPromise, WsProvider, Keyring} from '@polkadot/api';
import {ApiInterfaceEvents, SignerOptions} from '@polkadot/api/types';
-import {encodeAddress, decodeAddress, keccakAsHex, evmToAddress, addressToEvm} from '@polkadot/util-crypto';
+import {encodeAddress, decodeAddress, keccakAsHex, evmToAddress, addressToEvm, base58Encode, blake2AsU8a} from '@polkadot/util-crypto';
import {IKeyringPair} from '@polkadot/types/types';
-import {IApiListeners, IBlock, IEvent, IChainProperties, ICollectionCreationOptions, ICollectionLimits, ICollectionPermissions, ICrossAccountId, ICrossAccountIdLower, ILogger, INestingPermissions, IProperty, IStakingInfo, ISchedulerOptions, ISubstrateBalance, IToken, ITokenPropertyPermission, ITransactionResult, IUniqueHelperLog, TApiAllowedListeners, TEthereumAccount, TSigner, TSubstrateAccount, IForeignAssetMetadata, TNetworks, MoonbeamAssetInfo, DemocracyStandardAccountVote, AcalaAssetMetadata} from './types';
+import {IApiListeners, IBlock, IEvent, IChainProperties, ICollectionCreationOptions, ICollectionLimits, ICollectionPermissions, ICrossAccountId, ICrossAccountIdLower, ILogger, INestingPermissions, IProperty, IStakingInfo, ISchedulerOptions, ISubstrateBalance, IToken, ITokenPropertyPermission, ITransactionResult, IUniqueHelperLog, TApiAllowedListeners, TEthereumAccount, TSigner, TSubstrateAccount, IForeignAssetMetadata, TNetworks, MoonbeamAssetInfo, DemocracyStandardAccountVote, AcalaAssetMetadata, IEthCrossAccountId} from './types';
+import {hexToU8a} from '@polkadot/util/hex';
+import {u8aConcat} from '@polkadot/util/u8a';
export class CrossAccountId implements ICrossAccountId {
Substrate?: TSubstrateAccount;
@@ -2309,6 +2311,73 @@
return siblingPrefix + encodedParaId + suffix;
}
+
+ /**
+ * Encode key to substrate address
+ * @param key key for encoding address
+ * @param ss58Format prefix for encoding to the address of the corresponding network
+ * @returns encoded substrate address
+ */
+ encodeSubstrateAddress (key: Uint8Array | string | bigint, ss58Format = 42): string {
+ const u8a :Uint8Array = typeof key === 'string'
+ ? hexToU8a(key)
+ : typeof key === 'bigint'
+ ? hexToU8a(key.toString(16))
+ : key;
+
+ if (ss58Format < 0 || ss58Format > 16383 || [46, 47].includes(ss58Format)) {
+ throw new Error(`ss58Format is not valid, received ${typeof ss58Format} "${ss58Format}"`);
+ }
+
+ const allowedDecodedLengths = [1, 2, 4, 8, 32, 33];
+ if (!allowedDecodedLengths.includes(u8a.length)) {
+ throw new Error(`key length is not valid, received ${u8a.length}, valid values are ${allowedDecodedLengths.join(', ')}`);
+ }
+
+ const u8aPrefix = ss58Format < 64
+ ? new Uint8Array([ss58Format])
+ : new Uint8Array([
+ ((ss58Format & 0xfc) >> 2) | 0x40,
+ (ss58Format >> 8) | ((ss58Format & 0x03) << 6),
+ ]);
+
+ const input = u8aConcat(u8aPrefix, u8a);
+
+ return base58Encode(u8aConcat(
+ input,
+ blake2AsU8a(input).subarray(0, [32, 33].includes(u8a.length) ? 2 : 1),
+ ));
+ }
+
+ /**
+ * Restore substrate address from bigint representation
+ * @param number decimal representation of substrate address
+ * @returns substrate address
+ */
+ restoreCrossAccountFromBigInt(number: bigint): TSubstrateAccount {
+ if (this.helper.api === null) {
+ throw 'Not connected';
+ }
+ const res = this.helper.api.registry.createType('AccountId', '0x' + number.toString(16).padStart(64, '0')).toJSON();
+ if (res === undefined || res === null) {
+ throw 'Restore address error';
+ }
+ return res.toString();
+ }
+
+ /**
+ * Convert etherium cross account id to substrate cross account id
+ * @param ethCrossAccount etherium cross account
+ * @returns substrate cross account id
+ */
+ convertCrossAccountFromEthCrossAcoount(ethCrossAccount: IEthCrossAccountId): ICrossAccountId {
+ if (ethCrossAccount.field_1 === '0') {
+ return {Ethereum: ethCrossAccount.field_0.toLocaleLowerCase()};
+ }
+
+ const ss58 = this.restoreCrossAccountFromBigInt(BigInt(ethCrossAccount.field_1));
+ return {Substrate: ss58};
+ }
}
class StakingGroup extends HelperGroup<UniqueHelper> {