difftreelog
feat(refungible-pallet) ERC 1633 implementation and `set_parent_nft` method
in: master
30 files changed
pallets/common/src/erc.rsdiffbeforeafterboth25use pallet_evm_coder_substrate::dispatch_to_evm;25use pallet_evm_coder_substrate::dispatch_to_evm;26use sp_std::vec::Vec;26use sp_std::vec::Vec;27use up_data_structs::{27use up_data_structs::{28 Property, SponsoringRateLimit, OwnerRestrictedSet, AccessMode, CollectionPermissions,28 AccessMode, CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property,29 SponsoringRateLimit,29};30};30use alloc::format;31use alloc::format;3132409 save(self)410 save(self)410 }411 }412413 /// Check that account is the owner or admin of the collection414 ///415 /// @return "true" if account is the owner or admin416 fn verify_owner_or_admin(&mut self, caller: caller) -> Result<bool> {417 Ok(check_is_owner_or_admin(caller, self)418 .map(|_| true)419 .unwrap_or(false))420 }421422 /// Returns collection type423 ///424 /// @return `Fungible` or `NFT` or `ReFungible`425 fn unique_collection_type(&mut self) -> Result<string> {426 let mode = match self.collection.mode {427 CollectionMode::Fungible(_) => "Fungible",428 CollectionMode::NFT => "NFT",429 CollectionMode::ReFungible => "ReFungible",430 };431 Ok(mode.into())432 }411}433}412434413fn check_is_owner_or_admin<T: Config>(435fn check_is_owner_or_admin<T: Config>(463 property_key_from_bytes(b"suffix").expect(EXPECT_CONVERT_ERROR)485 property_key_from_bytes(b"suffix").expect(EXPECT_CONVERT_ERROR)464 }486 }487488 /// Key "parentNft".489 pub fn parent_nft() -> up_data_structs::PropertyKey {490 property_key_from_bytes(b"parentNft").expect(EXPECT_CONVERT_ERROR)491 }465 }492 }466493467 /// Values.494 /// Values.pallets/common/src/lib.rsdiffbeforeafterboth1111 collection: &CollectionHandle<T>,1111 collection: &CollectionHandle<T>,1112 sender: &T::CrossAccountId,1112 sender: &T::CrossAccountId,1113 property_permission: PropertyKeyPermission,1113 property_permission: PropertyKeyPermission,1114 ) -> DispatchResult {1114 ) -> DispatchResult {1115 Self::set_scoped_property_permission(1116 collection,1117 sender,1118 PropertyScope::None,1119 property_permission,1120 )1121 }11221123 /// Set collection property permission with scope.1124 ///1125 /// * `collection` - Collection handler.1126 /// * `sender` - The owner or administrator of the collection.1127 /// * `scope` - Property scope.1128 /// * `property_permission` - Property permission.1129 pub fn set_scoped_property_permission(1130 collection: &CollectionHandle<T>,1131 sender: &T::CrossAccountId,1132 scope: PropertyScope,1133 property_permission: PropertyKeyPermission,1134 ) -> DispatchResult {1115 collection.check_is_owner_or_admin(sender)?;1135 collection.check_is_owner_or_admin(sender)?;111611361117 let all_permissions = CollectionPropertyPermissions::<T>::get(collection.id);1137 let all_permissions = CollectionPropertyPermissions::<T>::get(collection.id);112511451126 CollectionPropertyPermissions::<T>::try_mutate(collection.id, |permissions| {1146 CollectionPropertyPermissions::<T>::try_mutate(collection.id, |permissions| {1127 let property_permission = property_permission.clone();1147 let property_permission = property_permission.clone();1128 permissions.try_set(property_permission.key, property_permission.permission)1148 permissions.try_scoped_set(1149 scope,1150 property_permission.key,1151 property_permission.permission,1152 )1129 })1153 })1130 .map_err(<Error<T>>::from)?;1154 .map_err(<Error<T>>::from)?;1147 collection: &CollectionHandle<T>,1171 collection: &CollectionHandle<T>,1148 sender: &T::CrossAccountId,1172 sender: &T::CrossAccountId,1149 property_permissions: Vec<PropertyKeyPermission>,1173 property_permissions: Vec<PropertyKeyPermission>,1150 ) -> DispatchResult {1174 ) -> DispatchResult {1175 Self::set_scoped_token_property_permissions(1176 collection,1177 sender,1178 PropertyScope::None,1179 property_permissions,1180 )1181 }11821183 /// Set token property permission with scope.1184 ///1185 /// * `collection` - Collection handler.1186 /// * `sender` - The owner or administrator of the collection.1187 /// * `scope` - Property scope.1188 /// * `property_permissions` - Property permissions.1189 #[transactional]1190 pub fn set_scoped_token_property_permissions(1191 collection: &CollectionHandle<T>,1192 sender: &T::CrossAccountId,1193 scope: PropertyScope,1194 property_permissions: Vec<PropertyKeyPermission>,1195 ) -> DispatchResult {1151 for prop_pemission in property_permissions {1196 for prop_pemission in property_permissions {1152 Self::set_property_permission(collection, sender, prop_pemission)?;1197 Self::set_scoped_property_permission(collection, sender, scope, prop_pemission)?;1153 }1198 }115411991155 Ok(())1200 Ok(())1430 .saturating_add(Self::burn_recursively_breadth_raw(max_breadth))1475 .saturating_add(Self::burn_recursively_breadth_raw(max_breadth))1431 }1476 }14771478 /// The price of retrieving token owner1479 fn token_owner() -> Weight;1432}1480}143314811434/// Weight info extension trait for refungible pallet.1482/// Weight info extension trait for refungible pallet.1567 ///1615 ///1568 /// * `sender` - Must be either the owner of the token or its admin.1616 /// * `sender` - Must be either the owner of the token or its admin.1569 /// * `token_id` - The token for which the properties are being set.1617 /// * `token_id` - The token for which the properties are being set.1570 /// * `properties` - Properties to be set.1618 /// * `property_permissions` - Property permissions to be set.1571 /// * `budget` - Budget for setting properties.1619 /// * `budget` - Budget for setting properties.1572 fn set_token_property_permissions(1620 fn set_token_property_permissions(1573 &self,1621 &self,pallets/fungible/src/common.rsdiffbeforeafterboth104 0104 0105 }105 }106107 fn token_owner() -> Weight {108 0109 }106}110}107111108/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallete112/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Palletepallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth43 }43 }44}44}4546// Selector: 7d9262e647contract Collection is Dummy, ERC165 {48 // Set collection property.49 //50 // @param key Property key.51 // @param value Propery value.52 //53 // Selector: setCollectionProperty(string,bytes) 2f073f6654 function setCollectionProperty(string memory key, bytes memory value)55 public56 {57 require(false, stub_error);58 key;59 value;60 dummy = 0;61 }6263 // Delete collection property.64 //65 // @param key Property key.66 //67 // Selector: deleteCollectionProperty(string) 7b7debce68 function deleteCollectionProperty(string memory key) public {69 require(false, stub_error);70 key;71 dummy = 0;72 }7374 // Get collection property.75 //76 // @dev Throws error if key not found.77 //78 // @param key Property key.79 // @return bytes The property corresponding to the key.80 //81 // Selector: collectionProperty(string) cf24fd6d82 function collectionProperty(string memory key)83 public84 view85 returns (bytes memory)86 {87 require(false, stub_error);88 key;89 dummy;90 return hex"";91 }9293 // Set the sponsor of the collection.94 //95 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.96 //97 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.98 //99 // Selector: setCollectionSponsor(address) 7623402e100 function setCollectionSponsor(address sponsor) public {101 require(false, stub_error);102 sponsor;103 dummy = 0;104 }105106 // Collection sponsorship confirmation.107 //108 // @dev After setting the sponsor for the collection, it must be confirmed with this function.109 //110 // Selector: confirmCollectionSponsorship() 3c50e97a111 function confirmCollectionSponsorship() public {112 require(false, stub_error);113 dummy = 0;114 }115116 // Set limits for the collection.117 // @dev Throws error if limit not found.118 // @param limit Name of the limit. Valid names:119 // "accountTokenOwnershipLimit",120 // "sponsoredDataSize",121 // "sponsoredDataRateLimit",122 // "tokenLimit",123 // "sponsorTransferTimeout",124 // "sponsorApproveTimeout"125 // @param value Value of the limit.126 //127 // Selector: setCollectionLimit(string,uint32) 6a3841db128 function setCollectionLimit(string memory limit, uint32 value) public {129 require(false, stub_error);130 limit;131 value;132 dummy = 0;133 }134135 // Set limits for the collection.136 // @dev Throws error if limit not found.137 // @param limit Name of the limit. Valid names:138 // "ownerCanTransfer",139 // "ownerCanDestroy",140 // "transfersEnabled"141 // @param value Value of the limit.142 //143 // Selector: setCollectionLimit(string,bool) 993b7fba144 function setCollectionLimit(string memory limit, bool value) public {145 require(false, stub_error);146 limit;147 value;148 dummy = 0;149 }150151 // Get contract address.152 //153 // Selector: contractAddress() f6b4dfb4154 function contractAddress() public view returns (address) {155 require(false, stub_error);156 dummy;157 return 0x0000000000000000000000000000000000000000;158 }159160 // Add collection admin by substrate address.161 // @param new_admin Substrate administrator address.162 //163 // Selector: addCollectionAdminSubstrate(uint256) 5730062b164 function addCollectionAdminSubstrate(uint256 newAdmin) public {165 require(false, stub_error);166 newAdmin;167 dummy = 0;168 }169170 // Remove collection admin by substrate address.171 // @param admin Substrate administrator address.172 //173 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9174 function removeCollectionAdminSubstrate(uint256 admin) public {175 require(false, stub_error);176 admin;177 dummy = 0;178 }179180 // Add collection admin.181 // @param new_admin Address of the added administrator.182 //183 // Selector: addCollectionAdmin(address) 92e462c7184 function addCollectionAdmin(address newAdmin) public {185 require(false, stub_error);186 newAdmin;187 dummy = 0;188 }189190 // Remove collection admin.191 //192 // @param new_admin Address of the removed administrator.193 //194 // Selector: removeCollectionAdmin(address) fafd7b42195 function removeCollectionAdmin(address admin) public {196 require(false, stub_error);197 admin;198 dummy = 0;199 }200201 // Toggle accessibility of collection nesting.202 //203 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'204 //205 // Selector: setCollectionNesting(bool) 112d4586206 function setCollectionNesting(bool enable) public {207 require(false, stub_error);208 enable;209 dummy = 0;210 }211212 // Toggle accessibility of collection nesting.213 //214 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'215 // @param collections Addresses of collections that will be available for nesting.216 //217 // Selector: setCollectionNesting(bool,address[]) 64872396218 function setCollectionNesting(bool enable, address[] memory collections)219 public220 {221 require(false, stub_error);222 enable;223 collections;224 dummy = 0;225 }226227 // Set the collection access method.228 // @param mode Access mode229 // 0 for Normal230 // 1 for AllowList231 //232 // Selector: setCollectionAccess(uint8) 41835d4c233 function setCollectionAccess(uint8 mode) public {234 require(false, stub_error);235 mode;236 dummy = 0;237 }238239 // Add the user to the allowed list.240 //241 // @param user Address of a trusted user.242 //243 // Selector: addToCollectionAllowList(address) 67844fe6244 function addToCollectionAllowList(address user) public {245 require(false, stub_error);246 user;247 dummy = 0;248 }249250 // Remove the user from the allowed list.251 //252 // @param user Address of a removed user.253 //254 // Selector: removeFromCollectionAllowList(address) 85c51acb255 function removeFromCollectionAllowList(address user) public {256 require(false, stub_error);257 user;258 dummy = 0;259 }260261 // Switch permission for minting.262 //263 // @param mode Enable if "true".264 //265 // Selector: setCollectionMintMode(bool) 00018e84266 function setCollectionMintMode(bool mode) public {267 require(false, stub_error);268 mode;269 dummy = 0;270 }271}27245273// Selector: 942e8b2246// Selector: 942e8b22274contract ERC20 is Dummy, ERC165, ERC20Events {47contract ERC20 is Dummy, ERC165, ERC20Events {354 }127 }355}128}129130// Selector: aa7d570d131contract Collection is Dummy, ERC165 {132 // Set collection property.133 //134 // @param key Property key.135 // @param value Propery value.136 //137 // Selector: setCollectionProperty(string,bytes) 2f073f66138 function setCollectionProperty(string memory key, bytes memory value)139 public140 {141 require(false, stub_error);142 key;143 value;144 dummy = 0;145 }146147 // Delete collection property.148 //149 // @param key Property key.150 //151 // Selector: deleteCollectionProperty(string) 7b7debce152 function deleteCollectionProperty(string memory key) public {153 require(false, stub_error);154 key;155 dummy = 0;156 }157158 // Get collection property.159 //160 // @dev Throws error if key not found.161 //162 // @param key Property key.163 // @return bytes The property corresponding to the key.164 //165 // Selector: collectionProperty(string) cf24fd6d166 function collectionProperty(string memory key)167 public168 view169 returns (bytes memory)170 {171 require(false, stub_error);172 key;173 dummy;174 return hex"";175 }176177 // Set the sponsor of the collection.178 //179 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.180 //181 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.182 //183 // Selector: setCollectionSponsor(address) 7623402e184 function setCollectionSponsor(address sponsor) public {185 require(false, stub_error);186 sponsor;187 dummy = 0;188 }189190 // Collection sponsorship confirmation.191 //192 // @dev After setting the sponsor for the collection, it must be confirmed with this function.193 //194 // Selector: confirmCollectionSponsorship() 3c50e97a195 function confirmCollectionSponsorship() public {196 require(false, stub_error);197 dummy = 0;198 }199200 // Set limits for the collection.201 // @dev Throws error if limit not found.202 // @param limit Name of the limit. Valid names:203 // "accountTokenOwnershipLimit",204 // "sponsoredDataSize",205 // "sponsoredDataRateLimit",206 // "tokenLimit",207 // "sponsorTransferTimeout",208 // "sponsorApproveTimeout"209 // @param value Value of the limit.210 //211 // Selector: setCollectionLimit(string,uint32) 6a3841db212 function setCollectionLimit(string memory limit, uint32 value) public {213 require(false, stub_error);214 limit;215 value;216 dummy = 0;217 }218219 // Set limits for the collection.220 // @dev Throws error if limit not found.221 // @param limit Name of the limit. Valid names:222 // "ownerCanTransfer",223 // "ownerCanDestroy",224 // "transfersEnabled"225 // @param value Value of the limit.226 //227 // Selector: setCollectionLimit(string,bool) 993b7fba228 function setCollectionLimit(string memory limit, bool value) public {229 require(false, stub_error);230 limit;231 value;232 dummy = 0;233 }234235 // Get contract address.236 //237 // Selector: contractAddress() f6b4dfb4238 function contractAddress() public view returns (address) {239 require(false, stub_error);240 dummy;241 return 0x0000000000000000000000000000000000000000;242 }243244 // Add collection admin by substrate address.245 // @param new_admin Substrate administrator address.246 //247 // Selector: addCollectionAdminSubstrate(uint256) 5730062b248 function addCollectionAdminSubstrate(uint256 newAdmin) public {249 require(false, stub_error);250 newAdmin;251 dummy = 0;252 }253254 // Remove collection admin by substrate address.255 // @param admin Substrate administrator address.256 //257 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9258 function removeCollectionAdminSubstrate(uint256 admin) public {259 require(false, stub_error);260 admin;261 dummy = 0;262 }263264 // Add collection admin.265 // @param new_admin Address of the added administrator.266 //267 // Selector: addCollectionAdmin(address) 92e462c7268 function addCollectionAdmin(address newAdmin) public {269 require(false, stub_error);270 newAdmin;271 dummy = 0;272 }273274 // Remove collection admin.275 //276 // @param new_admin Address of the removed administrator.277 //278 // Selector: removeCollectionAdmin(address) fafd7b42279 function removeCollectionAdmin(address admin) public {280 require(false, stub_error);281 admin;282 dummy = 0;283 }284285 // Toggle accessibility of collection nesting.286 //287 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'288 //289 // Selector: setCollectionNesting(bool) 112d4586290 function setCollectionNesting(bool enable) public {291 require(false, stub_error);292 enable;293 dummy = 0;294 }295296 // Toggle accessibility of collection nesting.297 //298 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'299 // @param collections Addresses of collections that will be available for nesting.300 //301 // Selector: setCollectionNesting(bool,address[]) 64872396302 function setCollectionNesting(bool enable, address[] memory collections)303 public304 {305 require(false, stub_error);306 enable;307 collections;308 dummy = 0;309 }310311 // Set the collection access method.312 // @param mode Access mode313 // 0 for Normal314 // 1 for AllowList315 //316 // Selector: setCollectionAccess(uint8) 41835d4c317 function setCollectionAccess(uint8 mode) public {318 require(false, stub_error);319 mode;320 dummy = 0;321 }322323 // Add the user to the allowed list.324 //325 // @param user Address of a trusted user.326 //327 // Selector: addToCollectionAllowList(address) 67844fe6328 function addToCollectionAllowList(address user) public {329 require(false, stub_error);330 user;331 dummy = 0;332 }333334 // Remove the user from the allowed list.335 //336 // @param user Address of a removed user.337 //338 // Selector: removeFromCollectionAllowList(address) 85c51acb339 function removeFromCollectionAllowList(address user) public {340 require(false, stub_error);341 user;342 dummy = 0;343 }344345 // Switch permission for minting.346 //347 // @param mode Enable if "true".348 //349 // Selector: setCollectionMintMode(bool) 00018e84350 function setCollectionMintMode(bool mode) public {351 require(false, stub_error);352 mode;353 dummy = 0;354 }355356 // Check that account is the owner or admin of the collection357 //358 // @return "true" if account is the owner or admin359 //360 // Selector: verifyOwnerOrAdmin() 04a46053361 function verifyOwnerOrAdmin() public returns (bool) {362 require(false, stub_error);363 dummy = 0;364 return false;365 }366367 // Selector: uniqueCollectionType() d34b55b8368 function uniqueCollectionType() public returns (string memory) {369 require(false, stub_error);370 dummy = 0;371 return "";372 }373}356374357contract UniqueFungible is375contract UniqueFungible is358 Dummy,376 Dummy,pallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth17use super::*;17use super::*;18use crate::{Pallet, Config, NonfungibleHandle};18use crate::{Pallet, Config, NonfungibleHandle};191920use sp_std::prelude::*;20use frame_benchmarking::{benchmarks, account};21use pallet_common::benchmarking::{create_collection_raw, property_key, property_value};21use pallet_common::{22 bench_init,23 benchmarking::{create_collection_raw, property_key, property_value},24 CommonCollectionOperations,25};22use frame_benchmarking::{benchmarks, account};26use sp_std::prelude::*;23use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, budget::Unlimited};27use up_data_structs::{CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, budget::Unlimited};24use pallet_common::bench_init;252826const SEED: u32 = 1;29const SEED: u32 = 1;2730209 let to_delete = (0..b).map(|k| property_key(k as usize)).collect::<Vec<_>>();212 let to_delete = (0..b).map(|k| property_key(k as usize)).collect::<Vec<_>>();210 }: {<Pallet<T>>::delete_token_properties(&collection, &owner, item, to_delete.into_iter(), &Unlimited)?}213 }: {<Pallet<T>>::delete_token_properties(&collection, &owner, item, to_delete.into_iter(), &Unlimited)?}214215 token_owner {216 bench_init!{217 owner: sub; collection: collection(owner);218 owner: cross_from_sub;219 };220 let item = create_max_item(&collection, &owner, owner.clone())?;221222 }: {collection.token_owner(item)}211}223}212224pallets/nonfungible/src/common.rsdiffbeforeafterboth119 .saturating_sub(Self::burn_recursively_self_raw().saturating_mul(amount as u64 + 1))119 .saturating_sub(Self::burn_recursively_self_raw().saturating_mul(amount as u64 + 1))120 }120 }121122 fn token_owner() -> Weight {123 0 //<SelfWeightOf<T>>::token_owner()124 }121}125}122126123fn map_create_data<T: Config>(127fn map_create_data<T: Config>(pallets/nonfungible/src/lib.rsdiffbeforeafterboth784 <PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)784 <PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)785 }785 }786787 /// Set property permissions for the token with scope.788 ///789 /// Sender should be the owner or admin of token's collection.790 pub fn set_scoped_token_property_permissions(791 collection: &CollectionHandle<T>,792 sender: &T::CrossAccountId,793 scope: PropertyScope,794 property_permissions: Vec<PropertyKeyPermission>,795 ) -> DispatchResult {796 <PalletCommon<T>>::set_scoped_token_property_permissions(797 collection,798 sender,799 scope,800 property_permissions,801 )802 }786803787 /// Set property permissions for the collection.804 /// Set property permissions for the collection.788 ///805 ///pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth415 }415 }416}416}417417418// Selector: 7d9262e6418// Selector: aa7d570d419contract Collection is Dummy, ERC165 {419contract Collection is Dummy, ERC165 {420 // Set collection property.420 // Set collection property.421 //421 //641 dummy = 0;641 dummy = 0;642 }642 }643644 // Check that account is the owner or admin of the collection645 //646 // @return "true" if account is the owner or admin647 //648 // Selector: verifyOwnerOrAdmin() 04a46053649 function verifyOwnerOrAdmin() public returns (bool) {650 require(false, stub_error);651 dummy = 0;652 return false;653 }654655 // Selector: uniqueCollectionType() d34b55b8656 function uniqueCollectionType() public returns (string memory) {657 require(false, stub_error);658 dummy = 0;659 return "";660 }643}661}644662645// Selector: d74d154f663// Selector: d74d154fpallets/nonfungible/src/weights.rsdiffbeforeafterboth3//! Autogenerated weights for pallet_nonfungible3//! Autogenerated weights for pallet_nonfungible4//!4//!5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev6//! DATE: 2022-07-20, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`6//! DATE: 2022-08-01, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`7//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 10247//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024889// Executed Command:9// Executed Command:46 fn set_token_property_permissions(b: u32, ) -> Weight;46 fn set_token_property_permissions(b: u32, ) -> Weight;47 fn set_token_properties(b: u32, ) -> Weight;47 fn set_token_properties(b: u32, ) -> Weight;48 fn delete_token_properties(b: u32, ) -> Weight;48 fn delete_token_properties(b: u32, ) -> Weight;49 fn token_owner() -> Weight;49}50}505151/// Weights for pallet_nonfungible using the Substrate node and recommended hardware.52/// Weights for pallet_nonfungible using the Substrate node and recommended hardware.56 // Storage: Nonfungible TokenData (r:0 w:1)57 // Storage: Nonfungible TokenData (r:0 w:1)57 // Storage: Nonfungible Owned (r:0 w:1)58 // Storage: Nonfungible Owned (r:0 w:1)58 fn create_item() -> Weight {59 fn create_item() -> Weight {59 (20_328_000 as Weight)60 (20_909_000 as Weight)60 .saturating_add(T::DbWeight::get().reads(2 as Weight))61 .saturating_add(T::DbWeight::get().reads(2 as Weight))61 .saturating_add(T::DbWeight::get().writes(4 as Weight))62 .saturating_add(T::DbWeight::get().writes(4 as Weight))62 }63 }65 // Storage: Nonfungible TokenData (r:0 w:4)66 // Storage: Nonfungible TokenData (r:0 w:4)66 // Storage: Nonfungible Owned (r:0 w:4)67 // Storage: Nonfungible Owned (r:0 w:4)67 fn create_multiple_items(b: u32, ) -> Weight {68 fn create_multiple_items(b: u32, ) -> Weight {68 (10_134_000 as Weight)69 (12_601_000 as Weight)69 // Standard Error: 3_00070 // Standard Error: 1_00070 .saturating_add((4_927_000 as Weight).saturating_mul(b as Weight))71 .saturating_add((4_920_000 as Weight).saturating_mul(b as Weight))71 .saturating_add(T::DbWeight::get().reads(2 as Weight))72 .saturating_add(T::DbWeight::get().reads(2 as Weight))72 .saturating_add(T::DbWeight::get().writes(2 as Weight))73 .saturating_add(T::DbWeight::get().writes(2 as Weight))73 .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(b as Weight)))74 .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(b as Weight)))77 // Storage: Nonfungible TokenData (r:0 w:4)78 // Storage: Nonfungible TokenData (r:0 w:4)78 // Storage: Nonfungible Owned (r:0 w:4)79 // Storage: Nonfungible Owned (r:0 w:4)79 fn create_multiple_items_ex(b: u32, ) -> Weight {80 fn create_multiple_items_ex(b: u32, ) -> Weight {80 (5_710_000 as Weight)81 (0 as Weight)81 // Standard Error: 4_00082 // Standard Error: 3_00082 .saturating_add((7_578_000 as Weight).saturating_mul(b as Weight))83 .saturating_add((7_734_000 as Weight).saturating_mul(b as Weight))83 .saturating_add(T::DbWeight::get().reads(1 as Weight))84 .saturating_add(T::DbWeight::get().reads(1 as Weight))84 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))85 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))85 .saturating_add(T::DbWeight::get().writes(1 as Weight))86 .saturating_add(T::DbWeight::get().writes(1 as Weight))93 // Storage: Nonfungible Owned (r:0 w:1)94 // Storage: Nonfungible Owned (r:0 w:1)94 // Storage: Nonfungible TokenProperties (r:0 w:1)95 // Storage: Nonfungible TokenProperties (r:0 w:1)95 fn burn_item() -> Weight {96 fn burn_item() -> Weight {96 (28_433_000 as Weight)97 (29_746_000 as Weight)97 .saturating_add(T::DbWeight::get().reads(5 as Weight))98 .saturating_add(T::DbWeight::get().reads(5 as Weight))98 .saturating_add(T::DbWeight::get().writes(5 as Weight))99 .saturating_add(T::DbWeight::get().writes(5 as Weight))99 }100 }105 // Storage: Nonfungible Owned (r:0 w:1)106 // Storage: Nonfungible Owned (r:0 w:1)106 // Storage: Nonfungible TokenProperties (r:0 w:1)107 // Storage: Nonfungible TokenProperties (r:0 w:1)107 fn burn_recursively_self_raw() -> Weight {108 fn burn_recursively_self_raw() -> Weight {108 (34_435_000 as Weight)109 (36_077_000 as Weight)109 .saturating_add(T::DbWeight::get().reads(5 as Weight))110 .saturating_add(T::DbWeight::get().reads(5 as Weight))110 .saturating_add(T::DbWeight::get().writes(5 as Weight))111 .saturating_add(T::DbWeight::get().writes(5 as Weight))111 }112 }119 // Storage: Common CollectionById (r:1 w:0)120 // Storage: Common CollectionById (r:1 w:0)120 fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32, ) -> Weight {121 fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32, ) -> Weight {121 (0 as Weight)122 (0 as Weight)122 // Standard Error: 1_539_000123 // Standard Error: 1_605_000123 .saturating_add((304_456_000 as Weight).saturating_mul(b as Weight))124 .saturating_add((312_391_000 as Weight).saturating_mul(b as Weight))124 .saturating_add(T::DbWeight::get().reads(7 as Weight))125 .saturating_add(T::DbWeight::get().reads(7 as Weight))125 .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(b as Weight)))126 .saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(b as Weight)))126 .saturating_add(T::DbWeight::get().writes(6 as Weight))127 .saturating_add(T::DbWeight::get().writes(6 as Weight))131 // Storage: Nonfungible Allowance (r:1 w:0)132 // Storage: Nonfungible Allowance (r:1 w:0)132 // Storage: Nonfungible Owned (r:0 w:2)133 // Storage: Nonfungible Owned (r:0 w:2)133 fn transfer() -> Weight {134 fn transfer() -> Weight {134 (24_376_000 as Weight)135 (25_248_000 as Weight)135 .saturating_add(T::DbWeight::get().reads(4 as Weight))136 .saturating_add(T::DbWeight::get().reads(4 as Weight))136 .saturating_add(T::DbWeight::get().writes(5 as Weight))137 .saturating_add(T::DbWeight::get().writes(5 as Weight))137 }138 }138 // Storage: Nonfungible TokenData (r:1 w:0)139 // Storage: Nonfungible TokenData (r:1 w:0)139 // Storage: Nonfungible Allowance (r:1 w:1)140 // Storage: Nonfungible Allowance (r:1 w:1)140 fn approve() -> Weight {141 fn approve() -> Weight {141 (15_890_000 as Weight)142 (16_321_000 as Weight)142 .saturating_add(T::DbWeight::get().reads(2 as Weight))143 .saturating_add(T::DbWeight::get().reads(2 as Weight))143 .saturating_add(T::DbWeight::get().writes(1 as Weight))144 .saturating_add(T::DbWeight::get().writes(1 as Weight))144 }145 }147 // Storage: Nonfungible AccountBalance (r:2 w:2)148 // Storage: Nonfungible AccountBalance (r:2 w:2)148 // Storage: Nonfungible Owned (r:0 w:2)149 // Storage: Nonfungible Owned (r:0 w:2)149 fn transfer_from() -> Weight {150 fn transfer_from() -> Weight {150 (28_634_000 as Weight)151 (29_325_000 as Weight)151 .saturating_add(T::DbWeight::get().reads(4 as Weight))152 .saturating_add(T::DbWeight::get().reads(4 as Weight))152 .saturating_add(T::DbWeight::get().writes(6 as Weight))153 .saturating_add(T::DbWeight::get().writes(6 as Weight))153 }154 }159 // Storage: Nonfungible Owned (r:0 w:1)160 // Storage: Nonfungible Owned (r:0 w:1)160 // Storage: Nonfungible TokenProperties (r:0 w:1)161 // Storage: Nonfungible TokenProperties (r:0 w:1)161 fn burn_from() -> Weight {162 fn burn_from() -> Weight {162 (32_201_000 as Weight)163 (33_323_000 as Weight)163 .saturating_add(T::DbWeight::get().reads(5 as Weight))164 .saturating_add(T::DbWeight::get().reads(5 as Weight))164 .saturating_add(T::DbWeight::get().writes(6 as Weight))165 .saturating_add(T::DbWeight::get().writes(6 as Weight))165 }166 }166 // Storage: Common CollectionPropertyPermissions (r:1 w:1)167 // Storage: Common CollectionPropertyPermissions (r:1 w:1)167 fn set_token_property_permissions(b: u32, ) -> Weight {168 fn set_token_property_permissions(b: u32, ) -> Weight {168 (0 as Weight)169 (0 as Weight)169 // Standard Error: 57_000170 // Standard Error: 62_000170 .saturating_add((15_232_000 as Weight).saturating_mul(b as Weight))171 .saturating_add((16_222_000 as Weight).saturating_mul(b as Weight))171 .saturating_add(T::DbWeight::get().reads(1 as Weight))172 .saturating_add(T::DbWeight::get().reads(1 as Weight))172 .saturating_add(T::DbWeight::get().writes(1 as Weight))173 .saturating_add(T::DbWeight::get().writes(1 as Weight))173 }174 }174 // Storage: Common CollectionPropertyPermissions (r:1 w:0)175 // Storage: Common CollectionPropertyPermissions (r:1 w:0)175 // Storage: Nonfungible TokenProperties (r:1 w:1)176 // Storage: Nonfungible TokenProperties (r:1 w:1)176 fn set_token_properties(b: u32, ) -> Weight {177 fn set_token_properties(b: u32, ) -> Weight {177 (0 as Weight)178 (0 as Weight)178 // Standard Error: 1_648_000179 // Standard Error: 1_750_000179 .saturating_add((288_654_000 as Weight).saturating_mul(b as Weight))180 .saturating_add((304_476_000 as Weight).saturating_mul(b as Weight))180 .saturating_add(T::DbWeight::get().reads(2 as Weight))181 .saturating_add(T::DbWeight::get().reads(2 as Weight))181 .saturating_add(T::DbWeight::get().writes(1 as Weight))182 .saturating_add(T::DbWeight::get().writes(1 as Weight))182 }183 }183 // Storage: Common CollectionPropertyPermissions (r:1 w:0)184 // Storage: Common CollectionPropertyPermissions (r:1 w:0)184 // Storage: Nonfungible TokenProperties (r:1 w:1)185 // Storage: Nonfungible TokenProperties (r:1 w:1)185 fn delete_token_properties(b: u32, ) -> Weight {186 fn delete_token_properties(b: u32, ) -> Weight {186 (0 as Weight)187 (0 as Weight)187 // Standard Error: 1_632_000188 // Standard Error: 1_638_000188 .saturating_add((289_190_000 as Weight).saturating_mul(b as Weight))189 .saturating_add((294_096_000 as Weight).saturating_mul(b as Weight))189 .saturating_add(T::DbWeight::get().reads(2 as Weight))190 .saturating_add(T::DbWeight::get().reads(2 as Weight))190 .saturating_add(T::DbWeight::get().writes(1 as Weight))191 .saturating_add(T::DbWeight::get().writes(1 as Weight))191 }192 }193 // Storage: Nonfungible TokenData (r:1 w:0)194 fn token_owner() -> Weight {195 (2_986_000 as Weight)196 .saturating_add(T::DbWeight::get().reads(1 as Weight))197 }192}198}193199194// For backwards compatibility and tests200// For backwards compatibility and tests198 // Storage: Nonfungible TokenData (r:0 w:1)204 // Storage: Nonfungible TokenData (r:0 w:1)199 // Storage: Nonfungible Owned (r:0 w:1)205 // Storage: Nonfungible Owned (r:0 w:1)200 fn create_item() -> Weight {206 fn create_item() -> Weight {201 (20_328_000 as Weight)207 (20_909_000 as Weight)202 .saturating_add(RocksDbWeight::get().reads(2 as Weight))208 .saturating_add(RocksDbWeight::get().reads(2 as Weight))203 .saturating_add(RocksDbWeight::get().writes(4 as Weight))209 .saturating_add(RocksDbWeight::get().writes(4 as Weight))204 }210 }207 // Storage: Nonfungible TokenData (r:0 w:4)213 // Storage: Nonfungible TokenData (r:0 w:4)208 // Storage: Nonfungible Owned (r:0 w:4)214 // Storage: Nonfungible Owned (r:0 w:4)209 fn create_multiple_items(b: u32, ) -> Weight {215 fn create_multiple_items(b: u32, ) -> Weight {210 (10_134_000 as Weight)216 (12_601_000 as Weight)211 // Standard Error: 3_000217 // Standard Error: 1_000212 .saturating_add((4_927_000 as Weight).saturating_mul(b as Weight))218 .saturating_add((4_920_000 as Weight).saturating_mul(b as Weight))213 .saturating_add(RocksDbWeight::get().reads(2 as Weight))219 .saturating_add(RocksDbWeight::get().reads(2 as Weight))214 .saturating_add(RocksDbWeight::get().writes(2 as Weight))220 .saturating_add(RocksDbWeight::get().writes(2 as Weight))215 .saturating_add(RocksDbWeight::get().writes((2 as Weight).saturating_mul(b as Weight)))221 .saturating_add(RocksDbWeight::get().writes((2 as Weight).saturating_mul(b as Weight)))219 // Storage: Nonfungible TokenData (r:0 w:4)225 // Storage: Nonfungible TokenData (r:0 w:4)220 // Storage: Nonfungible Owned (r:0 w:4)226 // Storage: Nonfungible Owned (r:0 w:4)221 fn create_multiple_items_ex(b: u32, ) -> Weight {227 fn create_multiple_items_ex(b: u32, ) -> Weight {222 (5_710_000 as Weight)228 (0 as Weight)223 // Standard Error: 4_000229 // Standard Error: 3_000224 .saturating_add((7_578_000 as Weight).saturating_mul(b as Weight))230 .saturating_add((7_734_000 as Weight).saturating_mul(b as Weight))225 .saturating_add(RocksDbWeight::get().reads(1 as Weight))231 .saturating_add(RocksDbWeight::get().reads(1 as Weight))226 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))232 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))227 .saturating_add(RocksDbWeight::get().writes(1 as Weight))233 .saturating_add(RocksDbWeight::get().writes(1 as Weight))235 // Storage: Nonfungible Owned (r:0 w:1)241 // Storage: Nonfungible Owned (r:0 w:1)236 // Storage: Nonfungible TokenProperties (r:0 w:1)242 // Storage: Nonfungible TokenProperties (r:0 w:1)237 fn burn_item() -> Weight {243 fn burn_item() -> Weight {238 (28_433_000 as Weight)244 (29_746_000 as Weight)239 .saturating_add(RocksDbWeight::get().reads(5 as Weight))245 .saturating_add(RocksDbWeight::get().reads(5 as Weight))240 .saturating_add(RocksDbWeight::get().writes(5 as Weight))246 .saturating_add(RocksDbWeight::get().writes(5 as Weight))241 }247 }247 // Storage: Nonfungible Owned (r:0 w:1)253 // Storage: Nonfungible Owned (r:0 w:1)248 // Storage: Nonfungible TokenProperties (r:0 w:1)254 // Storage: Nonfungible TokenProperties (r:0 w:1)249 fn burn_recursively_self_raw() -> Weight {255 fn burn_recursively_self_raw() -> Weight {250 (34_435_000 as Weight)256 (36_077_000 as Weight)251 .saturating_add(RocksDbWeight::get().reads(5 as Weight))257 .saturating_add(RocksDbWeight::get().reads(5 as Weight))252 .saturating_add(RocksDbWeight::get().writes(5 as Weight))258 .saturating_add(RocksDbWeight::get().writes(5 as Weight))253 }259 }261 // Storage: Common CollectionById (r:1 w:0)267 // Storage: Common CollectionById (r:1 w:0)262 fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32, ) -> Weight {268 fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32, ) -> Weight {263 (0 as Weight)269 (0 as Weight)264 // Standard Error: 1_539_000270 // Standard Error: 1_605_000265 .saturating_add((304_456_000 as Weight).saturating_mul(b as Weight))271 .saturating_add((312_391_000 as Weight).saturating_mul(b as Weight))266 .saturating_add(RocksDbWeight::get().reads(7 as Weight))272 .saturating_add(RocksDbWeight::get().reads(7 as Weight))267 .saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(b as Weight)))273 .saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(b as Weight)))268 .saturating_add(RocksDbWeight::get().writes(6 as Weight))274 .saturating_add(RocksDbWeight::get().writes(6 as Weight))273 // Storage: Nonfungible Allowance (r:1 w:0)279 // Storage: Nonfungible Allowance (r:1 w:0)274 // Storage: Nonfungible Owned (r:0 w:2)280 // Storage: Nonfungible Owned (r:0 w:2)275 fn transfer() -> Weight {281 fn transfer() -> Weight {276 (24_376_000 as Weight)282 (25_248_000 as Weight)277 .saturating_add(RocksDbWeight::get().reads(4 as Weight))283 .saturating_add(RocksDbWeight::get().reads(4 as Weight))278 .saturating_add(RocksDbWeight::get().writes(5 as Weight))284 .saturating_add(RocksDbWeight::get().writes(5 as Weight))279 }285 }280 // Storage: Nonfungible TokenData (r:1 w:0)286 // Storage: Nonfungible TokenData (r:1 w:0)281 // Storage: Nonfungible Allowance (r:1 w:1)287 // Storage: Nonfungible Allowance (r:1 w:1)282 fn approve() -> Weight {288 fn approve() -> Weight {283 (15_890_000 as Weight)289 (16_321_000 as Weight)284 .saturating_add(RocksDbWeight::get().reads(2 as Weight))290 .saturating_add(RocksDbWeight::get().reads(2 as Weight))285 .saturating_add(RocksDbWeight::get().writes(1 as Weight))291 .saturating_add(RocksDbWeight::get().writes(1 as Weight))286 }292 }289 // Storage: Nonfungible AccountBalance (r:2 w:2)295 // Storage: Nonfungible AccountBalance (r:2 w:2)290 // Storage: Nonfungible Owned (r:0 w:2)296 // Storage: Nonfungible Owned (r:0 w:2)291 fn transfer_from() -> Weight {297 fn transfer_from() -> Weight {292 (28_634_000 as Weight)298 (29_325_000 as Weight)293 .saturating_add(RocksDbWeight::get().reads(4 as Weight))299 .saturating_add(RocksDbWeight::get().reads(4 as Weight))294 .saturating_add(RocksDbWeight::get().writes(6 as Weight))300 .saturating_add(RocksDbWeight::get().writes(6 as Weight))295 }301 }301 // Storage: Nonfungible Owned (r:0 w:1)307 // Storage: Nonfungible Owned (r:0 w:1)302 // Storage: Nonfungible TokenProperties (r:0 w:1)308 // Storage: Nonfungible TokenProperties (r:0 w:1)303 fn burn_from() -> Weight {309 fn burn_from() -> Weight {304 (32_201_000 as Weight)310 (33_323_000 as Weight)305 .saturating_add(RocksDbWeight::get().reads(5 as Weight))311 .saturating_add(RocksDbWeight::get().reads(5 as Weight))306 .saturating_add(RocksDbWeight::get().writes(6 as Weight))312 .saturating_add(RocksDbWeight::get().writes(6 as Weight))307 }313 }308 // Storage: Common CollectionPropertyPermissions (r:1 w:1)314 // Storage: Common CollectionPropertyPermissions (r:1 w:1)309 fn set_token_property_permissions(b: u32, ) -> Weight {315 fn set_token_property_permissions(b: u32, ) -> Weight {310 (0 as Weight)316 (0 as Weight)311 // Standard Error: 57_000317 // Standard Error: 62_000312 .saturating_add((15_232_000 as Weight).saturating_mul(b as Weight))318 .saturating_add((16_222_000 as Weight).saturating_mul(b as Weight))313 .saturating_add(RocksDbWeight::get().reads(1 as Weight))319 .saturating_add(RocksDbWeight::get().reads(1 as Weight))314 .saturating_add(RocksDbWeight::get().writes(1 as Weight))320 .saturating_add(RocksDbWeight::get().writes(1 as Weight))315 }321 }316 // Storage: Common CollectionPropertyPermissions (r:1 w:0)322 // Storage: Common CollectionPropertyPermissions (r:1 w:0)317 // Storage: Nonfungible TokenProperties (r:1 w:1)323 // Storage: Nonfungible TokenProperties (r:1 w:1)318 fn set_token_properties(b: u32, ) -> Weight {324 fn set_token_properties(b: u32, ) -> Weight {319 (0 as Weight)325 (0 as Weight)320 // Standard Error: 1_648_000326 // Standard Error: 1_750_000321 .saturating_add((288_654_000 as Weight).saturating_mul(b as Weight))327 .saturating_add((304_476_000 as Weight).saturating_mul(b as Weight))322 .saturating_add(RocksDbWeight::get().reads(2 as Weight))328 .saturating_add(RocksDbWeight::get().reads(2 as Weight))323 .saturating_add(RocksDbWeight::get().writes(1 as Weight))329 .saturating_add(RocksDbWeight::get().writes(1 as Weight))324 }330 }325 // Storage: Common CollectionPropertyPermissions (r:1 w:0)331 // Storage: Common CollectionPropertyPermissions (r:1 w:0)326 // Storage: Nonfungible TokenProperties (r:1 w:1)332 // Storage: Nonfungible TokenProperties (r:1 w:1)327 fn delete_token_properties(b: u32, ) -> Weight {333 fn delete_token_properties(b: u32, ) -> Weight {328 (0 as Weight)334 (0 as Weight)329 // Standard Error: 1_632_000335 // Standard Error: 1_638_000330 .saturating_add((289_190_000 as Weight).saturating_mul(b as Weight))336 .saturating_add((294_096_000 as Weight).saturating_mul(b as Weight))331 .saturating_add(RocksDbWeight::get().reads(2 as Weight))337 .saturating_add(RocksDbWeight::get().reads(2 as Weight))332 .saturating_add(RocksDbWeight::get().writes(1 as Weight))338 .saturating_add(RocksDbWeight::get().writes(1 as Weight))333 }339 }340 // Storage: Nonfungible TokenData (r:1 w:0)341 fn token_owner() -> Weight {342 (2_986_000 as Weight)343 .saturating_add(RocksDbWeight::get().reads(1 as Weight))344 }334}345}335346pallets/refungible/src/benchmarking.rsdiffbeforeafterboth17use super::*;17use super::*;18use crate::{Pallet, Config, RefungibleHandle};18use crate::{Pallet, Config, RefungibleHandle};191920use sp_std::prelude::*;20use core::convert::TryInto;21use pallet_common::benchmarking::{create_collection_raw, property_key, property_value, create_data};21use core::iter::IntoIterator;22use frame_benchmarking::{benchmarks, account};22use frame_benchmarking::{benchmarks, account};23use up_data_structs::{23use pallet_common::{24 CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, CUSTOM_DATA_LIMIT,24 bench_init,25 budget::Unlimited,25 benchmarking::{create_collection_raw, property_key, property_value, create_data},26};26};27use pallet_common::bench_init;27use sp_core::H160;28use core::convert::TryInto;28use sp_std::prelude::*;29use core::iter::IntoIterator;29use up_data_structs::{30 CollectionMode, MAX_ITEMS_PER_BATCH, MAX_PROPERTIES_PER_ITEM, CUSTOM_DATA_LIMIT,31 budget::Unlimited,32};303331const SEED: u32 = 1;34const SEED: u32 = 1;323559) -> Result<RefungibleHandle<T>, DispatchError> {63) -> Result<RefungibleHandle<T>, DispatchError> {60 create_collection_raw(64 create_collection_raw(61 owner,65 owner,62 CollectionMode::NFT,66 CollectionMode::ReFungible,63 <Pallet<T>>::init_collection,67 <Pallet<T>>::init_collection,64 RefungibleHandle::cast,68 RefungibleHandle::cast,65 )69 )278 let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;283 let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;279 }: {<Pallet<T>>::repartition(&collection, &owner, item, 200)?}284 }: {<Pallet<T>>::repartition(&collection, &owner, item, 200)?}285286 set_parent_nft_unchecked {287 bench_init!{288 owner: sub; collection: collection(owner);289 sender: cross_from_sub(owner); owner: cross_sub;290 };291 let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;292293 }: {<Pallet<T>>::set_parent_nft_unchecked(&collection, item, owner, T::CrossAccountId::from_eth(H160::default()))?}294295 token_owner {296 bench_init!{297 owner: sub; collection: collection(owner);298 sender: cross_from_sub(owner); owner: cross_sub;299 };300 let item = create_max_item(&collection, &sender, [(owner.clone(), 100)])?;301 }: {<Pallet<T>>::token_owner(collection.id, item)}280}302}281303pallets/refungible/src/common.rsdiffbeforeafterboth149 0149 0150 }150 }151152 fn token_owner() -> Weight {153 0 //<SelfWeightOf<T>>::token_owner()154 }151}155}152156153fn map_create_data<T: Config>(157fn map_create_data<T: Config>(pallets/refungible/src/erc.rsdiffbeforeafterboth41use sp_core::H160;41use sp_core::H160;42use sp_std::{collections::btree_map::BTreeMap, vec::Vec, vec};42use sp_std::{collections::btree_map::BTreeMap, vec::Vec, vec};43use up_data_structs::{43use up_data_structs::{44 CollectionId, CollectionPropertiesVec, Property, PropertyKey, PropertyKeyPermission,44 CollectionId, CollectionPropertiesVec, mapping::TokenAddressMapping, Property, PropertyKey,45 PropertyPermission, TokenId,45 PropertyKeyPermission, PropertyPermission, TokenId,46};46};4747413}413}414414415/// Returns amount of pieces of `token` that `owner` have415/// Returns amount of pieces of `token` that `owner` have416fn balance<T: Config>(416pub fn balance<T: Config>(417 collection: &RefungibleHandle<T>,417 collection: &RefungibleHandle<T>,418 token: TokenId,418 token: TokenId,419 owner: &T::CrossAccountId,419 owner: &T::CrossAccountId,424}424}425425426/// Throws if `owner_balance` is lower than total amount of `token` pieces426/// Throws if `owner_balance` is lower than total amount of `token` pieces427fn ensure_single_owner<T: Config>(427pub fn ensure_single_owner<T: Config>(428 collection: &RefungibleHandle<T>,428 collection: &RefungibleHandle<T>,429 token: TokenId,429 token: TokenId,430 owner_balance: u128,430 owner_balance: u128,789 Ok(true)789 Ok(true)790 }790 }791792 /// Returns EVM address for refungible token793 ///794 /// @param token ID of the token795 fn token_contract_address(&self, token: uint256) -> Result<address> {796 Ok(T::EvmTokenAddressMapping::token_to_address(797 self.id,798 token.try_into().map_err(|_| "token id overflow")?,799 ))800 }791}801}792802793#[solidity_interface(803#[solidity_interface(pallets/refungible/src/erc_token.rsdiffbeforeafterboth212122extern crate alloc;22extern crate alloc;2324#[cfg(not(feature = "std"))]25use alloc::format;2623use core::{27use core::{24 char::{REPLACEMENT_CHARACTER, decode_utf16},28 char::{REPLACEMENT_CHARACTER, decode_utf16},25 convert::TryInto,29 convert::TryInto,26 ops::Deref,30 ops::Deref,27};31};28use evm_coder::{ToLog, execution::*, generate_stubgen, solidity_interface, types::*, weight};32use evm_coder::{ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*, weight};29use pallet_common::{33use pallet_common::{30 CommonWeightInfo,34 CommonWeightInfo,31 erc::{CommonEvmHandler, PrecompileResult},35 erc::{CommonEvmHandler, PrecompileResult, static_property::key},36 eth::map_eth_to_id,32};37};33use pallet_evm::{account::CrossAccountId, PrecompileHandle};38use pallet_evm::{account::CrossAccountId, PrecompileHandle};34use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};39use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};35use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};40use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};41use sp_core::H160;36use sp_std::vec::Vec;42use sp_std::vec::Vec;37use up_data_structs::TokenId;43use up_data_structs::{mapping::TokenAddressMapping, PropertyScope, TokenId};384439use crate::{45use crate::{40 Allowance, Balance, common::CommonWeights, Config, Pallet, RefungibleHandle, SelfWeightOf,46 Allowance, Balance, common::CommonWeights, Config, Pallet, RefungibleHandle, SelfWeightOf,41 weights::WeightInfo, TotalSupply,47 TokenProperties, TotalSupply, weights::WeightInfo,42};48};434944pub struct RefungibleTokenHandle<T: Config>(pub RefungibleHandle<T>, pub TokenId);50pub struct RefungibleTokenHandle<T: Config>(pub RefungibleHandle<T>, pub TokenId);5152#[solidity_interface(name = "ERC1633")]53impl<T: Config> RefungibleTokenHandle<T> {54 fn parent_token(&self) -> Result<address> {55 self.consume_store_reads(2)?;56 let props = <TokenProperties<T>>::get((self.id, self.1));57 let key = key::parent_nft();5859 let key_scoped = PropertyScope::Eth60 .apply(key)61 .expect("property key shouldn't exceed length limit");62 let value = props.get(&key_scoped).ok_or("key not found")?;63 Ok(H160::from_slice(value.as_slice()))64 }6566 fn parent_token_id(&self) -> Result<uint256> {67 self.consume_store_reads(2)?;68 let props = <TokenProperties<T>>::get((self.id, self.1));69 let key = key::parent_nft();7071 let key_scoped = PropertyScope::Eth72 .apply(key)73 .expect("property key shouldn't exceed length limit");74 let value = props.get(&key_scoped).ok_or("key not found")?;75 let nft_token_address = H160::from_slice(value.as_slice());76 let nft_token_account = T::CrossAccountId::from_eth(nft_token_address);77 let (_, token_id) = T::CrossTokenAddressMapping::address_to_token(&nft_token_account)78 .ok_or("parent NFT should contain NFT token address")?;7980 Ok(token_id.into())81 }82}8384#[solidity_interface(name = "ERC1633UniqueExtensions")]85impl<T: Config> RefungibleTokenHandle<T> {86 #[solidity(rename_selector = "setParentNFT")]87 #[weight(<CommonWeights<T>>::token_owner() + <SelfWeightOf<T>>::set_parent_nft_unchecked())]88 fn set_parent_nft(89 &mut self,90 caller: caller,91 collection: address,92 nft_id: uint256,93 ) -> Result<bool> {94 self.consume_store_reads(1)?;95 let caller = T::CrossAccountId::from_eth(caller);96 let nft_collection = map_eth_to_id(&collection).ok_or("collection not found")?;97 let nft_token = nft_id.try_into()?;9899 <Pallet<T>>::set_parent_nft(&self.0, self.1, caller, nft_collection, nft_token)100 .map_err(dispatch_to_evm::<T>)?;101102 Ok(true)103 }104}4510546#[derive(ToLog)]106#[derive(ToLog)]47pub enum ERC20Events {107pub enum ERC20Events {241301242#[solidity_interface(name = "UniqueRefungibleToken", is(ERC20, ERC20UniqueExtensions,))]302#[solidity_interface(303 name = "UniqueRefungibleToken",304 is(ERC20, ERC20UniqueExtensions, ERC1633, ERC1633UniqueExtensions)305)]243impl<T: Config> RefungibleTokenHandle<T> where T::AccountId: From<[u8; 32]> {}306impl<T: Config> RefungibleTokenHandle<T> where T::AccountId: From<[u8; 32]> {}244307pallets/refungible/src/lib.rsdiffbeforeafterboth99use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};99use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};100use pallet_evm_coder_substrate::WithRecorder;100use pallet_evm_coder_substrate::WithRecorder;101use pallet_common::{101use pallet_common::{102 CommonCollectionOperations, Error as CommonError, Event as CommonEvent,102 CollectionHandle, CommonCollectionOperations,103 dispatch::CollectionDispatch,104 erc::static_property::{key, property_value_from_bytes},105 Error as CommonError,103 eth::collection_id_to_address, Pallet as PalletCommon,106 eth::collection_id_to_address,107 Event as CommonEvent, Pallet as PalletCommon,104};108};105use pallet_structure::Pallet as PalletStructure;109use pallet_structure::Pallet as PalletStructure;106use scale_info::TypeInfo;110use scale_info::TypeInfo;107use sp_core::H160;111use sp_core::H160;108use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};112use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};109use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};113use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};110use up_data_structs::{114use up_data_structs::{111 AccessMode, budget::Budget, CollectionId, CreateCollectionData, CustomDataLimit,115 AccessMode, budget::Budget, CollectionId, CollectionMode, CollectionPropertiesVec, CreateCollectionData, CustomDataLimit,112 mapping::TokenAddressMapping, MAX_REFUNGIBLE_PIECES, MAX_ITEMS_PER_BATCH, TokenId, Property,116 mapping::TokenAddressMapping, MAX_ITEMS_PER_BATCH, MAX_REFUNGIBLE_PIECES, Property,113 PropertyKey, PropertyKeyPermission, PropertyPermission, PropertyScope, PropertyValue,117 PropertyKey, PropertyKeyPermission, PropertyPermission, PropertyScope, PropertyValue,114 TrySetProperty, CollectionPropertiesVec,118 TokenId, TrySetProperty,115};119};116use frame_support::BoundedBTreeMap;120use frame_support::BoundedBTreeMap;117use derivative::Derivative;121use derivative::Derivative;1341 <PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)1345 <PalletCommon<T>>::set_token_property_permissions(collection, sender, property_permissions)1342 }1346 }13471348 pub fn set_scoped_token_property_permissions(1349 collection: &RefungibleHandle<T>,1350 sender: &T::CrossAccountId,1351 scope: PropertyScope,1352 property_permissions: Vec<PropertyKeyPermission>,1353 ) -> DispatchResult {1354 <PalletCommon<T>>::set_scoped_token_property_permissions(1355 collection,1356 sender,1357 scope,1358 property_permissions,1359 )1360 }134313611344 /// Returns 10 token in no particular order.1362 /// Returns 10 token in no particular order.1345 ///1363 ///1363 }1381 }1364 }1382 }13831384 /// Sets the NFT token as a parent for the RFT token1385 ///1386 /// Throws if `sender` is not the owner of the NFT token.1387 /// Throws if `sender` is not the owner of all of the RFT token pieces.1388 pub fn set_parent_nft(1389 collection: &RefungibleHandle<T>,1390 rft_token_id: TokenId,1391 sender: T::CrossAccountId,1392 nft_collection: CollectionId,1393 nft_token: TokenId,1394 ) -> DispatchResult {1395 let handle = <CollectionHandle<T>>::try_get(nft_collection)?;1396 if handle.mode != CollectionMode::NFT {1397 return Err("Only NFT token could be parent to RFT".into());1398 }1399 let dispatch = T::CollectionDispatch::dispatch(handle);1400 let dispatch = dispatch.as_dyn();14011402 let owner = dispatch.token_owner(nft_token).ok_or("owner not found")?;1403 if owner != sender {1404 return Err("Only owned token could be set as parent".into());1405 }14061407 let nft_token_address =1408 T::CrossTokenAddressMapping::token_to_address(nft_collection, nft_token);14091410 Self::set_parent_nft_unchecked(collection, rft_token_id, sender, nft_token_address)1411 }14121413 /// Sets the NFT token as a parent for the RFT token1414 ///1415 /// `sender` should be the owner of the NFT token.1416 /// Throws if `sender` is not the owner of all of the RFT token pieces.1417 pub fn set_parent_nft_unchecked(1418 collection: &RefungibleHandle<T>,1419 rft_token_id: TokenId,1420 sender: T::CrossAccountId,1421 nft_token_address: T::CrossAccountId,1422 ) -> DispatchResult {1423 let owner_balance = <Balance<T>>::get((collection.id, rft_token_id, &sender));1424 let total_supply = <TotalSupply<T>>::get((collection.id, rft_token_id));1425 if total_supply != owner_balance {1426 return Err("token has multiple owners".into());1427 }14281429 let parent_nft_property_key = key::parent_nft();14301431 let parent_nft_property_value =1432 property_value_from_bytes(&nft_token_address.as_eth().to_fixed_bytes())1433 .expect("address should fit in value length limit");14341435 <Pallet<T>>::set_scoped_token_property(1436 collection.id,1437 rft_token_id,1438 PropertyScope::Eth,1439 Property {1440 key: parent_nft_property_key,1441 value: parent_nft_property_value,1442 },1443 )?;14441445 Ok(())1446 }1365}1447}13661448pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth413 }413 }414}414}415415416// Selector: 7d9262e6416// Selector: 7c3bef89417contract Collection is Dummy, ERC165 {417contract ERC721UniqueExtensions is Dummy, ERC165 {418 // @notice Transfer ownership of an RFT419 // @dev Throws unless `msg.sender` is the current owner. Throws if `to`420 // is the zero address. Throws if `tokenId` is not a valid RFT.421 // Throws if RFT pieces have multiple owners.422 // @param to The new owner423 // @param tokenId The RFT to transfer424 // @param _value Not used for an RFT425 //426 // Selector: transfer(address,uint256) a9059cbb427 function transfer(address to, uint256 tokenId) public {428 require(false, stub_error);429 to;430 tokenId;431 dummy = 0;432 }433434 // @notice Burns a specific ERC721 token.435 // @dev Throws unless `msg.sender` is the current owner or an authorized436 // operator for this RFT. Throws if `from` is not the current owner. Throws437 // if `to` is the zero address. Throws if `tokenId` is not a valid RFT.438 // Throws if RFT pieces have multiple owners.439 // @param from The current owner of the RFT440 // @param tokenId The RFT to transfer441 // @param _value Not used for an RFT442 //443 // Selector: burnFrom(address,uint256) 79cc6790444 function burnFrom(address from, uint256 tokenId) public {445 require(false, stub_error);446 from;447 tokenId;448 dummy = 0;449 }450451 // @notice Returns next free RFT ID.452 //453 // Selector: nextTokenId() 75794a3c454 function nextTokenId() public view returns (uint256) {455 require(false, stub_error);456 dummy;457 return 0;458 }459460 // @notice Function to mint multiple tokens.461 // @dev `tokenIds` should be an array of consecutive numbers and first number462 // should be obtained with `nextTokenId` method463 // @param to The new owner464 // @param tokenIds IDs of the minted RFTs465 //466 // Selector: mintBulk(address,uint256[]) 44a9945e467 function mintBulk(address to, uint256[] memory tokenIds)468 public469 returns (bool)470 {471 require(false, stub_error);472 to;473 tokenIds;474 dummy = 0;475 return false;476 }477478 // @notice Function to mint multiple tokens with the given tokenUris.479 // @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive480 // numbers and first number should be obtained with `nextTokenId` method481 // @param to The new owner482 // @param tokens array of pairs of token ID and token URI for minted tokens483 //484 // Selector: mintBulkWithTokenURI(address,(uint256,string)[]) 36543006485 function mintBulkWithTokenURI(address to, Tuple0[] memory tokens)486 public487 returns (bool)488 {489 require(false, stub_error);490 to;491 tokens;492 dummy = 0;493 return false;494 }495496 // Returns EVM address for refungible token497 //498 // @param token ID of the token499 //500 // Selector: tokenContractAddress(uint256) ab76fac6501 function tokenContractAddress(uint256 token) public view returns (address) {502 require(false, stub_error);503 token;504 dummy;505 return 0x0000000000000000000000000000000000000000;506 }507}508509// Selector: aa7d570d510contract Collection is Dummy, ERC165 {418 // Set collection property.511 // Set collection property.419 //512 //420 // @param key Property key.513 // @param key Property key.638 mode;731 mode;639 dummy = 0;732 dummy = 0;640 }733 }641}734642735 // Check that account is the owner or admin of the collection643// Selector: d74d154f644contract ERC721UniqueExtensions is Dummy, ERC165 {645 // @notice Transfer ownership of an RFT646 // @dev Throws unless `msg.sender` is the current owner. Throws if `to`647 // is the zero address. Throws if `tokenId` is not a valid RFT.648 // Throws if RFT pieces have multiple owners.649 // @param to The new owner650 // @param tokenId The RFT to transfer651 // @param _value Not used for an RFT652 //736 //653 // Selector: transfer(address,uint256) a9059cbb737 // @return "true" if account is the owner or admin654 function transfer(address to, uint256 tokenId) public {655 require(false, stub_error);656 to;657 tokenId;658 dummy = 0;659 }660661 // @notice Burns a specific ERC721 token.662 // @dev Throws unless `msg.sender` is the current owner or an authorized663 // operator for this RFT. Throws if `from` is not the current owner. Throws664 // if `to` is the zero address. Throws if `tokenId` is not a valid RFT.665 // Throws if RFT pieces have multiple owners.666 // @param from The current owner of the RFT667 // @param tokenId The RFT to transfer668 // @param _value Not used for an RFT669 //670 // Selector: burnFrom(address,uint256) 79cc6790671 function burnFrom(address from, uint256 tokenId) public {672 require(false, stub_error);673 from;674 tokenId;675 dummy = 0;676 }677678 // @notice Returns next free RFT ID.679 //738 //680 // Selector: nextTokenId() 75794a3c739 // Selector: verifyOwnerOrAdmin() 04a46053681 function nextTokenId() public view returns (uint256) {682 require(false, stub_error);683 dummy;684 return 0;685 }686687 // @notice Function to mint multiple tokens.688 // @dev `tokenIds` should be an array of consecutive numbers and first number689 // should be obtained with `nextTokenId` method690 // @param to The new owner691 // @param tokenIds IDs of the minted RFTs692 //693 // Selector: mintBulk(address,uint256[]) 44a9945e694 function mintBulk(address to, uint256[] memory tokenIds)740 function verifyOwnerOrAdmin() public returns (bool) {695 public696 returns (bool)697 {698 require(false, stub_error);741 require(false, stub_error);699 to;700 tokenIds;701 dummy = 0;742 dummy = 0;702 return false;743 return false;703 }744 }704745705 // @notice Function to mint multiple tokens with the given tokenUris.746 // Returns collection type706 // @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive747 //707 // numbers and first number should be obtained with `nextTokenId` method748 // @return `Fungible` or `NFT` or `ReFungible`708 // @param to The new owner709 // @param tokens array of pairs of token ID and token URI for minted tokens710 //749 //711 // Selector: mintBulkWithTokenURI(address,(uint256,string)[]) 36543006750 // Selector: uniqueCollectionType() d34b55b8712 function mintBulkWithTokenURI(address to, Tuple0[] memory tokens)751 function uniqueCollectionType() public returns (string memory) {713 public714 returns (bool)715 {716 require(false, stub_error);752 require(false, stub_error);717 to;718 tokens;719 dummy = 0;753 dummy = 0;720 return false;754 return "";721 }755 }722}756}723757724contract UniqueRefungible is758contract UniqueRefungible is725 Dummy,759 Dummy,pallets/refungible/src/stubs/UniqueRefungibleToken.soldiffbeforeafterboth31 );31 );32}32}3334// Selector: 042f110635contract ERC1633UniqueExtensions is Dummy, ERC165 {36 // Selector: setParentNFT(address,uint256) 042f110637 function setParentNFT(address collection, uint256 nftId)38 public39 returns (bool)40 {41 require(false, stub_error);42 collection;43 nftId;44 dummy = 0;45 return false;46 }47}4849// Selector: 5755c3f250contract ERC1633 is Dummy, ERC165 {51 // Selector: parentToken() 80a5400152 function parentToken() public view returns (address) {53 require(false, stub_error);54 dummy;55 return 0x0000000000000000000000000000000000000000;56 }5758 // Selector: parentTokenId() d7f083f359 function parentTokenId() public view returns (uint256) {60 require(false, stub_error);61 dummy;62 return 0;63 }64}336534// Selector: 942e8b2266// Selector: 942e8b2235contract ERC20 is Dummy, ERC165, ERC20Events {67contract ERC20 is Dummy, ERC165, ERC20Events {214 Dummy,215 ERC165,216 ERC20,217 ERC20UniqueExtensions,218 ERC1633,219 ERC1633UniqueExtensions220{}182221pallets/refungible/src/weights.rsdiffbeforeafterboth3//! Autogenerated weights for pallet_refungible3//! Autogenerated weights for pallet_refungible4//!4//!5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev6//! DATE: 2022-07-20, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`6//! DATE: 2022-08-01, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`7//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 10247//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024889// Executed Command:9// Executed Command:53 fn set_token_properties(b: u32, ) -> Weight;53 fn set_token_properties(b: u32, ) -> Weight;54 fn delete_token_properties(b: u32, ) -> Weight;54 fn delete_token_properties(b: u32, ) -> Weight;55 fn repartition_item() -> Weight;55 fn repartition_item() -> Weight;56 fn set_parent_nft_unchecked() -> Weight;57 fn token_owner() -> Weight;56}58}575958/// Weights for pallet_refungible using the Substrate node and recommended hardware.60/// Weights for pallet_refungible using the Substrate node and recommended hardware.65 // Storage: Refungible TokenData (r:0 w:1)67 // Storage: Refungible TokenData (r:0 w:1)66 // Storage: Refungible Owned (r:0 w:1)68 // Storage: Refungible Owned (r:0 w:1)67 fn create_item() -> Weight {69 fn create_item() -> Weight {68 (21_310_000 as Weight)70 (25_197_000 as Weight)69 .saturating_add(T::DbWeight::get().reads(2 as Weight))71 .saturating_add(T::DbWeight::get().reads(2 as Weight))70 .saturating_add(T::DbWeight::get().writes(6 as Weight))72 .saturating_add(T::DbWeight::get().writes(6 as Weight))71 }73 }76 // Storage: Refungible TokenData (r:0 w:4)78 // Storage: Refungible TokenData (r:0 w:4)77 // Storage: Refungible Owned (r:0 w:4)79 // Storage: Refungible Owned (r:0 w:4)78 fn create_multiple_items(b: u32, ) -> Weight {80 fn create_multiple_items(b: u32, ) -> Weight {79 (9_552_000 as Weight)81 (10_852_000 as Weight)80 // Standard Error: 2_00082 // Standard Error: 2_00081 .saturating_add((7_056_000 as Weight).saturating_mul(b as Weight))83 .saturating_add((8_087_000 as Weight).saturating_mul(b as Weight))82 .saturating_add(T::DbWeight::get().reads(2 as Weight))84 .saturating_add(T::DbWeight::get().reads(2 as Weight))83 .saturating_add(T::DbWeight::get().writes(2 as Weight))85 .saturating_add(T::DbWeight::get().writes(2 as Weight))84 .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))86 .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))90 // Storage: Refungible TokenData (r:0 w:4)92 // Storage: Refungible TokenData (r:0 w:4)91 // Storage: Refungible Owned (r:0 w:4)93 // Storage: Refungible Owned (r:0 w:4)92 fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight {94 fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight {93 (4_857_000 as Weight)95 (9_978_000 as Weight)94 // Standard Error: 2_00096 // Standard Error: 2_00095 .saturating_add((9_838_000 as Weight).saturating_mul(b as Weight))97 .saturating_add((10_848_000 as Weight).saturating_mul(b as Weight))96 .saturating_add(T::DbWeight::get().reads(1 as Weight))98 .saturating_add(T::DbWeight::get().reads(1 as Weight))97 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))99 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))98 .saturating_add(T::DbWeight::get().writes(1 as Weight))100 .saturating_add(T::DbWeight::get().writes(1 as Weight))105 // Storage: Refungible Balance (r:0 w:4)107 // Storage: Refungible Balance (r:0 w:4)106 // Storage: Refungible Owned (r:0 w:4)108 // Storage: Refungible Owned (r:0 w:4)107 fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight {109 fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight {108 (11_335_000 as Weight)110 (15_419_000 as Weight)109 // Standard Error: 2_000111 // Standard Error: 2_000110 .saturating_add((6_784_000 as Weight).saturating_mul(b as Weight))112 .saturating_add((7_813_000 as Weight).saturating_mul(b as Weight))111 .saturating_add(T::DbWeight::get().reads(1 as Weight))113 .saturating_add(T::DbWeight::get().reads(1 as Weight))112 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))114 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))113 .saturating_add(T::DbWeight::get().writes(3 as Weight))115 .saturating_add(T::DbWeight::get().writes(3 as Weight))118 // Storage: Refungible AccountBalance (r:1 w:1)120 // Storage: Refungible AccountBalance (r:1 w:1)119 // Storage: Refungible Owned (r:0 w:1)121 // Storage: Refungible Owned (r:0 w:1)120 fn burn_item_partial() -> Weight {122 fn burn_item_partial() -> Weight {121 (21_239_000 as Weight)123 (25_578_000 as Weight)122 .saturating_add(T::DbWeight::get().reads(3 as Weight))124 .saturating_add(T::DbWeight::get().reads(3 as Weight))123 .saturating_add(T::DbWeight::get().writes(4 as Weight))125 .saturating_add(T::DbWeight::get().writes(4 as Weight))124 }126 }130 // Storage: Refungible Owned (r:0 w:1)132 // Storage: Refungible Owned (r:0 w:1)131 // Storage: Refungible TokenProperties (r:0 w:1)133 // Storage: Refungible TokenProperties (r:0 w:1)132 fn burn_item_fully() -> Weight {134 fn burn_item_fully() -> Weight {133 (29_426_000 as Weight)135 (33_593_000 as Weight)134 .saturating_add(T::DbWeight::get().reads(4 as Weight))136 .saturating_add(T::DbWeight::get().reads(4 as Weight))135 .saturating_add(T::DbWeight::get().writes(7 as Weight))137 .saturating_add(T::DbWeight::get().writes(7 as Weight))136 }138 }137 // Storage: Refungible Balance (r:2 w:2)139 // Storage: Refungible Balance (r:2 w:2)138 fn transfer_normal() -> Weight {140 fn transfer_normal() -> Weight {139 (17_743_000 as Weight)141 (21_049_000 as Weight)140 .saturating_add(T::DbWeight::get().reads(2 as Weight))142 .saturating_add(T::DbWeight::get().reads(2 as Weight))141 .saturating_add(T::DbWeight::get().writes(2 as Weight))143 .saturating_add(T::DbWeight::get().writes(2 as Weight))142 }144 }143 // Storage: Refungible Balance (r:2 w:2)145 // Storage: Refungible Balance (r:2 w:2)144 // Storage: Refungible AccountBalance (r:1 w:1)146 // Storage: Refungible AccountBalance (r:1 w:1)145 // Storage: Refungible Owned (r:0 w:1)147 // Storage: Refungible Owned (r:0 w:1)146 fn transfer_creating() -> Weight {148 fn transfer_creating() -> Weight {147 (20_699_000 as Weight)149 (24_646_000 as Weight)148 .saturating_add(T::DbWeight::get().reads(3 as Weight))150 .saturating_add(T::DbWeight::get().reads(3 as Weight))149 .saturating_add(T::DbWeight::get().writes(4 as Weight))151 .saturating_add(T::DbWeight::get().writes(4 as Weight))150 }152 }151 // Storage: Refungible Balance (r:2 w:2)153 // Storage: Refungible Balance (r:2 w:2)152 // Storage: Refungible AccountBalance (r:1 w:1)154 // Storage: Refungible AccountBalance (r:1 w:1)153 // Storage: Refungible Owned (r:0 w:1)155 // Storage: Refungible Owned (r:0 w:1)154 fn transfer_removing() -> Weight {156 fn transfer_removing() -> Weight {155 (22_833_000 as Weight)157 (26_570_000 as Weight)156 .saturating_add(T::DbWeight::get().reads(3 as Weight))158 .saturating_add(T::DbWeight::get().reads(3 as Weight))157 .saturating_add(T::DbWeight::get().writes(4 as Weight))159 .saturating_add(T::DbWeight::get().writes(4 as Weight))158 }160 }159 // Storage: Refungible Balance (r:2 w:2)161 // Storage: Refungible Balance (r:2 w:2)160 // Storage: Refungible AccountBalance (r:2 w:2)162 // Storage: Refungible AccountBalance (r:2 w:2)161 // Storage: Refungible Owned (r:0 w:2)163 // Storage: Refungible Owned (r:0 w:2)162 fn transfer_creating_removing() -> Weight {164 fn transfer_creating_removing() -> Weight {163 (24_936_000 as Weight)165 (28_906_000 as Weight)164 .saturating_add(T::DbWeight::get().reads(4 as Weight))166 .saturating_add(T::DbWeight::get().reads(4 as Weight))165 .saturating_add(T::DbWeight::get().writes(6 as Weight))167 .saturating_add(T::DbWeight::get().writes(6 as Weight))166 }168 }167 // Storage: Refungible Balance (r:1 w:0)169 // Storage: Refungible Balance (r:1 w:0)168 // Storage: Refungible Allowance (r:0 w:1)170 // Storage: Refungible Allowance (r:0 w:1)169 fn approve() -> Weight {171 fn approve() -> Weight {170 (13_446_000 as Weight)172 (16_451_000 as Weight)171 .saturating_add(T::DbWeight::get().reads(1 as Weight))173 .saturating_add(T::DbWeight::get().reads(1 as Weight))172 .saturating_add(T::DbWeight::get().writes(1 as Weight))174 .saturating_add(T::DbWeight::get().writes(1 as Weight))173 }175 }174 // Storage: Refungible Allowance (r:1 w:1)176 // Storage: Refungible Allowance (r:1 w:1)175 // Storage: Refungible Balance (r:2 w:2)177 // Storage: Refungible Balance (r:2 w:2)176 fn transfer_from_normal() -> Weight {178 fn transfer_from_normal() -> Weight {177 (24_777_000 as Weight)179 (29_545_000 as Weight)178 .saturating_add(T::DbWeight::get().reads(3 as Weight))180 .saturating_add(T::DbWeight::get().reads(3 as Weight))179 .saturating_add(T::DbWeight::get().writes(3 as Weight))181 .saturating_add(T::DbWeight::get().writes(3 as Weight))180 }182 }183 // Storage: Refungible AccountBalance (r:1 w:1)185 // Storage: Refungible AccountBalance (r:1 w:1)184 // Storage: Refungible Owned (r:0 w:1)186 // Storage: Refungible Owned (r:0 w:1)185 fn transfer_from_creating() -> Weight {187 fn transfer_from_creating() -> Weight {186 (28_483_000 as Weight)188 (33_392_000 as Weight)187 .saturating_add(T::DbWeight::get().reads(4 as Weight))189 .saturating_add(T::DbWeight::get().reads(4 as Weight))188 .saturating_add(T::DbWeight::get().writes(5 as Weight))190 .saturating_add(T::DbWeight::get().writes(5 as Weight))189 }191 }192 // Storage: Refungible AccountBalance (r:1 w:1)194 // Storage: Refungible AccountBalance (r:1 w:1)193 // Storage: Refungible Owned (r:0 w:1)195 // Storage: Refungible Owned (r:0 w:1)194 fn transfer_from_removing() -> Weight {196 fn transfer_from_removing() -> Weight {195 (29_896_000 as Weight)197 (35_446_000 as Weight)196 .saturating_add(T::DbWeight::get().reads(4 as Weight))198 .saturating_add(T::DbWeight::get().reads(4 as Weight))197 .saturating_add(T::DbWeight::get().writes(5 as Weight))199 .saturating_add(T::DbWeight::get().writes(5 as Weight))198 }200 }201 // Storage: Refungible AccountBalance (r:2 w:2)203 // Storage: Refungible AccountBalance (r:2 w:2)202 // Storage: Refungible Owned (r:0 w:2)204 // Storage: Refungible Owned (r:0 w:2)203 fn transfer_from_creating_removing() -> Weight {205 fn transfer_from_creating_removing() -> Weight {204 (32_070_000 as Weight)206 (37_762_000 as Weight)205 .saturating_add(T::DbWeight::get().reads(5 as Weight))207 .saturating_add(T::DbWeight::get().reads(5 as Weight))206 .saturating_add(T::DbWeight::get().writes(7 as Weight))208 .saturating_add(T::DbWeight::get().writes(7 as Weight))207 }209 }214 // Storage: Refungible Owned (r:0 w:1)216 // Storage: Refungible Owned (r:0 w:1)215 // Storage: Refungible TokenProperties (r:0 w:1)217 // Storage: Refungible TokenProperties (r:0 w:1)216 fn burn_from() -> Weight {218 fn burn_from() -> Weight {217 (36_789_000 as Weight)219 (42_620_000 as Weight)218 .saturating_add(T::DbWeight::get().reads(5 as Weight))220 .saturating_add(T::DbWeight::get().reads(5 as Weight))219 .saturating_add(T::DbWeight::get().writes(8 as Weight))221 .saturating_add(T::DbWeight::get().writes(8 as Weight))220 }222 }221 // Storage: Common CollectionPropertyPermissions (r:1 w:1)223 // Storage: Common CollectionPropertyPermissions (r:1 w:1)222 fn set_token_property_permissions(b: u32, ) -> Weight {224 fn set_token_property_permissions(b: u32, ) -> Weight {223 (0 as Weight)225 (0 as Weight)224 // Standard Error: 62_000226 // Standard Error: 65_000225 .saturating_add((15_803_000 as Weight).saturating_mul(b as Weight))227 .saturating_add((16_513_000 as Weight).saturating_mul(b as Weight))226 .saturating_add(T::DbWeight::get().reads(1 as Weight))228 .saturating_add(T::DbWeight::get().reads(1 as Weight))227 .saturating_add(T::DbWeight::get().writes(1 as Weight))229 .saturating_add(T::DbWeight::get().writes(1 as Weight))228 }230 }229 // Storage: Common CollectionPropertyPermissions (r:1 w:0)231 // Storage: Common CollectionPropertyPermissions (r:1 w:0)230 // Storage: Refungible TokenProperties (r:1 w:1)232 // Storage: Refungible TokenProperties (r:1 w:1)231 fn set_token_properties(b: u32, ) -> Weight {233 fn set_token_properties(b: u32, ) -> Weight {232 (0 as Weight)234 (0 as Weight)233 // Standard Error: 1_668_000235 // Standard Error: 1_583_000234 .saturating_add((302_308_000 as Weight).saturating_mul(b as Weight))236 .saturating_add((291_392_000 as Weight).saturating_mul(b as Weight))235 .saturating_add(T::DbWeight::get().reads(2 as Weight))237 .saturating_add(T::DbWeight::get().reads(2 as Weight))236 .saturating_add(T::DbWeight::get().writes(1 as Weight))238 .saturating_add(T::DbWeight::get().writes(1 as Weight))237 }239 }238 // Storage: Common CollectionPropertyPermissions (r:1 w:0)240 // Storage: Common CollectionPropertyPermissions (r:1 w:0)239 // Storage: Refungible TokenProperties (r:1 w:1)241 // Storage: Refungible TokenProperties (r:1 w:1)240 fn delete_token_properties(b: u32, ) -> Weight {242 fn delete_token_properties(b: u32, ) -> Weight {241 (0 as Weight)243 (0 as Weight)242 // Standard Error: 1_619_000244 // Standard Error: 1_699_000243 .saturating_add((294_574_000 as Weight).saturating_mul(b as Weight))245 .saturating_add((293_270_000 as Weight).saturating_mul(b as Weight))244 .saturating_add(T::DbWeight::get().reads(2 as Weight))246 .saturating_add(T::DbWeight::get().reads(2 as Weight))245 .saturating_add(T::DbWeight::get().writes(1 as Weight))247 .saturating_add(T::DbWeight::get().writes(1 as Weight))246 }248 }247 // Storage: Refungible TotalSupply (r:1 w:1)249 // Storage: Refungible TotalSupply (r:1 w:1)248 // Storage: Refungible Balance (r:1 w:1)250 // Storage: Refungible Balance (r:1 w:1)249 fn repartition_item() -> Weight {251 fn repartition_item() -> Weight {250 (8_325_000 as Weight)252 (19_206_000 as Weight)251 .saturating_add(T::DbWeight::get().reads(2 as Weight))253 .saturating_add(T::DbWeight::get().reads(2 as Weight))252 .saturating_add(T::DbWeight::get().writes(2 as Weight))254 .saturating_add(T::DbWeight::get().writes(2 as Weight))253 }255 }256 // Storage: Refungible Balance (r:1 w:0)257 // Storage: Refungible TotalSupply (r:1 w:0)258 // Storage: Refungible TokenProperties (r:1 w:1)259 fn set_parent_nft_unchecked() -> Weight {260 (10_189_000 as Weight)261 .saturating_add(T::DbWeight::get().reads(3 as Weight))262 .saturating_add(T::DbWeight::get().writes(1 as Weight))263 }264 // Storage: Refungible Balance (r:2 w:0)265 fn token_owner() -> Weight {266 (8_205_000 as Weight)267 .saturating_add(T::DbWeight::get().reads(2 as Weight))268 }254}269}255270256// For backwards compatibility and tests271// For backwards compatibility and tests262 // Storage: Refungible TokenData (r:0 w:1)277 // Storage: Refungible TokenData (r:0 w:1)263 // Storage: Refungible Owned (r:0 w:1)278 // Storage: Refungible Owned (r:0 w:1)264 fn create_item() -> Weight {279 fn create_item() -> Weight {265 (21_310_000 as Weight)280 (25_197_000 as Weight)266 .saturating_add(RocksDbWeight::get().reads(2 as Weight))281 .saturating_add(RocksDbWeight::get().reads(2 as Weight))267 .saturating_add(RocksDbWeight::get().writes(6 as Weight))282 .saturating_add(RocksDbWeight::get().writes(6 as Weight))268 }283 }273 // Storage: Refungible TokenData (r:0 w:4)288 // Storage: Refungible TokenData (r:0 w:4)274 // Storage: Refungible Owned (r:0 w:4)289 // Storage: Refungible Owned (r:0 w:4)275 fn create_multiple_items(b: u32, ) -> Weight {290 fn create_multiple_items(b: u32, ) -> Weight {276 (9_552_000 as Weight)291 (10_852_000 as Weight)277 // Standard Error: 2_000292 // Standard Error: 2_000278 .saturating_add((7_056_000 as Weight).saturating_mul(b as Weight))293 .saturating_add((8_087_000 as Weight).saturating_mul(b as Weight))279 .saturating_add(RocksDbWeight::get().reads(2 as Weight))294 .saturating_add(RocksDbWeight::get().reads(2 as Weight))280 .saturating_add(RocksDbWeight::get().writes(2 as Weight))295 .saturating_add(RocksDbWeight::get().writes(2 as Weight))281 .saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))296 .saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))287 // Storage: Refungible TokenData (r:0 w:4)302 // Storage: Refungible TokenData (r:0 w:4)288 // Storage: Refungible Owned (r:0 w:4)303 // Storage: Refungible Owned (r:0 w:4)289 fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight {304 fn create_multiple_items_ex_multiple_items(b: u32, ) -> Weight {290 (4_857_000 as Weight)305 (9_978_000 as Weight)291 // Standard Error: 2_000306 // Standard Error: 2_000292 .saturating_add((9_838_000 as Weight).saturating_mul(b as Weight))307 .saturating_add((10_848_000 as Weight).saturating_mul(b as Weight))293 .saturating_add(RocksDbWeight::get().reads(1 as Weight))308 .saturating_add(RocksDbWeight::get().reads(1 as Weight))294 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))309 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))295 .saturating_add(RocksDbWeight::get().writes(1 as Weight))310 .saturating_add(RocksDbWeight::get().writes(1 as Weight))302 // Storage: Refungible Balance (r:0 w:4)317 // Storage: Refungible Balance (r:0 w:4)303 // Storage: Refungible Owned (r:0 w:4)318 // Storage: Refungible Owned (r:0 w:4)304 fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight {319 fn create_multiple_items_ex_multiple_owners(b: u32, ) -> Weight {305 (11_335_000 as Weight)320 (15_419_000 as Weight)306 // Standard Error: 2_000321 // Standard Error: 2_000307 .saturating_add((6_784_000 as Weight).saturating_mul(b as Weight))322 .saturating_add((7_813_000 as Weight).saturating_mul(b as Weight))308 .saturating_add(RocksDbWeight::get().reads(1 as Weight))323 .saturating_add(RocksDbWeight::get().reads(1 as Weight))309 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))324 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))310 .saturating_add(RocksDbWeight::get().writes(3 as Weight))325 .saturating_add(RocksDbWeight::get().writes(3 as Weight))315 // Storage: Refungible AccountBalance (r:1 w:1)330 // Storage: Refungible AccountBalance (r:1 w:1)316 // Storage: Refungible Owned (r:0 w:1)331 // Storage: Refungible Owned (r:0 w:1)317 fn burn_item_partial() -> Weight {332 fn burn_item_partial() -> Weight {318 (21_239_000 as Weight)333 (25_578_000 as Weight)319 .saturating_add(RocksDbWeight::get().reads(3 as Weight))334 .saturating_add(RocksDbWeight::get().reads(3 as Weight))320 .saturating_add(RocksDbWeight::get().writes(4 as Weight))335 .saturating_add(RocksDbWeight::get().writes(4 as Weight))321 }336 }327 // Storage: Refungible Owned (r:0 w:1)342 // Storage: Refungible Owned (r:0 w:1)328 // Storage: Refungible TokenProperties (r:0 w:1)343 // Storage: Refungible TokenProperties (r:0 w:1)329 fn burn_item_fully() -> Weight {344 fn burn_item_fully() -> Weight {330 (29_426_000 as Weight)345 (33_593_000 as Weight)331 .saturating_add(RocksDbWeight::get().reads(4 as Weight))346 .saturating_add(RocksDbWeight::get().reads(4 as Weight))332 .saturating_add(RocksDbWeight::get().writes(7 as Weight))347 .saturating_add(RocksDbWeight::get().writes(7 as Weight))333 }348 }334 // Storage: Refungible Balance (r:2 w:2)349 // Storage: Refungible Balance (r:2 w:2)335 fn transfer_normal() -> Weight {350 fn transfer_normal() -> Weight {336 (17_743_000 as Weight)351 (21_049_000 as Weight)337 .saturating_add(RocksDbWeight::get().reads(2 as Weight))352 .saturating_add(RocksDbWeight::get().reads(2 as Weight))338 .saturating_add(RocksDbWeight::get().writes(2 as Weight))353 .saturating_add(RocksDbWeight::get().writes(2 as Weight))339 }354 }340 // Storage: Refungible Balance (r:2 w:2)355 // Storage: Refungible Balance (r:2 w:2)341 // Storage: Refungible AccountBalance (r:1 w:1)356 // Storage: Refungible AccountBalance (r:1 w:1)342 // Storage: Refungible Owned (r:0 w:1)357 // Storage: Refungible Owned (r:0 w:1)343 fn transfer_creating() -> Weight {358 fn transfer_creating() -> Weight {344 (20_699_000 as Weight)359 (24_646_000 as Weight)345 .saturating_add(RocksDbWeight::get().reads(3 as Weight))360 .saturating_add(RocksDbWeight::get().reads(3 as Weight))346 .saturating_add(RocksDbWeight::get().writes(4 as Weight))361 .saturating_add(RocksDbWeight::get().writes(4 as Weight))347 }362 }348 // Storage: Refungible Balance (r:2 w:2)363 // Storage: Refungible Balance (r:2 w:2)349 // Storage: Refungible AccountBalance (r:1 w:1)364 // Storage: Refungible AccountBalance (r:1 w:1)350 // Storage: Refungible Owned (r:0 w:1)365 // Storage: Refungible Owned (r:0 w:1)351 fn transfer_removing() -> Weight {366 fn transfer_removing() -> Weight {352 (22_833_000 as Weight)367 (26_570_000 as Weight)353 .saturating_add(RocksDbWeight::get().reads(3 as Weight))368 .saturating_add(RocksDbWeight::get().reads(3 as Weight))354 .saturating_add(RocksDbWeight::get().writes(4 as Weight))369 .saturating_add(RocksDbWeight::get().writes(4 as Weight))355 }370 }356 // Storage: Refungible Balance (r:2 w:2)371 // Storage: Refungible Balance (r:2 w:2)357 // Storage: Refungible AccountBalance (r:2 w:2)372 // Storage: Refungible AccountBalance (r:2 w:2)358 // Storage: Refungible Owned (r:0 w:2)373 // Storage: Refungible Owned (r:0 w:2)359 fn transfer_creating_removing() -> Weight {374 fn transfer_creating_removing() -> Weight {360 (24_936_000 as Weight)375 (28_906_000 as Weight)361 .saturating_add(RocksDbWeight::get().reads(4 as Weight))376 .saturating_add(RocksDbWeight::get().reads(4 as Weight))362 .saturating_add(RocksDbWeight::get().writes(6 as Weight))377 .saturating_add(RocksDbWeight::get().writes(6 as Weight))363 }378 }364 // Storage: Refungible Balance (r:1 w:0)379 // Storage: Refungible Balance (r:1 w:0)365 // Storage: Refungible Allowance (r:0 w:1)380 // Storage: Refungible Allowance (r:0 w:1)366 fn approve() -> Weight {381 fn approve() -> Weight {367 (13_446_000 as Weight)382 (16_451_000 as Weight)368 .saturating_add(RocksDbWeight::get().reads(1 as Weight))383 .saturating_add(RocksDbWeight::get().reads(1 as Weight))369 .saturating_add(RocksDbWeight::get().writes(1 as Weight))384 .saturating_add(RocksDbWeight::get().writes(1 as Weight))370 }385 }371 // Storage: Refungible Allowance (r:1 w:1)386 // Storage: Refungible Allowance (r:1 w:1)372 // Storage: Refungible Balance (r:2 w:2)387 // Storage: Refungible Balance (r:2 w:2)373 fn transfer_from_normal() -> Weight {388 fn transfer_from_normal() -> Weight {374 (24_777_000 as Weight)389 (29_545_000 as Weight)375 .saturating_add(RocksDbWeight::get().reads(3 as Weight))390 .saturating_add(RocksDbWeight::get().reads(3 as Weight))376 .saturating_add(RocksDbWeight::get().writes(3 as Weight))391 .saturating_add(RocksDbWeight::get().writes(3 as Weight))377 }392 }380 // Storage: Refungible AccountBalance (r:1 w:1)395 // Storage: Refungible AccountBalance (r:1 w:1)381 // Storage: Refungible Owned (r:0 w:1)396 // Storage: Refungible Owned (r:0 w:1)382 fn transfer_from_creating() -> Weight {397 fn transfer_from_creating() -> Weight {383 (28_483_000 as Weight)398 (33_392_000 as Weight)384 .saturating_add(RocksDbWeight::get().reads(4 as Weight))399 .saturating_add(RocksDbWeight::get().reads(4 as Weight))385 .saturating_add(RocksDbWeight::get().writes(5 as Weight))400 .saturating_add(RocksDbWeight::get().writes(5 as Weight))386 }401 }389 // Storage: Refungible AccountBalance (r:1 w:1)404 // Storage: Refungible AccountBalance (r:1 w:1)390 // Storage: Refungible Owned (r:0 w:1)405 // Storage: Refungible Owned (r:0 w:1)391 fn transfer_from_removing() -> Weight {406 fn transfer_from_removing() -> Weight {392 (29_896_000 as Weight)407 (35_446_000 as Weight)393 .saturating_add(RocksDbWeight::get().reads(4 as Weight))408 .saturating_add(RocksDbWeight::get().reads(4 as Weight))394 .saturating_add(RocksDbWeight::get().writes(5 as Weight))409 .saturating_add(RocksDbWeight::get().writes(5 as Weight))395 }410 }398 // Storage: Refungible AccountBalance (r:2 w:2)413 // Storage: Refungible AccountBalance (r:2 w:2)399 // Storage: Refungible Owned (r:0 w:2)414 // Storage: Refungible Owned (r:0 w:2)400 fn transfer_from_creating_removing() -> Weight {415 fn transfer_from_creating_removing() -> Weight {401 (32_070_000 as Weight)416 (37_762_000 as Weight)402 .saturating_add(RocksDbWeight::get().reads(5 as Weight))417 .saturating_add(RocksDbWeight::get().reads(5 as Weight))403 .saturating_add(RocksDbWeight::get().writes(7 as Weight))418 .saturating_add(RocksDbWeight::get().writes(7 as Weight))404 }419 }411 // Storage: Refungible Owned (r:0 w:1)426 // Storage: Refungible Owned (r:0 w:1)412 // Storage: Refungible TokenProperties (r:0 w:1)427 // Storage: Refungible TokenProperties (r:0 w:1)413 fn burn_from() -> Weight {428 fn burn_from() -> Weight {414 (36_789_000 as Weight)429 (42_620_000 as Weight)415 .saturating_add(RocksDbWeight::get().reads(5 as Weight))430 .saturating_add(RocksDbWeight::get().reads(5 as Weight))416 .saturating_add(RocksDbWeight::get().writes(8 as Weight))431 .saturating_add(RocksDbWeight::get().writes(8 as Weight))417 }432 }418 // Storage: Common CollectionPropertyPermissions (r:1 w:1)433 // Storage: Common CollectionPropertyPermissions (r:1 w:1)419 fn set_token_property_permissions(b: u32, ) -> Weight {434 fn set_token_property_permissions(b: u32, ) -> Weight {420 (0 as Weight)435 (0 as Weight)421 // Standard Error: 62_000436 // Standard Error: 65_000422 .saturating_add((15_803_000 as Weight).saturating_mul(b as Weight))437 .saturating_add((16_513_000 as Weight).saturating_mul(b as Weight))423 .saturating_add(RocksDbWeight::get().reads(1 as Weight))438 .saturating_add(RocksDbWeight::get().reads(1 as Weight))424 .saturating_add(RocksDbWeight::get().writes(1 as Weight))439 .saturating_add(RocksDbWeight::get().writes(1 as Weight))425 }440 }426 // Storage: Common CollectionPropertyPermissions (r:1 w:0)441 // Storage: Common CollectionPropertyPermissions (r:1 w:0)427 // Storage: Refungible TokenProperties (r:1 w:1)442 // Storage: Refungible TokenProperties (r:1 w:1)428 fn set_token_properties(b: u32, ) -> Weight {443 fn set_token_properties(b: u32, ) -> Weight {429 (0 as Weight)444 (0 as Weight)430 // Standard Error: 1_668_000445 // Standard Error: 1_583_000431 .saturating_add((302_308_000 as Weight).saturating_mul(b as Weight))446 .saturating_add((291_392_000 as Weight).saturating_mul(b as Weight))432 .saturating_add(RocksDbWeight::get().reads(2 as Weight))447 .saturating_add(RocksDbWeight::get().reads(2 as Weight))433 .saturating_add(RocksDbWeight::get().writes(1 as Weight))448 .saturating_add(RocksDbWeight::get().writes(1 as Weight))434 }449 }435 // Storage: Common CollectionPropertyPermissions (r:1 w:0)450 // Storage: Common CollectionPropertyPermissions (r:1 w:0)436 // Storage: Refungible TokenProperties (r:1 w:1)451 // Storage: Refungible TokenProperties (r:1 w:1)437 fn delete_token_properties(b: u32, ) -> Weight {452 fn delete_token_properties(b: u32, ) -> Weight {438 (0 as Weight)453 (0 as Weight)439 // Standard Error: 1_619_000454 // Standard Error: 1_699_000440 .saturating_add((294_574_000 as Weight).saturating_mul(b as Weight))455 .saturating_add((293_270_000 as Weight).saturating_mul(b as Weight))441 .saturating_add(RocksDbWeight::get().reads(2 as Weight))456 .saturating_add(RocksDbWeight::get().reads(2 as Weight))442 .saturating_add(RocksDbWeight::get().writes(1 as Weight))457 .saturating_add(RocksDbWeight::get().writes(1 as Weight))443 }458 }444 // Storage: Refungible TotalSupply (r:1 w:1)459 // Storage: Refungible TotalSupply (r:1 w:1)445 // Storage: Refungible Balance (r:1 w:1)460 // Storage: Refungible Balance (r:1 w:1)446 fn repartition_item() -> Weight {461 fn repartition_item() -> Weight {447 (8_325_000 as Weight)462 (19_206_000 as Weight)448 .saturating_add(RocksDbWeight::get().reads(2 as Weight))463 .saturating_add(RocksDbWeight::get().reads(2 as Weight))449 .saturating_add(RocksDbWeight::get().writes(2 as Weight))464 .saturating_add(RocksDbWeight::get().writes(2 as Weight))450 }465 }466 // Storage: Refungible Balance (r:1 w:0)467 // Storage: Refungible TotalSupply (r:1 w:0)468 // Storage: Refungible TokenProperties (r:1 w:1)469 fn set_parent_nft_unchecked() -> Weight {470 (10_189_000 as Weight)471 .saturating_add(RocksDbWeight::get().reads(3 as Weight))472 .saturating_add(RocksDbWeight::get().writes(1 as Weight))473 }474 // Storage: Refungible Balance (r:2 w:0)475 fn token_owner() -> Weight {476 (8_205_000 as Weight)477 .saturating_add(RocksDbWeight::get().reads(2 as Weight))478 }451}479}452480pallets/unique/src/eth/mod.rsdiffbeforeafterboth17//! Implementation of CollectionHelpers contract.17//! Implementation of CollectionHelpers contract.181819use core::marker::PhantomData;19use core::marker::PhantomData;20use ethereum as _;20use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};21use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};22use frame_support::traits::Get;21use ethereum as _;23use pallet_common::{24 CollectionById, CollectionHandle,25 dispatch::CollectionDispatch,26 erc::{27 CollectionHelpersEvents,28 static_property::{key, value as property_value},29 },30 Pallet as PalletCommon,31};22use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};32use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};23use pallet_evm::{OnMethodCall, PrecompileResult, account::CrossAccountId, PrecompileHandle};33use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};34use pallet_evm_coder_substrate::dispatch_to_evm;24use up_data_structs::{35use up_data_structs::{25 CollectionName, CollectionDescription, CollectionTokenPrefix, CreateCollectionData,36 CollectionName, CollectionDescription, CollectionTokenPrefix, CreateCollectionData,26 CollectionMode, PropertyValue,37 CollectionMode, PropertyKeyPermission, PropertyPermission, PropertyScope, PropertyValue,27};38};28use frame_support::traits::Get;3929use pallet_common::{30 CollectionById,31 erc::{32 static_property::{key, value as property_value},33 CollectionHelpersEvents,34 },35 dispatch::CollectionDispatch,36};37use crate::{SelfWeightOf, Config, weights::WeightInfo};40use crate::{Config, SelfWeightOf, weights::WeightInfo};384139use sp_std::vec::Vec;42use sp_std::{vec, vec::Vec};40use alloc::format;43use alloc::format;414442/// See [`CollectionHelpersCall`]45/// See [`CollectionHelpersCall`]151 Ok(data)154 Ok(data)152}155}156157fn parent_nft_property_permissions() -> PropertyKeyPermission {158 PropertyKeyPermission {159 key: key::parent_nft(),160 permission: PropertyPermission {161 mutable: false,162 collection_admin: false,163 token_owner: true,164 },165 }166}167168fn create_refungible_collection_internal<169 T: Config + pallet_nonfungible::Config + pallet_refungible::Config,170>(171 caller: caller,172 name: string,173 description: string,174 token_prefix: string,175 base_uri: string,176 add_properties: bool,177) -> Result<address> {178 let (caller, name, description, token_prefix, base_uri_value) =179 convert_data::<T>(caller, name, description, token_prefix, base_uri)?;180 let data = make_data::<T>(181 name,182 CollectionMode::ReFungible,183 description,184 token_prefix,185 base_uri_value,186 add_properties,187 )?;188189 let collection_id = T::CollectionDispatch::create(caller.clone(), data)190 .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;191192 let handle = <CollectionHandle<T>>::try_get(collection_id).map_err(dispatch_to_evm::<T>)?;193 <PalletCommon<T>>::set_scoped_token_property_permissions(194 &handle,195 &caller,196 PropertyScope::Eth,197 vec![parent_nft_property_permissions()],198 )199 .map_err(dispatch_to_evm::<T>)?;200201 let address = pallet_common::eth::collection_id_to_address(collection_id);202 Ok(address)203}153204154/// @title Contract, which allows users to operate with collections205/// @title Contract, which allows users to operate with collections155#[solidity_interface(name = "CollectionHelpers", events(CollectionHelpersEvents))]206#[solidity_interface(name = "CollectionHelpers", events(CollectionHelpersEvents))]216267217 #[weight(<SelfWeightOf<T>>::create_collection())]268 #[weight(<SelfWeightOf<T>>::create_collection())]218 fn create_refungible_collection(269 fn create_refungible_collection(219 &self,270 &mut self,220 caller: caller,271 caller: caller,221 name: string,272 name: string,222 description: string,273 description: string,223 token_prefix: string,274 token_prefix: string,224 ) -> Result<address> {275 ) -> Result<address> {225 let (caller, name, description, token_prefix, _base_uri) =226 convert_data::<T>(caller, name, description, token_prefix, "".into())?;227 let data = make_data::<T>(276 create_refungible_collection_internal::<T>(277 caller,228 name,278 name,229 CollectionMode::ReFungible,230 description,279 description,231 token_prefix,280 token_prefix,232 Default::default(),281 Default::default(),233 false,282 false,234 )?;283 )235 let collection_id = T::CollectionDispatch::create(caller, data)236 .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;237238 let address = pallet_common::eth::collection_id_to_address(collection_id);239 Ok(address)240 }284 }241285242 #[weight(<SelfWeightOf<T>>::create_collection())]286 #[weight(<SelfWeightOf<T>>::create_collection())]249 token_prefix: string,293 token_prefix: string,250 base_uri: string,294 base_uri: string,251 ) -> Result<address> {295 ) -> Result<address> {252 let (caller, name, description, token_prefix, base_uri_value) =253 convert_data::<T>(caller, name, description, token_prefix, base_uri)?;296 create_refungible_collection_internal::<T>(254 let data = make_data::<T>(297 caller,255 name,298 name,256 CollectionMode::NFT,299 description,257 description,300 token_prefix,258 token_prefix,301 base_uri,259 base_uri_value,302 true,260 true,303 )261 )?;262 let collection_id = T::CollectionDispatch::create(caller, data)263 .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;264265 let address = pallet_common::eth::collection_id_to_address(collection_id);266 Ok(address)267 }304 }268305269 /// Check if a collection exists306 /// Check if a collection existspallets/unique/src/eth/stubs/CollectionHelpers.soldiffbeforeafterboth72 string memory name,72 string memory name,73 string memory description,73 string memory description,74 string memory tokenPrefix74 string memory tokenPrefix75 ) public view returns (address) {75 ) public returns (address) {76 require(false, stub_error);76 require(false, stub_error);77 name;77 name;78 description;78 description;79 tokenPrefix;79 tokenPrefix;80 dummy;80 dummy = 0;81 return 0x0000000000000000000000000000000000000000;81 return 0x0000000000000000000000000000000000000000;82 }82 }8383primitives/data-structs/src/lib.rsdiffbeforeafterboth1050pub enum PropertyScope {1050pub enum PropertyScope {1051 None,1051 None,1052 Rmrk,1052 Rmrk,1053 Eth,1053}1054}105410551055impl PropertyScope {1056impl PropertyScope {1058 let scope_str: &[u8] = match self {1059 let scope_str: &[u8] = match self {1059 Self::None => return Ok(key),1060 Self::None => return Ok(key),1060 Self::Rmrk => b"rmrk",1061 Self::Rmrk => b"rmrk",1062 Self::Eth => b"eth",1061 };1063 };106210641063 [scope_str, b":", key.as_slice()]1065 [scope_str, b":", key.as_slice()]runtime/common/src/weights.rsdiffbeforeafterboth100 max_weight_of!(burn_recursively_breadth_raw(amount))100 max_weight_of!(burn_recursively_breadth_raw(amount))101 }101 }102103 fn token_owner() -> Weight {104 max_weight_of!(token_owner())105 }102}106}103107104impl<T> RefungibleExtensionsWeightInfo for CommonWeights<T>108impl<T> RefungibleExtensionsWeightInfo for CommonWeights<T>tests/src/eth/api/CollectionHelpers.soldiffbeforeafterboth48 string memory name,48 string memory name,49 string memory description,49 string memory description,50 string memory tokenPrefix50 string memory tokenPrefix51 ) external view returns (address);51 ) external returns (address);525253 // Selector: createERC721MetadataCompatibleRFTCollection(string,string,string,string) a559638853 // Selector: createERC721MetadataCompatibleRFTCollection(string,string,string,string) a559638854 function createERC721MetadataCompatibleRFTCollection(54 function createERC721MetadataCompatibleRFTCollection(tests/src/eth/api/UniqueFungible.soldiffbeforeafterboth28 function burnFrom(address from, uint256 amount) external returns (bool);28 function burnFrom(address from, uint256 amount) external returns (bool);29}29}3031// Selector: 7d9262e632interface Collection is Dummy, ERC165 {33 // Set collection property.34 //35 // @param key Property key.36 // @param value Propery value.37 //38 // Selector: setCollectionProperty(string,bytes) 2f073f6639 function setCollectionProperty(string memory key, bytes memory value)40 external;4142 // Delete collection property.43 //44 // @param key Property key.45 //46 // Selector: deleteCollectionProperty(string) 7b7debce47 function deleteCollectionProperty(string memory key) external;4849 // Get collection property.50 //51 // @dev Throws error if key not found.52 //53 // @param key Property key.54 // @return bytes The property corresponding to the key.55 //56 // Selector: collectionProperty(string) cf24fd6d57 function collectionProperty(string memory key)58 external59 view60 returns (bytes memory);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 //68 // Selector: setCollectionSponsor(address) 7623402e69 function setCollectionSponsor(address sponsor) external;7071 // Collection sponsorship confirmation.72 //73 // @dev After setting the sponsor for the collection, it must be confirmed with this function.74 //75 // Selector: confirmCollectionSponsorship() 3c50e97a76 function confirmCollectionSponsorship() external;7778 // Set limits for the collection.79 // @dev Throws error if limit not found.80 // @param limit Name of the limit. Valid names:81 // "accountTokenOwnershipLimit",82 // "sponsoredDataSize",83 // "sponsoredDataRateLimit",84 // "tokenLimit",85 // "sponsorTransferTimeout",86 // "sponsorApproveTimeout"87 // @param value Value of the limit.88 //89 // Selector: setCollectionLimit(string,uint32) 6a3841db90 function setCollectionLimit(string memory limit, uint32 value) external;9192 // Set limits for the collection.93 // @dev Throws error if limit not found.94 // @param limit Name of the limit. Valid names:95 // "ownerCanTransfer",96 // "ownerCanDestroy",97 // "transfersEnabled"98 // @param value Value of the limit.99 //100 // Selector: setCollectionLimit(string,bool) 993b7fba101 function setCollectionLimit(string memory limit, bool value) external;102103 // Get contract address.104 //105 // Selector: contractAddress() f6b4dfb4106 function contractAddress() external view returns (address);107108 // Add collection admin by substrate address.109 // @param new_admin Substrate administrator address.110 //111 // Selector: addCollectionAdminSubstrate(uint256) 5730062b112 function addCollectionAdminSubstrate(uint256 newAdmin) external;113114 // Remove collection admin by substrate address.115 // @param admin Substrate administrator address.116 //117 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9118 function removeCollectionAdminSubstrate(uint256 admin) external;119120 // Add collection admin.121 // @param new_admin Address of the added administrator.122 //123 // Selector: addCollectionAdmin(address) 92e462c7124 function addCollectionAdmin(address newAdmin) external;125126 // Remove collection admin.127 //128 // @param new_admin Address of the removed administrator.129 //130 // Selector: removeCollectionAdmin(address) fafd7b42131 function removeCollectionAdmin(address admin) external;132133 // Toggle accessibility of collection nesting.134 //135 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'136 //137 // Selector: setCollectionNesting(bool) 112d4586138 function setCollectionNesting(bool enable) external;139140 // Toggle accessibility of collection nesting.141 //142 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'143 // @param collections Addresses of collections that will be available for nesting.144 //145 // Selector: setCollectionNesting(bool,address[]) 64872396146 function setCollectionNesting(bool enable, address[] memory collections)147 external;148149 // Set the collection access method.150 // @param mode Access mode151 // 0 for Normal152 // 1 for AllowList153 //154 // Selector: setCollectionAccess(uint8) 41835d4c155 function setCollectionAccess(uint8 mode) external;156157 // Add the user to the allowed list.158 //159 // @param user Address of a trusted user.160 //161 // Selector: addToCollectionAllowList(address) 67844fe6162 function addToCollectionAllowList(address user) external;163164 // Remove the user from the allowed list.165 //166 // @param user Address of a removed user.167 //168 // Selector: removeFromCollectionAllowList(address) 85c51acb169 function removeFromCollectionAllowList(address user) external;170171 // Switch permission for minting.172 //173 // @param mode Enable if "true".174 //175 // Selector: setCollectionMintMode(bool) 00018e84176 function setCollectionMintMode(bool mode) external;177}17830179// Selector: 942e8b2231// Selector: 942e8b22180interface ERC20 is Dummy, ERC165, ERC20Events {32interface ERC20 is Dummy, ERC165, ERC20Events {213 returns (uint256);65 returns (uint256);214}66}6768// Selector: aa7d570d69interface Collection is Dummy, ERC165 {70 // Set collection property.71 //72 // @param key Property key.73 // @param value Propery value.74 //75 // Selector: setCollectionProperty(string,bytes) 2f073f6676 function setCollectionProperty(string memory key, bytes memory value)77 external;7879 // Delete collection property.80 //81 // @param key Property key.82 //83 // Selector: deleteCollectionProperty(string) 7b7debce84 function deleteCollectionProperty(string memory key) external;8586 // Get collection property.87 //88 // @dev Throws error if key not found.89 //90 // @param key Property key.91 // @return bytes The property corresponding to the key.92 //93 // Selector: collectionProperty(string) cf24fd6d94 function collectionProperty(string memory key)95 external96 view97 returns (bytes memory);9899 // Set the sponsor of the collection.100 //101 // @dev In order for sponsorship to work, it must be confirmed on behalf of the sponsor.102 //103 // @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.104 //105 // Selector: setCollectionSponsor(address) 7623402e106 function setCollectionSponsor(address sponsor) external;107108 // Collection sponsorship confirmation.109 //110 // @dev After setting the sponsor for the collection, it must be confirmed with this function.111 //112 // Selector: confirmCollectionSponsorship() 3c50e97a113 function confirmCollectionSponsorship() external;114115 // Set limits for the collection.116 // @dev Throws error if limit not found.117 // @param limit Name of the limit. Valid names:118 // "accountTokenOwnershipLimit",119 // "sponsoredDataSize",120 // "sponsoredDataRateLimit",121 // "tokenLimit",122 // "sponsorTransferTimeout",123 // "sponsorApproveTimeout"124 // @param value Value of the limit.125 //126 // Selector: setCollectionLimit(string,uint32) 6a3841db127 function setCollectionLimit(string memory limit, uint32 value) external;128129 // Set limits for the collection.130 // @dev Throws error if limit not found.131 // @param limit Name of the limit. Valid names:132 // "ownerCanTransfer",133 // "ownerCanDestroy",134 // "transfersEnabled"135 // @param value Value of the limit.136 //137 // Selector: setCollectionLimit(string,bool) 993b7fba138 function setCollectionLimit(string memory limit, bool value) external;139140 // Get contract address.141 //142 // Selector: contractAddress() f6b4dfb4143 function contractAddress() external view returns (address);144145 // Add collection admin by substrate address.146 // @param new_admin Substrate administrator address.147 //148 // Selector: addCollectionAdminSubstrate(uint256) 5730062b149 function addCollectionAdminSubstrate(uint256 newAdmin) external;150151 // Remove collection admin by substrate address.152 // @param admin Substrate administrator address.153 //154 // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9155 function removeCollectionAdminSubstrate(uint256 admin) external;156157 // Add collection admin.158 // @param new_admin Address of the added administrator.159 //160 // Selector: addCollectionAdmin(address) 92e462c7161 function addCollectionAdmin(address newAdmin) external;162163 // Remove collection admin.164 //165 // @param new_admin Address of the removed administrator.166 //167 // Selector: removeCollectionAdmin(address) fafd7b42168 function removeCollectionAdmin(address admin) external;169170 // Toggle accessibility of collection nesting.171 //172 // @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'173 //174 // Selector: setCollectionNesting(bool) 112d4586175 function setCollectionNesting(bool enable) external;176177 // Toggle accessibility of collection nesting.178 //179 // @param enable If "true" degenerates to nesting: {OwnerRestricted: [1, 2, 3]} else to nesting: 'Disabled'180 // @param collections Addresses of collections that will be available for nesting.181 //182 // Selector: setCollectionNesting(bool,address[]) 64872396183 function setCollectionNesting(bool enable, address[] memory collections)184 external;185186 // Set the collection access method.187 // @param mode Access mode188 // 0 for Normal189 // 1 for AllowList190 //191 // Selector: setCollectionAccess(uint8) 41835d4c192 function setCollectionAccess(uint8 mode) external;193194 // Add the user to the allowed list.195 //196 // @param user Address of a trusted user.197 //198 // Selector: addToCollectionAllowList(address) 67844fe6199 function addToCollectionAllowList(address user) external;200201 // Remove the user from the allowed list.202 //203 // @param user Address of a removed user.204 //205 // Selector: removeFromCollectionAllowList(address) 85c51acb206 function removeFromCollectionAllowList(address user) external;207208 // Switch permission for minting.209 //210 // @param mode Enable if "true".211 //212 // Selector: setCollectionMintMode(bool) 00018e84213 function setCollectionMintMode(bool mode) external;214215 // Check that account is the owner or admin of the collection216 //217 // @return "true" if account is the owner or admin218 //219 // Selector: verifyOwnerOrAdmin() 04a46053220 function verifyOwnerOrAdmin() external returns (bool);221222 // Selector: uniqueCollectionType() d34b55b8223 function uniqueCollectionType() external returns (string memory);224}215225216interface UniqueFungible is226interface UniqueFungible is217 Dummy,227 Dummy,tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth276 function totalSupply() external view returns (uint256);276 function totalSupply() external view returns (uint256);277}277}278278279// Selector: 7d9262e6279// Selector: aa7d570d280interface Collection is Dummy, ERC165 {280interface Collection is Dummy, ERC165 {281 // Set collection property.281 // Set collection property.282 //282 //423 // Selector: setCollectionMintMode(bool) 00018e84423 // Selector: setCollectionMintMode(bool) 00018e84424 function setCollectionMintMode(bool mode) external;424 function setCollectionMintMode(bool mode) external;425426 // Check that account is the owner or admin of the collection427 //428 // @return "true" if account is the owner or admin429 //430 // Selector: verifyOwnerOrAdmin() 04a46053431 function verifyOwnerOrAdmin() external returns (bool);432433 // Selector: uniqueCollectionType() d34b55b8434 function uniqueCollectionType() external returns (string memory);425}435}426436427// Selector: d74d154f437// Selector: d74d154ftests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth274 function totalSupply() external view returns (uint256);274 function totalSupply() external view returns (uint256);275}275}276276277// Selector: 7d9262e6277// Selector: 7c3bef89278interface Collection is Dummy, ERC165 {278interface ERC721UniqueExtensions is Dummy, ERC165 {279 // @notice Transfer ownership of an RFT280 // @dev Throws unless `msg.sender` is the current owner. Throws if `to`281 // is the zero address. Throws if `tokenId` is not a valid RFT.282 // Throws if RFT pieces have multiple owners.283 // @param to The new owner284 // @param tokenId The RFT to transfer285 // @param _value Not used for an RFT286 //287 // Selector: transfer(address,uint256) a9059cbb288 function transfer(address to, uint256 tokenId) external;289290 // @notice Burns a specific ERC721 token.291 // @dev Throws unless `msg.sender` is the current owner or an authorized292 // operator for this RFT. Throws if `from` is not the current owner. Throws293 // if `to` is the zero address. Throws if `tokenId` is not a valid RFT.294 // Throws if RFT pieces have multiple owners.295 // @param from The current owner of the RFT296 // @param tokenId The RFT to transfer297 // @param _value Not used for an RFT298 //299 // Selector: burnFrom(address,uint256) 79cc6790300 function burnFrom(address from, uint256 tokenId) external;301302 // @notice Returns next free RFT ID.303 //304 // Selector: nextTokenId() 75794a3c305 function nextTokenId() external view returns (uint256);306307 // @notice Function to mint multiple tokens.308 // @dev `tokenIds` should be an array of consecutive numbers and first number309 // should be obtained with `nextTokenId` method310 // @param to The new owner311 // @param tokenIds IDs of the minted RFTs312 //313 // Selector: mintBulk(address,uint256[]) 44a9945e314 function mintBulk(address to, uint256[] memory tokenIds)315 external316 returns (bool);317318 // @notice Function to mint multiple tokens with the given tokenUris.319 // @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive320 // numbers and first number should be obtained with `nextTokenId` method321 // @param to The new owner322 // @param tokens array of pairs of token ID and token URI for minted tokens323 //324 // Selector: mintBulkWithTokenURI(address,(uint256,string)[]) 36543006325 function mintBulkWithTokenURI(address to, Tuple0[] memory tokens)326 external327 returns (bool);328329 // Returns EVM address for refungible token330 //331 // @param token ID of the token332 //333 // Selector: tokenContractAddress(uint256) ab76fac6334 function tokenContractAddress(uint256 token)335 external336 view337 returns (address);338}339340// Selector: aa7d570d341interface Collection is Dummy, ERC165 {279 // Set collection property.342 // Set collection property.280 //343 //281 // @param key Property key.344 // @param key Property key.420 //483 //421 // Selector: setCollectionMintMode(bool) 00018e84484 // Selector: setCollectionMintMode(bool) 00018e84422 function setCollectionMintMode(bool mode) external;485 function setCollectionMintMode(bool mode) external;423}486424487 // Check that account is the owner or admin of the collection425// Selector: d74d154f426interface ERC721UniqueExtensions is Dummy, ERC165 {427 // @notice Transfer ownership of an RFT428 // @dev Throws unless `msg.sender` is the current owner. Throws if `to`429 // is the zero address. Throws if `tokenId` is not a valid RFT.430 // Throws if RFT pieces have multiple owners.431 // @param to The new owner432 // @param tokenId The RFT to transfer433 // @param _value Not used for an RFT434 //488 //435 // Selector: transfer(address,uint256) a9059cbb489 // @return "true" if account is the owner or admin436 function transfer(address to, uint256 tokenId) external;437438 // @notice Burns a specific ERC721 token.439 // @dev Throws unless `msg.sender` is the current owner or an authorized440 // operator for this RFT. Throws if `from` is not the current owner. Throws441 // if `to` is the zero address. Throws if `tokenId` is not a valid RFT.442 // Throws if RFT pieces have multiple owners.443 // @param from The current owner of the RFT444 // @param tokenId The RFT to transfer445 // @param _value Not used for an RFT446 //447 // Selector: burnFrom(address,uint256) 79cc6790448 function burnFrom(address from, uint256 tokenId) external;449450 // @notice Returns next free RFT ID.451 //490 //452 // Selector: nextTokenId() 75794a3c491 // Selector: verifyOwnerOrAdmin() 04a46053453 function nextTokenId() external view returns (uint256);454455 // @notice Function to mint multiple tokens.456 // @dev `tokenIds` should be an array of consecutive numbers and first number457 // should be obtained with `nextTokenId` method458 // @param to The new owner459 // @param tokenIds IDs of the minted RFTs460 //461 // Selector: mintBulk(address,uint256[]) 44a9945e462 function mintBulk(address to, uint256[] memory tokenIds)492 function verifyOwnerOrAdmin() external returns (bool);463 external493464 returns (bool);494 // Returns collection type465495 //466 // @notice Function to mint multiple tokens with the given tokenUris.496 // @return `Fungible` or `NFT` or `ReFungible`467 // @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive468 // numbers and first number should be obtained with `nextTokenId` method469 // @param to The new owner470 // @param tokens array of pairs of token ID and token URI for minted tokens471 //497 //472 // Selector: mintBulkWithTokenURI(address,(uint256,string)[]) 36543006498 // Selector: uniqueCollectionType() d34b55b8473 function mintBulkWithTokenURI(address to, Tuple0[] memory tokens)499 function uniqueCollectionType() external returns (string memory);474 external500}475 returns (bool);476}477501478interface UniqueRefungible is502interface UniqueRefungible is479 Dummy,503 Dummy,tests/src/eth/api/UniqueRefungibleToken.soldiffbeforeafterboth22 );22 );23}23}2425// Selector: 042f110626interface ERC1633UniqueExtensions is Dummy, ERC165 {27 // Selector: setParentNFT(address,uint256) 042f110628 function setParentNFT(address collection, uint256 nftId)29 external30 returns (bool);31}3233// Selector: 5755c3f234interface ERC1633 is Dummy, ERC165 {35 // Selector: parentToken() 80a5400136 function parentToken() external view returns (address);3738 // Selector: parentTokenId() d7f083f339 function parentTokenId() external view returns (uint256);40}244125// Selector: 942e8b2242// Selector: 942e8b2226interface ERC20 is Dummy, ERC165, ERC20Events {43interface ERC20 is Dummy, ERC165, ERC20Events {115 Dummy,132 Dummy,116 ERC165,133 ERC165,117 ERC20,134 ERC20,118 ERC20UniqueExtensions135 ERC20UniqueExtensions,136 ERC1633,137 ERC1633UniqueExtensions119{}138{}120139tests/src/eth/reFungibleAbi.jsondiffbeforeafterboth480 "stateMutability": "view",480 "stateMutability": "view",481 "type": "function"481 "type": "function"482 },482 },483 {484 "inputs": [485 { "internalType": "uint256", "name": "token", "type": "uint256" }486 ],487 "name": "tokenContractAddress",488 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],489 "stateMutability": "view",490 "type": "function"491 },483 {492 {484 "inputs": [493 "inputs": [485 { "internalType": "address", "name": "owner", "type": "address" },494 { "internalType": "address", "name": "owner", "type": "address" },526 "outputs": [],535 "outputs": [],527 "stateMutability": "nonpayable",536 "stateMutability": "nonpayable",528 "type": "function"537 "type": "function"529 }538 },539 {540 "inputs": [],541 "name": "uniqueCollectionType",542 "outputs": [{ "internalType": "string", "name": "", "type": "string" }],543 "stateMutability": "nonpayable",544 "type": "function"545 },546 {547 "inputs": [],548 "name": "verifyOwnerOrAdmin",549 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],550 "stateMutability": "nonpayable",551 "type": "function"552 }530]553]531554tests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.161617import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE} from '../util/helpers';17import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE} from '../util/helpers';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth} from './util/helpers';18import {collectionIdFromAddress, collectionIdToAddress, createEthAccount, createEthAccountWithBalance, createNonfungibleCollection, createRefungibleCollection, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth, uniqueNFT, uniqueRefungible, uniqueRefungibleToken} from './util/helpers';19import reFungibleTokenAbi from './reFungibleTokenAbi.json';19import reFungibleTokenAbi from './reFungibleTokenAbi.json';202021import chai from 'chai';21import chai from 'chai';631 });631 });632});632});633634describe('ERC 1633 implementation', () => {635 itWeb3('Parent NFT token address and id', async ({api, web3, privateKeyWrapper}) => {636 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);637638 const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);639 const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);640 const nftTokenId = await nftContract.methods.nextTokenId().call();641 await nftContract.methods.mint(owner, nftTokenId).send();642 const nftCollectionId = collectionIdFromAddress(nftCollectionAddress);643644 const {collectionIdAddress, collectionId} = await createRefungibleCollection(api, web3, owner);645 const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);646 const refungibleTokenId = await refungibleContract.methods.nextTokenId().call();647 await refungibleContract.methods.mint(owner, refungibleTokenId).send();648649 const rftTokenAddress = tokenIdToAddress(collectionId, refungibleTokenId);650 const refungibleTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);651 await refungibleTokenContract.methods.setParentNFT(nftCollectionAddress, nftTokenId).send();652653 const tokenAddress = await refungibleTokenContract.methods.parentToken().call();654 const tokenId = await refungibleTokenContract.methods.parentTokenId().call();655 const nftTokenAddress = tokenIdToAddress(nftCollectionId, nftTokenId);656 expect(tokenAddress).to.be.equal(nftTokenAddress);657 expect(tokenId).to.be.equal(nftTokenId);658 });659});633660661tests/src/eth/reFungibleTokenAbi.jsondiffbeforeafterboth102 "stateMutability": "view",102 "stateMutability": "view",103 "type": "function"103 "type": "function"104 },104 },105 {106 "inputs": [],107 "name": "parentToken",108 "outputs": [{ "internalType": "address", "name": "", "type": "address" }],109 "stateMutability": "view",110 "type": "function"111 },112 {113 "inputs": [],114 "name": "parentTokenId",115 "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],116 "stateMutability": "view",117 "type": "function"118 },105 {119 {106 "inputs": [120 "inputs": [107 { "internalType": "uint256", "name": "amount", "type": "uint256" }121 { "internalType": "uint256", "name": "amount", "type": "uint256" }111 "stateMutability": "nonpayable",125 "stateMutability": "nonpayable",112 "type": "function"126 "type": "function"113 },127 },128 {129 "inputs": [130 { "internalType": "address", "name": "collection", "type": "address" },131 { "internalType": "uint256", "name": "nftId", "type": "uint256" }132 ],133 "name": "setParentNFT",134 "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],135 "stateMutability": "nonpayable",136 "type": "function"137 },114 {138 {115 "inputs": [139 "inputs": [116 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }140 { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }