difftreelog
Merge pull request #728 from UniqueNetwork/feature/newCallMethods
in: master
Added new call functions
31 files changed
crates/evm-coder/src/abi/impls.rsdiffbeforeafterboth--- a/crates/evm-coder/src/abi/impls.rs
+++ b/crates/evm-coder/src/abi/impls.rs
@@ -184,8 +184,7 @@
impl AbiWrite for Property {
fn abi_write(&self, writer: &mut AbiWriter) {
- self.key.abi_write(writer);
- self.value.abi_write(writer);
+ (&self.key, &self.value).abi_write(writer);
}
}
crates/evm-coder/src/abi/traits.rsdiffbeforeafterboth--- a/crates/evm-coder/src/abi/traits.rs
+++ b/crates/evm-coder/src/abi/traits.rs
@@ -49,3 +49,9 @@
Ok(writer.into())
}
}
+
+impl<T: AbiWrite> AbiWrite for &T {
+ fn abi_write(&self, writer: &mut AbiWriter) {
+ T::abi_write(self, writer);
+ }
+}
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -178,7 +178,7 @@
///
/// @param keys Properties keys. Empty keys for all propertyes.
/// @return Vector of properties key/value pairs.
- fn collection_properties(&self, keys: Vec<string>) -> Result<Vec<(string, bytes)>> {
+ fn collection_properties(&self, keys: Vec<string>) -> Result<Vec<PropertyStruct>> {
let keys = keys
.into_iter()
.map(|key| {
@@ -200,7 +200,7 @@
let key =
string::from_utf8(p.key.into()).map_err(|e| Error::Revert(format!("{}", e)))?;
let value = bytes(p.value.to_vec());
- Ok((key, value))
+ Ok(PropertyStruct { key, value })
})
.collect::<Result<Vec<_>>>()?;
Ok(properties)
pallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/CHANGELOG.mddiffbeforeafterboth--- a/pallets/fungible/CHANGELOG.md
+++ b/pallets/fungible/CHANGELOG.md
@@ -4,12 +4,22 @@
<!-- bureaucrate goes here -->
+## [0.1.8] - 2022-11-18
+
+### Added
+
+- The function `description` to `ERC20UniqueExtensions` interface.
+
## [0.1.7] - 2022-11-14
### Changed
- Added `transfer_cross` in eth functions.
+### Changed
+
+- Use named structure `EthCrossAccount` in eth functions.
+
## [0.1.6] - 2022-11-02
### Changed
pallets/fungible/src/erc.rsdiffbeforeafterboth--- a/pallets/fungible/src/erc.rs
+++ b/pallets/fungible/src/erc.rs
@@ -158,6 +158,13 @@
where
T::AccountId: From<[u8; 32]>,
{
+ /// @notice A description for the collection.
+ fn description(&self) -> Result<string> {
+ Ok(decode_utf16(self.description.iter().copied())
+ .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
+ .collect::<string>())
+ }
+
#[weight(<SelfWeightOf<T>>::approve())]
fn approve_cross(
&mut self,
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 0x8b91d19222contract 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 /// Set collection properties.37 ///38 /// @param properties Vector of properties key/value pair.39 /// @dev EVM selector for this function is: 0x50b26b2a,40 /// or in textual repr: setCollectionProperties((string,bytes)[])41 function setCollectionProperties(Property[] memory properties) public {42 require(false, stub_error);43 properties;44 dummy = 0;45 }4647 // /// Delete collection property.48 // ///49 // /// @param key Property key.50 // /// @dev EVM selector for this function is: 0x7b7debce,51 // /// or in textual repr: deleteCollectionProperty(string)52 // function deleteCollectionProperty(string memory key) public {53 // require(false, stub_error);54 // key;55 // dummy = 0;56 // }5758 /// Delete collection properties.59 ///60 /// @param keys Properties keys.61 /// @dev EVM selector for this function is: 0xee206ee3,62 /// or in textual repr: deleteCollectionProperties(string[])63 function deleteCollectionProperties(string[] memory keys) public {64 require(false, stub_error);65 keys;66 dummy = 0;67 }6869 /// Get collection property.70 ///71 /// @dev Throws error if key not found.72 ///73 /// @param key Property key.74 /// @return bytes The property corresponding to the key.75 /// @dev EVM selector for this function is: 0xcf24fd6d,76 /// or in textual repr: collectionProperty(string)77 function collectionProperty(string memory key) public view returns (bytes memory) {78 require(false, stub_error);79 key;80 dummy;81 return hex"";82 }8384 /// Get collection properties.85 ///86 /// @param keys Properties keys. Empty keys for all propertyes.87 /// @return Vector of properties key/value pairs.88 /// @dev EVM selector for this function is: 0x285fb8e6,89 /// or in textual repr: collectionProperties(string[])90 function collectionProperties(string[] memory keys) public view returns (Tuple16[] memory) {91 require(false, stub_error);92 keys;93 dummy;94 return new Tuple16[](0);95 }9697 // /// Set the sponsor of the collection.98 // ///99 // /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.100 // ///101 // /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.102 // /// @dev EVM selector for this function is: 0x7623402e,103 // /// or in textual repr: setCollectionSponsor(address)104 // function setCollectionSponsor(address sponsor) public {105 // require(false, stub_error);106 // sponsor;107 // dummy = 0;108 // }109110 /// Set the sponsor of the collection.111 ///112 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.113 ///114 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.115 /// @dev EVM selector for this function is: 0x84a1d5a8,116 /// or in textual repr: setCollectionSponsorCross((address,uint256))117 function setCollectionSponsorCross(EthCrossAccount memory sponsor) public {118 require(false, stub_error);119 sponsor;120 dummy = 0;121 }122123 /// Whether there is a pending sponsor.124 /// @dev EVM selector for this function is: 0x058ac185,125 /// or in textual repr: hasCollectionPendingSponsor()126 function hasCollectionPendingSponsor() public view returns (bool) {127 require(false, stub_error);128 dummy;129 return false;130 }131132 /// Collection sponsorship confirmation.133 ///134 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.135 /// @dev EVM selector for this function is: 0x3c50e97a,136 /// or in textual repr: confirmCollectionSponsorship()137 function confirmCollectionSponsorship() public {138 require(false, stub_error);139 dummy = 0;140 }141142 /// Remove collection sponsor.143 /// @dev EVM selector for this function is: 0x6e0326a3,144 /// or in textual repr: removeCollectionSponsor()145 function removeCollectionSponsor() public {146 require(false, stub_error);147 dummy = 0;148 }149150 /// Get current sponsor.151 ///152 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.153 /// @dev EVM selector for this function is: 0x6ec0a9f1,154 /// or in textual repr: collectionSponsor()155 function collectionSponsor() public view returns (Tuple8 memory) {156 require(false, stub_error);157 dummy;158 return Tuple8(0x0000000000000000000000000000000000000000, 0);159 }160161 /// Set limits for the collection.162 /// @dev Throws error if limit not found.163 /// @param limit Name of the limit. Valid names:164 /// "accountTokenOwnershipLimit",165 /// "sponsoredDataSize",166 /// "sponsoredDataRateLimit",167 /// "tokenLimit",168 /// "sponsorTransferTimeout",169 /// "sponsorApproveTimeout"170 /// "ownerCanTransfer",171 /// "ownerCanDestroy",172 /// "transfersEnabled"173 /// @param value Value of the limit.174 /// @dev EVM selector for this function is: 0x4ad890a8,175 /// or in textual repr: setCollectionLimit(string,uint256)176 function setCollectionLimit(string memory limit, uint256 value) public {177 require(false, stub_error);178 limit;179 value;180 dummy = 0;181 }182183 /// Get contract address.184 /// @dev EVM selector for this function is: 0xf6b4dfb4,185 /// or in textual repr: contractAddress()186 function contractAddress() public view returns (address) {187 require(false, stub_error);188 dummy;189 return 0x0000000000000000000000000000000000000000;190 }191192 /// Add collection admin.193 /// @param newAdmin Cross account administrator address.194 /// @dev EVM selector for this function is: 0x859aa7d6,195 /// or in textual repr: addCollectionAdminCross((address,uint256))196 function addCollectionAdminCross(EthCrossAccount memory newAdmin) public {197 require(false, stub_error);198 newAdmin;199 dummy = 0;200 }201202 /// Remove collection admin.203 /// @param admin Cross account administrator address.204 /// @dev EVM selector for this function is: 0x6c0cd173,205 /// or in textual repr: removeCollectionAdminCross((address,uint256))206 function removeCollectionAdminCross(EthCrossAccount memory admin) public {207 require(false, stub_error);208 admin;209 dummy = 0;210 }211212 // /// Add collection admin.213 // /// @param newAdmin Address of the added administrator.214 // /// @dev EVM selector for this function is: 0x92e462c7,215 // /// or in textual repr: addCollectionAdmin(address)216 // function addCollectionAdmin(address newAdmin) public {217 // require(false, stub_error);218 // newAdmin;219 // dummy = 0;220 // }221222 // /// Remove collection admin.223 // ///224 // /// @param admin Address of the removed administrator.225 // /// @dev EVM selector for this function is: 0xfafd7b42,226 // /// or in textual repr: removeCollectionAdmin(address)227 // function removeCollectionAdmin(address admin) public {228 // require(false, stub_error);229 // admin;230 // dummy = 0;231 // }232233 /// Toggle accessibility of collection nesting.234 ///235 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'236 /// @dev EVM selector for this function is: 0x112d4586,237 /// or in textual repr: setCollectionNesting(bool)238 function setCollectionNesting(bool enable) public {239 require(false, stub_error);240 enable;241 dummy = 0;242 }243244 /// Toggle accessibility of collection nesting.245 ///246 /// @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'247 /// @param collections Addresses of collections that will be available for nesting.248 /// @dev EVM selector for this function is: 0x64872396,249 /// or in textual repr: setCollectionNesting(bool,address[])250 function setCollectionNesting(bool enable, address[] memory collections) public {251 require(false, stub_error);252 enable;253 collections;254 dummy = 0;255 }256257 /// Set the collection access method.258 /// @param mode Access mode259 /// 0 for Normal260 /// 1 for AllowList261 /// @dev EVM selector for this function is: 0x41835d4c,262 /// or in textual repr: setCollectionAccess(uint8)263 function setCollectionAccess(uint8 mode) public {264 require(false, stub_error);265 mode;266 dummy = 0;267 }268269 /// Checks that user allowed to operate with collection.270 ///271 /// @param user User address to check.272 /// @dev EVM selector for this function is: 0xd63a8e11,273 /// or in textual repr: allowed(address)274 function allowed(address user) public view returns (bool) {275 require(false, stub_error);276 user;277 dummy;278 return false;279 }280281 // /// Add the user to the allowed list.282 // ///283 // /// @param user Address of a trusted user.284 // /// @dev EVM selector for this function is: 0x67844fe6,285 // /// or in textual repr: addToCollectionAllowList(address)286 // function addToCollectionAllowList(address user) public {287 // require(false, stub_error);288 // user;289 // dummy = 0;290 // }291292 /// Add user to allowed list.293 ///294 /// @param user User cross account address.295 /// @dev EVM selector for this function is: 0xa0184a3a,296 /// or in textual repr: addToCollectionAllowListCross((address,uint256))297 function addToCollectionAllowListCross(EthCrossAccount memory user) public {298 require(false, stub_error);299 user;300 dummy = 0;301 }302303 // /// Remove the user from the allowed list.304 // ///305 // /// @param user Address of a removed user.306 // /// @dev EVM selector for this function is: 0x85c51acb,307 // /// or in textual repr: removeFromCollectionAllowList(address)308 // function removeFromCollectionAllowList(address user) public {309 // require(false, stub_error);310 // user;311 // dummy = 0;312 // }313314 /// Remove user from allowed list.315 ///316 /// @param user User cross account address.317 /// @dev EVM selector for this function is: 0x09ba452a,318 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))319 function removeFromCollectionAllowListCross(EthCrossAccount memory user) public {320 require(false, stub_error);321 user;322 dummy = 0;323 }324325 /// Switch permission for minting.326 ///327 /// @param mode Enable if "true".328 /// @dev EVM selector for this function is: 0x00018e84,329 /// or in textual repr: setCollectionMintMode(bool)330 function setCollectionMintMode(bool mode) public {331 require(false, stub_error);332 mode;333 dummy = 0;334 }335336 // /// Check that account is the owner or admin of the collection337 // ///338 // /// @param user account to verify339 // /// @return "true" if account is the owner or admin340 // /// @dev EVM selector for this function is: 0x9811b0c7,341 // /// or in textual repr: isOwnerOrAdmin(address)342 // function isOwnerOrAdmin(address user) public view returns (bool) {343 // require(false, stub_error);344 // user;345 // dummy;346 // return false;347 // }348349 /// Check that account is the owner or admin of the collection350 ///351 /// @param user User cross account to verify352 /// @return "true" if account is the owner or admin353 /// @dev EVM selector for this function is: 0x3e75a905,354 /// or in textual repr: isOwnerOrAdminCross((address,uint256))355 function isOwnerOrAdminCross(EthCrossAccount memory user) public view returns (bool) {356 require(false, stub_error);357 user;358 dummy;359 return false;360 }361362 /// Returns collection type363 ///364 /// @return `Fungible` or `NFT` or `ReFungible`365 /// @dev EVM selector for this function is: 0xd34b55b8,366 /// or in textual repr: uniqueCollectionType()367 function uniqueCollectionType() public view returns (string memory) {368 require(false, stub_error);369 dummy;370 return "";371 }372373 /// Get collection owner.374 ///375 /// @return Tuble with sponsor address and his substrate mirror.376 /// If address is canonical then substrate mirror is zero and vice versa.377 /// @dev EVM selector for this function is: 0xdf727d3b,378 /// or in textual repr: collectionOwner()379 function collectionOwner() public view returns (EthCrossAccount memory) {380 require(false, stub_error);381 dummy;382 return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);383 }384385 // /// Changes collection owner to another account386 // ///387 // /// @dev Owner can be changed only by current owner388 // /// @param newOwner new owner account389 // /// @dev EVM selector for this function is: 0x4f53e226,390 // /// or in textual repr: changeCollectionOwner(address)391 // function changeCollectionOwner(address newOwner) public {392 // require(false, stub_error);393 // newOwner;394 // dummy = 0;395 // }396397 /// Get collection administrators398 ///399 /// @return Vector of tuples with admins address and his substrate mirror.400 /// If address is canonical then substrate mirror is zero and vice versa.401 /// @dev EVM selector for this function is: 0x5813216b,402 /// or in textual repr: collectionAdmins()403 function collectionAdmins() public view returns (EthCrossAccount[] memory) {404 require(false, stub_error);405 dummy;406 return new EthCrossAccount[](0);407 }408409 /// Changes collection owner to another account410 ///411 /// @dev Owner can be changed only by current owner412 /// @param newOwner new owner cross account413 /// @dev EVM selector for this function is: 0x6496c497,414 /// or in textual repr: changeCollectionOwnerCross((address,uint256))415 function changeCollectionOwnerCross(EthCrossAccount memory newOwner) public {416 require(false, stub_error);417 newOwner;418 dummy = 0;419 }420}421422/// @dev Cross account struct423struct EthCrossAccount {424 address eth;425 uint256 sub;426}427428/// @dev anonymous struct429struct Tuple16 {430 string field_0;431 bytes field_1;432}433434/// @dev Property struct435struct Property {436 string key;437 bytes value;438}439440/// @dev the ERC-165 identifier for this interface is 0x29f4dcd9441contract ERC20UniqueExtensions is Dummy, ERC165 {442 /// @dev EVM selector for this function is: 0x0ecd0ab0,443 /// or in textual repr: approveCross((address,uint256),uint256)444 function approveCross(EthCrossAccount memory spender, uint256 amount) public returns (bool) {445 require(false, stub_error);446 spender;447 amount;448 dummy = 0;449 return false;450 }451452 // /// Burn tokens from account453 // /// @dev Function that burns an `amount` of the tokens of a given account,454 // /// deducting from the sender's allowance for said account.455 // /// @param from The account whose tokens will be burnt.456 // /// @param amount The amount that will be burnt.457 // /// @dev EVM selector for this function is: 0x79cc6790,458 // /// or in textual repr: burnFrom(address,uint256)459 // function burnFrom(address from, uint256 amount) public returns (bool) {460 // require(false, stub_error);461 // from;462 // amount;463 // dummy = 0;464 // return false;465 // }466467 /// Burn tokens from account468 /// @dev Function that burns an `amount` of the tokens of a given account,469 /// deducting from the sender's allowance for said account.470 /// @param from The account whose tokens will be burnt.471 /// @param amount The amount that will be burnt.472 /// @dev EVM selector for this function is: 0xbb2f5a58,473 /// or in textual repr: burnFromCross((address,uint256),uint256)474 function burnFromCross(EthCrossAccount memory from, uint256 amount) public returns (bool) {475 require(false, stub_error);476 from;477 amount;478 dummy = 0;479 return false;480 }481482 /// Mint tokens for multiple accounts.483 /// @param amounts array of pairs of account address and amount484 /// @dev EVM selector for this function is: 0x1acf2d55,485 /// or in textual repr: mintBulk((address,uint256)[])486 function mintBulk(Tuple8[] memory amounts) public returns (bool) {487 require(false, stub_error);488 amounts;489 dummy = 0;490 return false;491 }492493 /// @dev EVM selector for this function is: 0x2ada85ff,494 /// or in textual repr: transferCross((address,uint256),uint256)495 function transferCross(EthCrossAccount memory to, uint256 amount) public returns (bool) {496 require(false, stub_error);497 to;498 amount;499 dummy = 0;500 return false;501 }502503 /// @dev EVM selector for this function is: 0xd5cf430b,504 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)505 function transferFromCross(506 EthCrossAccount memory from,507 EthCrossAccount memory to,508 uint256 amount509 ) public returns (bool) {510 require(false, stub_error);511 from;512 to;513 amount;514 dummy = 0;515 return false;516 }517}518519/// @dev anonymous struct520struct Tuple8 {521 address field_0;522 uint256 field_1;523}524525/// @dev the ERC-165 identifier for this interface is 0x40c10f19526contract ERC20Mintable is Dummy, ERC165 {527 /// Mint tokens for `to` account.528 /// @param to account that will receive minted tokens529 /// @param amount amount of tokens to mint530 /// @dev EVM selector for this function is: 0x40c10f19,531 /// or in textual repr: mint(address,uint256)532 function mint(address to, uint256 amount) public returns (bool) {533 require(false, stub_error);534 to;535 amount;536 dummy = 0;537 return false;538 }539}540541/// @dev inlined interface542contract ERC20Events {543 event Transfer(address indexed from, address indexed to, uint256 value);544 event Approval(address indexed owner, address indexed spender, uint256 value);545}546547/// @dev the ERC-165 identifier for this interface is 0x942e8b22548contract ERC20 is Dummy, ERC165, ERC20Events {549 /// @dev EVM selector for this function is: 0x06fdde03,550 /// or in textual repr: name()551 function name() public view returns (string memory) {552 require(false, stub_error);553 dummy;554 return "";555 }556557 /// @dev EVM selector for this function is: 0x95d89b41,558 /// or in textual repr: symbol()559 function symbol() public view returns (string memory) {560 require(false, stub_error);561 dummy;562 return "";563 }564565 /// @dev EVM selector for this function is: 0x18160ddd,566 /// or in textual repr: totalSupply()567 function totalSupply() public view returns (uint256) {568 require(false, stub_error);569 dummy;570 return 0;571 }572573 /// @dev EVM selector for this function is: 0x313ce567,574 /// or in textual repr: decimals()575 function decimals() public view returns (uint8) {576 require(false, stub_error);577 dummy;578 return 0;579 }580581 /// @dev EVM selector for this function is: 0x70a08231,582 /// or in textual repr: balanceOf(address)583 function balanceOf(address owner) public view returns (uint256) {584 require(false, stub_error);585 owner;586 dummy;587 return 0;588 }589590 /// @dev EVM selector for this function is: 0xa9059cbb,591 /// or in textual repr: transfer(address,uint256)592 function transfer(address to, uint256 amount) public returns (bool) {593 require(false, stub_error);594 to;595 amount;596 dummy = 0;597 return false;598 }599600 /// @dev EVM selector for this function is: 0x23b872dd,601 /// or in textual repr: transferFrom(address,address,uint256)602 function transferFrom(603 address from,604 address to,605 uint256 amount606 ) public returns (bool) {607 require(false, stub_error);608 from;609 to;610 amount;611 dummy = 0;612 return false;613 }614615 /// @dev EVM selector for this function is: 0x095ea7b3,616 /// or in textual repr: approve(address,uint256)617 function approve(address spender, uint256 amount) public returns (bool) {618 require(false, stub_error);619 spender;620 amount;621 dummy = 0;622 return false;623 }624625 /// @dev EVM selector for this function is: 0xdd62ed3e,626 /// or in textual repr: allowance(address,address)627 function allowance(address owner, address spender) public view returns (uint256) {628 require(false, stub_error);629 owner;630 spender;631 dummy;632 return 0;633 }634}635636contract 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 0x8b91d19222contract 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 /// Set collection properties.37 ///38 /// @param properties Vector of properties key/value pair.39 /// @dev EVM selector for this function is: 0x50b26b2a,40 /// or in textual repr: setCollectionProperties((string,bytes)[])41 function setCollectionProperties(Property[] memory properties) public {42 require(false, stub_error);43 properties;44 dummy = 0;45 }4647 // /// Delete collection property.48 // ///49 // /// @param key Property key.50 // /// @dev EVM selector for this function is: 0x7b7debce,51 // /// or in textual repr: deleteCollectionProperty(string)52 // function deleteCollectionProperty(string memory key) public {53 // require(false, stub_error);54 // key;55 // dummy = 0;56 // }5758 /// Delete collection properties.59 ///60 /// @param keys Properties keys.61 /// @dev EVM selector for this function is: 0xee206ee3,62 /// or in textual repr: deleteCollectionProperties(string[])63 function deleteCollectionProperties(string[] memory keys) public {64 require(false, stub_error);65 keys;66 dummy = 0;67 }6869 /// Get collection property.70 ///71 /// @dev Throws error if key not found.72 ///73 /// @param key Property key.74 /// @return bytes The property corresponding to the key.75 /// @dev EVM selector for this function is: 0xcf24fd6d,76 /// or in textual repr: collectionProperty(string)77 function collectionProperty(string memory key) public view returns (bytes memory) {78 require(false, stub_error);79 key;80 dummy;81 return hex"";82 }8384 /// Get collection properties.85 ///86 /// @param keys Properties keys. Empty keys for all propertyes.87 /// @return Vector of properties key/value pairs.88 /// @dev EVM selector for this function is: 0x285fb8e6,89 /// or in textual repr: collectionProperties(string[])90 function collectionProperties(string[] memory keys) public view returns (Property[] memory) {91 require(false, stub_error);92 keys;93 dummy;94 return new Property[](0);95 }9697 // /// Set the sponsor of the collection.98 // ///99 // /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.100 // ///101 // /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.102 // /// @dev EVM selector for this function is: 0x7623402e,103 // /// or in textual repr: setCollectionSponsor(address)104 // function setCollectionSponsor(address sponsor) public {105 // require(false, stub_error);106 // sponsor;107 // dummy = 0;108 // }109110 /// Set the sponsor of the collection.111 ///112 /// @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.113 ///114 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.115 /// @dev EVM selector for this function is: 0x84a1d5a8,116 /// or in textual repr: setCollectionSponsorCross((address,uint256))117 function setCollectionSponsorCross(EthCrossAccount memory sponsor) public {118 require(false, stub_error);119 sponsor;120 dummy = 0;121 }122123 /// Whether there is a pending sponsor.124 /// @dev EVM selector for this function is: 0x058ac185,125 /// or in textual repr: hasCollectionPendingSponsor()126 function hasCollectionPendingSponsor() public view returns (bool) {127 require(false, stub_error);128 dummy;129 return false;130 }131132 /// Collection sponsorship confirmation.133 ///134 /// @dev After setting the sponsor for the collection, it must be confirmed with this function.135 /// @dev EVM selector for this function is: 0x3c50e97a,136 /// or in textual repr: confirmCollectionSponsorship()137 function confirmCollectionSponsorship() public {138 require(false, stub_error);139 dummy = 0;140 }141142 /// Remove collection sponsor.143 /// @dev EVM selector for this function is: 0x6e0326a3,144 /// or in textual repr: removeCollectionSponsor()145 function removeCollectionSponsor() public {146 require(false, stub_error);147 dummy = 0;148 }149150 /// Get current sponsor.151 ///152 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.153 /// @dev EVM selector for this function is: 0x6ec0a9f1,154 /// or in textual repr: collectionSponsor()155 function collectionSponsor() public view returns (Tuple8 memory) {156 require(false, stub_error);157 dummy;158 return Tuple8(0x0000000000000000000000000000000000000000, 0);159 }160161 /// Set limits for the collection.162 /// @dev Throws error if limit not found.163 /// @param limit Name of the limit. Valid names:164 /// "accountTokenOwnershipLimit",165 /// "sponsoredDataSize",166 /// "sponsoredDataRateLimit",167 /// "tokenLimit",168 /// "sponsorTransferTimeout",169 /// "sponsorApproveTimeout"170 /// "ownerCanTransfer",171 /// "ownerCanDestroy",172 /// "transfersEnabled"173 /// @param value Value of the limit.174 /// @dev EVM selector for this function is: 0x4ad890a8,175 /// or in textual repr: setCollectionLimit(string,uint256)176 function setCollectionLimit(string memory limit, uint256 value) public {177 require(false, stub_error);178 limit;179 value;180 dummy = 0;181 }182183 /// Get contract address.184 /// @dev EVM selector for this function is: 0xf6b4dfb4,185 /// or in textual repr: contractAddress()186 function contractAddress() public view returns (address) {187 require(false, stub_error);188 dummy;189 return 0x0000000000000000000000000000000000000000;190 }191192 /// Add collection admin.193 /// @param newAdmin Cross account administrator address.194 /// @dev EVM selector for this function is: 0x859aa7d6,195 /// or in textual repr: addCollectionAdminCross((address,uint256))196 function addCollectionAdminCross(EthCrossAccount memory newAdmin) public {197 require(false, stub_error);198 newAdmin;199 dummy = 0;200 }201202 /// Remove collection admin.203 /// @param admin Cross account administrator address.204 /// @dev EVM selector for this function is: 0x6c0cd173,205 /// or in textual repr: removeCollectionAdminCross((address,uint256))206 function removeCollectionAdminCross(EthCrossAccount memory admin) public {207 require(false, stub_error);208 admin;209 dummy = 0;210 }211212 // /// Add collection admin.213 // /// @param newAdmin Address of the added administrator.214 // /// @dev EVM selector for this function is: 0x92e462c7,215 // /// or in textual repr: addCollectionAdmin(address)216 // function addCollectionAdmin(address newAdmin) public {217 // require(false, stub_error);218 // newAdmin;219 // dummy = 0;220 // }221222 // /// Remove collection admin.223 // ///224 // /// @param admin Address of the removed administrator.225 // /// @dev EVM selector for this function is: 0xfafd7b42,226 // /// or in textual repr: removeCollectionAdmin(address)227 // function removeCollectionAdmin(address admin) public {228 // require(false, stub_error);229 // admin;230 // dummy = 0;231 // }232233 /// Toggle accessibility of collection nesting.234 ///235 /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'236 /// @dev EVM selector for this function is: 0x112d4586,237 /// or in textual repr: setCollectionNesting(bool)238 function setCollectionNesting(bool enable) public {239 require(false, stub_error);240 enable;241 dummy = 0;242 }243244 /// Toggle accessibility of collection nesting.245 ///246 /// @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'247 /// @param collections Addresses of collections that will be available for nesting.248 /// @dev EVM selector for this function is: 0x64872396,249 /// or in textual repr: setCollectionNesting(bool,address[])250 function setCollectionNesting(bool enable, address[] memory collections) public {251 require(false, stub_error);252 enable;253 collections;254 dummy = 0;255 }256257 /// Set the collection access method.258 /// @param mode Access mode259 /// 0 for Normal260 /// 1 for AllowList261 /// @dev EVM selector for this function is: 0x41835d4c,262 /// or in textual repr: setCollectionAccess(uint8)263 function setCollectionAccess(uint8 mode) public {264 require(false, stub_error);265 mode;266 dummy = 0;267 }268269 /// Checks that user allowed to operate with collection.270 ///271 /// @param user User address to check.272 /// @dev EVM selector for this function is: 0xd63a8e11,273 /// or in textual repr: allowed(address)274 function allowed(address user) public view returns (bool) {275 require(false, stub_error);276 user;277 dummy;278 return false;279 }280281 // /// Add the user to the allowed list.282 // ///283 // /// @param user Address of a trusted user.284 // /// @dev EVM selector for this function is: 0x67844fe6,285 // /// or in textual repr: addToCollectionAllowList(address)286 // function addToCollectionAllowList(address user) public {287 // require(false, stub_error);288 // user;289 // dummy = 0;290 // }291292 /// Add user to allowed list.293 ///294 /// @param user User cross account address.295 /// @dev EVM selector for this function is: 0xa0184a3a,296 /// or in textual repr: addToCollectionAllowListCross((address,uint256))297 function addToCollectionAllowListCross(EthCrossAccount memory user) public {298 require(false, stub_error);299 user;300 dummy = 0;301 }302303 // /// Remove the user from the allowed list.304 // ///305 // /// @param user Address of a removed user.306 // /// @dev EVM selector for this function is: 0x85c51acb,307 // /// or in textual repr: removeFromCollectionAllowList(address)308 // function removeFromCollectionAllowList(address user) public {309 // require(false, stub_error);310 // user;311 // dummy = 0;312 // }313314 /// Remove user from allowed list.315 ///316 /// @param user User cross account address.317 /// @dev EVM selector for this function is: 0x09ba452a,318 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))319 function removeFromCollectionAllowListCross(EthCrossAccount memory user) public {320 require(false, stub_error);321 user;322 dummy = 0;323 }324325 /// Switch permission for minting.326 ///327 /// @param mode Enable if "true".328 /// @dev EVM selector for this function is: 0x00018e84,329 /// or in textual repr: setCollectionMintMode(bool)330 function setCollectionMintMode(bool mode) public {331 require(false, stub_error);332 mode;333 dummy = 0;334 }335336 // /// Check that account is the owner or admin of the collection337 // ///338 // /// @param user account to verify339 // /// @return "true" if account is the owner or admin340 // /// @dev EVM selector for this function is: 0x9811b0c7,341 // /// or in textual repr: isOwnerOrAdmin(address)342 // function isOwnerOrAdmin(address user) public view returns (bool) {343 // require(false, stub_error);344 // user;345 // dummy;346 // return false;347 // }348349 /// Check that account is the owner or admin of the collection350 ///351 /// @param user User cross account to verify352 /// @return "true" if account is the owner or admin353 /// @dev EVM selector for this function is: 0x3e75a905,354 /// or in textual repr: isOwnerOrAdminCross((address,uint256))355 function isOwnerOrAdminCross(EthCrossAccount memory user) public view returns (bool) {356 require(false, stub_error);357 user;358 dummy;359 return false;360 }361362 /// Returns collection type363 ///364 /// @return `Fungible` or `NFT` or `ReFungible`365 /// @dev EVM selector for this function is: 0xd34b55b8,366 /// or in textual repr: uniqueCollectionType()367 function uniqueCollectionType() public view returns (string memory) {368 require(false, stub_error);369 dummy;370 return "";371 }372373 /// Get collection owner.374 ///375 /// @return Tuble with sponsor address and his substrate mirror.376 /// If address is canonical then substrate mirror is zero and vice versa.377 /// @dev EVM selector for this function is: 0xdf727d3b,378 /// or in textual repr: collectionOwner()379 function collectionOwner() public view returns (EthCrossAccount memory) {380 require(false, stub_error);381 dummy;382 return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);383 }384385 // /// Changes collection owner to another account386 // ///387 // /// @dev Owner can be changed only by current owner388 // /// @param newOwner new owner account389 // /// @dev EVM selector for this function is: 0x4f53e226,390 // /// or in textual repr: changeCollectionOwner(address)391 // function changeCollectionOwner(address newOwner) public {392 // require(false, stub_error);393 // newOwner;394 // dummy = 0;395 // }396397 /// Get collection administrators398 ///399 /// @return Vector of tuples with admins address and his substrate mirror.400 /// If address is canonical then substrate mirror is zero and vice versa.401 /// @dev EVM selector for this function is: 0x5813216b,402 /// or in textual repr: collectionAdmins()403 function collectionAdmins() public view returns (EthCrossAccount[] memory) {404 require(false, stub_error);405 dummy;406 return new EthCrossAccount[](0);407 }408409 /// Changes collection owner to another account410 ///411 /// @dev Owner can be changed only by current owner412 /// @param newOwner new owner cross account413 /// @dev EVM selector for this function is: 0x6496c497,414 /// or in textual repr: changeCollectionOwnerCross((address,uint256))415 function changeCollectionOwnerCross(EthCrossAccount memory newOwner) public {416 require(false, stub_error);417 newOwner;418 dummy = 0;419 }420}421422/// @dev Cross account struct423struct EthCrossAccount {424 address eth;425 uint256 sub;426}427428/// @dev Property struct429struct Property {430 string key;431 bytes value;432}433434/// @dev the ERC-165 identifier for this interface is 0x5b7038cf435contract ERC20UniqueExtensions is Dummy, ERC165 {436 /// @notice A description for the collection.437 /// @dev EVM selector for this function is: 0x7284e416,438 /// or in textual repr: description()439 function description() public view returns (string memory) {440 require(false, stub_error);441 dummy;442 return "";443 }444445 /// @dev EVM selector for this function is: 0x0ecd0ab0,446 /// or in textual repr: approveCross((address,uint256),uint256)447 function approveCross(EthCrossAccount memory spender, uint256 amount) public returns (bool) {448 require(false, stub_error);449 spender;450 amount;451 dummy = 0;452 return false;453 }454455 // /// Burn tokens from account456 // /// @dev Function that burns an `amount` of the tokens of a given account,457 // /// deducting from the sender's allowance for said account.458 // /// @param from The account whose tokens will be burnt.459 // /// @param amount The amount that will be burnt.460 // /// @dev EVM selector for this function is: 0x79cc6790,461 // /// or in textual repr: burnFrom(address,uint256)462 // function burnFrom(address from, uint256 amount) public returns (bool) {463 // require(false, stub_error);464 // from;465 // amount;466 // dummy = 0;467 // return false;468 // }469470 /// Burn tokens from account471 /// @dev Function that burns an `amount` of the tokens of a given account,472 /// deducting from the sender's allowance for said account.473 /// @param from The account whose tokens will be burnt.474 /// @param amount The amount that will be burnt.475 /// @dev EVM selector for this function is: 0xbb2f5a58,476 /// or in textual repr: burnFromCross((address,uint256),uint256)477 function burnFromCross(EthCrossAccount memory from, uint256 amount) public returns (bool) {478 require(false, stub_error);479 from;480 amount;481 dummy = 0;482 return false;483 }484485 /// Mint tokens for multiple accounts.486 /// @param amounts array of pairs of account address and amount487 /// @dev EVM selector for this function is: 0x1acf2d55,488 /// or in textual repr: mintBulk((address,uint256)[])489 function mintBulk(Tuple8[] memory amounts) public returns (bool) {490 require(false, stub_error);491 amounts;492 dummy = 0;493 return false;494 }495496 /// @dev EVM selector for this function is: 0x2ada85ff,497 /// or in textual repr: transferCross((address,uint256),uint256)498 function transferCross(EthCrossAccount memory to, uint256 amount) public returns (bool) {499 require(false, stub_error);500 to;501 amount;502 dummy = 0;503 return false;504 }505506 /// @dev EVM selector for this function is: 0xd5cf430b,507 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)508 function transferFromCross(509 EthCrossAccount memory from,510 EthCrossAccount memory to,511 uint256 amount512 ) public returns (bool) {513 require(false, stub_error);514 from;515 to;516 amount;517 dummy = 0;518 return false;519 }520}521522/// @dev anonymous struct523struct Tuple8 {524 address field_0;525 uint256 field_1;526}527528/// @dev the ERC-165 identifier for this interface is 0x40c10f19529contract ERC20Mintable is Dummy, ERC165 {530 /// Mint tokens for `to` account.531 /// @param to account that will receive minted tokens532 /// @param amount amount of tokens to mint533 /// @dev EVM selector for this function is: 0x40c10f19,534 /// or in textual repr: mint(address,uint256)535 function mint(address to, uint256 amount) public returns (bool) {536 require(false, stub_error);537 to;538 amount;539 dummy = 0;540 return false;541 }542}543544/// @dev inlined interface545contract ERC20Events {546 event Transfer(address indexed from, address indexed to, uint256 value);547 event Approval(address indexed owner, address indexed spender, uint256 value);548}549550/// @dev the ERC-165 identifier for this interface is 0x942e8b22551contract ERC20 is Dummy, ERC165, ERC20Events {552 /// @dev EVM selector for this function is: 0x06fdde03,553 /// or in textual repr: name()554 function name() public view returns (string memory) {555 require(false, stub_error);556 dummy;557 return "";558 }559560 /// @dev EVM selector for this function is: 0x95d89b41,561 /// or in textual repr: symbol()562 function symbol() public view returns (string memory) {563 require(false, stub_error);564 dummy;565 return "";566 }567568 /// @dev EVM selector for this function is: 0x18160ddd,569 /// or in textual repr: totalSupply()570 function totalSupply() public view returns (uint256) {571 require(false, stub_error);572 dummy;573 return 0;574 }575576 /// @dev EVM selector for this function is: 0x313ce567,577 /// or in textual repr: decimals()578 function decimals() public view returns (uint8) {579 require(false, stub_error);580 dummy;581 return 0;582 }583584 /// @dev EVM selector for this function is: 0x70a08231,585 /// or in textual repr: balanceOf(address)586 function balanceOf(address owner) public view returns (uint256) {587 require(false, stub_error);588 owner;589 dummy;590 return 0;591 }592593 /// @dev EVM selector for this function is: 0xa9059cbb,594 /// or in textual repr: transfer(address,uint256)595 function transfer(address to, uint256 amount) public returns (bool) {596 require(false, stub_error);597 to;598 amount;599 dummy = 0;600 return false;601 }602603 /// @dev EVM selector for this function is: 0x23b872dd,604 /// or in textual repr: transferFrom(address,address,uint256)605 function transferFrom(606 address from,607 address to,608 uint256 amount609 ) public returns (bool) {610 require(false, stub_error);611 from;612 to;613 amount;614 dummy = 0;615 return false;616 }617618 /// @dev EVM selector for this function is: 0x095ea7b3,619 /// or in textual repr: approve(address,uint256)620 function approve(address spender, uint256 amount) public returns (bool) {621 require(false, stub_error);622 spender;623 amount;624 dummy = 0;625 return false;626 }627628 /// @dev EVM selector for this function is: 0xdd62ed3e,629 /// or in textual repr: allowance(address,address)630 function allowance(address owner, address spender) public view returns (uint256) {631 require(false, stub_error);632 owner;633 spender;634 dummy;635 return 0;636 }637}638639contract UniqueFungible is Dummy, ERC165, ERC20, ERC20Mintable, ERC20UniqueExtensions, Collection {}pallets/nonfungible/CHANGELOG.mddiffbeforeafterboth--- a/pallets/nonfungible/CHANGELOG.md
+++ b/pallets/nonfungible/CHANGELOG.md
@@ -4,6 +4,12 @@
<!-- bureaucrate goes here -->
+## [0.1.10] - 2022-11-18
+
+### Added
+
+- The functions `description`, `crossOwnerOf`, `tokenProperties` to `ERC721UniqueExtensions` interface.
+
## [0.1.9] - 2022-11-14
### Changed
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -37,7 +37,7 @@
use sp_std::vec::Vec;
use pallet_common::{
erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key},
- CollectionHandle, CollectionPropertyPermissions,
+ CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
};
use pallet_evm::{account::CrossAccountId, PrecompileHandle};
use pallet_evm_coder_substrate::call;
@@ -278,7 +278,7 @@
#[solidity_interface(name = ERC721Metadata, expect_selector = 0x5b5e139f)]
impl<T: Config> NonfungibleHandle<T>
where
- T::AccountId: From<[u8; 32]>,
+ T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
{
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev real implementation of this function lies in `ERC721UniqueExtensions`
@@ -686,7 +686,7 @@
#[solidity_interface(name = ERC721UniqueExtensions)]
impl<T: Config> NonfungibleHandle<T>
where
- T::AccountId: From<[u8; 32]>,
+ T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
{
/// @notice A descriptive name for a collection of NFTs in this contract
fn name(&self) -> Result<string> {
@@ -700,6 +700,56 @@
Ok(string::from_utf8_lossy(&self.token_prefix).into())
}
+ /// @notice A description for the collection.
+ fn description(&self) -> Result<string> {
+ Ok(decode_utf16(self.description.iter().copied())
+ .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
+ .collect::<string>())
+ }
+
+ /// Returns the owner (in cross format) of the token.
+ ///
+ /// @param tokenId Id for the token.
+ fn cross_owner_of(&self, token_id: uint256) -> Result<EthCrossAccount> {
+ Self::token_owner(&self, token_id.try_into()?)
+ .map(|o| EthCrossAccount::from_sub_cross_account::<T>(&o))
+ .ok_or(Error::Revert("key too large".into()))
+ }
+
+ /// Returns the token properties.
+ ///
+ /// @param tokenId Id for the token.
+ /// @param keys Properties keys. Empty keys for all propertyes.
+ /// @return Vector of properties key/value pairs.
+ fn token_properties(
+ &self,
+ token_id: uint256,
+ keys: Vec<string>,
+ ) -> Result<Vec<PropertyStruct>> {
+ let keys = keys
+ .into_iter()
+ .map(|key| {
+ <Vec<u8>>::from(key)
+ .try_into()
+ .map_err(|_| Error::Revert("key too large".into()))
+ })
+ .collect::<Result<Vec<_>>>()?;
+
+ <Self as CommonCollectionOperations<T>>::token_properties(
+ &self,
+ token_id.try_into()?,
+ if keys.is_empty() { None } else { Some(keys) },
+ )
+ .into_iter()
+ .map(|p| {
+ let key = string::from_utf8(p.key.to_vec())
+ .map_err(|e| Error::Revert(alloc::format!("{}", e)))?;
+ let value = bytes(p.value.to_vec());
+ Ok(PropertyStruct { key, value })
+ })
+ .collect::<Result<Vec<_>>>()
+ }
+
/// @notice Set or reaffirm the approved address for an NFT
/// @dev The zero address indicates there is no approved address.
/// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
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
@@ -188,11 +188,11 @@
/// @return Vector of properties key/value pairs.
/// @dev EVM selector for this function is: 0x285fb8e6,
/// or in textual repr: collectionProperties(string[])
- function collectionProperties(string[] memory keys) public view returns (Tuple23[] memory) {
+ function collectionProperties(string[] memory keys) public view returns (Property[] memory) {
require(false, stub_error);
keys;
dummy;
- return new Tuple23[](0);
+ return new Property[](0);
}
// /// Set the sponsor of the collection.
@@ -253,10 +253,10 @@
/// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
/// @dev EVM selector for this function is: 0x6ec0a9f1,
/// or in textual repr: collectionSponsor()
- function collectionSponsor() public view returns (Tuple26 memory) {
+ function collectionSponsor() public view returns (Tuple30 memory) {
require(false, stub_error);
dummy;
- return Tuple26(0x0000000000000000000000000000000000000000, 0);
+ return Tuple30(0x0000000000000000000000000000000000000000, 0);
}
/// Set limits for the collection.
@@ -527,17 +527,11 @@
}
/// @dev anonymous struct
-struct Tuple26 {
+struct Tuple30 {
address field_0;
uint256 field_1;
}
-/// @dev anonymous struct
-struct Tuple23 {
- string field_0;
- bytes field_1;
-}
-
/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
/// @dev the ERC-165 identifier for this interface is 0x5b5e139f
@@ -682,7 +676,7 @@
}
/// @title Unique extensions for ERC721.
-/// @dev the ERC-165 identifier for this interface is 0x0e9fc611
+/// @dev the ERC-165 identifier for this interface is 0xb8f094a0
contract ERC721UniqueExtensions is Dummy, ERC165 {
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev EVM selector for this function is: 0x06fdde03,
@@ -702,6 +696,42 @@
return "";
}
+ /// @notice A description for the collection.
+ /// @dev EVM selector for this function is: 0x7284e416,
+ /// or in textual repr: description()
+ function description() public view returns (string memory) {
+ require(false, stub_error);
+ dummy;
+ return "";
+ }
+
+ /// Returns the owner (in cross format) of the token.
+ ///
+ /// @param tokenId Id for the token.
+ /// @dev EVM selector for this function is: 0x2b29dace,
+ /// or in textual repr: crossOwnerOf(uint256)
+ function crossOwnerOf(uint256 tokenId) public view returns (EthCrossAccount memory) {
+ require(false, stub_error);
+ tokenId;
+ dummy;
+ return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);
+ }
+
+ /// Returns the token properties.
+ ///
+ /// @param tokenId Id for the token.
+ /// @param keys Properties keys. Empty keys for all propertyes.
+ /// @return Vector of properties key/value pairs.
+ /// @dev EVM selector for this function is: 0xefc26c69,
+ /// or in textual repr: tokenProperties(uint256,string[])
+ function tokenProperties(uint256 tokenId, string[] memory keys) public view returns (Property[] memory) {
+ require(false, stub_error);
+ tokenId;
+ keys;
+ dummy;
+ return new Property[](0);
+ }
+
/// @notice Set or reaffirm the approved address for an NFT
/// @dev The zero address indicates there is no approved address.
/// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
@@ -825,7 +855,7 @@
// /// @param tokens array of pairs of token ID and token URI for minted tokens
// /// @dev EVM selector for this function is: 0x36543006,
// /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])
- // function mintBulkWithTokenURI(address to, Tuple11[] memory tokens) public returns (bool) {
+ // function mintBulkWithTokenURI(address to, Tuple15[] memory tokens) public returns (bool) {
// require(false, stub_error);
// to;
// tokens;
@@ -836,7 +866,7 @@
}
/// @dev anonymous struct
-struct Tuple11 {
+struct Tuple15 {
uint256 field_0;
string field_1;
}
pallets/refungible/CHANGELOG.mddiffbeforeafterboth--- a/pallets/refungible/CHANGELOG.md
+++ b/pallets/refungible/CHANGELOG.md
@@ -4,6 +4,12 @@
<!-- bureaucrate goes here -->
+## [0.2.9] - 2022-11-18
+
+### Added
+
+- The functions `description`, `crossOwnerOf`, `tokenProperties` to `ERC721UniqueExtensions` interface.
+
## [0.2.8] - 2022-11-14
### Changed
pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -33,6 +33,7 @@
use pallet_common::{
CollectionHandle, CollectionPropertyPermissions,
erc::{CommonEvmHandler, CollectionCall, static_property::key},
+ CommonCollectionOperations,
};
use pallet_evm::{account::CrossAccountId, PrecompileHandle};
use pallet_evm_coder_substrate::{call, dispatch_to_evm};
@@ -273,7 +274,7 @@
#[solidity_interface(name = ERC721Metadata)]
impl<T: Config> RefungibleHandle<T>
where
- T::AccountId: From<[u8; 32]>,
+ T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
{
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev real implementation of this function lies in `ERC721UniqueExtensions`
@@ -713,7 +714,7 @@
#[solidity_interface(name = ERC721UniqueExtensions)]
impl<T: Config> RefungibleHandle<T>
where
- T::AccountId: From<[u8; 32]>,
+ T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
{
/// @notice A descriptive name for a collection of NFTs in this contract
fn name(&self) -> Result<string> {
@@ -727,6 +728,55 @@
Ok(string::from_utf8_lossy(&self.token_prefix).into())
}
+ /// @notice A description for the collection.
+ fn description(&self) -> Result<string> {
+ Ok(decode_utf16(self.description.iter().copied())
+ .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
+ .collect::<string>())
+ }
+
+ /// Returns the owner (in cross format) of the token.
+ ///
+ /// @param tokenId Id for the token.
+ fn cross_owner_of(&self, token_id: uint256) -> Result<EthCrossAccount> {
+ Self::token_owner(&self, token_id.try_into()?)
+ .map(|o| EthCrossAccount::from_sub_cross_account::<T>(&o))
+ .ok_or(Error::Revert("key too large".into()))
+ }
+
+ /// Returns the token properties.
+ ///
+ /// @param tokenId Id for the token.
+ /// @param keys Properties keys. Empty keys for all propertyes.
+ /// @return Vector of properties key/value pairs.
+ fn token_properties(
+ &self,
+ token_id: uint256,
+ keys: Vec<string>,
+ ) -> Result<Vec<PropertyStruct>> {
+ let keys = keys
+ .into_iter()
+ .map(|key| {
+ <Vec<u8>>::from(key)
+ .try_into()
+ .map_err(|_| Error::Revert("key too large".into()))
+ })
+ .collect::<Result<Vec<_>>>()?;
+
+ <Self as CommonCollectionOperations<T>>::token_properties(
+ &self,
+ token_id.try_into()?,
+ if keys.is_empty() { None } else { Some(keys) },
+ )
+ .into_iter()
+ .map(|p| {
+ let key = string::from_utf8(p.key.to_vec())
+ .map_err(|e| Error::Revert(alloc::format!("{}", e)))?;
+ let value = bytes(p.value.to_vec());
+ Ok(PropertyStruct { key, value })
+ })
+ .collect::<Result<Vec<_>>>()
+ }
/// @notice Transfer ownership of an RFT
/// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
/// is the zero address. Throws if `tokenId` is not a valid RFT.
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
@@ -188,11 +188,11 @@
/// @return Vector of properties key/value pairs.
/// @dev EVM selector for this function is: 0x285fb8e6,
/// or in textual repr: collectionProperties(string[])
- function collectionProperties(string[] memory keys) public view returns (Tuple22[] memory) {
+ function collectionProperties(string[] memory keys) public view returns (Property[] memory) {
require(false, stub_error);
keys;
dummy;
- return new Tuple22[](0);
+ return new Property[](0);
}
// /// Set the sponsor of the collection.
@@ -253,10 +253,10 @@
/// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
/// @dev EVM selector for this function is: 0x6ec0a9f1,
/// or in textual repr: collectionSponsor()
- function collectionSponsor() public view returns (Tuple25 memory) {
+ function collectionSponsor() public view returns (Tuple29 memory) {
require(false, stub_error);
dummy;
- return Tuple25(0x0000000000000000000000000000000000000000, 0);
+ return Tuple29(0x0000000000000000000000000000000000000000, 0);
}
/// Set limits for the collection.
@@ -527,17 +527,11 @@
}
/// @dev anonymous struct
-struct Tuple25 {
+struct Tuple29 {
address field_0;
uint256 field_1;
}
-/// @dev anonymous struct
-struct Tuple22 {
- string field_0;
- bytes field_1;
-}
-
/// @dev the ERC-165 identifier for this interface is 0x5b5e139f
contract ERC721Metadata is Dummy, ERC165 {
// /// @notice A descriptive name for a collection of NFTs in this contract
@@ -680,7 +674,7 @@
}
/// @title Unique extensions for ERC721.
-/// @dev the ERC-165 identifier for this interface is 0xab243667
+/// @dev the ERC-165 identifier for this interface is 0x1d4b64d6
contract ERC721UniqueExtensions is Dummy, ERC165 {
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev EVM selector for this function is: 0x06fdde03,
@@ -700,6 +694,42 @@
return "";
}
+ /// @notice A description for the collection.
+ /// @dev EVM selector for this function is: 0x7284e416,
+ /// or in textual repr: description()
+ function description() public view returns (string memory) {
+ require(false, stub_error);
+ dummy;
+ return "";
+ }
+
+ /// Returns the owner (in cross format) of the token.
+ ///
+ /// @param tokenId Id for the token.
+ /// @dev EVM selector for this function is: 0x2b29dace,
+ /// or in textual repr: crossOwnerOf(uint256)
+ function crossOwnerOf(uint256 tokenId) public view returns (EthCrossAccount memory) {
+ require(false, stub_error);
+ tokenId;
+ dummy;
+ return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);
+ }
+
+ /// Returns the token properties.
+ ///
+ /// @param tokenId Id for the token.
+ /// @param keys Properties keys. Empty keys for all propertyes.
+ /// @return Vector of properties key/value pairs.
+ /// @dev EVM selector for this function is: 0xefc26c69,
+ /// or in textual repr: tokenProperties(uint256,string[])
+ function tokenProperties(uint256 tokenId, string[] memory keys) public view returns (Property[] memory) {
+ require(false, stub_error);
+ tokenId;
+ keys;
+ dummy;
+ return new Property[](0);
+ }
+
/// @notice Transfer ownership of an RFT
/// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
/// is the zero address. Throws if `tokenId` is not a valid RFT.
@@ -813,7 +843,7 @@
// /// @param tokens array of pairs of token ID and token URI for minted tokens
// /// @dev EVM selector for this function is: 0x36543006,
// /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])
- // function mintBulkWithTokenURI(address to, Tuple10[] memory tokens) public returns (bool) {
+ // function mintBulkWithTokenURI(address to, Tuple14[] memory tokens) public returns (bool) {
// require(false, stub_error);
// to;
// tokens;
@@ -835,7 +865,7 @@
}
/// @dev anonymous struct
-struct Tuple10 {
+struct Tuple14 {
uint256 field_0;
string field_1;
}
pallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterbothbinary blob — no preview
pallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterbothbinary blob — no preview
tests/src/eth/abi/fungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/fungible.json
+++ b/tests/src/eth/abi/fungible.json
@@ -216,10 +216,10 @@
"outputs": [
{
"components": [
- { "internalType": "string", "name": "field_0", "type": "string" },
- { "internalType": "bytes", "name": "field_1", "type": "bytes" }
+ { "internalType": "string", "name": "key", "type": "string" },
+ { "internalType": "bytes", "name": "value", "type": "bytes" }
],
- "internalType": "struct Tuple16[]",
+ "internalType": "struct Property[]",
"name": "",
"type": "tuple[]"
}
@@ -283,6 +283,13 @@
},
{
"inputs": [],
+ "name": "description",
+ "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
"name": "hasCollectionPendingSponsor",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
tests/src/eth/abi/nonFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/nonFungible.json
+++ b/tests/src/eth/abi/nonFungible.json
@@ -246,10 +246,10 @@
"outputs": [
{
"components": [
- { "internalType": "string", "name": "field_0", "type": "string" },
- { "internalType": "bytes", "name": "field_1", "type": "bytes" }
+ { "internalType": "string", "name": "key", "type": "string" },
+ { "internalType": "bytes", "name": "value", "type": "bytes" }
],
- "internalType": "struct Tuple23[]",
+ "internalType": "struct Property[]",
"name": "",
"type": "tuple[]"
}
@@ -273,7 +273,7 @@
{ "internalType": "address", "name": "field_0", "type": "address" },
{ "internalType": "uint256", "name": "field_1", "type": "uint256" }
],
- "internalType": "struct Tuple26",
+ "internalType": "struct Tuple30",
"name": "",
"type": "tuple"
}
@@ -297,6 +297,25 @@
},
{
"inputs": [
+ { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
+ ],
+ "name": "crossOwnerOf",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "eth", "type": "address" },
+ { "internalType": "uint256", "name": "sub", "type": "uint256" }
+ ],
+ "internalType": "struct EthCrossAccount",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "string[]", "name": "keys", "type": "string[]" }
],
"name": "deleteCollectionProperties",
@@ -316,6 +335,13 @@
},
{
"inputs": [],
+ "name": "description",
+ "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
"name": "finishMinting",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "nonpayable",
@@ -641,6 +667,26 @@
},
{
"inputs": [
+ { "internalType": "uint256", "name": "tokenId", "type": "uint256" },
+ { "internalType": "string[]", "name": "keys", "type": "string[]" }
+ ],
+ "name": "tokenProperties",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "string", "name": "key", "type": "string" },
+ { "internalType": "bytes", "name": "value", "type": "bytes" }
+ ],
+ "internalType": "struct Property[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "uint256", "name": "tokenId", "type": "uint256" }
],
"name": "tokenURI",
tests/src/eth/abi/reFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -228,10 +228,10 @@
"outputs": [
{
"components": [
- { "internalType": "string", "name": "field_0", "type": "string" },
- { "internalType": "bytes", "name": "field_1", "type": "bytes" }
+ { "internalType": "string", "name": "key", "type": "string" },
+ { "internalType": "bytes", "name": "value", "type": "bytes" }
],
- "internalType": "struct Tuple22[]",
+ "internalType": "struct Property[]",
"name": "",
"type": "tuple[]"
}
@@ -255,7 +255,7 @@
{ "internalType": "address", "name": "field_0", "type": "address" },
{ "internalType": "uint256", "name": "field_1", "type": "uint256" }
],
- "internalType": "struct Tuple25",
+ "internalType": "struct Tuple29",
"name": "",
"type": "tuple"
}
@@ -279,6 +279,25 @@
},
{
"inputs": [
+ { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
+ ],
+ "name": "crossOwnerOf",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "eth", "type": "address" },
+ { "internalType": "uint256", "name": "sub", "type": "uint256" }
+ ],
+ "internalType": "struct EthCrossAccount",
+ "name": "",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "string[]", "name": "keys", "type": "string[]" }
],
"name": "deleteCollectionProperties",
@@ -298,6 +317,13 @@
},
{
"inputs": [],
+ "name": "description",
+ "outputs": [{ "internalType": "string", "name": "", "type": "string" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
"name": "finishMinting",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "nonpayable",
@@ -632,6 +658,26 @@
},
{
"inputs": [
+ { "internalType": "uint256", "name": "tokenId", "type": "uint256" },
+ { "internalType": "string[]", "name": "keys", "type": "string[]" }
+ ],
+ "name": "tokenProperties",
+ "outputs": [
+ {
+ "components": [
+ { "internalType": "string", "name": "key", "type": "string" },
+ { "internalType": "bytes", "name": "value", "type": "bytes" }
+ ],
+ "internalType": "struct Property[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "uint256", "name": "tokenId", "type": "uint256" }
],
"name": "tokenURI",
tests/src/eth/api/UniqueFungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -60,7 +60,7 @@
/// @return Vector of properties key/value pairs.
/// @dev EVM selector for this function is: 0x285fb8e6,
/// or in textual repr: collectionProperties(string[])
- function collectionProperties(string[] memory keys) external view returns (Tuple16[] memory);
+ function collectionProperties(string[] memory keys) external view returns (Property[] memory);
// /// Set the sponsor of the collection.
// ///
@@ -276,12 +276,6 @@
struct EthCrossAccount {
address eth;
uint256 sub;
-}
-
-/// @dev anonymous struct
-struct Tuple16 {
- string field_0;
- bytes field_1;
}
/// @dev Property struct
@@ -290,8 +284,13 @@
bytes value;
}
-/// @dev the ERC-165 identifier for this interface is 0x29f4dcd9
+/// @dev the ERC-165 identifier for this interface is 0x5b7038cf
interface ERC20UniqueExtensions is Dummy, ERC165 {
+ /// @notice A description for the collection.
+ /// @dev EVM selector for this function is: 0x7284e416,
+ /// or in textual repr: description()
+ function description() external view returns (string memory);
+
/// @dev EVM selector for this function is: 0x0ecd0ab0,
/// or in textual repr: approveCross((address,uint256),uint256)
function approveCross(EthCrossAccount memory spender, uint256 amount) external returns (bool);
tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -127,7 +127,7 @@
/// @return Vector of properties key/value pairs.
/// @dev EVM selector for this function is: 0x285fb8e6,
/// or in textual repr: collectionProperties(string[])
- function collectionProperties(string[] memory keys) external view returns (Tuple23[] memory);
+ function collectionProperties(string[] memory keys) external view returns (Property[] memory);
// /// Set the sponsor of the collection.
// ///
@@ -169,7 +169,7 @@
/// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
/// @dev EVM selector for this function is: 0x6ec0a9f1,
/// or in textual repr: collectionSponsor()
- function collectionSponsor() external view returns (Tuple26 memory);
+ function collectionSponsor() external view returns (Tuple27 memory);
/// Set limits for the collection.
/// @dev Throws error if limit not found.
@@ -346,15 +346,9 @@
}
/// @dev anonymous struct
-struct Tuple26 {
+struct Tuple27 {
address field_0;
uint256 field_1;
-}
-
-/// @dev anonymous struct
-struct Tuple23 {
- string field_0;
- bytes field_1;
}
/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
@@ -452,7 +446,7 @@
}
/// @title Unique extensions for ERC721.
-/// @dev the ERC-165 identifier for this interface is 0x0e9fc611
+/// @dev the ERC-165 identifier for this interface is 0xb8f094a0
interface ERC721UniqueExtensions is Dummy, ERC165 {
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev EVM selector for this function is: 0x06fdde03,
@@ -464,6 +458,27 @@
/// or in textual repr: symbol()
function symbol() external view returns (string memory);
+ /// @notice A description for the collection.
+ /// @dev EVM selector for this function is: 0x7284e416,
+ /// or in textual repr: description()
+ function description() external view returns (string memory);
+
+ /// Returns the owner (in cross format) of the token.
+ ///
+ /// @param tokenId Id for the token.
+ /// @dev EVM selector for this function is: 0x2b29dace,
+ /// or in textual repr: crossOwnerOf(uint256)
+ function crossOwnerOf(uint256 tokenId) external view returns (EthCrossAccount memory);
+
+ /// Returns the token properties.
+ ///
+ /// @param tokenId Id for the token.
+ /// @param keys Properties keys. Empty keys for all propertyes.
+ /// @return Vector of properties key/value pairs.
+ /// @dev EVM selector for this function is: 0xefc26c69,
+ /// or in textual repr: tokenProperties(uint256,string[])
+ function tokenProperties(uint256 tokenId, string[] memory keys) external view returns (Property[] memory);
+
/// @notice Set or reaffirm the approved address for an NFT
/// @dev The zero address indicates there is no approved address.
/// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
@@ -546,12 +561,12 @@
// /// @param tokens array of pairs of token ID and token URI for minted tokens
// /// @dev EVM selector for this function is: 0x36543006,
// /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])
- // function mintBulkWithTokenURI(address to, Tuple11[] memory tokens) external returns (bool);
+ // function mintBulkWithTokenURI(address to, Tuple13[] memory tokens) external returns (bool);
}
/// @dev anonymous struct
-struct Tuple11 {
+struct Tuple13 {
uint256 field_0;
string field_1;
}
tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -127,7 +127,7 @@
/// @return Vector of properties key/value pairs.
/// @dev EVM selector for this function is: 0x285fb8e6,
/// or in textual repr: collectionProperties(string[])
- function collectionProperties(string[] memory keys) external view returns (Tuple22[] memory);
+ function collectionProperties(string[] memory keys) external view returns (Property[] memory);
// /// Set the sponsor of the collection.
// ///
@@ -169,7 +169,7 @@
/// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
/// @dev EVM selector for this function is: 0x6ec0a9f1,
/// or in textual repr: collectionSponsor()
- function collectionSponsor() external view returns (Tuple25 memory);
+ function collectionSponsor() external view returns (Tuple26 memory);
/// Set limits for the collection.
/// @dev Throws error if limit not found.
@@ -346,15 +346,9 @@
}
/// @dev anonymous struct
-struct Tuple25 {
+struct Tuple26 {
address field_0;
uint256 field_1;
-}
-
-/// @dev anonymous struct
-struct Tuple22 {
- string field_0;
- bytes field_1;
}
/// @dev the ERC-165 identifier for this interface is 0x5b5e139f
@@ -450,7 +444,7 @@
}
/// @title Unique extensions for ERC721.
-/// @dev the ERC-165 identifier for this interface is 0xab243667
+/// @dev the ERC-165 identifier for this interface is 0x1d4b64d6
interface ERC721UniqueExtensions is Dummy, ERC165 {
/// @notice A descriptive name for a collection of NFTs in this contract
/// @dev EVM selector for this function is: 0x06fdde03,
@@ -462,6 +456,27 @@
/// or in textual repr: symbol()
function symbol() external view returns (string memory);
+ /// @notice A description for the collection.
+ /// @dev EVM selector for this function is: 0x7284e416,
+ /// or in textual repr: description()
+ function description() external view returns (string memory);
+
+ /// Returns the owner (in cross format) of the token.
+ ///
+ /// @param tokenId Id for the token.
+ /// @dev EVM selector for this function is: 0x2b29dace,
+ /// or in textual repr: crossOwnerOf(uint256)
+ function crossOwnerOf(uint256 tokenId) external view returns (EthCrossAccount memory);
+
+ /// Returns the token properties.
+ ///
+ /// @param tokenId Id for the token.
+ /// @param keys Properties keys. Empty keys for all propertyes.
+ /// @return Vector of properties key/value pairs.
+ /// @dev EVM selector for this function is: 0xefc26c69,
+ /// or in textual repr: tokenProperties(uint256,string[])
+ function tokenProperties(uint256 tokenId, string[] memory keys) external view returns (Property[] memory);
+
/// @notice Transfer ownership of an RFT
/// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
/// is the zero address. Throws if `tokenId` is not a valid RFT.
@@ -539,7 +554,7 @@
// /// @param tokens array of pairs of token ID and token URI for minted tokens
// /// @dev EVM selector for this function is: 0x36543006,
// /// or in textual repr: mintBulkWithTokenURI(address,(uint256,string)[])
- // function mintBulkWithTokenURI(address to, Tuple10[] memory tokens) external returns (bool);
+ // function mintBulkWithTokenURI(address to, Tuple12[] memory tokens) external returns (bool);
/// Returns EVM address for refungible token
///
@@ -550,7 +565,7 @@
}
/// @dev anonymous struct
-struct Tuple10 {
+struct Tuple12 {
uint256 field_0;
string field_1;
}
tests/src/eth/base.test.tsdiffbeforeafterboth--- a/tests/src/eth/base.test.ts
+++ b/tests/src/eth/base.test.ts
@@ -117,7 +117,7 @@
});
itEth('ERC721UniqueExtensions support', async ({helper}) => {
- await checkInterface(helper, '0x0e9fc611', true, true);
+ await checkInterface(helper, '0xb8f094a0', true, true);
});
itEth('ERC721Burnable - 0x42966c68 - support', async ({helper}) => {
tests/src/eth/createFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createFTCollection.test.ts
+++ b/tests/src/eth/createFTCollection.test.ts
@@ -36,9 +36,11 @@
const owner = await helper.eth.createAccountWithBalance(donor);
const sponsor = await helper.eth.createAccountWithBalance(donor);
const ss58Format = helper.chain.getChainProperties().ss58Format;
- const {collectionId, collectionAddress} = await helper.eth.createFungibleCollection(owner, 'Sponsor', DECIMALS, 'absolutely anything', 'ENVY');
+ const description = 'absolutely anything';
+
+ const {collectionId, collectionAddress} = await helper.eth.createFungibleCollection(owner, 'Sponsor', DECIMALS, description, 'ENVY');
- const collection = helper.ethNativeContract.collection(collectionAddress, 'rft', owner, true);
+ const collection = helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);
await collection.methods.setCollectionSponsor(sponsor).send();
let data = (await helper.rft.getData(collectionId))!;
@@ -57,8 +59,9 @@
const owner = await helper.eth.createAccountWithBalance(donor);
const sponsor = await helper.eth.createAccountWithBalance(donor);
const ss58Format = helper.chain.getChainProperties().ss58Format;
- const {collectionId, collectionAddress} = await helper.eth.createFungibleCollection(owner, 'Sponsor', DECIMALS, 'absolutely anything', 'ENVY');
-
+ const description = 'absolutely anything';
+ const {collectionId, collectionAddress} = await helper.eth.createFungibleCollection(owner, 'Sponsor', DECIMALS, description, 'ENVY');
+
const collection = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
await collection.methods.setCollectionSponsorCross(sponsorCross).send();
@@ -73,6 +76,7 @@
data = (await helper.rft.getData(collectionId))!;
expect(data.raw.sponsorship.Confirmed).to.be.equal(evmToAddress(sponsor, Number(ss58Format)));
+ expect(await collection.methods.description().call()).to.deep.equal(description);
});
itEth('Set limits', async ({helper}) => {
tests/src/eth/createNFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createNFTCollection.test.ts
+++ b/tests/src/eth/createNFTCollection.test.ts
@@ -28,7 +28,7 @@
});
});
- itEth('Create collection with properties', async ({helper}) => {
+ itEth('Create collection with properties & get desctription', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const name = 'CollectionEVM';
@@ -37,7 +37,8 @@
const baseUri = 'BaseURI';
const {collectionId, collectionAddress, events} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, name, description, prefix, baseUri);
-
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');
+
expect(events).to.be.deep.equal([
{
address: '0x6C4E9fE1AE37a41E93CEE429e8E1881aBdcbb54F',
@@ -56,7 +57,9 @@
expect(data.description).to.be.eq(description);
expect(data.raw.tokenPrefix).to.be.eq(prefix);
expect(data.raw.mode).to.be.eq('NFT');
-
+
+ expect(await contract.methods.description().call()).to.deep.equal(description);
+
const options = await collection.getOptions();
expect(options.tokenPropertyPermissions).to.be.deep.equal([
{
@@ -92,11 +95,12 @@
expect(data.raw.sponsorship.Confirmed).to.be.equal(evmToAddress(sponsor, Number(ss58Format)));
});
- itEth('[cross] Set sponsorship', async ({helper}) => {
+ itEth('[cross] Set sponsorship & get description', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const sponsor = await helper.eth.createAccountWithBalance(donor);
const ss58Format = helper.chain.getChainProperties().ss58Format;
- const {collectionId, collectionAddress} = await helper.eth.createNFTCollection(owner, 'Sponsor', 'absolutely anything', 'ROC');
+ const description = 'absolutely anything';
+ const {collectionId, collectionAddress} = await helper.eth.createNFTCollection(owner, 'Sponsor', description, 'ROC');
const collection = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
@@ -112,6 +116,8 @@
data = (await helper.nft.getData(collectionId))!;
expect(data.raw.sponsorship.Confirmed).to.be.equal(evmToAddress(sponsor, Number(ss58Format)));
+
+ expect(await sponsorCollection.methods.description().call()).to.deep.equal(description);
});
itEth('Set limits', async ({helper}) => {
tests/src/eth/createRFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createRFTCollection.test.ts
+++ b/tests/src/eth/createRFTCollection.test.ts
@@ -53,7 +53,7 @@
- itEth('Create collection with properties', async ({helper}) => {
+ itEth('Create collection with properties & get description', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const name = 'CollectionEVM';
@@ -61,7 +61,8 @@
const prefix = 'token prefix';
const baseUri = 'BaseURI';
- const {collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, name, description, prefix, baseUri);
+ const {collectionId, collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, name, description, prefix, baseUri);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');
const collection = helper.rft.getCollectionObject(collectionId);
const data = (await collection.getData())!;
@@ -71,6 +72,8 @@
expect(data.raw.tokenPrefix).to.be.eq(prefix);
expect(data.raw.mode).to.be.eq('ReFungible');
+ expect(await contract.methods.description().call()).to.deep.equal(description);
+
const options = await collection.getOptions();
expect(options.tokenPropertyPermissions).to.be.deep.equal([
{
tests/src/eth/nonFungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/nonFungible.test.ts
+++ b/tests/src/eth/nonFungible.test.ts
@@ -17,6 +17,7 @@
import {itEth, usingEthPlaygrounds, expect, EthUniqueHelper} from './util';
import {IKeyringPair} from '@polkadot/types/types';
import {Contract} from 'web3-eth-contract';
+import exp from 'constants';
describe('NFT: Information getting', () => {
@@ -149,7 +150,7 @@
});
});
- itEth('Can perform mint()', async ({helper}) => {
+ itEth('Can perform mint() & get crossOwner()', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const receiver = helper.eth.createAccount();
@@ -166,7 +167,8 @@
expect(event.returnValues.to).to.be.equal(receiver);
expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
-
+ console.log(await contract.methods.crossOwnerOf(tokenId).call());
+ expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
// TODO: this wont work right now, need release 919000 first
// await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send();
// const tokenUri = await contract.methods.tokenURI(nextTokenId).call();
tests/src/eth/reFungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/reFungible.test.ts
+++ b/tests/src/eth/reFungible.test.ts
@@ -117,7 +117,7 @@
});
});
- itEth('Can perform mint()', async ({helper}) => {
+ itEth('Can perform mint() & crossOwnerOf()', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const receiver = helper.eth.createAccount();
const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Minty', '6', '6', '');
@@ -132,6 +132,7 @@
const tokenId = event.returnValues.tokenId;
expect(tokenId).to.be.equal('1');
+ expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);
expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
});
tests/src/eth/tokenProperties.test.tsdiffbeforeafterboth--- a/tests/src/eth/tokenProperties.test.ts
+++ b/tests/src/eth/tokenProperties.test.ts
@@ -14,10 +14,11 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-import {itEth, usingEthPlaygrounds, expect} from './util';
+import {itEth, usingEthPlaygrounds, expect, EthUniqueHelper} from './util';
import {IKeyringPair} from '@polkadot/types/types';
-import {ITokenPropertyPermission} from '../util/playgrounds/types';
+import {ITokenPropertyPermission, TCollectionMode} from '../util/playgrounds/types';
import {Pallets} from '../util';
+import {UniqueNFTCollection, UniqueRFTCollection} from '../util/playgrounds/unique';
describe('EVM token properties', () => {
let donor: IKeyringPair;
@@ -95,7 +96,7 @@
expect(value).to.equal('testValue');
});
- itEth('Can be multiple set for NFT ', async({helper}) => {
+ async function checkProps(helper: EthUniqueHelper, mode: TCollectionMode) {
const caller = await helper.eth.createAccountWithBalance(donor);
const properties = Array(5).fill(0).map((_, i) => { return {key: `key_${i}`, value: Buffer.from(`value_${i}`)}; });
@@ -103,56 +104,44 @@
collectionAdmin: true,
mutable: true}}; });
- const collection = await helper.nft.mintCollection(alice, {
+ const collection = await helper[mode].mintCollection(alice, {
tokenPrefix: 'ethp',
tokenPropertyPermissions: permissions,
- });
+ }) as UniqueNFTCollection | UniqueRFTCollection;
const token = await collection.mintToken(alice);
const valuesBefore = await token.getProperties(properties.map(p => p.key));
expect(valuesBefore).to.be.deep.equal([]);
+
await collection.addAdmin(alice, {Ethereum: caller});
-
+
const address = helper.ethAddress.fromCollectionId(collection.collectionId);
- const contract = helper.ethNativeContract.collection(address, 'nft', caller);
+ const contract = helper.ethNativeContract.collection(address, mode, caller);
+
+ expect(await contract.methods.tokenProperties(token.tokenId, []).call()).to.be.deep.equal([]);
await contract.methods.setProperties(token.tokenId, properties).send({from: caller});
const values = await token.getProperties(properties.map(p => p.key));
expect(values).to.be.deep.equal(properties.map(p => { return {key: p.key, value: p.value.toString()}; }));
- });
-
- itEth.ifWithPallets('Can be multiple set for RFT ', [Pallets.ReFungible], async({helper}) => {
- const caller = await helper.eth.createAccountWithBalance(donor);
- const properties = Array(5).fill(0).map((_, i) => { return {key: `key_${i}`, value: Buffer.from(`value_${i}`)}; });
- const permissions: ITokenPropertyPermission[] = properties.map(p => { return {key: p.key, permission: {tokenOwner: true,
- collectionAdmin: true,
- mutable: true}}; });
-
- const collection = await helper.rft.mintCollection(alice, {
- tokenPrefix: 'ethp',
- tokenPropertyPermissions: permissions,
- });
-
- const token = await collection.mintToken(alice);
-
- const valuesBefore = await token.getProperties(properties.map(p => p.key));
- expect(valuesBefore).to.be.deep.equal([]);
+ expect(await contract.methods.tokenProperties(token.tokenId, []).call()).to.be.like(properties
+ .map(p => { return helper.ethProperty.property(p.key, p.value.toString()); }));
- await collection.addAdmin(alice, {Ethereum: caller});
-
- const address = helper.ethAddress.fromCollectionId(collection.collectionId);
- const contract = helper.ethNativeContract.collection(address, 'rft', caller);
-
- await contract.methods.setProperties(token.tokenId, properties).send({from: caller});
-
- const values = await token.getProperties(properties.map(p => p.key));
- expect(values).to.be.deep.equal(properties.map(p => { return {key: p.key, value: p.value.toString()}; }));
+ expect(await contract.methods.tokenProperties(token.tokenId, [properties[0].key]).call())
+ .to.be.like([helper.ethProperty.property(properties[0].key, properties[0].value.toString())]);
+ }
+
+ itEth('Can be multiple set/read for NFT ', async({helper}) => {
+ await checkProps(helper, 'nft');
+ });
+
+ itEth.ifWithPallets('Can be multiple set/read for RFT ', [Pallets.ReFungible], async({helper}) => {
+ await checkProps(helper, 'rft');
});
-
+
itEth('Can be deleted', async({helper}) => {
const caller = await helper.eth.createAccountWithBalance(donor);
const collection = await helper.nft.mintCollection(alice, {