git.delta.rocks / unique-network / refs/commits / 15e4512df81d

difftreelog

fix after rebase

Trubnikov Sergey2022-10-20parent: #ee71bd9.patch.diff
in: master

4 files changed

addedpallets/nonfungible/expand.rsdiffbeforeafterboth
after · pallets/nonfungible/expand.rs
1#![feature(prelude_import)]2//! # Nonfungible Pallet3//!4//! The Nonfungible pallet provides functionality for handling nonfungible collections and tokens.5//!6//! - [`Config`]7//! - [`NonfungibleHandle`]8//! - [`Pallet`]9//! - [`CommonWeights`](common::CommonWeights)10//!11//! ## Overview12//!13//! The Nonfungible pallet provides functions for:14//!15//! - NFT collection creation and removal16//! - Minting and burning of NFT tokens17//! - Retrieving account balances18//! - Transfering NFT tokens19//! - Setting and checking allowance for NFT tokens20//! - Setting properties and permissions for NFT collections and tokens21//! - Nesting and unnesting tokens22//!23//! ### Terminology24//!25//! - **NFT token:** Non fungible token.26//!27//! - **NFT Collection:** A collection of NFT tokens. All NFT tokens are part of a collection.28//!   Each collection can define it's own properties, properties for it's tokens and set of permissions.29//!30//! - **Balance:** Number of NFT tokens owned by an account31//!32//! - **Allowance:** NFT tokens owned by one account that another account is allowed to make operations on33//!34//! - **Burning:** The process of “deleting” a token from a collection and from35//!   an account balance of the owner.36//!37//! - **Nesting:** Setting up parent-child relationship between tokens. Nested tokens are inhereting38//!   owner from their parent. There could be multiple levels of nesting. Token couldn't be nested in39//!   it's child token i.e. parent-child relationship graph shouldn't have cycles.40//!41//! - **Properties:** Key-Values pairs. Token properties are attached to a token. Collection properties are42//!   attached to a collection. Set of permissions could be defined for each property.43//!44//! ### Implementations45//!46//! The Nonfungible pallet provides implementations for the following traits. If these traits provide47//! the functionality that you need, then you can avoid coupling with the Nonfungible pallet.48//!49//! - [`CommonWeightInfo`](pallet_common::CommonWeightInfo): Functions for retrieval of transaction weight50//! - [`CommonCollectionOperations`](pallet_common::CommonCollectionOperations): Functions for dealing51//!   with collections52//!53//! ## Interface54//!55//! ### Dispatchable Functions56//!57//! - `init_collection` - Create NFT collection. NFT collection can be configured to allow or deny access for58//!   some accounts.59//! - `destroy_collection` - Destroy exising NFT collection. There should be no tokens in the collection.60//! - `burn` - Burn NFT token owned by account.61//! - `transfer` - Transfer NFT token. Transfers should be enabled for NFT collection.62//!   Nests the NFT token if it is sent to another token.63//! - `create_item` - Mint NFT token in collection. Sender should have permission to mint tokens.64//! - `set_allowance` - Set allowance for another account.65//! - `set_token_property` - Set token property value.66//! - `delete_token_property` - Remove property from the token.67//! - `set_collection_properties` - Set collection properties.68//! - `delete_collection_properties` - Remove properties from the collection.69//! - `set_property_permission` - Set collection property permission.70//! - `set_token_property_permissions` - Set token property permissions.71//!72//! ## Assumptions73//!74//! * To perform operations on tokens sender should be in collection's allow list if collection access mode is `AllowList`.75#[prelude_import]76use std::prelude::rust_2021::*;77#[macro_use]78extern crate std;79use erc::ERC721Events;80use evm_coder::ToLog;81use frame_support::{82    BoundedVec, ensure, fail, transactional, storage::with_transaction,83    pallet_prelude::DispatchResultWithPostInfo, pallet_prelude::Weight,84    weights::{PostDispatchInfo, Pays},85};86use up_data_structs::{87    AccessMode, CollectionId, CollectionFlags, CustomDataLimit, TokenId,88    CreateCollectionData, CreateNftExData, mapping::TokenAddressMapping, budget::Budget,89    Property, PropertyPermission, PropertyKey, PropertyValue, PropertyKeyPermission,90    Properties, PropertyScope, TrySetProperty, TokenChild, AuxPropertyValue,91};92use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};93use pallet_common::{94    Error as CommonError, Pallet as PalletCommon, Event as CommonEvent, CollectionHandle,95    eth::collection_id_to_address,96};97use pallet_structure::{Pallet as PalletStructure, Error as StructureError};98use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};99use sp_core::H160;100use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};101use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};102use core::ops::Deref;103use codec::{Encode, Decode, MaxEncodedLen};104use scale_info::TypeInfo;105pub use pallet::*;106use weights::WeightInfo;107pub mod common {108    use core::marker::PhantomData;109    use frame_support::{110        dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight,111    };112    use up_data_structs::{113        TokenId, CreateItemExData, CollectionId, budget::Budget, Property, PropertyKey,114        PropertyKeyPermission, PropertyValue,115    };116    use pallet_common::{117        CommonCollectionOperations, CommonWeightInfo, RefungibleExtensions, with_weight,118        weights::WeightInfo as _,119    };120    use sp_runtime::DispatchError;121    use sp_std::{vec::Vec, vec};122    use crate::{123        AccountBalance, Allowance, Config, CreateItemData, Error, NonfungibleHandle,124        Owned, Pallet, SelfWeightOf, TokenData, weights::WeightInfo, TokensMinted,125    };126    pub struct CommonWeights<T: Config>(PhantomData<T>);127    impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {128        fn create_item() -> Weight {129            <SelfWeightOf<T>>::create_item()130        }131        fn create_multiple_items_ex(132            data: &CreateItemExData<T::CrossAccountId>,133        ) -> Weight {134            match data {135                CreateItemExData::NFT(t) => {136                    <SelfWeightOf<T>>::create_multiple_items_ex(t.len() as u32)137                        + t138                            .iter()139                            .filter_map(|t| {140                                if t.properties.len() > 0 {141                                    Some(Self::set_token_properties(t.properties.len() as u32))142                                } else {143                                    None144                                }145                            })146                            .fold(Weight::zero(), |a, b| a.saturating_add(b))147                }148                _ => Weight::zero(),149            }150        }151        fn create_multiple_items(data: &[up_data_structs::CreateItemData]) -> Weight {152            <SelfWeightOf<T>>::create_multiple_items(data.len() as u32)153                + data154                    .iter()155                    .filter_map(|t| match t {156                        up_data_structs::CreateItemData::NFT(157                            n,158                        ) if n.properties.len() > 0 => {159                            Some(Self::set_token_properties(n.properties.len() as u32))160                        }161                        _ => None,162                    })163                    .fold(Weight::zero(), |a, b| a.saturating_add(b))164        }165        fn burn_item() -> Weight {166            <SelfWeightOf<T>>::burn_item()167        }168        fn set_collection_properties(amount: u32) -> Weight {169            <pallet_common::SelfWeightOf<T>>::set_collection_properties(amount)170        }171        fn delete_collection_properties(amount: u32) -> Weight {172            <pallet_common::SelfWeightOf<T>>::delete_collection_properties(amount)173        }174        fn set_token_properties(amount: u32) -> Weight {175            <SelfWeightOf<T>>::set_token_properties(amount)176        }177        fn delete_token_properties(amount: u32) -> Weight {178            <SelfWeightOf<T>>::delete_token_properties(amount)179        }180        fn set_token_property_permissions(amount: u32) -> Weight {181            <SelfWeightOf<T>>::set_token_property_permissions(amount)182        }183        fn transfer() -> Weight {184            <SelfWeightOf<T>>::transfer()185        }186        fn approve() -> Weight {187            <SelfWeightOf<T>>::approve()188        }189        fn transfer_from() -> Weight {190            <SelfWeightOf<T>>::transfer_from()191        }192        fn burn_from() -> Weight {193            <SelfWeightOf<T>>::burn_from()194        }195        fn burn_recursively_self_raw() -> Weight {196            <SelfWeightOf<T>>::burn_recursively_self_raw()197        }198        fn burn_recursively_breadth_raw(amount: u32) -> Weight {199            <SelfWeightOf<200                T,201            >>::burn_recursively_breadth_plus_self_plus_self_per_each_raw(amount)202                .saturating_sub(203                    Self::burn_recursively_self_raw().saturating_mul(amount as u64 + 1),204                )205        }206        fn token_owner() -> Weight {207            <SelfWeightOf<T>>::token_owner()208        }209    }210    fn map_create_data<T: Config>(211        data: up_data_structs::CreateItemData,212        to: &T::CrossAccountId,213    ) -> Result<CreateItemData<T>, DispatchError> {214        match data {215            up_data_structs::CreateItemData::NFT(data) => {216                Ok(CreateItemData::<T> {217                    properties: data.properties,218                    owner: to.clone(),219                })220            }221            _ => {222                return Err(223                    <Error<T>>::NotNonfungibleDataUsedToMintFungibleCollectionToken224                        .into(),225                );226            }227        }228    }229    /// Implementation of `CommonCollectionOperations` for `NonfungibleHandle`. It wraps Nonfungible Pallete230    /// methods and adds weight info.231    impl<T: Config> CommonCollectionOperations<T> for NonfungibleHandle<T> {232        fn create_item(233            &self,234            sender: T::CrossAccountId,235            to: T::CrossAccountId,236            data: up_data_structs::CreateItemData,237            nesting_budget: &dyn Budget,238        ) -> DispatchResultWithPostInfo {239            with_weight(240                <Pallet<241                    T,242                >>::create_item(243                    self,244                    &sender,245                    map_create_data::<T>(data, &to)?,246                    nesting_budget,247                ),248                <CommonWeights<T>>::create_item(),249            )250        }251        fn create_multiple_items(252            &self,253            sender: T::CrossAccountId,254            to: T::CrossAccountId,255            data: Vec<up_data_structs::CreateItemData>,256            nesting_budget: &dyn Budget,257        ) -> DispatchResultWithPostInfo {258            let weight = <CommonWeights<T>>::create_multiple_items(&data);259            let data = data260                .into_iter()261                .map(|d| map_create_data::<T>(d, &to))262                .collect::<Result<Vec<_>, DispatchError>>()?;263            with_weight(264                <Pallet<T>>::create_multiple_items(self, &sender, data, nesting_budget),265                weight,266            )267        }268        fn create_multiple_items_ex(269            &self,270            sender: <T>::CrossAccountId,271            data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,272            nesting_budget: &dyn Budget,273        ) -> DispatchResultWithPostInfo {274            let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);275            let data = match data {276                up_data_structs::CreateItemExData::NFT(nft) => nft,277                _ => {278                    return Err(279                        Error::<T>::NotNonfungibleDataUsedToMintFungibleCollectionToken280                            .into(),281                    );282                }283            };284            with_weight(285                <Pallet<286                    T,287                >>::create_multiple_items(288                    self,289                    &sender,290                    data.into_inner(),291                    nesting_budget,292                ),293                weight,294            )295        }296        fn set_collection_properties(297            &self,298            sender: T::CrossAccountId,299            properties: Vec<Property>,300        ) -> DispatchResultWithPostInfo {301            let weight = <CommonWeights<302                T,303            >>::set_collection_properties(properties.len() as u32);304            with_weight(305                <Pallet<T>>::set_collection_properties(self, &sender, properties),306                weight,307            )308        }309        fn delete_collection_properties(310            &self,311            sender: &T::CrossAccountId,312            property_keys: Vec<PropertyKey>,313        ) -> DispatchResultWithPostInfo {314            let weight = <CommonWeights<315                T,316            >>::delete_collection_properties(property_keys.len() as u32);317            with_weight(318                <Pallet<T>>::delete_collection_properties(self, sender, property_keys),319                weight,320            )321        }322        fn set_token_properties(323            &self,324            sender: T::CrossAccountId,325            token_id: TokenId,326            properties: Vec<Property>,327            nesting_budget: &dyn Budget,328        ) -> DispatchResultWithPostInfo {329            let weight = <CommonWeights<330                T,331            >>::set_token_properties(properties.len() as u32);332            with_weight(333                <Pallet<334                    T,335                >>::set_token_properties(336                    self,337                    &sender,338                    token_id,339                    properties.into_iter(),340                    false,341                    nesting_budget,342                ),343                weight,344            )345        }346        fn delete_token_properties(347            &self,348            sender: T::CrossAccountId,349            token_id: TokenId,350            property_keys: Vec<PropertyKey>,351            nesting_budget: &dyn Budget,352        ) -> DispatchResultWithPostInfo {353            let weight = <CommonWeights<354                T,355            >>::delete_token_properties(property_keys.len() as u32);356            with_weight(357                <Pallet<358                    T,359                >>::delete_token_properties(360                    self,361                    &sender,362                    token_id,363                    property_keys.into_iter(),364                    nesting_budget,365                ),366                weight,367            )368        }369        fn set_token_property_permissions(370            &self,371            sender: &T::CrossAccountId,372            property_permissions: Vec<PropertyKeyPermission>,373        ) -> DispatchResultWithPostInfo {374            let weight = <CommonWeights<375                T,376            >>::set_token_property_permissions(property_permissions.len() as u32);377            with_weight(378                <Pallet<379                    T,380                >>::set_token_property_permissions(self, sender, property_permissions),381                weight,382            )383        }384        fn burn_item(385            &self,386            sender: T::CrossAccountId,387            token: TokenId,388            amount: u128,389        ) -> DispatchResultWithPostInfo {390            {391                if !(amount <= 1) {392                    { return Err(<Error<T>>::NonfungibleItemsHaveNoAmount.into()) };393                }394            };395            if amount == 1 {396                with_weight(397                    <Pallet<T>>::burn(self, &sender, token),398                    <CommonWeights<T>>::burn_item(),399                )400            } else {401                Ok(().into())402            }403        }404        fn burn_item_recursively(405            &self,406            sender: T::CrossAccountId,407            token: TokenId,408            self_budget: &dyn Budget,409            breadth_budget: &dyn Budget,410        ) -> DispatchResultWithPostInfo {411            <Pallet<412                T,413            >>::burn_recursively(self, &sender, token, self_budget, breadth_budget)414        }415        fn transfer(416            &self,417            from: T::CrossAccountId,418            to: T::CrossAccountId,419            token: TokenId,420            amount: u128,421            nesting_budget: &dyn Budget,422        ) -> DispatchResultWithPostInfo {423            {424                if !(amount <= 1) {425                    { return Err(<Error<T>>::NonfungibleItemsHaveNoAmount.into()) };426                }427            };428            if amount == 1 {429                with_weight(430                    <Pallet<T>>::transfer(self, &from, &to, token, nesting_budget),431                    <CommonWeights<T>>::transfer(),432                )433            } else {434                Ok(().into())435            }436        }437        fn approve(438            &self,439            sender: T::CrossAccountId,440            spender: T::CrossAccountId,441            token: TokenId,442            amount: u128,443        ) -> DispatchResultWithPostInfo {444            {445                if !(amount <= 1) {446                    { return Err(<Error<T>>::NonfungibleItemsHaveNoAmount.into()) };447                }448            };449            with_weight(450                if amount == 1 {451                    <Pallet<T>>::set_allowance(self, &sender, token, Some(&spender))452                } else {453                    <Pallet<T>>::set_allowance(self, &sender, token, None)454                },455                <CommonWeights<T>>::approve(),456            )457        }458        fn transfer_from(459            &self,460            sender: T::CrossAccountId,461            from: T::CrossAccountId,462            to: T::CrossAccountId,463            token: TokenId,464            amount: u128,465            nesting_budget: &dyn Budget,466        ) -> DispatchResultWithPostInfo {467            {468                if !(amount <= 1) {469                    { return Err(<Error<T>>::NonfungibleItemsHaveNoAmount.into()) };470                }471            };472            if amount == 1 {473                with_weight(474                    <Pallet<475                        T,476                    >>::transfer_from(self, &sender, &from, &to, token, nesting_budget),477                    <CommonWeights<T>>::transfer_from(),478                )479            } else {480                Ok(().into())481            }482        }483        fn burn_from(484            &self,485            sender: T::CrossAccountId,486            from: T::CrossAccountId,487            token: TokenId,488            amount: u128,489            nesting_budget: &dyn Budget,490        ) -> DispatchResultWithPostInfo {491            {492                if !(amount <= 1) {493                    { return Err(<Error<T>>::NonfungibleItemsHaveNoAmount.into()) };494                }495            };496            if amount == 1 {497                with_weight(498                    <Pallet<T>>::burn_from(self, &sender, &from, token, nesting_budget),499                    <CommonWeights<T>>::burn_from(),500                )501            } else {502                Ok(().into())503            }504        }505        fn check_nesting(506            &self,507            sender: T::CrossAccountId,508            from: (CollectionId, TokenId),509            under: TokenId,510            nesting_budget: &dyn Budget,511        ) -> sp_runtime::DispatchResult {512            <Pallet<T>>::check_nesting(self, sender, from, under, nesting_budget)513        }514        fn nest(&self, under: TokenId, to_nest: (CollectionId, TokenId)) {515            <Pallet<T>>::nest((self.id, under), to_nest);516        }517        fn unnest(&self, under: TokenId, to_unnest: (CollectionId, TokenId)) {518            <Pallet<T>>::unnest((self.id, under), to_unnest);519        }520        fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {521            <Owned<T>>::iter_prefix((self.id, account)).map(|(id, _)| id).collect()522        }523        fn collection_tokens(&self) -> Vec<TokenId> {524            <TokenData<T>>::iter_prefix((self.id,)).map(|(id, _)| id).collect()525        }526        fn token_exists(&self, token: TokenId) -> bool {527            <Pallet<T>>::token_exists(self, token)528        }529        fn last_token_id(&self) -> TokenId {530            TokenId(<TokensMinted<T>>::get(self.id))531        }532        fn token_owner(&self, token: TokenId) -> Option<T::CrossAccountId> {533            <TokenData<T>>::get((self.id, token)).map(|t| t.owner)534        }535        /// Returns token owners.536        fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId> {537            self.token_owner(token)538                .map_or_else(539                    || ::alloc::vec::Vec::new(),540                    |t| <[_]>::into_vec(#[rustc_box] ::alloc::boxed::Box::new([t])),541                )542        }543        fn token_property(544            &self,545            token_id: TokenId,546            key: &PropertyKey,547        ) -> Option<PropertyValue> {548            <Pallet<T>>::token_properties((self.id, token_id)).get(key).cloned()549        }550        fn token_properties(551            &self,552            token_id: TokenId,553            keys: Option<Vec<PropertyKey>>,554        ) -> Vec<Property> {555            let properties = <Pallet<T>>::token_properties((self.id, token_id));556            keys.map(|keys| {557                    keys.into_iter()558                        .filter_map(|key| {559                            properties560                                .get(&key)561                                .map(|value| Property {562                                    key,563                                    value: value.clone(),564                                })565                        })566                        .collect()567                })568                .unwrap_or_else(|| {569                    properties570                        .into_iter()571                        .map(|(key, value)| Property { key, value })572                        .collect()573                })574        }575        fn total_supply(&self) -> u32 {576            <Pallet<T>>::total_supply(self)577        }578        fn account_balance(&self, account: T::CrossAccountId) -> u32 {579            <AccountBalance<T>>::get((self.id, account))580        }581        fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {582            if <TokenData<T>>::get((self.id, token))583                .map(|a| a.owner == account)584                .unwrap_or(false)585            {586                1587            } else {588                0589            }590        }591        fn allowance(592            &self,593            sender: T::CrossAccountId,594            spender: T::CrossAccountId,595            token: TokenId,596        ) -> u128 {597            if <TokenData<T>>::get((self.id, token))598                .map(|a| a.owner != sender)599                .unwrap_or(true)600            {601                0602            } else if <Allowance<T>>::get((self.id, token)) == Some(spender) {603                1604            } else {605                0606            }607        }608        fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>> {609            None610        }611        fn total_pieces(&self, token: TokenId) -> Option<u128> {612            if <TokenData<T>>::contains_key((self.id, token)) { Some(1) } else { None }613        }614    }615}616pub mod erc {617    //! # Nonfungible Pallet EVM API618    //!619    //! Provides ERC-721 standart support implementation and EVM API for unique extensions for Nonfungible Pallet.620    //! Method implementations are mostly doing parameter conversion and calling Nonfungible Pallet methods.621    extern crate alloc;622    use alloc::{format, string::ToString};623    use core::{624        char::{REPLACEMENT_CHARACTER, decode_utf16},625        convert::TryInto,626    };627    use evm_coder::{628        ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*,629        weight, custom_signature::{FunctionName, FunctionSignature},630        make_signature,631    };632    use frame_support::BoundedVec;633    use up_data_structs::{634        TokenId, PropertyPermission, PropertyKeyPermission, Property, CollectionId,635        PropertyKey, CollectionPropertiesVec,636    };637    use pallet_evm_coder_substrate::dispatch_to_evm;638    use sp_std::vec::Vec;639    use pallet_common::{640        erc::{641            CommonEvmHandler, PrecompileResult, CollectionCall,642            static_property::{key, value as property_value},643        },644        CollectionHandle, CollectionPropertyPermissions,645        eth::convert_tuple_to_cross_account,646    };647    use pallet_evm::{account::CrossAccountId, PrecompileHandle};648    use pallet_evm_coder_substrate::call;649    use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};650    use crate::{651        AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData,652        TokensMinted, SelfWeightOf, weights::WeightInfo, TokenProperties,653    };654    /// @title A contract that allows to set and delete token properties and change token property permissions.655    impl<T: Config> NonfungibleHandle<T> {656        /// @notice Set permissions for token property.657        /// @dev Throws error if `msg.sender` is not admin or owner of the collection.658        /// @param key Property key.659        /// @param isMutable Permission to mutate property.660        /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.661        /// @param tokenOwner Permission to mutate property by token owner if property is mutable.662        fn set_token_property_permission(663            &mut self,664            caller: caller,665            key: string,666            is_mutable: bool,667            collection_admin: bool,668            token_owner: bool,669        ) -> Result<()> {670            let caller = T::CrossAccountId::from_eth(caller);671            <Pallet<672                T,673            >>::set_property_permission(674                    self,675                    &caller,676                    PropertyKeyPermission {677                        key: <Vec<u8>>::from(key)678                            .try_into()679                            .map_err(|_| "too long key")?,680                        permission: PropertyPermission {681                            mutable: is_mutable,682                            collection_admin,683                            token_owner,684                        },685                    },686                )687                .map_err(dispatch_to_evm::<T>)688        }689        /// @notice Set token property value.690        /// @dev Throws error if `msg.sender` has no permission to edit the property.691        /// @param tokenId ID of the token.692        /// @param key Property key.693        /// @param value Property value.694        fn set_property(695            &mut self,696            caller: caller,697            token_id: uint256,698            key: string,699            value: bytes,700        ) -> Result<()> {701            let caller = T::CrossAccountId::from_eth(caller);702            let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;703            let key = <Vec<u8>>::from(key).try_into().map_err(|_| "key too long")?;704            let value = value.0.try_into().map_err(|_| "value too long")?;705            let nesting_budget = self706                .recorder707                .weight_calls_budget(<StructureWeight<T>>::find_parent());708            <Pallet<709                T,710            >>::set_token_property(711                    self,712                    &caller,713                    TokenId(token_id),714                    Property { key, value },715                    &nesting_budget,716                )717                .map_err(dispatch_to_evm::<T>)718        }719        /// @notice Delete token property value.720        /// @dev Throws error if `msg.sender` has no permission to edit the property.721        /// @param tokenId ID of the token.722        /// @param key Property key.723        fn delete_property(724            &mut self,725            token_id: uint256,726            caller: caller,727            key: string,728        ) -> Result<()> {729            let caller = T::CrossAccountId::from_eth(caller);730            let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;731            let key = <Vec<u8>>::from(key).try_into().map_err(|_| "key too long")?;732            let nesting_budget = self733                .recorder734                .weight_calls_budget(<StructureWeight<T>>::find_parent());735            <Pallet<736                T,737            >>::delete_token_property(738                    self,739                    &caller,740                    TokenId(token_id),741                    key,742                    &nesting_budget,743                )744                .map_err(dispatch_to_evm::<T>)745        }746        /// @notice Get token property value.747        /// @dev Throws error if key not found748        /// @param tokenId ID of the token.749        /// @param key Property key.750        /// @return Property value bytes751        fn property(&self, token_id: uint256, key: string) -> Result<bytes> {752            let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;753            let key = <Vec<u8>>::from(key).try_into().map_err(|_| "key too long")?;754            let props = <TokenProperties<T>>::get((self.id, token_id));755            let prop = props.get(&key).ok_or("key not found")?;756            Ok(prop.to_vec().into())757        }758    }759    /// @title A contract that allows to set and delete token properties and change token property permissions.760    pub enum TokenPropertiesCall<T> {761        /// Inherited method762        ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<T>),763        /// @notice Set permissions for token property.764        /// @dev Throws error if `msg.sender` is not admin or owner of the collection.765        /// @param key Property key.766        /// @param isMutable Permission to mutate property.767        /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.768        /// @param tokenOwner Permission to mutate property by token owner if property is mutable.769        #[allow(missing_docs)]770        SetTokenPropertyPermission {771            key: string,772            is_mutable: bool,773            collection_admin: bool,774            token_owner: bool,775        },776        /// @notice Set token property value.777        /// @dev Throws error if `msg.sender` has no permission to edit the property.778        /// @param tokenId ID of the token.779        /// @param key Property key.780        /// @param value Property value.781        #[allow(missing_docs)]782        SetProperty { token_id: uint256, key: string, value: bytes },783        /// @notice Delete token property value.784        /// @dev Throws error if `msg.sender` has no permission to edit the property.785        /// @param tokenId ID of the token.786        /// @param key Property key.787        #[allow(missing_docs)]788        DeleteProperty { token_id: uint256, key: string },789        /// @notice Get token property value.790        /// @dev Throws error if key not found791        /// @param tokenId ID of the token.792        /// @param key Property key.793        /// @return Property value bytes794        #[allow(missing_docs)]795        Property { token_id: uint256, key: string },796    }797    #[automatically_derived]798    impl<T: ::core::fmt::Debug> ::core::fmt::Debug for TokenPropertiesCall<T> {799        fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {800            match self {801                TokenPropertiesCall::ERC165Call(__self_0, __self_1) => {802                    ::core::fmt::Formatter::debug_tuple_field2_finish(803                        f,804                        "ERC165Call",805                        &__self_0,806                        &__self_1,807                    )808                }809                TokenPropertiesCall::SetTokenPropertyPermission {810                    key: __self_0,811                    is_mutable: __self_1,812                    collection_admin: __self_2,813                    token_owner: __self_3,814                } => {815                    ::core::fmt::Formatter::debug_struct_field4_finish(816                        f,817                        "SetTokenPropertyPermission",818                        "key",819                        &__self_0,820                        "is_mutable",821                        &__self_1,822                        "collection_admin",823                        &__self_2,824                        "token_owner",825                        &__self_3,826                    )827                }828                TokenPropertiesCall::SetProperty {829                    token_id: __self_0,830                    key: __self_1,831                    value: __self_2,832                } => {833                    ::core::fmt::Formatter::debug_struct_field3_finish(834                        f,835                        "SetProperty",836                        "token_id",837                        &__self_0,838                        "key",839                        &__self_1,840                        "value",841                        &__self_2,842                    )843                }844                TokenPropertiesCall::DeleteProperty {845                    token_id: __self_0,846                    key: __self_1,847                } => {848                    ::core::fmt::Formatter::debug_struct_field2_finish(849                        f,850                        "DeleteProperty",851                        "token_id",852                        &__self_0,853                        "key",854                        &__self_1,855                    )856                }857                TokenPropertiesCall::Property { token_id: __self_0, key: __self_1 } => {858                    ::core::fmt::Formatter::debug_struct_field2_finish(859                        f,860                        "Property",861                        "token_id",862                        &__self_0,863                        "key",864                        &__self_1,865                    )866                }867            }868        }869    }870    impl<T> TokenPropertiesCall<T> {871        const SET_TOKEN_PROPERTY_PERMISSION_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {872            {873                let fs = FunctionSignature::new(874                    &&FunctionName::new("setTokenPropertyPermission"),875                );876                let fs = FunctionSignature::done(877                    FunctionSignature::add_param(878                        FunctionSignature::add_param(879                            FunctionSignature::add_param(880                                FunctionSignature::add_param(881                                    fs,882                                    (<string>::SIGNATURE, <string>::SIGNATURE_LEN),883                                ),884                                (<bool>::SIGNATURE, <bool>::SIGNATURE_LEN),885                            ),886                            (<bool>::SIGNATURE, <bool>::SIGNATURE_LEN),887                        ),888                        (<bool>::SIGNATURE, <bool>::SIGNATURE_LEN),889                    ),890                    true,891                );892                fs893            }894        };895        ///setTokenPropertyPermission(string,bool,bool,bool)896        const SET_TOKEN_PROPERTY_PERMISSION: ::evm_coder::types::bytes4 = {897            let a = ::evm_coder::sha3_const::Keccak256::new()898                .update_with_size(899                    &Self::SET_TOKEN_PROPERTY_PERMISSION_SIGNATURE.signature,900                    Self::SET_TOKEN_PROPERTY_PERMISSION_SIGNATURE.signature_len,901                )902                .finalize();903            [a[0], a[1], a[2], a[3]]904        };905        const SET_PROPERTY_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {906            {907                let fs = FunctionSignature::new(&&FunctionName::new("setProperty"));908                let fs = FunctionSignature::done(909                    FunctionSignature::add_param(910                        FunctionSignature::add_param(911                            FunctionSignature::add_param(912                                fs,913                                (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),914                            ),915                            (<string>::SIGNATURE, <string>::SIGNATURE_LEN),916                        ),917                        (<bytes>::SIGNATURE, <bytes>::SIGNATURE_LEN),918                    ),919                    true,920                );921                fs922            }923        };924        ///setProperty(uint256,string,bytes)925        const SET_PROPERTY: ::evm_coder::types::bytes4 = {926            let a = ::evm_coder::sha3_const::Keccak256::new()927                .update_with_size(928                    &Self::SET_PROPERTY_SIGNATURE.signature,929                    Self::SET_PROPERTY_SIGNATURE.signature_len,930                )931                .finalize();932            [a[0], a[1], a[2], a[3]]933        };934        const DELETE_PROPERTY_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {935            {936                let fs = FunctionSignature::new(&&FunctionName::new("deleteProperty"));937                let fs = FunctionSignature::done(938                    FunctionSignature::add_param(939                        FunctionSignature::add_param(940                            fs,941                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),942                        ),943                        (<string>::SIGNATURE, <string>::SIGNATURE_LEN),944                    ),945                    true,946                );947                fs948            }949        };950        ///deleteProperty(uint256,string)951        const DELETE_PROPERTY: ::evm_coder::types::bytes4 = {952            let a = ::evm_coder::sha3_const::Keccak256::new()953                .update_with_size(954                    &Self::DELETE_PROPERTY_SIGNATURE.signature,955                    Self::DELETE_PROPERTY_SIGNATURE.signature_len,956                )957                .finalize();958            [a[0], a[1], a[2], a[3]]959        };960        const PROPERTY_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {961            {962                let fs = FunctionSignature::new(&&FunctionName::new("property"));963                let fs = FunctionSignature::done(964                    FunctionSignature::add_param(965                        FunctionSignature::add_param(966                            fs,967                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),968                        ),969                        (<string>::SIGNATURE, <string>::SIGNATURE_LEN),970                    ),971                    true,972                );973                fs974            }975        };976        ///property(uint256,string)977        const PROPERTY: ::evm_coder::types::bytes4 = {978            let a = ::evm_coder::sha3_const::Keccak256::new()979                .update_with_size(980                    &Self::PROPERTY_SIGNATURE.signature,981                    Self::PROPERTY_SIGNATURE.signature_len,982                )983                .finalize();984            [a[0], a[1], a[2], a[3]]985        };986        /// Return this call ERC165 selector987        pub fn interface_id() -> ::evm_coder::types::bytes4 {988            let mut interface_id = 0;989            interface_id ^= u32::from_be_bytes(Self::SET_TOKEN_PROPERTY_PERMISSION);990            interface_id ^= u32::from_be_bytes(Self::SET_PROPERTY);991            interface_id ^= u32::from_be_bytes(Self::DELETE_PROPERTY);992            interface_id ^= u32::from_be_bytes(Self::PROPERTY);993            u32::to_be_bytes(interface_id)994        }995        /// Generate solidity definitions for methods described in this interface996        pub fn generate_solidity_interface(997            tc: &evm_coder::solidity::TypeCollector,998            is_impl: bool,999        ) {1000            use evm_coder::solidity::*;1001            use core::fmt::Write;1002            let interface = SolidityInterface {1003                docs: &[1004                    " @title A contract that allows to set and delete token properties and change token property permissions.",1005                ],1006                name: "TokenProperties",1007                selector: Self::interface_id(),1008                is: &["Dummy", "ERC165"],1009                functions: (1010                    SolidityFunction {1011                        docs: &[1012                            " @notice Set permissions for token property.",1013                            " @dev Throws error if `msg.sender` is not admin or owner of the collection.",1014                            " @param key Property key.",1015                            " @param isMutable Permission to mutate property.",1016                            " @param collectionAdmin Permission to mutate property by collection admin if property is mutable.",1017                            " @param tokenOwner Permission to mutate property by token owner if property is mutable.",1018                        ],1019                        selector_str: "setTokenPropertyPermission(string,bool,bool,bool)",1020                        selector: u32::from_be_bytes(1021                            Self::SET_TOKEN_PROPERTY_PERMISSION,1022                        ),1023                        custom_signature: {1024                            const cs: FunctionSignature = {1025                                {1026                                    let fs = FunctionSignature::new(1027                                        &&FunctionName::new("setTokenPropertyPermission"),1028                                    );1029                                    let fs = FunctionSignature::done(1030                                        FunctionSignature::add_param(1031                                            FunctionSignature::add_param(1032                                                FunctionSignature::add_param(1033                                                    FunctionSignature::add_param(1034                                                        fs,1035                                                        (<string>::SIGNATURE, <string>::SIGNATURE_LEN),1036                                                    ),1037                                                    (<bool>::SIGNATURE, <bool>::SIGNATURE_LEN),1038                                                ),1039                                                (<bool>::SIGNATURE, <bool>::SIGNATURE_LEN),1040                                            ),1041                                            (<bool>::SIGNATURE, <bool>::SIGNATURE_LEN),1042                                        ),1043                                        true,1044                                    );1045                                    fs1046                                }1047                            };1048                            cs1049                        },1050                        name: "setTokenPropertyPermission",1051                        mutability: SolidityMutability::Mutable,1052                        is_payable: false,1053                        args: (1054                            <NamedArgument<string>>::new("key"),1055                            <NamedArgument<bool>>::new("isMutable"),1056                            <NamedArgument<bool>>::new("collectionAdmin"),1057                            <NamedArgument<bool>>::new("tokenOwner"),1058                        ),1059                        result: <UnnamedArgument<()>>::default(),1060                    },1061                    SolidityFunction {1062                        docs: &[1063                            " @notice Set token property value.",1064                            " @dev Throws error if `msg.sender` has no permission to edit the property.",1065                            " @param tokenId ID of the token.",1066                            " @param key Property key.",1067                            " @param value Property value.",1068                        ],1069                        selector_str: "setProperty(uint256,string,bytes)",1070                        selector: u32::from_be_bytes(Self::SET_PROPERTY),1071                        custom_signature: {1072                            const cs: FunctionSignature = {1073                                {1074                                    let fs = FunctionSignature::new(1075                                        &&FunctionName::new("setProperty"),1076                                    );1077                                    let fs = FunctionSignature::done(1078                                        FunctionSignature::add_param(1079                                            FunctionSignature::add_param(1080                                                FunctionSignature::add_param(1081                                                    fs,1082                                                    (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),1083                                                ),1084                                                (<string>::SIGNATURE, <string>::SIGNATURE_LEN),1085                                            ),1086                                            (<bytes>::SIGNATURE, <bytes>::SIGNATURE_LEN),1087                                        ),1088                                        true,1089                                    );1090                                    fs1091                                }1092                            };1093                            cs1094                        },1095                        name: "setProperty",1096                        mutability: SolidityMutability::Mutable,1097                        is_payable: false,1098                        args: (1099                            <NamedArgument<uint256>>::new("tokenId"),1100                            <NamedArgument<string>>::new("key"),1101                            <NamedArgument<bytes>>::new("value"),1102                        ),1103                        result: <UnnamedArgument<()>>::default(),1104                    },1105                    SolidityFunction {1106                        docs: &[1107                            " @notice Delete token property value.",1108                            " @dev Throws error if `msg.sender` has no permission to edit the property.",1109                            " @param tokenId ID of the token.",1110                            " @param key Property key.",1111                        ],1112                        selector_str: "deleteProperty(uint256,string)",1113                        selector: u32::from_be_bytes(Self::DELETE_PROPERTY),1114                        custom_signature: {1115                            const cs: FunctionSignature = {1116                                {1117                                    let fs = FunctionSignature::new(1118                                        &&FunctionName::new("deleteProperty"),1119                                    );1120                                    let fs = FunctionSignature::done(1121                                        FunctionSignature::add_param(1122                                            FunctionSignature::add_param(1123                                                fs,1124                                                (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),1125                                            ),1126                                            (<string>::SIGNATURE, <string>::SIGNATURE_LEN),1127                                        ),1128                                        true,1129                                    );1130                                    fs1131                                }1132                            };1133                            cs1134                        },1135                        name: "deleteProperty",1136                        mutability: SolidityMutability::Mutable,1137                        is_payable: false,1138                        args: (1139                            <NamedArgument<uint256>>::new("tokenId"),1140                            <NamedArgument<string>>::new("key"),1141                        ),1142                        result: <UnnamedArgument<()>>::default(),1143                    },1144                    SolidityFunction {1145                        docs: &[1146                            " @notice Get token property value.",1147                            " @dev Throws error if key not found",1148                            " @param tokenId ID of the token.",1149                            " @param key Property key.",1150                            " @return Property value bytes",1151                        ],1152                        selector_str: "property(uint256,string)",1153                        selector: u32::from_be_bytes(Self::PROPERTY),1154                        custom_signature: {1155                            const cs: FunctionSignature = {1156                                {1157                                    let fs = FunctionSignature::new(1158                                        &&FunctionName::new("property"),1159                                    );1160                                    let fs = FunctionSignature::done(1161                                        FunctionSignature::add_param(1162                                            FunctionSignature::add_param(1163                                                fs,1164                                                (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),1165                                            ),1166                                            (<string>::SIGNATURE, <string>::SIGNATURE_LEN),1167                                        ),1168                                        true,1169                                    );1170                                    fs1171                                }1172                            };1173                            cs1174                        },1175                        name: "property",1176                        mutability: SolidityMutability::View,1177                        is_payable: false,1178                        args: (1179                            <NamedArgument<uint256>>::new("tokenId"),1180                            <NamedArgument<string>>::new("key"),1181                        ),1182                        result: <UnnamedArgument<bytes>>::default(),1183                    },1184                ),1185            };1186            let mut out = ::evm_coder::types::string::new();1187            if "TokenProperties".starts_with("Inline") {1188                out.push_str("/// @dev inlined interface\n");1189            }1190            let _ = interface.format(is_impl, &mut out, tc);1191            tc.collect(out);1192            if is_impl {1193                tc.collect(1194                    "/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n"1195                        .into(),1196                );1197            } else {1198                tc.collect(1199                    "/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n"1200                        .into(),1201                );1202            }1203        }1204    }1205    impl<T> ::evm_coder::Call for TokenPropertiesCall<T> {1206        fn parse(1207            method_id: ::evm_coder::types::bytes4,1208            reader: &mut ::evm_coder::abi::AbiReader,1209        ) -> ::evm_coder::execution::Result<Option<Self>> {1210            use ::evm_coder::abi::AbiRead;1211            match method_id {1212                ::evm_coder::ERC165Call::INTERFACE_ID => {1213                    return Ok(1214                        ::evm_coder::ERC165Call::parse(method_id, reader)?1215                            .map(|c| Self::ERC165Call(c, ::core::marker::PhantomData)),1216                    );1217                }1218                Self::SET_TOKEN_PROPERTY_PERMISSION => {1219                    return Ok(1220                        Some(Self::SetTokenPropertyPermission {1221                            key: reader.abi_read()?,1222                            is_mutable: reader.abi_read()?,1223                            collection_admin: reader.abi_read()?,1224                            token_owner: reader.abi_read()?,1225                        }),1226                    );1227                }1228                Self::SET_PROPERTY => {1229                    return Ok(1230                        Some(Self::SetProperty {1231                            token_id: reader.abi_read()?,1232                            key: reader.abi_read()?,1233                            value: reader.abi_read()?,1234                        }),1235                    );1236                }1237                Self::DELETE_PROPERTY => {1238                    return Ok(1239                        Some(Self::DeleteProperty {1240                            token_id: reader.abi_read()?,1241                            key: reader.abi_read()?,1242                        }),1243                    );1244                }1245                Self::PROPERTY => {1246                    return Ok(1247                        Some(Self::Property {1248                            token_id: reader.abi_read()?,1249                            key: reader.abi_read()?,1250                        }),1251                    );1252                }1253                _ => {}1254            }1255            return Ok(None);1256        }1257    }1258    impl<T: Config> TokenPropertiesCall<T> {1259        /// Is this contract implements specified ERC165 selector1260        pub fn supports_interface(1261            this: &NonfungibleHandle<T>,1262            interface_id: ::evm_coder::types::bytes4,1263        ) -> bool {1264            interface_id != u32::to_be_bytes(0xffffff)1265                && (interface_id == ::evm_coder::ERC165Call::INTERFACE_ID1266                    || interface_id == Self::interface_id())1267        }1268    }1269    impl<T: Config> ::evm_coder::Weighted for TokenPropertiesCall<T> {1270        #[allow(unused_variables)]1271        fn weight(&self) -> ::evm_coder::execution::DispatchInfo {1272            match self {1273                Self::ERC165Call(1274                    ::evm_coder::ERC165Call::SupportsInterface { .. },1275                    _,1276                ) => ::frame_support::weights::Weight::from_ref_time(100).into(),1277                Self::SetTokenPropertyPermission { .. } => ().into(),1278                Self::SetProperty { .. } => ().into(),1279                Self::DeleteProperty { .. } => ().into(),1280                Self::Property { .. } => ().into(),1281            }1282        }1283    }1284    impl<T: Config> ::evm_coder::Callable<TokenPropertiesCall<T>>1285    for NonfungibleHandle<T> {1286        #[allow(unreachable_code)]1287        fn call(1288            &mut self,1289            c: Msg<TokenPropertiesCall<T>>,1290        ) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> {1291            use ::evm_coder::abi::AbiWrite;1292            match c.call {1293                TokenPropertiesCall::ERC165Call(1294                    ::evm_coder::ERC165Call::SupportsInterface { interface_id },1295                    _,1296                ) => {1297                    let mut writer = ::evm_coder::abi::AbiWriter::default();1298                    writer1299                        .bool(1300                            &<TokenPropertiesCall<1301                                T,1302                            >>::supports_interface(self, interface_id),1303                        );1304                    return Ok(writer.into());1305                }1306                _ => {}1307            }1308            let mut writer = ::evm_coder::abi::AbiWriter::default();1309            match c.call {1310                TokenPropertiesCall::SetTokenPropertyPermission {1311                    key,1312                    is_mutable,1313                    collection_admin,1314                    token_owner,1315                } => {1316                    let result = self1317                        .set_token_property_permission(1318                            c.caller.clone(),1319                            key,1320                            is_mutable,1321                            collection_admin,1322                            token_owner,1323                        )?;1324                    (&result).to_result()1325                }1326                TokenPropertiesCall::SetProperty { token_id, key, value } => {1327                    let result = self1328                        .set_property(c.caller.clone(), token_id, key, value)?;1329                    (&result).to_result()1330                }1331                TokenPropertiesCall::DeleteProperty { token_id, key } => {1332                    let result = self.delete_property(token_id, c.caller.clone(), key)?;1333                    (&result).to_result()1334                }1335                TokenPropertiesCall::Property { token_id, key } => {1336                    let result = self.property(token_id, key)?;1337                    (&result).to_result()1338                }1339                _ => {1340                    Err(1341                        ::evm_coder::execution::Error::from("method is not available")1342                            .into(),1343                    )1344                }1345            }1346        }1347    }1348    pub enum ERC721Events {1349        /// @dev This emits when ownership of any NFT changes by any mechanism.1350        ///  This event emits when NFTs are created (`from` == 0) and destroyed1351        ///  (`to` == 0). Exception: during contract creation, any number of NFTs1352        ///  may be created and assigned without emitting Transfer. At the time of1353        ///  any transfer, the approved address for that NFT (if any) is reset to none.1354        Transfer {1355            #[indexed]1356            from: address,1357            #[indexed]1358            to: address,1359            #[indexed]1360            token_id: uint256,1361        },1362        /// @dev This emits when the approved address for an NFT is changed or1363        ///  reaffirmed. The zero address indicates there is no approved address.1364        ///  When a Transfer event emits, this also indicates that the approved1365        ///  address for that NFT (if any) is reset to none.1366        Approval {1367            #[indexed]1368            owner: address,1369            #[indexed]1370            approved: address,1371            #[indexed]1372            token_id: uint256,1373        },1374        /// @dev This emits when an operator is enabled or disabled for an owner.1375        ///  The operator can manage all NFTs of the owner.1376        #[allow(dead_code)]1377        ApprovalForAll {1378            #[indexed]1379            owner: address,1380            #[indexed]1381            operator: address,1382            approved: bool,1383        },1384    }1385    impl ERC721Events {1386        ///Transfer(address,address,uint256)1387        const TRANSFER: [u8; 32] = [1388            221u8,1389            242u8,1390            82u8,1391            173u8,1392            27u8,1393            226u8,1394            200u8,1395            155u8,1396            105u8,1397            194u8,1398            176u8,1399            104u8,1400            252u8,1401            55u8,1402            141u8,1403            170u8,1404            149u8,1405            43u8,1406            167u8,1407            241u8,1408            99u8,1409            196u8,1410            161u8,1411            22u8,1412            40u8,1413            245u8,1414            90u8,1415            77u8,1416            245u8,1417            35u8,1418            179u8,1419            239u8,1420        ];1421        ///Approval(address,address,uint256)1422        const APPROVAL: [u8; 32] = [1423            140u8,1424            91u8,1425            225u8,1426            229u8,1427            235u8,1428            236u8,1429            125u8,1430            91u8,1431            209u8,1432            79u8,1433            113u8,1434            66u8,1435            125u8,1436            30u8,1437            132u8,1438            243u8,1439            221u8,1440            3u8,1441            20u8,1442            192u8,1443            247u8,1444            178u8,1445            41u8,1446            30u8,1447            91u8,1448            32u8,1449            10u8,1450            200u8,1451            199u8,1452            195u8,1453            185u8,1454            37u8,1455        ];1456        ///ApprovalForAll(address,address,bool)1457        const APPROVAL_FOR_ALL: [u8; 32] = [1458            23u8,1459            48u8,1460            126u8,1461            171u8,1462            57u8,1463            171u8,1464            97u8,1465            7u8,1466            232u8,1467            137u8,1468            152u8,1469            69u8,1470            173u8,1471            61u8,1472            89u8,1473            189u8,1474            150u8,1475            83u8,1476            242u8,1477            0u8,1478            242u8,1479            32u8,1480            146u8,1481            4u8,1482            137u8,1483            202u8,1484            43u8,1485            89u8,1486            55u8,1487            105u8,1488            108u8,1489            49u8,1490        ];1491        pub fn generate_solidity_interface(1492            tc: &evm_coder::solidity::TypeCollector,1493            is_impl: bool,1494        ) {1495            use evm_coder::solidity::*;1496            use core::fmt::Write;1497            let interface = SolidityInterface {1498                docs: &[],1499                selector: [0; 4],1500                name: "ERC721Events",1501                is: &[],1502                functions: (1503                    SolidityEvent {1504                        name: "Transfer",1505                        args: (1506                            <SolidityEventArgument<address>>::new(true, "from"),1507                            <SolidityEventArgument<address>>::new(true, "to"),1508                            <SolidityEventArgument<uint256>>::new(true, "tokenId"),1509                        ),1510                    },1511                    SolidityEvent {1512                        name: "Approval",1513                        args: (1514                            <SolidityEventArgument<address>>::new(true, "owner"),1515                            <SolidityEventArgument<address>>::new(true, "approved"),1516                            <SolidityEventArgument<uint256>>::new(true, "tokenId"),1517                        ),1518                    },1519                    SolidityEvent {1520                        name: "ApprovalForAll",1521                        args: (1522                            <SolidityEventArgument<address>>::new(true, "owner"),1523                            <SolidityEventArgument<address>>::new(true, "operator"),1524                            <SolidityEventArgument<bool>>::new(false, "approved"),1525                        ),1526                    },1527                ),1528            };1529            let mut out = string::new();1530            out.push_str("/// @dev inlined interface\n");1531            let _ = interface.format(is_impl, &mut out, tc);1532            tc.collect(out);1533        }1534    }1535    #[automatically_derived]1536    impl ::evm_coder::events::ToLog for ERC721Events {1537        fn to_log(&self, contract: address) -> ::ethereum::Log {1538            use ::evm_coder::events::ToTopic;1539            use ::evm_coder::abi::AbiWrite;1540            let mut writer = ::evm_coder::abi::AbiWriter::new();1541            let mut topics = Vec::new();1542            match self {1543                Self::Transfer { from, to, token_id } => {1544                    topics.push(topic::from(Self::TRANSFER));1545                    topics.push(from.to_topic());1546                    topics.push(to.to_topic());1547                    topics.push(token_id.to_topic());1548                }1549                Self::Approval { owner, approved, token_id } => {1550                    topics.push(topic::from(Self::APPROVAL));1551                    topics.push(owner.to_topic());1552                    topics.push(approved.to_topic());1553                    topics.push(token_id.to_topic());1554                }1555                Self::ApprovalForAll { owner, operator, approved } => {1556                    topics.push(topic::from(Self::APPROVAL_FOR_ALL));1557                    topics.push(owner.to_topic());1558                    topics.push(operator.to_topic());1559                    approved.abi_write(&mut writer);1560                }1561            }1562            ::ethereum::Log {1563                address: contract,1564                topics,1565                data: writer.finish(),1566            }1567        }1568    }1569    pub enum ERC721MintableEvents {1570        #[allow(dead_code)]1571        MintingFinished {},1572    }1573    impl ERC721MintableEvents {1574        ///MintingFinished()1575        const MINTING_FINISHED: [u8; 32] = [1576            184u8,1577            40u8,1578            217u8,1579            181u8,1580            199u8,1581            128u8,1582            149u8,1583            222u8,1584            238u8,1585            239u8,1586            242u8,1587            236u8,1588            162u8,1589            229u8,1590            212u8,1591            254u8,1592            4u8,1593            108u8,1594            227u8,1595            254u8,1596            180u8,1597            201u8,1598            151u8,1599            2u8,1600            98u8,1601            74u8,1602            63u8,1603            211u8,1604            132u8,1605            173u8,1606            45u8,1607            188u8,1608        ];1609        pub fn generate_solidity_interface(1610            tc: &evm_coder::solidity::TypeCollector,1611            is_impl: bool,1612        ) {1613            use evm_coder::solidity::*;1614            use core::fmt::Write;1615            let interface = SolidityInterface {1616                docs: &[],1617                selector: [0; 4],1618                name: "ERC721MintableEvents",1619                is: &[],1620                functions: (1621                    SolidityEvent {1622                        name: "MintingFinished",1623                        args: (),1624                    },1625                ),1626            };1627            let mut out = string::new();1628            out.push_str("/// @dev inlined interface\n");1629            let _ = interface.format(is_impl, &mut out, tc);1630            tc.collect(out);1631        }1632    }1633    #[automatically_derived]1634    impl ::evm_coder::events::ToLog for ERC721MintableEvents {1635        fn to_log(&self, contract: address) -> ::ethereum::Log {1636            use ::evm_coder::events::ToTopic;1637            use ::evm_coder::abi::AbiWrite;1638            let mut writer = ::evm_coder::abi::AbiWriter::new();1639            let mut topics = Vec::new();1640            match self {1641                Self::MintingFinished {} => {1642                    topics.push(topic::from(Self::MINTING_FINISHED));1643                }1644            }1645            ::ethereum::Log {1646                address: contract,1647                topics,1648                data: writer.finish(),1649            }1650        }1651    }1652    /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension1653    /// @dev See https://eips.ethereum.org/EIPS/eip-7211654    impl<T: Config> NonfungibleHandle<T> {1655        /// @notice A descriptive name for a collection of NFTs in this contract1656        fn name(&self) -> Result<string> {1657            Ok(1658                decode_utf16(self.name.iter().copied())1659                    .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))1660                    .collect::<string>(),1661            )1662        }1663        /// @notice An abbreviated name for NFTs in this contract1664        fn symbol(&self) -> Result<string> {1665            Ok(string::from_utf8_lossy(&self.token_prefix).into())1666        }1667        /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.1668        ///1669        /// @dev If the token has a `url` property and it is not empty, it is returned.1670        ///  Else If the collection does not have a property with key `schemaName` or its value is not equal to `ERC721Metadata`, it return an error `tokenURI not set`.1671        ///  If the collection property `baseURI` is empty or absent, return "" (empty string)1672        ///  otherwise, if token property `suffix` present and is non-empty, return concatenation of baseURI and suffix1673        ///  otherwise, return concatenation of `baseURI` and stringified token id (decimal stringifying, without paddings).1674        ///1675        /// @return token's const_metadata1676        fn token_uri(&self, token_id: uint256) -> Result<string> {1677            let token_id_u32: u32 = token_id1678                .try_into()1679                .map_err(|_| "token id overflow")?;1680            if let Ok(url) = get_token_property(self, token_id_u32, &key::url()) {1681                if !url.is_empty() {1682                    return Ok(url);1683                }1684            } else if !is_erc721_metadata_compatible::<T>(self.id) {1685                return Err("tokenURI not set".into());1686            }1687            if let Some(base_uri)1688                = pallet_common::Pallet::<1689                    T,1690                >::get_collection_property(self.id, &key::base_uri()) {1691                if !base_uri.is_empty() {1692                    let base_uri = string::from_utf8(base_uri.into_inner())1693                        .map_err(|e| {1694                            Error::Revert({1695                                let res = ::alloc::fmt::format(1696                                    ::core::fmt::Arguments::new_v1(1697                                        &[1698                                            "Can not convert value \"baseURI\" to string with error \"",1699                                            "\"",1700                                        ],1701                                        &[::core::fmt::ArgumentV1::new_display(&e)],1702                                    ),1703                                );1704                                res1705                            })1706                        })?;1707                    if let Ok(suffix)1708                        = get_token_property(self, token_id_u32, &key::suffix()) {1709                        if !suffix.is_empty() {1710                            return Ok(base_uri + suffix.as_str());1711                        }1712                    }1713                    return Ok(base_uri + token_id.to_string().as_str());1714                }1715            }1716            Ok("".into())1717        }1718    }1719    /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension1720    /// @dev See https://eips.ethereum.org/EIPS/eip-7211721    pub enum ERC721MetadataCall<T> {1722        /// Inherited method1723        ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<T>),1724        Name,1725        Symbol,1726        /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.1727        ///1728        /// @dev If the token has a `url` property and it is not empty, it is returned.1729        ///  Else If the collection does not have a property with key `schemaName` or its value is not equal to `ERC721Metadata`, it return an error `tokenURI not set`.1730        ///  If the collection property `baseURI` is empty or absent, return "" (empty string)1731        ///  otherwise, if token property `suffix` present and is non-empty, return concatenation of baseURI and suffix1732        ///  otherwise, return concatenation of `baseURI` and stringified token id (decimal stringifying, without paddings).1733        ///1734        /// @return token's const_metadata1735        #[allow(missing_docs)]1736        TokenUri { token_id: uint256 },1737    }1738    #[automatically_derived]1739    impl<T: ::core::fmt::Debug> ::core::fmt::Debug for ERC721MetadataCall<T> {1740        fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {1741            match self {1742                ERC721MetadataCall::ERC165Call(__self_0, __self_1) => {1743                    ::core::fmt::Formatter::debug_tuple_field2_finish(1744                        f,1745                        "ERC165Call",1746                        &__self_0,1747                        &__self_1,1748                    )1749                }1750                ERC721MetadataCall::Name => ::core::fmt::Formatter::write_str(f, "Name"),1751                ERC721MetadataCall::Symbol => {1752                    ::core::fmt::Formatter::write_str(f, "Symbol")1753                }1754                ERC721MetadataCall::TokenUri { token_id: __self_0 } => {1755                    ::core::fmt::Formatter::debug_struct_field1_finish(1756                        f,1757                        "TokenUri",1758                        "token_id",1759                        &__self_0,1760                    )1761                }1762            }1763        }1764    }1765    impl<T> ERC721MetadataCall<T> {1766        const NAME_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {1767            {1768                let fs = FunctionSignature::new(&&FunctionName::new("name"));1769                let fs = FunctionSignature::done(fs, false);1770                fs1771            }1772        };1773        ///name()1774        const NAME: ::evm_coder::types::bytes4 = {1775            let a = ::evm_coder::sha3_const::Keccak256::new()1776                .update_with_size(1777                    &Self::NAME_SIGNATURE.signature,1778                    Self::NAME_SIGNATURE.signature_len,1779                )1780                .finalize();1781            [a[0], a[1], a[2], a[3]]1782        };1783        const SYMBOL_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {1784            {1785                let fs = FunctionSignature::new(&&FunctionName::new("symbol"));1786                let fs = FunctionSignature::done(fs, false);1787                fs1788            }1789        };1790        ///symbol()1791        const SYMBOL: ::evm_coder::types::bytes4 = {1792            let a = ::evm_coder::sha3_const::Keccak256::new()1793                .update_with_size(1794                    &Self::SYMBOL_SIGNATURE.signature,1795                    Self::SYMBOL_SIGNATURE.signature_len,1796                )1797                .finalize();1798            [a[0], a[1], a[2], a[3]]1799        };1800        const TOKEN_URI_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {1801            {1802                let fs = FunctionSignature::new(&&FunctionName::new("tokenURI"));1803                let fs = FunctionSignature::done(1804                    FunctionSignature::add_param(1805                        fs,1806                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),1807                    ),1808                    true,1809                );1810                fs1811            }1812        };1813        ///tokenURI(uint256)1814        const TOKEN_URI: ::evm_coder::types::bytes4 = {1815            let a = ::evm_coder::sha3_const::Keccak256::new()1816                .update_with_size(1817                    &Self::TOKEN_URI_SIGNATURE.signature,1818                    Self::TOKEN_URI_SIGNATURE.signature_len,1819                )1820                .finalize();1821            [a[0], a[1], a[2], a[3]]1822        };1823        /// Return this call ERC165 selector1824        pub fn interface_id() -> ::evm_coder::types::bytes4 {1825            let mut interface_id = 0;1826            interface_id ^= u32::from_be_bytes(Self::NAME);1827            interface_id ^= u32::from_be_bytes(Self::SYMBOL);1828            interface_id ^= u32::from_be_bytes(Self::TOKEN_URI);1829            u32::to_be_bytes(interface_id)1830        }1831        /// Generate solidity definitions for methods described in this interface1832        pub fn generate_solidity_interface(1833            tc: &evm_coder::solidity::TypeCollector,1834            is_impl: bool,1835        ) {1836            use evm_coder::solidity::*;1837            use core::fmt::Write;1838            let interface = SolidityInterface {1839                docs: &[1840                    " @title ERC-721 Non-Fungible Token Standard, optional metadata extension",1841                    " @dev See https://eips.ethereum.org/EIPS/eip-721",1842                ],1843                name: "ERC721Metadata",1844                selector: Self::interface_id(),1845                is: &["Dummy", "ERC165"],1846                functions: (1847                    SolidityFunction {1848                        docs: &[1849                            " @notice A descriptive name for a collection of NFTs in this contract",1850                        ],1851                        selector_str: "name()",1852                        selector: u32::from_be_bytes(Self::NAME),1853                        custom_signature: {1854                            const cs: FunctionSignature = {1855                                {1856                                    let fs = FunctionSignature::new(1857                                        &&FunctionName::new("name"),1858                                    );1859                                    let fs = FunctionSignature::done(fs, false);1860                                    fs1861                                }1862                            };1863                            cs1864                        },1865                        name: "name",1866                        mutability: SolidityMutability::View,1867                        is_payable: false,1868                        args: (),1869                        result: <UnnamedArgument<string>>::default(),1870                    },1871                    SolidityFunction {1872                        docs: &[1873                            " @notice An abbreviated name for NFTs in this contract",1874                        ],1875                        selector_str: "symbol()",1876                        selector: u32::from_be_bytes(Self::SYMBOL),1877                        custom_signature: {1878                            const cs: FunctionSignature = {1879                                {1880                                    let fs = FunctionSignature::new(1881                                        &&FunctionName::new("symbol"),1882                                    );1883                                    let fs = FunctionSignature::done(fs, false);1884                                    fs1885                                }1886                            };1887                            cs1888                        },1889                        name: "symbol",1890                        mutability: SolidityMutability::View,1891                        is_payable: false,1892                        args: (),1893                        result: <UnnamedArgument<string>>::default(),1894                    },1895                    SolidityFunction {1896                        docs: &[1897                            " @notice A distinct Uniform Resource Identifier (URI) for a given asset.",1898                            "",1899                            " @dev If the token has a `url` property and it is not empty, it is returned.",1900                            "  Else If the collection does not have a property with key `schemaName` or its value is not equal to `ERC721Metadata`, it return an error `tokenURI not set`.",1901                            "  If the collection property `baseURI` is empty or absent, return \"\" (empty string)",1902                            "  otherwise, if token property `suffix` present and is non-empty, return concatenation of baseURI and suffix",1903                            "  otherwise, return concatenation of `baseURI` and stringified token id (decimal stringifying, without paddings).",1904                            "",1905                            " @return token's const_metadata",1906                        ],1907                        selector_str: "tokenURI(uint256)",1908                        selector: u32::from_be_bytes(Self::TOKEN_URI),1909                        custom_signature: {1910                            const cs: FunctionSignature = {1911                                {1912                                    let fs = FunctionSignature::new(1913                                        &&FunctionName::new("tokenURI"),1914                                    );1915                                    let fs = FunctionSignature::done(1916                                        FunctionSignature::add_param(1917                                            fs,1918                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),1919                                        ),1920                                        true,1921                                    );1922                                    fs1923                                }1924                            };1925                            cs1926                        },1927                        name: "tokenURI",1928                        mutability: SolidityMutability::View,1929                        is_payable: false,1930                        args: (<NamedArgument<uint256>>::new("tokenId"),),1931                        result: <UnnamedArgument<string>>::default(),1932                    },1933                ),1934            };1935            let mut out = ::evm_coder::types::string::new();1936            if "ERC721Metadata".starts_with("Inline") {1937                out.push_str("/// @dev inlined interface\n");1938            }1939            let _ = interface.format(is_impl, &mut out, tc);1940            tc.collect(out);1941            if is_impl {1942                tc.collect(1943                    "/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n"1944                        .into(),1945                );1946            } else {1947                tc.collect(1948                    "/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n"1949                        .into(),1950                );1951            }1952        }1953    }1954    impl<T> ::evm_coder::Call for ERC721MetadataCall<T> {1955        fn parse(1956            method_id: ::evm_coder::types::bytes4,1957            reader: &mut ::evm_coder::abi::AbiReader,1958        ) -> ::evm_coder::execution::Result<Option<Self>> {1959            use ::evm_coder::abi::AbiRead;1960            match method_id {1961                ::evm_coder::ERC165Call::INTERFACE_ID => {1962                    return Ok(1963                        ::evm_coder::ERC165Call::parse(method_id, reader)?1964                            .map(|c| Self::ERC165Call(c, ::core::marker::PhantomData)),1965                    );1966                }1967                Self::NAME => return Ok(Some(Self::Name)),1968                Self::SYMBOL => return Ok(Some(Self::Symbol)),1969                Self::TOKEN_URI => {1970                    return Ok(1971                        Some(Self::TokenUri {1972                            token_id: reader.abi_read()?,1973                        }),1974                    );1975                }1976                _ => {}1977            }1978            return Ok(None);1979        }1980    }1981    impl<T: Config> ERC721MetadataCall<T> {1982        /// Is this contract implements specified ERC165 selector1983        pub fn supports_interface(1984            this: &NonfungibleHandle<T>,1985            interface_id: ::evm_coder::types::bytes4,1986        ) -> bool {1987            interface_id != u32::to_be_bytes(0xffffff)1988                && (interface_id == ::evm_coder::ERC165Call::INTERFACE_ID1989                    || interface_id == Self::interface_id())1990        }1991    }1992    impl<T: Config> ::evm_coder::Weighted for ERC721MetadataCall<T> {1993        #[allow(unused_variables)]1994        fn weight(&self) -> ::evm_coder::execution::DispatchInfo {1995            match self {1996                Self::ERC165Call(1997                    ::evm_coder::ERC165Call::SupportsInterface { .. },1998                    _,1999                ) => ::frame_support::weights::Weight::from_ref_time(100).into(),2000                Self::Name => ().into(),2001                Self::Symbol => ().into(),2002                Self::TokenUri { .. } => ().into(),2003            }2004        }2005    }2006    impl<T: Config> ::evm_coder::Callable<ERC721MetadataCall<T>>2007    for NonfungibleHandle<T> {2008        #[allow(unreachable_code)]2009        fn call(2010            &mut self,2011            c: Msg<ERC721MetadataCall<T>>,2012        ) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> {2013            use ::evm_coder::abi::AbiWrite;2014            match c.call {2015                ERC721MetadataCall::ERC165Call(2016                    ::evm_coder::ERC165Call::SupportsInterface { interface_id },2017                    _,2018                ) => {2019                    let mut writer = ::evm_coder::abi::AbiWriter::default();2020                    writer2021                        .bool(2022                            &<ERC721MetadataCall<2023                                T,2024                            >>::supports_interface(self, interface_id),2025                        );2026                    return Ok(writer.into());2027                }2028                _ => {}2029            }2030            let mut writer = ::evm_coder::abi::AbiWriter::default();2031            match c.call {2032                ERC721MetadataCall::Name => {2033                    let result = self.name()?;2034                    (&result).to_result()2035                }2036                ERC721MetadataCall::Symbol => {2037                    let result = self.symbol()?;2038                    (&result).to_result()2039                }2040                ERC721MetadataCall::TokenUri { token_id } => {2041                    let result = self.token_uri(token_id)?;2042                    (&result).to_result()2043                }2044                _ => {2045                    Err(2046                        ::evm_coder::execution::Error::from("method is not available")2047                            .into(),2048                    )2049                }2050            }2051        }2052    }2053    /// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension2054    /// @dev See https://eips.ethereum.org/EIPS/eip-7212055    impl<T: Config> NonfungibleHandle<T> {2056        /// @notice Enumerate valid NFTs2057        /// @param index A counter less than `totalSupply()`2058        /// @return The token identifier for the `index`th NFT,2059        ///  (sort order not specified)2060        fn token_by_index(&self, index: uint256) -> Result<uint256> {2061            Ok(index)2062        }2063        /// @dev Not implemented2064        fn token_of_owner_by_index(2065            &self,2066            _owner: address,2067            _index: uint256,2068        ) -> Result<uint256> {2069            Err("not implemented".into())2070        }2071        /// @notice Count NFTs tracked by this contract2072        /// @return A count of valid NFTs tracked by this contract, where each one of2073        ///  them has an assigned and queryable owner not equal to the zero address2074        fn total_supply(&self) -> Result<uint256> {2075            self.consume_store_reads(1)?;2076            Ok(<Pallet<T>>::total_supply(self).into())2077        }2078    }2079    /// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension2080    /// @dev See https://eips.ethereum.org/EIPS/eip-7212081    pub enum ERC721EnumerableCall<T> {2082        /// Inherited method2083        ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<T>),2084        /// @notice Enumerate valid NFTs2085        /// @param index A counter less than `totalSupply()`2086        /// @return The token identifier for the `index`th NFT,2087        ///  (sort order not specified)2088        #[allow(missing_docs)]2089        TokenByIndex { index: uint256 },2090        /// @dev Not implemented2091        #[allow(missing_docs)]2092        TokenOfOwnerByIndex { _owner: address, _index: uint256 },2093        TotalSupply,2094    }2095    #[automatically_derived]2096    impl<T: ::core::fmt::Debug> ::core::fmt::Debug for ERC721EnumerableCall<T> {2097        fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {2098            match self {2099                ERC721EnumerableCall::ERC165Call(__self_0, __self_1) => {2100                    ::core::fmt::Formatter::debug_tuple_field2_finish(2101                        f,2102                        "ERC165Call",2103                        &__self_0,2104                        &__self_1,2105                    )2106                }2107                ERC721EnumerableCall::TokenByIndex { index: __self_0 } => {2108                    ::core::fmt::Formatter::debug_struct_field1_finish(2109                        f,2110                        "TokenByIndex",2111                        "index",2112                        &__self_0,2113                    )2114                }2115                ERC721EnumerableCall::TokenOfOwnerByIndex {2116                    _owner: __self_0,2117                    _index: __self_1,2118                } => {2119                    ::core::fmt::Formatter::debug_struct_field2_finish(2120                        f,2121                        "TokenOfOwnerByIndex",2122                        "_owner",2123                        &__self_0,2124                        "_index",2125                        &__self_1,2126                    )2127                }2128                ERC721EnumerableCall::TotalSupply => {2129                    ::core::fmt::Formatter::write_str(f, "TotalSupply")2130                }2131            }2132        }2133    }2134    impl<T> ERC721EnumerableCall<T> {2135        const TOKEN_BY_INDEX_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {2136            {2137                let fs = FunctionSignature::new(&&FunctionName::new("tokenByIndex"));2138                let fs = FunctionSignature::done(2139                    FunctionSignature::add_param(2140                        fs,2141                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),2142                    ),2143                    true,2144                );2145                fs2146            }2147        };2148        ///tokenByIndex(uint256)2149        const TOKEN_BY_INDEX: ::evm_coder::types::bytes4 = {2150            let a = ::evm_coder::sha3_const::Keccak256::new()2151                .update_with_size(2152                    &Self::TOKEN_BY_INDEX_SIGNATURE.signature,2153                    Self::TOKEN_BY_INDEX_SIGNATURE.signature_len,2154                )2155                .finalize();2156            [a[0], a[1], a[2], a[3]]2157        };2158        const TOKEN_OF_OWNER_BY_INDEX_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {2159            {2160                let fs = FunctionSignature::new(2161                    &&FunctionName::new("tokenOfOwnerByIndex"),2162                );2163                let fs = FunctionSignature::done(2164                    FunctionSignature::add_param(2165                        FunctionSignature::add_param(2166                            fs,2167                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2168                        ),2169                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),2170                    ),2171                    true,2172                );2173                fs2174            }2175        };2176        ///tokenOfOwnerByIndex(address,uint256)2177        const TOKEN_OF_OWNER_BY_INDEX: ::evm_coder::types::bytes4 = {2178            let a = ::evm_coder::sha3_const::Keccak256::new()2179                .update_with_size(2180                    &Self::TOKEN_OF_OWNER_BY_INDEX_SIGNATURE.signature,2181                    Self::TOKEN_OF_OWNER_BY_INDEX_SIGNATURE.signature_len,2182                )2183                .finalize();2184            [a[0], a[1], a[2], a[3]]2185        };2186        const TOTAL_SUPPLY_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {2187            {2188                let fs = FunctionSignature::new(&&FunctionName::new("totalSupply"));2189                let fs = FunctionSignature::done(fs, false);2190                fs2191            }2192        };2193        ///totalSupply()2194        const TOTAL_SUPPLY: ::evm_coder::types::bytes4 = {2195            let a = ::evm_coder::sha3_const::Keccak256::new()2196                .update_with_size(2197                    &Self::TOTAL_SUPPLY_SIGNATURE.signature,2198                    Self::TOTAL_SUPPLY_SIGNATURE.signature_len,2199                )2200                .finalize();2201            [a[0], a[1], a[2], a[3]]2202        };2203        /// Return this call ERC165 selector2204        pub fn interface_id() -> ::evm_coder::types::bytes4 {2205            let mut interface_id = 0;2206            interface_id ^= u32::from_be_bytes(Self::TOKEN_BY_INDEX);2207            interface_id ^= u32::from_be_bytes(Self::TOKEN_OF_OWNER_BY_INDEX);2208            interface_id ^= u32::from_be_bytes(Self::TOTAL_SUPPLY);2209            u32::to_be_bytes(interface_id)2210        }2211        /// Generate solidity definitions for methods described in this interface2212        pub fn generate_solidity_interface(2213            tc: &evm_coder::solidity::TypeCollector,2214            is_impl: bool,2215        ) {2216            use evm_coder::solidity::*;2217            use core::fmt::Write;2218            let interface = SolidityInterface {2219                docs: &[2220                    " @title ERC-721 Non-Fungible Token Standard, optional enumeration extension",2221                    " @dev See https://eips.ethereum.org/EIPS/eip-721",2222                ],2223                name: "ERC721Enumerable",2224                selector: Self::interface_id(),2225                is: &["Dummy", "ERC165"],2226                functions: (2227                    SolidityFunction {2228                        docs: &[2229                            " @notice Enumerate valid NFTs",2230                            " @param index A counter less than `totalSupply()`",2231                            " @return The token identifier for the `index`th NFT,",2232                            "  (sort order not specified)",2233                        ],2234                        selector_str: "tokenByIndex(uint256)",2235                        selector: u32::from_be_bytes(Self::TOKEN_BY_INDEX),2236                        custom_signature: {2237                            const cs: FunctionSignature = {2238                                {2239                                    let fs = FunctionSignature::new(2240                                        &&FunctionName::new("tokenByIndex"),2241                                    );2242                                    let fs = FunctionSignature::done(2243                                        FunctionSignature::add_param(2244                                            fs,2245                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),2246                                        ),2247                                        true,2248                                    );2249                                    fs2250                                }2251                            };2252                            cs2253                        },2254                        name: "tokenByIndex",2255                        mutability: SolidityMutability::View,2256                        is_payable: false,2257                        args: (<NamedArgument<uint256>>::new("index"),),2258                        result: <UnnamedArgument<uint256>>::default(),2259                    },2260                    SolidityFunction {2261                        docs: &[" @dev Not implemented"],2262                        selector_str: "tokenOfOwnerByIndex(address,uint256)",2263                        selector: u32::from_be_bytes(Self::TOKEN_OF_OWNER_BY_INDEX),2264                        custom_signature: {2265                            const cs: FunctionSignature = {2266                                {2267                                    let fs = FunctionSignature::new(2268                                        &&FunctionName::new("tokenOfOwnerByIndex"),2269                                    );2270                                    let fs = FunctionSignature::done(2271                                        FunctionSignature::add_param(2272                                            FunctionSignature::add_param(2273                                                fs,2274                                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2275                                            ),2276                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),2277                                        ),2278                                        true,2279                                    );2280                                    fs2281                                }2282                            };2283                            cs2284                        },2285                        name: "tokenOfOwnerByIndex",2286                        mutability: SolidityMutability::View,2287                        is_payable: false,2288                        args: (2289                            <NamedArgument<address>>::new("owner"),2290                            <NamedArgument<uint256>>::new("index"),2291                        ),2292                        result: <UnnamedArgument<uint256>>::default(),2293                    },2294                    SolidityFunction {2295                        docs: &[2296                            " @notice Count NFTs tracked by this contract",2297                            " @return A count of valid NFTs tracked by this contract, where each one of",2298                            "  them has an assigned and queryable owner not equal to the zero address",2299                        ],2300                        selector_str: "totalSupply()",2301                        selector: u32::from_be_bytes(Self::TOTAL_SUPPLY),2302                        custom_signature: {2303                            const cs: FunctionSignature = {2304                                {2305                                    let fs = FunctionSignature::new(2306                                        &&FunctionName::new("totalSupply"),2307                                    );2308                                    let fs = FunctionSignature::done(fs, false);2309                                    fs2310                                }2311                            };2312                            cs2313                        },2314                        name: "totalSupply",2315                        mutability: SolidityMutability::View,2316                        is_payable: false,2317                        args: (),2318                        result: <UnnamedArgument<uint256>>::default(),2319                    },2320                ),2321            };2322            let mut out = ::evm_coder::types::string::new();2323            if "ERC721Enumerable".starts_with("Inline") {2324                out.push_str("/// @dev inlined interface\n");2325            }2326            let _ = interface.format(is_impl, &mut out, tc);2327            tc.collect(out);2328            if is_impl {2329                tc.collect(2330                    "/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n"2331                        .into(),2332                );2333            } else {2334                tc.collect(2335                    "/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n"2336                        .into(),2337                );2338            }2339        }2340    }2341    impl<T> ::evm_coder::Call for ERC721EnumerableCall<T> {2342        fn parse(2343            method_id: ::evm_coder::types::bytes4,2344            reader: &mut ::evm_coder::abi::AbiReader,2345        ) -> ::evm_coder::execution::Result<Option<Self>> {2346            use ::evm_coder::abi::AbiRead;2347            match method_id {2348                ::evm_coder::ERC165Call::INTERFACE_ID => {2349                    return Ok(2350                        ::evm_coder::ERC165Call::parse(method_id, reader)?2351                            .map(|c| Self::ERC165Call(c, ::core::marker::PhantomData)),2352                    );2353                }2354                Self::TOKEN_BY_INDEX => {2355                    return Ok(2356                        Some(Self::TokenByIndex {2357                            index: reader.abi_read()?,2358                        }),2359                    );2360                }2361                Self::TOKEN_OF_OWNER_BY_INDEX => {2362                    return Ok(2363                        Some(Self::TokenOfOwnerByIndex {2364                            _owner: reader.abi_read()?,2365                            _index: reader.abi_read()?,2366                        }),2367                    );2368                }2369                Self::TOTAL_SUPPLY => return Ok(Some(Self::TotalSupply)),2370                _ => {}2371            }2372            return Ok(None);2373        }2374    }2375    impl<T: Config> ERC721EnumerableCall<T> {2376        /// Is this contract implements specified ERC165 selector2377        pub fn supports_interface(2378            this: &NonfungibleHandle<T>,2379            interface_id: ::evm_coder::types::bytes4,2380        ) -> bool {2381            interface_id != u32::to_be_bytes(0xffffff)2382                && (interface_id == ::evm_coder::ERC165Call::INTERFACE_ID2383                    || interface_id == Self::interface_id())2384        }2385    }2386    impl<T: Config> ::evm_coder::Weighted for ERC721EnumerableCall<T> {2387        #[allow(unused_variables)]2388        fn weight(&self) -> ::evm_coder::execution::DispatchInfo {2389            match self {2390                Self::ERC165Call(2391                    ::evm_coder::ERC165Call::SupportsInterface { .. },2392                    _,2393                ) => ::frame_support::weights::Weight::from_ref_time(100).into(),2394                Self::TokenByIndex { .. } => ().into(),2395                Self::TokenOfOwnerByIndex { .. } => ().into(),2396                Self::TotalSupply => ().into(),2397            }2398        }2399    }2400    impl<T: Config> ::evm_coder::Callable<ERC721EnumerableCall<T>>2401    for NonfungibleHandle<T> {2402        #[allow(unreachable_code)]2403        fn call(2404            &mut self,2405            c: Msg<ERC721EnumerableCall<T>>,2406        ) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> {2407            use ::evm_coder::abi::AbiWrite;2408            match c.call {2409                ERC721EnumerableCall::ERC165Call(2410                    ::evm_coder::ERC165Call::SupportsInterface { interface_id },2411                    _,2412                ) => {2413                    let mut writer = ::evm_coder::abi::AbiWriter::default();2414                    writer2415                        .bool(2416                            &<ERC721EnumerableCall<2417                                T,2418                            >>::supports_interface(self, interface_id),2419                        );2420                    return Ok(writer.into());2421                }2422                _ => {}2423            }2424            let mut writer = ::evm_coder::abi::AbiWriter::default();2425            match c.call {2426                ERC721EnumerableCall::TokenByIndex { index } => {2427                    let result = self.token_by_index(index)?;2428                    (&result).to_result()2429                }2430                ERC721EnumerableCall::TokenOfOwnerByIndex { _owner, _index } => {2431                    let result = self.token_of_owner_by_index(_owner, _index)?;2432                    (&result).to_result()2433                }2434                ERC721EnumerableCall::TotalSupply => {2435                    let result = self.total_supply()?;2436                    (&result).to_result()2437                }2438                _ => {2439                    Err(2440                        ::evm_coder::execution::Error::from("method is not available")2441                            .into(),2442                    )2443                }2444            }2445        }2446    }2447    /// @title ERC-721 Non-Fungible Token Standard2448    /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md2449    impl<T: Config> NonfungibleHandle<T> {2450        /// @notice Count all NFTs assigned to an owner2451        /// @dev NFTs assigned to the zero address are considered invalid, and this2452        ///  function throws for queries about the zero address.2453        /// @param owner An address for whom to query the balance2454        /// @return The number of NFTs owned by `owner`, possibly zero2455        fn balance_of(&self, owner: address) -> Result<uint256> {2456            self.consume_store_reads(1)?;2457            let owner = T::CrossAccountId::from_eth(owner);2458            let balance = <AccountBalance<T>>::get((self.id, owner));2459            Ok(balance.into())2460        }2461        /// @notice Find the owner of an NFT2462        /// @dev NFTs assigned to zero address are considered invalid, and queries2463        ///  about them do throw.2464        /// @param tokenId The identifier for an NFT2465        /// @return The address of the owner of the NFT2466        fn owner_of(&self, token_id: uint256) -> Result<address> {2467            self.consume_store_reads(1)?;2468            let token: TokenId = token_id.try_into()?;2469            Ok(2470                *<TokenData<T>>::get((self.id, token))2471                    .ok_or("token not found")?2472                    .owner2473                    .as_eth(),2474            )2475        }2476        /// @dev Not implemented2477        fn safe_transfer_from_with_data(2478            &mut self,2479            _from: address,2480            _to: address,2481            _token_id: uint256,2482            _data: bytes,2483        ) -> Result<void> {2484            Err("not implemented".into())2485        }2486        /// @dev Not implemented2487        fn safe_transfer_from(2488            &mut self,2489            _from: address,2490            _to: address,2491            _token_id: uint256,2492        ) -> Result<void> {2493            Err("not implemented".into())2494        }2495        /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE2496        ///  TO CONFIRM THAT `to` IS CAPABLE OF RECEIVING NFTS OR ELSE2497        ///  THEY MAY BE PERMANENTLY LOST2498        /// @dev Throws unless `msg.sender` is the current owner or an authorized2499        ///  operator for this NFT. Throws if `from` is not the current owner. Throws2500        ///  if `to` is the zero address. Throws if `tokenId` is not a valid NFT.2501        /// @param from The current owner of the NFT2502        /// @param to The new owner2503        /// @param tokenId The NFT to transfer2504        fn transfer_from(2505            &mut self,2506            caller: caller,2507            from: address,2508            to: address,2509            token_id: uint256,2510        ) -> Result<void> {2511            let caller = T::CrossAccountId::from_eth(caller);2512            let from = T::CrossAccountId::from_eth(from);2513            let to = T::CrossAccountId::from_eth(to);2514            let token = token_id.try_into()?;2515            let budget = self2516                .recorder2517                .weight_calls_budget(<StructureWeight<T>>::find_parent());2518            <Pallet<T>>::transfer_from(self, &caller, &from, &to, token, &budget)2519                .map_err(dispatch_to_evm::<T>)?;2520            Ok(())2521        }2522        /// @notice Set or reaffirm the approved address for an NFT2523        /// @dev The zero address indicates there is no approved address.2524        /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized2525        ///  operator of the current owner.2526        /// @param approved The new approved NFT controller2527        /// @param tokenId The NFT to approve2528        fn approve(2529            &mut self,2530            caller: caller,2531            approved: address,2532            token_id: uint256,2533        ) -> Result<void> {2534            let caller = T::CrossAccountId::from_eth(caller);2535            let approved = T::CrossAccountId::from_eth(approved);2536            let token = token_id.try_into()?;2537            <Pallet<T>>::set_allowance(self, &caller, token, Some(&approved))2538                .map_err(dispatch_to_evm::<T>)?;2539            Ok(())2540        }2541        /// @dev Not implemented2542        fn set_approval_for_all(2543            &mut self,2544            _caller: caller,2545            _operator: address,2546            _approved: bool,2547        ) -> Result<void> {2548            Err("not implemented".into())2549        }2550        /// @dev Not implemented2551        fn get_approved(&self, _token_id: uint256) -> Result<address> {2552            Err("not implemented".into())2553        }2554        /// @dev Not implemented2555        fn is_approved_for_all(2556            &self,2557            _owner: address,2558            _operator: address,2559        ) -> Result<address> {2560            Err("not implemented".into())2561        }2562    }2563    /// @title ERC-721 Non-Fungible Token Standard2564    /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md2565    pub enum ERC721Call<T> {2566        /// Inherited method2567        ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<T>),2568        /// @notice Count all NFTs assigned to an owner2569        /// @dev NFTs assigned to the zero address are considered invalid, and this2570        ///  function throws for queries about the zero address.2571        /// @param owner An address for whom to query the balance2572        /// @return The number of NFTs owned by `owner`, possibly zero2573        #[allow(missing_docs)]2574        BalanceOf { owner: address },2575        /// @notice Find the owner of an NFT2576        /// @dev NFTs assigned to zero address are considered invalid, and queries2577        ///  about them do throw.2578        /// @param tokenId The identifier for an NFT2579        /// @return The address of the owner of the NFT2580        #[allow(missing_docs)]2581        OwnerOf { token_id: uint256 },2582        /// @dev Not implemented2583        #[allow(missing_docs)]2584        SafeTransferFromWithData {2585            _from: address,2586            _to: address,2587            _token_id: uint256,2588            _data: bytes,2589        },2590        /// @dev Not implemented2591        #[allow(missing_docs)]2592        SafeTransferFrom { _from: address, _to: address, _token_id: uint256 },2593        /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE2594        ///  TO CONFIRM THAT `to` IS CAPABLE OF RECEIVING NFTS OR ELSE2595        ///  THEY MAY BE PERMANENTLY LOST2596        /// @dev Throws unless `msg.sender` is the current owner or an authorized2597        ///  operator for this NFT. Throws if `from` is not the current owner. Throws2598        ///  if `to` is the zero address. Throws if `tokenId` is not a valid NFT.2599        /// @param from The current owner of the NFT2600        /// @param to The new owner2601        /// @param tokenId The NFT to transfer2602        #[allow(missing_docs)]2603        TransferFrom { from: address, to: address, token_id: uint256 },2604        /// @notice Set or reaffirm the approved address for an NFT2605        /// @dev The zero address indicates there is no approved address.2606        /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized2607        ///  operator of the current owner.2608        /// @param approved The new approved NFT controller2609        /// @param tokenId The NFT to approve2610        #[allow(missing_docs)]2611        Approve { approved: address, token_id: uint256 },2612        /// @dev Not implemented2613        #[allow(missing_docs)]2614        SetApprovalForAll { _operator: address, _approved: bool },2615        /// @dev Not implemented2616        #[allow(missing_docs)]2617        GetApproved { _token_id: uint256 },2618        /// @dev Not implemented2619        #[allow(missing_docs)]2620        IsApprovedForAll { _owner: address, _operator: address },2621    }2622    #[automatically_derived]2623    impl<T: ::core::fmt::Debug> ::core::fmt::Debug for ERC721Call<T> {2624        fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {2625            match self {2626                ERC721Call::ERC165Call(__self_0, __self_1) => {2627                    ::core::fmt::Formatter::debug_tuple_field2_finish(2628                        f,2629                        "ERC165Call",2630                        &__self_0,2631                        &__self_1,2632                    )2633                }2634                ERC721Call::BalanceOf { owner: __self_0 } => {2635                    ::core::fmt::Formatter::debug_struct_field1_finish(2636                        f,2637                        "BalanceOf",2638                        "owner",2639                        &__self_0,2640                    )2641                }2642                ERC721Call::OwnerOf { token_id: __self_0 } => {2643                    ::core::fmt::Formatter::debug_struct_field1_finish(2644                        f,2645                        "OwnerOf",2646                        "token_id",2647                        &__self_0,2648                    )2649                }2650                ERC721Call::SafeTransferFromWithData {2651                    _from: __self_0,2652                    _to: __self_1,2653                    _token_id: __self_2,2654                    _data: __self_3,2655                } => {2656                    ::core::fmt::Formatter::debug_struct_field4_finish(2657                        f,2658                        "SafeTransferFromWithData",2659                        "_from",2660                        &__self_0,2661                        "_to",2662                        &__self_1,2663                        "_token_id",2664                        &__self_2,2665                        "_data",2666                        &__self_3,2667                    )2668                }2669                ERC721Call::SafeTransferFrom {2670                    _from: __self_0,2671                    _to: __self_1,2672                    _token_id: __self_2,2673                } => {2674                    ::core::fmt::Formatter::debug_struct_field3_finish(2675                        f,2676                        "SafeTransferFrom",2677                        "_from",2678                        &__self_0,2679                        "_to",2680                        &__self_1,2681                        "_token_id",2682                        &__self_2,2683                    )2684                }2685                ERC721Call::TransferFrom {2686                    from: __self_0,2687                    to: __self_1,2688                    token_id: __self_2,2689                } => {2690                    ::core::fmt::Formatter::debug_struct_field3_finish(2691                        f,2692                        "TransferFrom",2693                        "from",2694                        &__self_0,2695                        "to",2696                        &__self_1,2697                        "token_id",2698                        &__self_2,2699                    )2700                }2701                ERC721Call::Approve { approved: __self_0, token_id: __self_1 } => {2702                    ::core::fmt::Formatter::debug_struct_field2_finish(2703                        f,2704                        "Approve",2705                        "approved",2706                        &__self_0,2707                        "token_id",2708                        &__self_1,2709                    )2710                }2711                ERC721Call::SetApprovalForAll {2712                    _operator: __self_0,2713                    _approved: __self_1,2714                } => {2715                    ::core::fmt::Formatter::debug_struct_field2_finish(2716                        f,2717                        "SetApprovalForAll",2718                        "_operator",2719                        &__self_0,2720                        "_approved",2721                        &__self_1,2722                    )2723                }2724                ERC721Call::GetApproved { _token_id: __self_0 } => {2725                    ::core::fmt::Formatter::debug_struct_field1_finish(2726                        f,2727                        "GetApproved",2728                        "_token_id",2729                        &__self_0,2730                    )2731                }2732                ERC721Call::IsApprovedForAll {2733                    _owner: __self_0,2734                    _operator: __self_1,2735                } => {2736                    ::core::fmt::Formatter::debug_struct_field2_finish(2737                        f,2738                        "IsApprovedForAll",2739                        "_owner",2740                        &__self_0,2741                        "_operator",2742                        &__self_1,2743                    )2744                }2745            }2746        }2747    }2748    impl<T> ERC721Call<T> {2749        const BALANCE_OF_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {2750            {2751                let fs = FunctionSignature::new(&&FunctionName::new("balanceOf"));2752                let fs = FunctionSignature::done(2753                    FunctionSignature::add_param(2754                        fs,2755                        (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2756                    ),2757                    true,2758                );2759                fs2760            }2761        };2762        ///balanceOf(address)2763        const BALANCE_OF: ::evm_coder::types::bytes4 = {2764            let a = ::evm_coder::sha3_const::Keccak256::new()2765                .update_with_size(2766                    &Self::BALANCE_OF_SIGNATURE.signature,2767                    Self::BALANCE_OF_SIGNATURE.signature_len,2768                )2769                .finalize();2770            [a[0], a[1], a[2], a[3]]2771        };2772        const OWNER_OF_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {2773            {2774                let fs = FunctionSignature::new(&&FunctionName::new("ownerOf"));2775                let fs = FunctionSignature::done(2776                    FunctionSignature::add_param(2777                        fs,2778                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),2779                    ),2780                    true,2781                );2782                fs2783            }2784        };2785        ///ownerOf(uint256)2786        const OWNER_OF: ::evm_coder::types::bytes4 = {2787            let a = ::evm_coder::sha3_const::Keccak256::new()2788                .update_with_size(2789                    &Self::OWNER_OF_SIGNATURE.signature,2790                    Self::OWNER_OF_SIGNATURE.signature_len,2791                )2792                .finalize();2793            [a[0], a[1], a[2], a[3]]2794        };2795        const SAFE_TRANSFER_FROM_WITH_DATA_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {2796            {2797                let fs = FunctionSignature::new(&&FunctionName::new("safeTransferFrom"));2798                let fs = FunctionSignature::done(2799                    FunctionSignature::add_param(2800                        FunctionSignature::add_param(2801                            FunctionSignature::add_param(2802                                FunctionSignature::add_param(2803                                    fs,2804                                    (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2805                                ),2806                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2807                            ),2808                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),2809                        ),2810                        (<bytes>::SIGNATURE, <bytes>::SIGNATURE_LEN),2811                    ),2812                    true,2813                );2814                fs2815            }2816        };2817        ///safeTransferFrom(address,address,uint256,bytes)2818        const SAFE_TRANSFER_FROM_WITH_DATA: ::evm_coder::types::bytes4 = {2819            let a = ::evm_coder::sha3_const::Keccak256::new()2820                .update_with_size(2821                    &Self::SAFE_TRANSFER_FROM_WITH_DATA_SIGNATURE.signature,2822                    Self::SAFE_TRANSFER_FROM_WITH_DATA_SIGNATURE.signature_len,2823                )2824                .finalize();2825            [a[0], a[1], a[2], a[3]]2826        };2827        const SAFE_TRANSFER_FROM_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {2828            {2829                let fs = FunctionSignature::new(&&FunctionName::new("safeTransferFrom"));2830                let fs = FunctionSignature::done(2831                    FunctionSignature::add_param(2832                        FunctionSignature::add_param(2833                            FunctionSignature::add_param(2834                                fs,2835                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2836                            ),2837                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2838                        ),2839                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),2840                    ),2841                    true,2842                );2843                fs2844            }2845        };2846        ///safeTransferFrom(address,address,uint256)2847        const SAFE_TRANSFER_FROM: ::evm_coder::types::bytes4 = {2848            let a = ::evm_coder::sha3_const::Keccak256::new()2849                .update_with_size(2850                    &Self::SAFE_TRANSFER_FROM_SIGNATURE.signature,2851                    Self::SAFE_TRANSFER_FROM_SIGNATURE.signature_len,2852                )2853                .finalize();2854            [a[0], a[1], a[2], a[3]]2855        };2856        const TRANSFER_FROM_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {2857            {2858                let fs = FunctionSignature::new(&&FunctionName::new("transferFrom"));2859                let fs = FunctionSignature::done(2860                    FunctionSignature::add_param(2861                        FunctionSignature::add_param(2862                            FunctionSignature::add_param(2863                                fs,2864                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2865                            ),2866                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2867                        ),2868                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),2869                    ),2870                    true,2871                );2872                fs2873            }2874        };2875        ///transferFrom(address,address,uint256)2876        const TRANSFER_FROM: ::evm_coder::types::bytes4 = {2877            let a = ::evm_coder::sha3_const::Keccak256::new()2878                .update_with_size(2879                    &Self::TRANSFER_FROM_SIGNATURE.signature,2880                    Self::TRANSFER_FROM_SIGNATURE.signature_len,2881                )2882                .finalize();2883            [a[0], a[1], a[2], a[3]]2884        };2885        const APPROVE_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {2886            {2887                let fs = FunctionSignature::new(&&FunctionName::new("approve"));2888                let fs = FunctionSignature::done(2889                    FunctionSignature::add_param(2890                        FunctionSignature::add_param(2891                            fs,2892                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2893                        ),2894                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),2895                    ),2896                    true,2897                );2898                fs2899            }2900        };2901        ///approve(address,uint256)2902        const APPROVE: ::evm_coder::types::bytes4 = {2903            let a = ::evm_coder::sha3_const::Keccak256::new()2904                .update_with_size(2905                    &Self::APPROVE_SIGNATURE.signature,2906                    Self::APPROVE_SIGNATURE.signature_len,2907                )2908                .finalize();2909            [a[0], a[1], a[2], a[3]]2910        };2911        const SET_APPROVAL_FOR_ALL_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {2912            {2913                let fs = FunctionSignature::new(2914                    &&FunctionName::new("setApprovalForAll"),2915                );2916                let fs = FunctionSignature::done(2917                    FunctionSignature::add_param(2918                        FunctionSignature::add_param(2919                            fs,2920                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2921                        ),2922                        (<bool>::SIGNATURE, <bool>::SIGNATURE_LEN),2923                    ),2924                    true,2925                );2926                fs2927            }2928        };2929        ///setApprovalForAll(address,bool)2930        const SET_APPROVAL_FOR_ALL: ::evm_coder::types::bytes4 = {2931            let a = ::evm_coder::sha3_const::Keccak256::new()2932                .update_with_size(2933                    &Self::SET_APPROVAL_FOR_ALL_SIGNATURE.signature,2934                    Self::SET_APPROVAL_FOR_ALL_SIGNATURE.signature_len,2935                )2936                .finalize();2937            [a[0], a[1], a[2], a[3]]2938        };2939        const GET_APPROVED_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {2940            {2941                let fs = FunctionSignature::new(&&FunctionName::new("getApproved"));2942                let fs = FunctionSignature::done(2943                    FunctionSignature::add_param(2944                        fs,2945                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),2946                    ),2947                    true,2948                );2949                fs2950            }2951        };2952        ///getApproved(uint256)2953        const GET_APPROVED: ::evm_coder::types::bytes4 = {2954            let a = ::evm_coder::sha3_const::Keccak256::new()2955                .update_with_size(2956                    &Self::GET_APPROVED_SIGNATURE.signature,2957                    Self::GET_APPROVED_SIGNATURE.signature_len,2958                )2959                .finalize();2960            [a[0], a[1], a[2], a[3]]2961        };2962        const IS_APPROVED_FOR_ALL_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {2963            {2964                let fs = FunctionSignature::new(&&FunctionName::new("isApprovedForAll"));2965                let fs = FunctionSignature::done(2966                    FunctionSignature::add_param(2967                        FunctionSignature::add_param(2968                            fs,2969                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2970                        ),2971                        (<address>::SIGNATURE, <address>::SIGNATURE_LEN),2972                    ),2973                    true,2974                );2975                fs2976            }2977        };2978        ///isApprovedForAll(address,address)2979        const IS_APPROVED_FOR_ALL: ::evm_coder::types::bytes4 = {2980            let a = ::evm_coder::sha3_const::Keccak256::new()2981                .update_with_size(2982                    &Self::IS_APPROVED_FOR_ALL_SIGNATURE.signature,2983                    Self::IS_APPROVED_FOR_ALL_SIGNATURE.signature_len,2984                )2985                .finalize();2986            [a[0], a[1], a[2], a[3]]2987        };2988        /// Return this call ERC165 selector2989        pub fn interface_id() -> ::evm_coder::types::bytes4 {2990            let mut interface_id = 0;2991            interface_id ^= u32::from_be_bytes(Self::BALANCE_OF);2992            interface_id ^= u32::from_be_bytes(Self::OWNER_OF);2993            interface_id ^= u32::from_be_bytes(Self::SAFE_TRANSFER_FROM_WITH_DATA);2994            interface_id ^= u32::from_be_bytes(Self::SAFE_TRANSFER_FROM);2995            interface_id ^= u32::from_be_bytes(Self::TRANSFER_FROM);2996            interface_id ^= u32::from_be_bytes(Self::APPROVE);2997            interface_id ^= u32::from_be_bytes(Self::SET_APPROVAL_FOR_ALL);2998            interface_id ^= u32::from_be_bytes(Self::GET_APPROVED);2999            interface_id ^= u32::from_be_bytes(Self::IS_APPROVED_FOR_ALL);3000            u32::to_be_bytes(interface_id)3001        }3002        /// Generate solidity definitions for methods described in this interface3003        pub fn generate_solidity_interface(3004            tc: &evm_coder::solidity::TypeCollector,3005            is_impl: bool,3006        ) {3007            use evm_coder::solidity::*;3008            use core::fmt::Write;3009            let interface = SolidityInterface {3010                docs: &[3011                    " @title ERC-721 Non-Fungible Token Standard",3012                    " @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md",3013                ],3014                name: "ERC721",3015                selector: Self::interface_id(),3016                is: &["Dummy", "ERC165", "ERC721Events"],3017                functions: (3018                    SolidityFunction {3019                        docs: &[3020                            " @notice Count all NFTs assigned to an owner",3021                            " @dev NFTs assigned to the zero address are considered invalid, and this",3022                            "  function throws for queries about the zero address.",3023                            " @param owner An address for whom to query the balance",3024                            " @return The number of NFTs owned by `owner`, possibly zero",3025                        ],3026                        selector_str: "balanceOf(address)",3027                        selector: u32::from_be_bytes(Self::BALANCE_OF),3028                        custom_signature: {3029                            const cs: FunctionSignature = {3030                                {3031                                    let fs = FunctionSignature::new(3032                                        &&FunctionName::new("balanceOf"),3033                                    );3034                                    let fs = FunctionSignature::done(3035                                        FunctionSignature::add_param(3036                                            fs,3037                                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),3038                                        ),3039                                        true,3040                                    );3041                                    fs3042                                }3043                            };3044                            cs3045                        },3046                        name: "balanceOf",3047                        mutability: SolidityMutability::View,3048                        is_payable: false,3049                        args: (<NamedArgument<address>>::new("owner"),),3050                        result: <UnnamedArgument<uint256>>::default(),3051                    },3052                    SolidityFunction {3053                        docs: &[3054                            " @notice Find the owner of an NFT",3055                            " @dev NFTs assigned to zero address are considered invalid, and queries",3056                            "  about them do throw.",3057                            " @param tokenId The identifier for an NFT",3058                            " @return The address of the owner of the NFT",3059                        ],3060                        selector_str: "ownerOf(uint256)",3061                        selector: u32::from_be_bytes(Self::OWNER_OF),3062                        custom_signature: {3063                            const cs: FunctionSignature = {3064                                {3065                                    let fs = FunctionSignature::new(3066                                        &&FunctionName::new("ownerOf"),3067                                    );3068                                    let fs = FunctionSignature::done(3069                                        FunctionSignature::add_param(3070                                            fs,3071                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),3072                                        ),3073                                        true,3074                                    );3075                                    fs3076                                }3077                            };3078                            cs3079                        },3080                        name: "ownerOf",3081                        mutability: SolidityMutability::View,3082                        is_payable: false,3083                        args: (<NamedArgument<uint256>>::new("tokenId"),),3084                        result: <UnnamedArgument<address>>::default(),3085                    },3086                    SolidityFunction {3087                        docs: &[" @dev Not implemented"],3088                        selector_str: "safeTransferFrom(address,address,uint256,bytes)",3089                        selector: u32::from_be_bytes(Self::SAFE_TRANSFER_FROM_WITH_DATA),3090                        custom_signature: {3091                            const cs: FunctionSignature = {3092                                {3093                                    let fs = FunctionSignature::new(3094                                        &&FunctionName::new("safeTransferFrom"),3095                                    );3096                                    let fs = FunctionSignature::done(3097                                        FunctionSignature::add_param(3098                                            FunctionSignature::add_param(3099                                                FunctionSignature::add_param(3100                                                    FunctionSignature::add_param(3101                                                        fs,3102                                                        (<address>::SIGNATURE, <address>::SIGNATURE_LEN),3103                                                    ),3104                                                    (<address>::SIGNATURE, <address>::SIGNATURE_LEN),3105                                                ),3106                                                (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),3107                                            ),3108                                            (<bytes>::SIGNATURE, <bytes>::SIGNATURE_LEN),3109                                        ),3110                                        true,3111                                    );3112                                    fs3113                                }3114                            };3115                            cs3116                        },3117                        name: "safeTransferFrom",3118                        mutability: SolidityMutability::Mutable,3119                        is_payable: false,3120                        args: (3121                            <NamedArgument<address>>::new("from"),3122                            <NamedArgument<address>>::new("to"),3123                            <NamedArgument<uint256>>::new("tokenId"),3124                            <NamedArgument<bytes>>::new("data"),3125                        ),3126                        result: <UnnamedArgument<void>>::default(),3127                    },3128                    SolidityFunction {3129                        docs: &[" @dev Not implemented"],3130                        selector_str: "safeTransferFrom(address,address,uint256)",3131                        selector: u32::from_be_bytes(Self::SAFE_TRANSFER_FROM),3132                        custom_signature: {3133                            const cs: FunctionSignature = {3134                                {3135                                    let fs = FunctionSignature::new(3136                                        &&FunctionName::new("safeTransferFrom"),3137                                    );3138                                    let fs = FunctionSignature::done(3139                                        FunctionSignature::add_param(3140                                            FunctionSignature::add_param(3141                                                FunctionSignature::add_param(3142                                                    fs,3143                                                    (<address>::SIGNATURE, <address>::SIGNATURE_LEN),3144                                                ),3145                                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),3146                                            ),3147                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),3148                                        ),3149                                        true,3150                                    );3151                                    fs3152                                }3153                            };3154                            cs3155                        },3156                        name: "safeTransferFrom",3157                        mutability: SolidityMutability::Mutable,3158                        is_payable: false,3159                        args: (3160                            <NamedArgument<address>>::new("from"),3161                            <NamedArgument<address>>::new("to"),3162                            <NamedArgument<uint256>>::new("tokenId"),3163                        ),3164                        result: <UnnamedArgument<void>>::default(),3165                    },3166                    SolidityFunction {3167                        docs: &[3168                            " @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE",3169                            "  TO CONFIRM THAT `to` IS CAPABLE OF RECEIVING NFTS OR ELSE",3170                            "  THEY MAY BE PERMANENTLY LOST",3171                            " @dev Throws unless `msg.sender` is the current owner or an authorized",3172                            "  operator for this NFT. Throws if `from` is not the current owner. Throws",3173                            "  if `to` is the zero address. Throws if `tokenId` is not a valid NFT.",3174                            " @param from The current owner of the NFT",3175                            " @param to The new owner",3176                            " @param tokenId The NFT to transfer",3177                        ],3178                        selector_str: "transferFrom(address,address,uint256)",3179                        selector: u32::from_be_bytes(Self::TRANSFER_FROM),3180                        custom_signature: {3181                            const cs: FunctionSignature = {3182                                {3183                                    let fs = FunctionSignature::new(3184                                        &&FunctionName::new("transferFrom"),3185                                    );3186                                    let fs = FunctionSignature::done(3187                                        FunctionSignature::add_param(3188                                            FunctionSignature::add_param(3189                                                FunctionSignature::add_param(3190                                                    fs,3191                                                    (<address>::SIGNATURE, <address>::SIGNATURE_LEN),3192                                                ),3193                                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),3194                                            ),3195                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),3196                                        ),3197                                        true,3198                                    );3199                                    fs3200                                }3201                            };3202                            cs3203                        },3204                        name: "transferFrom",3205                        mutability: SolidityMutability::Mutable,3206                        is_payable: false,3207                        args: (3208                            <NamedArgument<address>>::new("from"),3209                            <NamedArgument<address>>::new("to"),3210                            <NamedArgument<uint256>>::new("tokenId"),3211                        ),3212                        result: <UnnamedArgument<void>>::default(),3213                    },3214                    SolidityFunction {3215                        docs: &[3216                            " @notice Set or reaffirm the approved address for an NFT",3217                            " @dev The zero address indicates there is no approved address.",3218                            " @dev Throws unless `msg.sender` is the current NFT owner, or an authorized",3219                            "  operator of the current owner.",3220                            " @param approved The new approved NFT controller",3221                            " @param tokenId The NFT to approve",3222                        ],3223                        selector_str: "approve(address,uint256)",3224                        selector: u32::from_be_bytes(Self::APPROVE),3225                        custom_signature: {3226                            const cs: FunctionSignature = {3227                                {3228                                    let fs = FunctionSignature::new(3229                                        &&FunctionName::new("approve"),3230                                    );3231                                    let fs = FunctionSignature::done(3232                                        FunctionSignature::add_param(3233                                            FunctionSignature::add_param(3234                                                fs,3235                                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),3236                                            ),3237                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),3238                                        ),3239                                        true,3240                                    );3241                                    fs3242                                }3243                            };3244                            cs3245                        },3246                        name: "approve",3247                        mutability: SolidityMutability::Mutable,3248                        is_payable: false,3249                        args: (3250                            <NamedArgument<address>>::new("approved"),3251                            <NamedArgument<uint256>>::new("tokenId"),3252                        ),3253                        result: <UnnamedArgument<void>>::default(),3254                    },3255                    SolidityFunction {3256                        docs: &[" @dev Not implemented"],3257                        selector_str: "setApprovalForAll(address,bool)",3258                        selector: u32::from_be_bytes(Self::SET_APPROVAL_FOR_ALL),3259                        custom_signature: {3260                            const cs: FunctionSignature = {3261                                {3262                                    let fs = FunctionSignature::new(3263                                        &&FunctionName::new("setApprovalForAll"),3264                                    );3265                                    let fs = FunctionSignature::done(3266                                        FunctionSignature::add_param(3267                                            FunctionSignature::add_param(3268                                                fs,3269                                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),3270                                            ),3271                                            (<bool>::SIGNATURE, <bool>::SIGNATURE_LEN),3272                                        ),3273                                        true,3274                                    );3275                                    fs3276                                }3277                            };3278                            cs3279                        },3280                        name: "setApprovalForAll",3281                        mutability: SolidityMutability::Mutable,3282                        is_payable: false,3283                        args: (3284                            <NamedArgument<address>>::new("operator"),3285                            <NamedArgument<bool>>::new("approved"),3286                        ),3287                        result: <UnnamedArgument<void>>::default(),3288                    },3289                    SolidityFunction {3290                        docs: &[" @dev Not implemented"],3291                        selector_str: "getApproved(uint256)",3292                        selector: u32::from_be_bytes(Self::GET_APPROVED),3293                        custom_signature: {3294                            const cs: FunctionSignature = {3295                                {3296                                    let fs = FunctionSignature::new(3297                                        &&FunctionName::new("getApproved"),3298                                    );3299                                    let fs = FunctionSignature::done(3300                                        FunctionSignature::add_param(3301                                            fs,3302                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),3303                                        ),3304                                        true,3305                                    );3306                                    fs3307                                }3308                            };3309                            cs3310                        },3311                        name: "getApproved",3312                        mutability: SolidityMutability::View,3313                        is_payable: false,3314                        args: (<NamedArgument<uint256>>::new("tokenId"),),3315                        result: <UnnamedArgument<address>>::default(),3316                    },3317                    SolidityFunction {3318                        docs: &[" @dev Not implemented"],3319                        selector_str: "isApprovedForAll(address,address)",3320                        selector: u32::from_be_bytes(Self::IS_APPROVED_FOR_ALL),3321                        custom_signature: {3322                            const cs: FunctionSignature = {3323                                {3324                                    let fs = FunctionSignature::new(3325                                        &&FunctionName::new("isApprovedForAll"),3326                                    );3327                                    let fs = FunctionSignature::done(3328                                        FunctionSignature::add_param(3329                                            FunctionSignature::add_param(3330                                                fs,3331                                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),3332                                            ),3333                                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),3334                                        ),3335                                        true,3336                                    );3337                                    fs3338                                }3339                            };3340                            cs3341                        },3342                        name: "isApprovedForAll",3343                        mutability: SolidityMutability::View,3344                        is_payable: false,3345                        args: (3346                            <NamedArgument<address>>::new("owner"),3347                            <NamedArgument<address>>::new("operator"),3348                        ),3349                        result: <UnnamedArgument<address>>::default(),3350                    },3351                ),3352            };3353            let mut out = ::evm_coder::types::string::new();3354            if "ERC721".starts_with("Inline") {3355                out.push_str("/// @dev inlined interface\n");3356            }3357            let _ = interface.format(is_impl, &mut out, tc);3358            tc.collect(out);3359            ERC721Events::generate_solidity_interface(tc, is_impl);3360            if is_impl {3361                tc.collect(3362                    "/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n"3363                        .into(),3364                );3365            } else {3366                tc.collect(3367                    "/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n"3368                        .into(),3369                );3370            }3371        }3372    }3373    impl<T> ::evm_coder::Call for ERC721Call<T> {3374        fn parse(3375            method_id: ::evm_coder::types::bytes4,3376            reader: &mut ::evm_coder::abi::AbiReader,3377        ) -> ::evm_coder::execution::Result<Option<Self>> {3378            use ::evm_coder::abi::AbiRead;3379            match method_id {3380                ::evm_coder::ERC165Call::INTERFACE_ID => {3381                    return Ok(3382                        ::evm_coder::ERC165Call::parse(method_id, reader)?3383                            .map(|c| Self::ERC165Call(c, ::core::marker::PhantomData)),3384                    );3385                }3386                Self::BALANCE_OF => {3387                    return Ok(3388                        Some(Self::BalanceOf {3389                            owner: reader.abi_read()?,3390                        }),3391                    );3392                }3393                Self::OWNER_OF => {3394                    return Ok(3395                        Some(Self::OwnerOf {3396                            token_id: reader.abi_read()?,3397                        }),3398                    );3399                }3400                Self::SAFE_TRANSFER_FROM_WITH_DATA => {3401                    return Ok(3402                        Some(Self::SafeTransferFromWithData {3403                            _from: reader.abi_read()?,3404                            _to: reader.abi_read()?,3405                            _token_id: reader.abi_read()?,3406                            _data: reader.abi_read()?,3407                        }),3408                    );3409                }3410                Self::SAFE_TRANSFER_FROM => {3411                    return Ok(3412                        Some(Self::SafeTransferFrom {3413                            _from: reader.abi_read()?,3414                            _to: reader.abi_read()?,3415                            _token_id: reader.abi_read()?,3416                        }),3417                    );3418                }3419                Self::TRANSFER_FROM => {3420                    return Ok(3421                        Some(Self::TransferFrom {3422                            from: reader.abi_read()?,3423                            to: reader.abi_read()?,3424                            token_id: reader.abi_read()?,3425                        }),3426                    );3427                }3428                Self::APPROVE => {3429                    return Ok(3430                        Some(Self::Approve {3431                            approved: reader.abi_read()?,3432                            token_id: reader.abi_read()?,3433                        }),3434                    );3435                }3436                Self::SET_APPROVAL_FOR_ALL => {3437                    return Ok(3438                        Some(Self::SetApprovalForAll {3439                            _operator: reader.abi_read()?,3440                            _approved: reader.abi_read()?,3441                        }),3442                    );3443                }3444                Self::GET_APPROVED => {3445                    return Ok(3446                        Some(Self::GetApproved {3447                            _token_id: reader.abi_read()?,3448                        }),3449                    );3450                }3451                Self::IS_APPROVED_FOR_ALL => {3452                    return Ok(3453                        Some(Self::IsApprovedForAll {3454                            _owner: reader.abi_read()?,3455                            _operator: reader.abi_read()?,3456                        }),3457                    );3458                }3459                _ => {}3460            }3461            return Ok(None);3462        }3463    }3464    impl<T: Config> ERC721Call<T> {3465        /// Is this contract implements specified ERC165 selector3466        pub fn supports_interface(3467            this: &NonfungibleHandle<T>,3468            interface_id: ::evm_coder::types::bytes4,3469        ) -> bool {3470            interface_id != u32::to_be_bytes(0xffffff)3471                && (interface_id == ::evm_coder::ERC165Call::INTERFACE_ID3472                    || interface_id == Self::interface_id())3473        }3474    }3475    impl<T: Config> ::evm_coder::Weighted for ERC721Call<T> {3476        #[allow(unused_variables)]3477        fn weight(&self) -> ::evm_coder::execution::DispatchInfo {3478            match self {3479                Self::ERC165Call(3480                    ::evm_coder::ERC165Call::SupportsInterface { .. },3481                    _,3482                ) => ::frame_support::weights::Weight::from_ref_time(100).into(),3483                Self::BalanceOf { .. } => ().into(),3484                Self::OwnerOf { .. } => ().into(),3485                Self::SafeTransferFromWithData { .. } => ().into(),3486                Self::SafeTransferFrom { .. } => ().into(),3487                Self::TransferFrom { from, to, token_id } => {3488                    (<SelfWeightOf<T>>::transfer_from()).into()3489                }3490                Self::Approve { approved, token_id } => {3491                    (<SelfWeightOf<T>>::approve()).into()3492                }3493                Self::SetApprovalForAll { .. } => ().into(),3494                Self::GetApproved { .. } => ().into(),3495                Self::IsApprovedForAll { .. } => ().into(),3496            }3497        }3498    }3499    impl<T: Config> ::evm_coder::Callable<ERC721Call<T>> for NonfungibleHandle<T> {3500        #[allow(unreachable_code)]3501        fn call(3502            &mut self,3503            c: Msg<ERC721Call<T>>,3504        ) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> {3505            use ::evm_coder::abi::AbiWrite;3506            match c.call {3507                ERC721Call::ERC165Call(3508                    ::evm_coder::ERC165Call::SupportsInterface { interface_id },3509                    _,3510                ) => {3511                    let mut writer = ::evm_coder::abi::AbiWriter::default();3512                    writer3513                        .bool(&<ERC721Call<T>>::supports_interface(self, interface_id));3514                    return Ok(writer.into());3515                }3516                _ => {}3517            }3518            let mut writer = ::evm_coder::abi::AbiWriter::default();3519            match c.call {3520                ERC721Call::BalanceOf { owner } => {3521                    let result = self.balance_of(owner)?;3522                    (&result).to_result()3523                }3524                ERC721Call::OwnerOf { token_id } => {3525                    let result = self.owner_of(token_id)?;3526                    (&result).to_result()3527                }3528                ERC721Call::SafeTransferFromWithData {3529                    _from,3530                    _to,3531                    _token_id,3532                    _data,3533                } => {3534                    let result = self3535                        .safe_transfer_from_with_data(_from, _to, _token_id, _data)?;3536                    (&result).to_result()3537                }3538                ERC721Call::SafeTransferFrom { _from, _to, _token_id } => {3539                    let result = self.safe_transfer_from(_from, _to, _token_id)?;3540                    (&result).to_result()3541                }3542                ERC721Call::TransferFrom { from, to, token_id } => {3543                    let result = self3544                        .transfer_from(c.caller.clone(), from, to, token_id)?;3545                    (&result).to_result()3546                }3547                ERC721Call::Approve { approved, token_id } => {3548                    let result = self.approve(c.caller.clone(), approved, token_id)?;3549                    (&result).to_result()3550                }3551                ERC721Call::SetApprovalForAll { _operator, _approved } => {3552                    let result = self3553                        .set_approval_for_all(c.caller.clone(), _operator, _approved)?;3554                    (&result).to_result()3555                }3556                ERC721Call::GetApproved { _token_id } => {3557                    let result = self.get_approved(_token_id)?;3558                    (&result).to_result()3559                }3560                ERC721Call::IsApprovedForAll { _owner, _operator } => {3561                    let result = self.is_approved_for_all(_owner, _operator)?;3562                    (&result).to_result()3563                }3564                _ => {3565                    Err(3566                        ::evm_coder::execution::Error::from("method is not available")3567                            .into(),3568                    )3569                }3570            }3571        }3572    }3573    /// @title ERC721 Token that can be irreversibly burned (destroyed).3574    impl<T: Config> NonfungibleHandle<T> {3575        /// @notice Burns a specific ERC721 token.3576        /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized3577        ///  operator of the current owner.3578        /// @param tokenId The NFT to approve3579        fn burn(&mut self, caller: caller, token_id: uint256) -> Result<void> {3580            let caller = T::CrossAccountId::from_eth(caller);3581            let token = token_id.try_into()?;3582            <Pallet<T>>::burn(self, &caller, token).map_err(dispatch_to_evm::<T>)?;3583            Ok(())3584        }3585    }3586    /// @title ERC721 Token that can be irreversibly burned (destroyed).3587    pub enum ERC721BurnableCall<T> {3588        /// Inherited method3589        ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<T>),3590        /// @notice Burns a specific ERC721 token.3591        /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized3592        ///  operator of the current owner.3593        /// @param tokenId The NFT to approve3594        #[allow(missing_docs)]3595        Burn { token_id: uint256 },3596    }3597    #[automatically_derived]3598    impl<T: ::core::fmt::Debug> ::core::fmt::Debug for ERC721BurnableCall<T> {3599        fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {3600            match self {3601                ERC721BurnableCall::ERC165Call(__self_0, __self_1) => {3602                    ::core::fmt::Formatter::debug_tuple_field2_finish(3603                        f,3604                        "ERC165Call",3605                        &__self_0,3606                        &__self_1,3607                    )3608                }3609                ERC721BurnableCall::Burn { token_id: __self_0 } => {3610                    ::core::fmt::Formatter::debug_struct_field1_finish(3611                        f,3612                        "Burn",3613                        "token_id",3614                        &__self_0,3615                    )3616                }3617            }3618        }3619    }3620    impl<T> ERC721BurnableCall<T> {3621        const BURN_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {3622            {3623                let fs = FunctionSignature::new(&&FunctionName::new("burn"));3624                let fs = FunctionSignature::done(3625                    FunctionSignature::add_param(3626                        fs,3627                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),3628                    ),3629                    true,3630                );3631                fs3632            }3633        };3634        ///burn(uint256)3635        const BURN: ::evm_coder::types::bytes4 = {3636            let a = ::evm_coder::sha3_const::Keccak256::new()3637                .update_with_size(3638                    &Self::BURN_SIGNATURE.signature,3639                    Self::BURN_SIGNATURE.signature_len,3640                )3641                .finalize();3642            [a[0], a[1], a[2], a[3]]3643        };3644        /// Return this call ERC165 selector3645        pub fn interface_id() -> ::evm_coder::types::bytes4 {3646            let mut interface_id = 0;3647            interface_id ^= u32::from_be_bytes(Self::BURN);3648            u32::to_be_bytes(interface_id)3649        }3650        /// Generate solidity definitions for methods described in this interface3651        pub fn generate_solidity_interface(3652            tc: &evm_coder::solidity::TypeCollector,3653            is_impl: bool,3654        ) {3655            use evm_coder::solidity::*;3656            use core::fmt::Write;3657            let interface = SolidityInterface {3658                docs: &[3659                    " @title ERC721 Token that can be irreversibly burned (destroyed).",3660                ],3661                name: "ERC721Burnable",3662                selector: Self::interface_id(),3663                is: &["Dummy", "ERC165"],3664                functions: (3665                    SolidityFunction {3666                        docs: &[3667                            " @notice Burns a specific ERC721 token.",3668                            " @dev Throws unless `msg.sender` is the current NFT owner, or an authorized",3669                            "  operator of the current owner.",3670                            " @param tokenId The NFT to approve",3671                        ],3672                        selector_str: "burn(uint256)",3673                        selector: u32::from_be_bytes(Self::BURN),3674                        custom_signature: {3675                            const cs: FunctionSignature = {3676                                {3677                                    let fs = FunctionSignature::new(3678                                        &&FunctionName::new("burn"),3679                                    );3680                                    let fs = FunctionSignature::done(3681                                        FunctionSignature::add_param(3682                                            fs,3683                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),3684                                        ),3685                                        true,3686                                    );3687                                    fs3688                                }3689                            };3690                            cs3691                        },3692                        name: "burn",3693                        mutability: SolidityMutability::Mutable,3694                        is_payable: false,3695                        args: (<NamedArgument<uint256>>::new("tokenId"),),3696                        result: <UnnamedArgument<void>>::default(),3697                    },3698                ),3699            };3700            let mut out = ::evm_coder::types::string::new();3701            if "ERC721Burnable".starts_with("Inline") {3702                out.push_str("/// @dev inlined interface\n");3703            }3704            let _ = interface.format(is_impl, &mut out, tc);3705            tc.collect(out);3706            if is_impl {3707                tc.collect(3708                    "/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n"3709                        .into(),3710                );3711            } else {3712                tc.collect(3713                    "/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n"3714                        .into(),3715                );3716            }3717        }3718    }3719    impl<T> ::evm_coder::Call for ERC721BurnableCall<T> {3720        fn parse(3721            method_id: ::evm_coder::types::bytes4,3722            reader: &mut ::evm_coder::abi::AbiReader,3723        ) -> ::evm_coder::execution::Result<Option<Self>> {3724            use ::evm_coder::abi::AbiRead;3725            match method_id {3726                ::evm_coder::ERC165Call::INTERFACE_ID => {3727                    return Ok(3728                        ::evm_coder::ERC165Call::parse(method_id, reader)?3729                            .map(|c| Self::ERC165Call(c, ::core::marker::PhantomData)),3730                    );3731                }3732                Self::BURN => {3733                    return Ok(3734                        Some(Self::Burn {3735                            token_id: reader.abi_read()?,3736                        }),3737                    );3738                }3739                _ => {}3740            }3741            return Ok(None);3742        }3743    }3744    impl<T: Config> ERC721BurnableCall<T> {3745        /// Is this contract implements specified ERC165 selector3746        pub fn supports_interface(3747            this: &NonfungibleHandle<T>,3748            interface_id: ::evm_coder::types::bytes4,3749        ) -> bool {3750            interface_id != u32::to_be_bytes(0xffffff)3751                && (interface_id == ::evm_coder::ERC165Call::INTERFACE_ID3752                    || interface_id == Self::interface_id())3753        }3754    }3755    impl<T: Config> ::evm_coder::Weighted for ERC721BurnableCall<T> {3756        #[allow(unused_variables)]3757        fn weight(&self) -> ::evm_coder::execution::DispatchInfo {3758            match self {3759                Self::ERC165Call(3760                    ::evm_coder::ERC165Call::SupportsInterface { .. },3761                    _,3762                ) => ::frame_support::weights::Weight::from_ref_time(100).into(),3763                Self::Burn { token_id } => (<SelfWeightOf<T>>::burn_item()).into(),3764            }3765        }3766    }3767    impl<T: Config> ::evm_coder::Callable<ERC721BurnableCall<T>>3768    for NonfungibleHandle<T> {3769        #[allow(unreachable_code)]3770        fn call(3771            &mut self,3772            c: Msg<ERC721BurnableCall<T>>,3773        ) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> {3774            use ::evm_coder::abi::AbiWrite;3775            match c.call {3776                ERC721BurnableCall::ERC165Call(3777                    ::evm_coder::ERC165Call::SupportsInterface { interface_id },3778                    _,3779                ) => {3780                    let mut writer = ::evm_coder::abi::AbiWriter::default();3781                    writer3782                        .bool(3783                            &<ERC721BurnableCall<3784                                T,3785                            >>::supports_interface(self, interface_id),3786                        );3787                    return Ok(writer.into());3788                }3789                _ => {}3790            }3791            let mut writer = ::evm_coder::abi::AbiWriter::default();3792            match c.call {3793                ERC721BurnableCall::Burn { token_id } => {3794                    let result = self.burn(c.caller.clone(), token_id)?;3795                    (&result).to_result()3796                }3797                _ => {3798                    Err(3799                        ::evm_coder::execution::Error::from("method is not available")3800                            .into(),3801                    )3802                }3803            }3804        }3805    }3806    /// @title ERC721 minting logic.3807    impl<T: Config> NonfungibleHandle<T> {3808        fn minting_finished(&self) -> Result<bool> {3809            Ok(false)3810        }3811        /// @notice Function to mint token.3812        /// @dev `tokenId` should be obtained with `nextTokenId` method,3813        ///  unlike standard, you can't specify it manually3814        /// @param to The new owner3815        /// @param tokenId ID of the minted NFT3816        fn mint(3817            &mut self,3818            caller: caller,3819            to: address,3820            token_id: uint256,3821        ) -> Result<bool> {3822            let caller = T::CrossAccountId::from_eth(caller);3823            let to = T::CrossAccountId::from_eth(to);3824            let token_id: u32 = token_id.try_into()?;3825            let budget = self3826                .recorder3827                .weight_calls_budget(<StructureWeight<T>>::find_parent());3828            if <TokensMinted<T>>::get(self.id).checked_add(1).ok_or("item id overflow")?3829                != token_id3830            {3831                return Err("item id should be next".into());3832            }3833            <Pallet<3834                T,3835            >>::create_item(3836                    self,3837                    &caller,3838                    CreateItemData::<T> {3839                        properties: BoundedVec::default(),3840                        owner: to,3841                    },3842                    &budget,3843                )3844                .map_err(dispatch_to_evm::<T>)?;3845            Ok(true)3846        }3847        /// @notice Function to mint token with the given tokenUri.3848        /// @dev `tokenId` should be obtained with `nextTokenId` method,3849        ///  unlike standard, you can't specify it manually3850        /// @param to The new owner3851        /// @param tokenId ID of the minted NFT3852        /// @param tokenUri Token URI that would be stored in the NFT properties3853        fn mint_with_token_uri(3854            &mut self,3855            caller: caller,3856            to: address,3857            token_id: uint256,3858            token_uri: string,3859        ) -> Result<bool> {3860            let key = key::url();3861            let permission = get_token_permission::<T>(self.id, &key)?;3862            if !permission.collection_admin {3863                return Err("Operation is not allowed".into());3864            }3865            let caller = T::CrossAccountId::from_eth(caller);3866            let to = T::CrossAccountId::from_eth(to);3867            let token_id: u32 = token_id.try_into().map_err(|_| "amount overflow")?;3868            let budget = self3869                .recorder3870                .weight_calls_budget(<StructureWeight<T>>::find_parent());3871            if <TokensMinted<T>>::get(self.id).checked_add(1).ok_or("item id overflow")?3872                != token_id3873            {3874                return Err("item id should be next".into());3875            }3876            let mut properties = CollectionPropertiesVec::default();3877            properties3878                .try_push(Property {3879                    key,3880                    value: token_uri3881                        .into_bytes()3882                        .try_into()3883                        .map_err(|_| "token uri is too long")?,3884                })3885                .map_err(|e| Error::Revert({3886                    let res = ::alloc::fmt::format(3887                        ::core::fmt::Arguments::new_v1(3888                            &["Can\'t add property: "],3889                            &[::core::fmt::ArgumentV1::new_debug(&e)],3890                        ),3891                    );3892                    res3893                }))?;3894            <Pallet<3895                T,3896            >>::create_item(3897                    self,3898                    &caller,3899                    CreateItemData::<T> {3900                        properties,3901                        owner: to,3902                    },3903                    &budget,3904                )3905                .map_err(dispatch_to_evm::<T>)?;3906            Ok(true)3907        }3908        /// @dev Not implemented3909        fn finish_minting(&mut self, _caller: caller) -> Result<bool> {3910            Err("not implementable".into())3911        }3912    }3913    /// @title ERC721 minting logic.3914    pub enum ERC721MintableCall<T> {3915        /// Inherited method3916        ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<T>),3917        MintingFinished,3918        /// @notice Function to mint token.3919        /// @dev `tokenId` should be obtained with `nextTokenId` method,3920        ///  unlike standard, you can't specify it manually3921        /// @param to The new owner3922        /// @param tokenId ID of the minted NFT3923        #[allow(missing_docs)]3924        Mint { to: address, token_id: uint256 },3925        /// @notice Function to mint token with the given tokenUri.3926        /// @dev `tokenId` should be obtained with `nextTokenId` method,3927        ///  unlike standard, you can't specify it manually3928        /// @param to The new owner3929        /// @param tokenId ID of the minted NFT3930        /// @param tokenUri Token URI that would be stored in the NFT properties3931        #[allow(missing_docs)]3932        MintWithTokenUri { to: address, token_id: uint256, token_uri: string },3933        FinishMinting,3934    }3935    #[automatically_derived]3936    impl<T: ::core::fmt::Debug> ::core::fmt::Debug for ERC721MintableCall<T> {3937        fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {3938            match self {3939                ERC721MintableCall::ERC165Call(__self_0, __self_1) => {3940                    ::core::fmt::Formatter::debug_tuple_field2_finish(3941                        f,3942                        "ERC165Call",3943                        &__self_0,3944                        &__self_1,3945                    )3946                }3947                ERC721MintableCall::MintingFinished => {3948                    ::core::fmt::Formatter::write_str(f, "MintingFinished")3949                }3950                ERC721MintableCall::Mint { to: __self_0, token_id: __self_1 } => {3951                    ::core::fmt::Formatter::debug_struct_field2_finish(3952                        f,3953                        "Mint",3954                        "to",3955                        &__self_0,3956                        "token_id",3957                        &__self_1,3958                    )3959                }3960                ERC721MintableCall::MintWithTokenUri {3961                    to: __self_0,3962                    token_id: __self_1,3963                    token_uri: __self_2,3964                } => {3965                    ::core::fmt::Formatter::debug_struct_field3_finish(3966                        f,3967                        "MintWithTokenUri",3968                        "to",3969                        &__self_0,3970                        "token_id",3971                        &__self_1,3972                        "token_uri",3973                        &__self_2,3974                    )3975                }3976                ERC721MintableCall::FinishMinting => {3977                    ::core::fmt::Formatter::write_str(f, "FinishMinting")3978                }3979            }3980        }3981    }3982    impl<T> ERC721MintableCall<T> {3983        const MINTING_FINISHED_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {3984            {3985                let fs = FunctionSignature::new(&&FunctionName::new("mintingFinished"));3986                let fs = FunctionSignature::done(fs, false);3987                fs3988            }3989        };3990        ///mintingFinished()3991        const MINTING_FINISHED: ::evm_coder::types::bytes4 = {3992            let a = ::evm_coder::sha3_const::Keccak256::new()3993                .update_with_size(3994                    &Self::MINTING_FINISHED_SIGNATURE.signature,3995                    Self::MINTING_FINISHED_SIGNATURE.signature_len,3996                )3997                .finalize();3998            [a[0], a[1], a[2], a[3]]3999        };4000        const MINT_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {4001            {4002                let fs = FunctionSignature::new(&&FunctionName::new("mint"));4003                let fs = FunctionSignature::done(4004                    FunctionSignature::add_param(4005                        FunctionSignature::add_param(4006                            fs,4007                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),4008                        ),4009                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),4010                    ),4011                    true,4012                );4013                fs4014            }4015        };4016        ///mint(address,uint256)4017        const MINT: ::evm_coder::types::bytes4 = {4018            let a = ::evm_coder::sha3_const::Keccak256::new()4019                .update_with_size(4020                    &Self::MINT_SIGNATURE.signature,4021                    Self::MINT_SIGNATURE.signature_len,4022                )4023                .finalize();4024            [a[0], a[1], a[2], a[3]]4025        };4026        const MINT_WITH_TOKEN_URI_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {4027            {4028                let fs = FunctionSignature::new(&&FunctionName::new("mintWithTokenURI"));4029                let fs = FunctionSignature::done(4030                    FunctionSignature::add_param(4031                        FunctionSignature::add_param(4032                            FunctionSignature::add_param(4033                                fs,4034                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),4035                            ),4036                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),4037                        ),4038                        (<string>::SIGNATURE, <string>::SIGNATURE_LEN),4039                    ),4040                    true,4041                );4042                fs4043            }4044        };4045        ///mintWithTokenURI(address,uint256,string)4046        const MINT_WITH_TOKEN_URI: ::evm_coder::types::bytes4 = {4047            let a = ::evm_coder::sha3_const::Keccak256::new()4048                .update_with_size(4049                    &Self::MINT_WITH_TOKEN_URI_SIGNATURE.signature,4050                    Self::MINT_WITH_TOKEN_URI_SIGNATURE.signature_len,4051                )4052                .finalize();4053            [a[0], a[1], a[2], a[3]]4054        };4055        const FINISH_MINTING_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {4056            {4057                let fs = FunctionSignature::new(&&FunctionName::new("finishMinting"));4058                let fs = FunctionSignature::done(fs, false);4059                fs4060            }4061        };4062        ///finishMinting()4063        const FINISH_MINTING: ::evm_coder::types::bytes4 = {4064            let a = ::evm_coder::sha3_const::Keccak256::new()4065                .update_with_size(4066                    &Self::FINISH_MINTING_SIGNATURE.signature,4067                    Self::FINISH_MINTING_SIGNATURE.signature_len,4068                )4069                .finalize();4070            [a[0], a[1], a[2], a[3]]4071        };4072        /// Return this call ERC165 selector4073        pub fn interface_id() -> ::evm_coder::types::bytes4 {4074            let mut interface_id = 0;4075            interface_id ^= u32::from_be_bytes(Self::MINTING_FINISHED);4076            interface_id ^= u32::from_be_bytes(Self::MINT);4077            interface_id ^= u32::from_be_bytes(Self::MINT_WITH_TOKEN_URI);4078            interface_id ^= u32::from_be_bytes(Self::FINISH_MINTING);4079            u32::to_be_bytes(interface_id)4080        }4081        /// Generate solidity definitions for methods described in this interface4082        pub fn generate_solidity_interface(4083            tc: &evm_coder::solidity::TypeCollector,4084            is_impl: bool,4085        ) {4086            use evm_coder::solidity::*;4087            use core::fmt::Write;4088            let interface = SolidityInterface {4089                docs: &[" @title ERC721 minting logic."],4090                name: "ERC721Mintable",4091                selector: Self::interface_id(),4092                is: &["Dummy", "ERC165", "ERC721MintableEvents"],4093                functions: (4094                    SolidityFunction {4095                        docs: &[],4096                        selector_str: "mintingFinished()",4097                        selector: u32::from_be_bytes(Self::MINTING_FINISHED),4098                        custom_signature: {4099                            const cs: FunctionSignature = {4100                                {4101                                    let fs = FunctionSignature::new(4102                                        &&FunctionName::new("mintingFinished"),4103                                    );4104                                    let fs = FunctionSignature::done(fs, false);4105                                    fs4106                                }4107                            };4108                            cs4109                        },4110                        name: "mintingFinished",4111                        mutability: SolidityMutability::View,4112                        is_payable: false,4113                        args: (),4114                        result: <UnnamedArgument<bool>>::default(),4115                    },4116                    SolidityFunction {4117                        docs: &[4118                            " @notice Function to mint token.",4119                            " @dev `tokenId` should be obtained with `nextTokenId` method,",4120                            "  unlike standard, you can't specify it manually",4121                            " @param to The new owner",4122                            " @param tokenId ID of the minted NFT",4123                        ],4124                        selector_str: "mint(address,uint256)",4125                        selector: u32::from_be_bytes(Self::MINT),4126                        custom_signature: {4127                            const cs: FunctionSignature = {4128                                {4129                                    let fs = FunctionSignature::new(4130                                        &&FunctionName::new("mint"),4131                                    );4132                                    let fs = FunctionSignature::done(4133                                        FunctionSignature::add_param(4134                                            FunctionSignature::add_param(4135                                                fs,4136                                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),4137                                            ),4138                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),4139                                        ),4140                                        true,4141                                    );4142                                    fs4143                                }4144                            };4145                            cs4146                        },4147                        name: "mint",4148                        mutability: SolidityMutability::Mutable,4149                        is_payable: false,4150                        args: (4151                            <NamedArgument<address>>::new("to"),4152                            <NamedArgument<uint256>>::new("tokenId"),4153                        ),4154                        result: <UnnamedArgument<bool>>::default(),4155                    },4156                    SolidityFunction {4157                        docs: &[4158                            " @notice Function to mint token with the given tokenUri.",4159                            " @dev `tokenId` should be obtained with `nextTokenId` method,",4160                            "  unlike standard, you can't specify it manually",4161                            " @param to The new owner",4162                            " @param tokenId ID of the minted NFT",4163                            " @param tokenUri Token URI that would be stored in the NFT properties",4164                        ],4165                        selector_str: "mintWithTokenURI(address,uint256,string)",4166                        selector: u32::from_be_bytes(Self::MINT_WITH_TOKEN_URI),4167                        custom_signature: {4168                            const cs: FunctionSignature = {4169                                {4170                                    let fs = FunctionSignature::new(4171                                        &&FunctionName::new("mintWithTokenURI"),4172                                    );4173                                    let fs = FunctionSignature::done(4174                                        FunctionSignature::add_param(4175                                            FunctionSignature::add_param(4176                                                FunctionSignature::add_param(4177                                                    fs,4178                                                    (<address>::SIGNATURE, <address>::SIGNATURE_LEN),4179                                                ),4180                                                (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),4181                                            ),4182                                            (<string>::SIGNATURE, <string>::SIGNATURE_LEN),4183                                        ),4184                                        true,4185                                    );4186                                    fs4187                                }4188                            };4189                            cs4190                        },4191                        name: "mintWithTokenURI",4192                        mutability: SolidityMutability::Mutable,4193                        is_payable: false,4194                        args: (4195                            <NamedArgument<address>>::new("to"),4196                            <NamedArgument<uint256>>::new("tokenId"),4197                            <NamedArgument<string>>::new("tokenUri"),4198                        ),4199                        result: <UnnamedArgument<bool>>::default(),4200                    },4201                    SolidityFunction {4202                        docs: &[" @dev Not implemented"],4203                        selector_str: "finishMinting()",4204                        selector: u32::from_be_bytes(Self::FINISH_MINTING),4205                        custom_signature: {4206                            const cs: FunctionSignature = {4207                                {4208                                    let fs = FunctionSignature::new(4209                                        &&FunctionName::new("finishMinting"),4210                                    );4211                                    let fs = FunctionSignature::done(fs, false);4212                                    fs4213                                }4214                            };4215                            cs4216                        },4217                        name: "finishMinting",4218                        mutability: SolidityMutability::Mutable,4219                        is_payable: false,4220                        args: (),4221                        result: <UnnamedArgument<bool>>::default(),4222                    },4223                ),4224            };4225            let mut out = ::evm_coder::types::string::new();4226            if "ERC721Mintable".starts_with("Inline") {4227                out.push_str("/// @dev inlined interface\n");4228            }4229            let _ = interface.format(is_impl, &mut out, tc);4230            tc.collect(out);4231            ERC721MintableEvents::generate_solidity_interface(tc, is_impl);4232            if is_impl {4233                tc.collect(4234                    "/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n"4235                        .into(),4236                );4237            } else {4238                tc.collect(4239                    "/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n"4240                        .into(),4241                );4242            }4243        }4244    }4245    impl<T> ::evm_coder::Call for ERC721MintableCall<T> {4246        fn parse(4247            method_id: ::evm_coder::types::bytes4,4248            reader: &mut ::evm_coder::abi::AbiReader,4249        ) -> ::evm_coder::execution::Result<Option<Self>> {4250            use ::evm_coder::abi::AbiRead;4251            match method_id {4252                ::evm_coder::ERC165Call::INTERFACE_ID => {4253                    return Ok(4254                        ::evm_coder::ERC165Call::parse(method_id, reader)?4255                            .map(|c| Self::ERC165Call(c, ::core::marker::PhantomData)),4256                    );4257                }4258                Self::MINTING_FINISHED => return Ok(Some(Self::MintingFinished)),4259                Self::MINT => {4260                    return Ok(4261                        Some(Self::Mint {4262                            to: reader.abi_read()?,4263                            token_id: reader.abi_read()?,4264                        }),4265                    );4266                }4267                Self::MINT_WITH_TOKEN_URI => {4268                    return Ok(4269                        Some(Self::MintWithTokenUri {4270                            to: reader.abi_read()?,4271                            token_id: reader.abi_read()?,4272                            token_uri: reader.abi_read()?,4273                        }),4274                    );4275                }4276                Self::FINISH_MINTING => return Ok(Some(Self::FinishMinting)),4277                _ => {}4278            }4279            return Ok(None);4280        }4281    }4282    impl<T: Config> ERC721MintableCall<T> {4283        /// Is this contract implements specified ERC165 selector4284        pub fn supports_interface(4285            this: &NonfungibleHandle<T>,4286            interface_id: ::evm_coder::types::bytes4,4287        ) -> bool {4288            interface_id != u32::to_be_bytes(0xffffff)4289                && (interface_id == ::evm_coder::ERC165Call::INTERFACE_ID4290                    || interface_id == Self::interface_id())4291        }4292    }4293    impl<T: Config> ::evm_coder::Weighted for ERC721MintableCall<T> {4294        #[allow(unused_variables)]4295        fn weight(&self) -> ::evm_coder::execution::DispatchInfo {4296            match self {4297                Self::ERC165Call(4298                    ::evm_coder::ERC165Call::SupportsInterface { .. },4299                    _,4300                ) => ::frame_support::weights::Weight::from_ref_time(100).into(),4301                Self::MintingFinished => ().into(),4302                Self::Mint { to, token_id } => (<SelfWeightOf<T>>::create_item()).into(),4303                Self::MintWithTokenUri { to, token_id, token_uri } => {4304                    (<SelfWeightOf<T>>::create_item()).into()4305                }4306                Self::FinishMinting => ().into(),4307            }4308        }4309    }4310    impl<T: Config> ::evm_coder::Callable<ERC721MintableCall<T>>4311    for NonfungibleHandle<T> {4312        #[allow(unreachable_code)]4313        fn call(4314            &mut self,4315            c: Msg<ERC721MintableCall<T>>,4316        ) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> {4317            use ::evm_coder::abi::AbiWrite;4318            match c.call {4319                ERC721MintableCall::ERC165Call(4320                    ::evm_coder::ERC165Call::SupportsInterface { interface_id },4321                    _,4322                ) => {4323                    let mut writer = ::evm_coder::abi::AbiWriter::default();4324                    writer4325                        .bool(4326                            &<ERC721MintableCall<4327                                T,4328                            >>::supports_interface(self, interface_id),4329                        );4330                    return Ok(writer.into());4331                }4332                _ => {}4333            }4334            let mut writer = ::evm_coder::abi::AbiWriter::default();4335            match c.call {4336                ERC721MintableCall::MintingFinished => {4337                    let result = self.minting_finished()?;4338                    (&result).to_result()4339                }4340                ERC721MintableCall::Mint { to, token_id } => {4341                    let result = self.mint(c.caller.clone(), to, token_id)?;4342                    (&result).to_result()4343                }4344                ERC721MintableCall::MintWithTokenUri { to, token_id, token_uri } => {4345                    let result = self4346                        .mint_with_token_uri(c.caller.clone(), to, token_id, token_uri)?;4347                    (&result).to_result()4348                }4349                ERC721MintableCall::FinishMinting => {4350                    let result = self.finish_minting(c.caller.clone())?;4351                    (&result).to_result()4352                }4353                _ => {4354                    Err(4355                        ::evm_coder::execution::Error::from("method is not available")4356                            .into(),4357                    )4358                }4359            }4360        }4361    }4362    fn get_token_property<T: Config>(4363        collection: &CollectionHandle<T>,4364        token_id: u32,4365        key: &up_data_structs::PropertyKey,4366    ) -> Result<string> {4367        collection.consume_store_reads(1)?;4368        let properties = <TokenProperties<T>>::try_get((collection.id, token_id))4369            .map_err(|_| Error::Revert("Token properties not found".into()))?;4370        if let Some(property) = properties.get(key) {4371            return Ok(string::from_utf8_lossy(property).into());4372        }4373        Err("Property tokenURI not found".into())4374    }4375    fn is_erc721_metadata_compatible<T: Config>(collection_id: CollectionId) -> bool {4376        if let Some(shema_name)4377            = pallet_common::Pallet::<4378                T,4379            >::get_collection_property(collection_id, &key::schema_name()) {4380            let shema_name = shema_name.into_inner();4381            shema_name == property_value::ERC721_METADATA4382        } else {4383            false4384        }4385    }4386    fn get_token_permission<T: Config>(4387        collection_id: CollectionId,4388        key: &PropertyKey,4389    ) -> Result<PropertyPermission> {4390        let token_property_permissions = CollectionPropertyPermissions::<4391            T,4392        >::try_get(collection_id)4393            .map_err(|_| Error::Revert("No permissions for collection".into()))?;4394        let a = token_property_permissions4395            .get(key)4396            .map(Clone::clone)4397            .ok_or_else(|| {4398                let key = string::from_utf8(key.clone().into_inner())4399                    .unwrap_or_default();4400                Error::Revert({4401                    let res = ::alloc::fmt::format(4402                        ::core::fmt::Arguments::new_v1(4403                            &["No permission for key "],4404                            &[::core::fmt::ArgumentV1::new_display(&key)],4405                        ),4406                    );4407                    res4408                })4409            })?;4410        Ok(a)4411    }4412    fn has_token_permission<T: Config>(4413        collection_id: CollectionId,4414        key: &PropertyKey,4415    ) -> bool {4416        if let Ok(token_property_permissions)4417            = CollectionPropertyPermissions::<T>::try_get(collection_id) {4418            return token_property_permissions.contains_key(key);4419        }4420        false4421    }4422    /// @title Unique extensions for ERC721.4423    impl<T: Config> NonfungibleHandle<T>4424    where4425        T::AccountId: From<[u8; 32]>,4426    {4427        /// @notice Set or reaffirm the approved address for an NFT4428        /// @dev The zero address indicates there is no approved address.4429        /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized4430        ///  operator of the current owner.4431        /// @param approved The new substrate address approved NFT controller4432        /// @param tokenId The NFT to approve4433        fn approve_cross(4434            &mut self,4435            caller: caller,4436            approved: (address, uint256),4437            token_id: uint256,4438        ) -> Result<void> {4439            let caller = T::CrossAccountId::from_eth(caller);4440            let approved = convert_tuple_to_cross_account::<T>(approved)?;4441            let token = token_id.try_into()?;4442            <Pallet<T>>::set_allowance(self, &caller, token, Some(&approved))4443                .map_err(dispatch_to_evm::<T>)?;4444            Ok(())4445        }4446        /// @notice Transfer ownership of an NFT4447        /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`4448        ///  is the zero address. Throws if `tokenId` is not a valid NFT.4449        /// @param to The new owner4450        /// @param tokenId The NFT to transfer4451        fn transfer(4452            &mut self,4453            caller: caller,4454            to: address,4455            token_id: uint256,4456        ) -> Result<void> {4457            let caller = T::CrossAccountId::from_eth(caller);4458            let to = T::CrossAccountId::from_eth(to);4459            let token = token_id.try_into()?;4460            let budget = self4461                .recorder4462                .weight_calls_budget(<StructureWeight<T>>::find_parent());4463            <Pallet<T>>::transfer(self, &caller, &to, token, &budget)4464                .map_err(dispatch_to_evm::<T>)?;4465            Ok(())4466        }4467        /// @notice Transfer ownership of an NFT from cross account address to cross account address4468        /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`4469        ///  is the zero address. Throws if `tokenId` is not a valid NFT.4470        /// @param from Cross acccount address of current owner4471        /// @param to Cross acccount address of new owner4472        /// @param tokenId The NFT to transfer4473        fn transfer_from_cross(4474            &mut self,4475            caller: caller,4476            from: EthCrossAccount,4477            to: EthCrossAccount,4478            token_id: uint256,4479        ) -> Result<void> {4480            let caller = T::CrossAccountId::from_eth(caller);4481            let from = from.into_sub_cross_account::<T>()?;4482            let to = to.into_sub_cross_account::<T>()?;4483            let token_id = token_id.try_into()?;4484            let budget = self4485                .recorder4486                .weight_calls_budget(<StructureWeight<T>>::find_parent());4487            Pallet::<T>::transfer_from(self, &caller, &from, &to, token_id, &budget)4488                .map_err(dispatch_to_evm::<T>)?;4489            Ok(())4490        }4491        /// @notice Burns a specific ERC721 token.4492        /// @dev Throws unless `msg.sender` is the current owner or an authorized4493        ///  operator for this NFT. Throws if `from` is not the current owner. Throws4494        ///  if `to` is the zero address. Throws if `tokenId` is not a valid NFT.4495        /// @param from The current owner of the NFT4496        /// @param tokenId The NFT to transfer4497        fn burn_from(4498            &mut self,4499            caller: caller,4500            from: address,4501            token_id: uint256,4502        ) -> Result<void> {4503            let caller = T::CrossAccountId::from_eth(caller);4504            let from = T::CrossAccountId::from_eth(from);4505            let token = token_id.try_into()?;4506            let budget = self4507                .recorder4508                .weight_calls_budget(<StructureWeight<T>>::find_parent());4509            <Pallet<T>>::burn_from(self, &caller, &from, token, &budget)4510                .map_err(dispatch_to_evm::<T>)?;4511            Ok(())4512        }4513        /// @notice Burns a specific ERC721 token.4514        /// @dev Throws unless `msg.sender` is the current owner or an authorized4515        ///  operator for this NFT. Throws if `from` is not the current owner. Throws4516        ///  if `to` is the zero address. Throws if `tokenId` is not a valid NFT.4517        /// @param from The current owner of the NFT4518        /// @param tokenId The NFT to transfer4519        fn burn_from_cross(4520            &mut self,4521            caller: caller,4522            from: (address, uint256),4523            token_id: uint256,4524        ) -> Result<void> {4525            let caller = T::CrossAccountId::from_eth(caller);4526            let from = convert_tuple_to_cross_account::<T>(from)?;4527            let token = token_id.try_into()?;4528            let budget = self4529                .recorder4530                .weight_calls_budget(<StructureWeight<T>>::find_parent());4531            <Pallet<T>>::burn_from(self, &caller, &from, token, &budget)4532                .map_err(dispatch_to_evm::<T>)?;4533            Ok(())4534        }4535        /// @notice Returns next free NFT ID.4536        fn next_token_id(&self) -> Result<uint256> {4537            self.consume_store_reads(1)?;4538            Ok(4539                <TokensMinted<T>>::get(self.id)4540                    .checked_add(1)4541                    .ok_or("item id overflow")?4542                    .into(),4543            )4544        }4545        /// @notice Function to mint multiple tokens.4546        /// @dev `tokenIds` should be an array of consecutive numbers and first number4547        ///  should be obtained with `nextTokenId` method4548        /// @param to The new owner4549        /// @param tokenIds IDs of the minted NFTs4550        fn mint_bulk(4551            &mut self,4552            caller: caller,4553            to: address,4554            token_ids: Vec<uint256>,4555        ) -> Result<bool> {4556            let caller = T::CrossAccountId::from_eth(caller);4557            let to = T::CrossAccountId::from_eth(to);4558            let mut expected_index = <TokensMinted<T>>::get(self.id)4559                .checked_add(1)4560                .ok_or("item id overflow")?;4561            let budget = self4562                .recorder4563                .weight_calls_budget(<StructureWeight<T>>::find_parent());4564            let total_tokens = token_ids.len();4565            for id in token_ids.into_iter() {4566                let id: u32 = id.try_into().map_err(|_| "token id overflow")?;4567                if id != expected_index {4568                    return Err("item id should be next".into());4569                }4570                expected_index = expected_index4571                    .checked_add(1)4572                    .ok_or("item id overflow")?;4573            }4574            let data = (0..total_tokens)4575                .map(|_| CreateItemData::<T> {4576                    properties: BoundedVec::default(),4577                    owner: to.clone(),4578                })4579                .collect();4580            <Pallet<T>>::create_multiple_items(self, &caller, data, &budget)4581                .map_err(dispatch_to_evm::<T>)?;4582            Ok(true)4583        }4584        /// @notice Function to mint multiple tokens with the given tokenUris.4585        /// @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive4586        ///  numbers and first number should be obtained with `nextTokenId` method4587        /// @param to The new owner4588        /// @param tokens array of pairs of token ID and token URI for minted tokens4589        fn mint_bulk_with_token_uri(4590            &mut self,4591            caller: caller,4592            to: address,4593            tokens: Vec<(uint256, string)>,4594        ) -> Result<bool> {4595            let key = key::url();4596            let caller = T::CrossAccountId::from_eth(caller);4597            let to = T::CrossAccountId::from_eth(to);4598            let mut expected_index = <TokensMinted<T>>::get(self.id)4599                .checked_add(1)4600                .ok_or("item id overflow")?;4601            let budget = self4602                .recorder4603                .weight_calls_budget(<StructureWeight<T>>::find_parent());4604            let mut data = Vec::with_capacity(tokens.len());4605            for (id, token_uri) in tokens {4606                let id: u32 = id.try_into().map_err(|_| "token id overflow")?;4607                if id != expected_index {4608                    return Err("item id should be next".into());4609                }4610                expected_index = expected_index4611                    .checked_add(1)4612                    .ok_or("item id overflow")?;4613                let mut properties = CollectionPropertiesVec::default();4614                properties4615                    .try_push(Property {4616                        key: key.clone(),4617                        value: token_uri4618                            .into_bytes()4619                            .try_into()4620                            .map_err(|_| "token uri is too long")?,4621                    })4622                    .map_err(|e| Error::Revert({4623                        let res = ::alloc::fmt::format(4624                            ::core::fmt::Arguments::new_v1(4625                                &["Can\'t add property: "],4626                                &[::core::fmt::ArgumentV1::new_debug(&e)],4627                            ),4628                        );4629                        res4630                    }))?;4631                data.push(CreateItemData::<T> {4632                    properties,4633                    owner: to.clone(),4634                });4635            }4636            <Pallet<T>>::create_multiple_items(self, &caller, data, &budget)4637                .map_err(dispatch_to_evm::<T>)?;4638            Ok(true)4639        }4640    }4641    /// @title Unique extensions for ERC721.4642    pub enum ERC721UniqueExtensionsCall<T> {4643        /// Inherited method4644        ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<T>),4645        /// @notice Set or reaffirm the approved address for an NFT4646        /// @dev The zero address indicates there is no approved address.4647        /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized4648        ///  operator of the current owner.4649        /// @param approved The new substrate address approved NFT controller4650        /// @param tokenId The NFT to approve4651        #[allow(missing_docs)]4652        ApproveCross { approved: (address, uint256), token_id: uint256 },4653        /// @notice Transfer ownership of an NFT4654        /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`4655        ///  is the zero address. Throws if `tokenId` is not a valid NFT.4656        /// @param to The new owner4657        /// @param tokenId The NFT to transfer4658        #[allow(missing_docs)]4659        Transfer { to: address, token_id: uint256 },4660        /// @notice Transfer ownership of an NFT from cross account address to cross account address4661        /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`4662        ///  is the zero address. Throws if `tokenId` is not a valid NFT.4663        /// @param from Cross acccount address of current owner4664        /// @param to Cross acccount address of new owner4665        /// @param tokenId The NFT to transfer4666        #[allow(missing_docs)]4667        TransferFromCross {4668            from: EthCrossAccount,4669            to: EthCrossAccount,4670            token_id: uint256,4671        },4672        /// @notice Burns a specific ERC721 token.4673        /// @dev Throws unless `msg.sender` is the current owner or an authorized4674        ///  operator for this NFT. Throws if `from` is not the current owner. Throws4675        ///  if `to` is the zero address. Throws if `tokenId` is not a valid NFT.4676        /// @param from The current owner of the NFT4677        /// @param tokenId The NFT to transfer4678        #[allow(missing_docs)]4679        BurnFrom { from: address, token_id: uint256 },4680        /// @notice Burns a specific ERC721 token.4681        /// @dev Throws unless `msg.sender` is the current owner or an authorized4682        ///  operator for this NFT. Throws if `from` is not the current owner. Throws4683        ///  if `to` is the zero address. Throws if `tokenId` is not a valid NFT.4684        /// @param from The current owner of the NFT4685        /// @param tokenId The NFT to transfer4686        #[allow(missing_docs)]4687        BurnFromCross { from: (address, uint256), token_id: uint256 },4688        NextTokenId,4689        /// @notice Function to mint multiple tokens.4690        /// @dev `tokenIds` should be an array of consecutive numbers and first number4691        ///  should be obtained with `nextTokenId` method4692        /// @param to The new owner4693        /// @param tokenIds IDs of the minted NFTs4694        #[allow(missing_docs)]4695        MintBulk { to: address, token_ids: Vec<uint256> },4696        /// @notice Function to mint multiple tokens with the given tokenUris.4697        /// @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive4698        ///  numbers and first number should be obtained with `nextTokenId` method4699        /// @param to The new owner4700        /// @param tokens array of pairs of token ID and token URI for minted tokens4701        #[allow(missing_docs)]4702        MintBulkWithTokenUri { to: address, tokens: Vec<(uint256, string)> },4703    }4704    #[automatically_derived]4705    impl<T: ::core::fmt::Debug> ::core::fmt::Debug for ERC721UniqueExtensionsCall<T> {4706        fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {4707            match self {4708                ERC721UniqueExtensionsCall::ERC165Call(__self_0, __self_1) => {4709                    ::core::fmt::Formatter::debug_tuple_field2_finish(4710                        f,4711                        "ERC165Call",4712                        &__self_0,4713                        &__self_1,4714                    )4715                }4716                ERC721UniqueExtensionsCall::ApproveCross {4717                    approved: __self_0,4718                    token_id: __self_1,4719                } => {4720                    ::core::fmt::Formatter::debug_struct_field2_finish(4721                        f,4722                        "ApproveCross",4723                        "approved",4724                        &__self_0,4725                        "token_id",4726                        &__self_1,4727                    )4728                }4729                ERC721UniqueExtensionsCall::Transfer {4730                    to: __self_0,4731                    token_id: __self_1,4732                } => {4733                    ::core::fmt::Formatter::debug_struct_field2_finish(4734                        f,4735                        "Transfer",4736                        "to",4737                        &__self_0,4738                        "token_id",4739                        &__self_1,4740                    )4741                }4742                ERC721UniqueExtensionsCall::TransferFromCross {4743                    from: __self_0,4744                    to: __self_1,4745                    token_id: __self_2,4746                } => {4747                    ::core::fmt::Formatter::debug_struct_field3_finish(4748                        f,4749                        "TransferFromCross",4750                        "from",4751                        &__self_0,4752                        "to",4753                        &__self_1,4754                        "token_id",4755                        &__self_2,4756                    )4757                }4758                ERC721UniqueExtensionsCall::BurnFrom {4759                    from: __self_0,4760                    token_id: __self_1,4761                } => {4762                    ::core::fmt::Formatter::debug_struct_field2_finish(4763                        f,4764                        "BurnFrom",4765                        "from",4766                        &__self_0,4767                        "token_id",4768                        &__self_1,4769                    )4770                }4771                ERC721UniqueExtensionsCall::BurnFromCross {4772                    from: __self_0,4773                    token_id: __self_1,4774                } => {4775                    ::core::fmt::Formatter::debug_struct_field2_finish(4776                        f,4777                        "BurnFromCross",4778                        "from",4779                        &__self_0,4780                        "token_id",4781                        &__self_1,4782                    )4783                }4784                ERC721UniqueExtensionsCall::NextTokenId => {4785                    ::core::fmt::Formatter::write_str(f, "NextTokenId")4786                }4787                ERC721UniqueExtensionsCall::MintBulk {4788                    to: __self_0,4789                    token_ids: __self_1,4790                } => {4791                    ::core::fmt::Formatter::debug_struct_field2_finish(4792                        f,4793                        "MintBulk",4794                        "to",4795                        &__self_0,4796                        "token_ids",4797                        &__self_1,4798                    )4799                }4800                ERC721UniqueExtensionsCall::MintBulkWithTokenUri {4801                    to: __self_0,4802                    tokens: __self_1,4803                } => {4804                    ::core::fmt::Formatter::debug_struct_field2_finish(4805                        f,4806                        "MintBulkWithTokenUri",4807                        "to",4808                        &__self_0,4809                        "tokens",4810                        &__self_1,4811                    )4812                }4813            }4814        }4815    }4816    impl<T> ERC721UniqueExtensionsCall<T> {4817        const APPROVE_CROSS_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {4818            {4819                let fs = FunctionSignature::new(&&FunctionName::new("approveCross"));4820                let fs = FunctionSignature::done(4821                    FunctionSignature::add_param(4822                        fs,4823                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),4824                    ),4825                    true,4826                );4827                fs4828            }4829        };4830        ///approveCross((address,uint256),uint256)4831        const APPROVE_CROSS: ::evm_coder::types::bytes4 = {4832            let a = ::evm_coder::sha3_const::Keccak256::new()4833                .update_with_size(4834                    &Self::APPROVE_CROSS_SIGNATURE.signature,4835                    Self::APPROVE_CROSS_SIGNATURE.signature_len,4836                )4837                .finalize();4838            [a[0], a[1], a[2], a[3]]4839        };4840        const TRANSFER_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {4841            {4842                let fs = FunctionSignature::new(&&FunctionName::new("transfer"));4843                let fs = FunctionSignature::done(4844                    FunctionSignature::add_param(4845                        FunctionSignature::add_param(4846                            fs,4847                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),4848                        ),4849                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),4850                    ),4851                    true,4852                );4853                fs4854            }4855        };4856        ///transfer(address,uint256)4857        const TRANSFER: ::evm_coder::types::bytes4 = {4858            let a = ::evm_coder::sha3_const::Keccak256::new()4859                .update_with_size(4860                    &Self::TRANSFER_SIGNATURE.signature,4861                    Self::TRANSFER_SIGNATURE.signature_len,4862                )4863                .finalize();4864            [a[0], a[1], a[2], a[3]]4865        };4866        const TRANSFER_FROM_CROSS_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {4867            {4868                let fs = FunctionSignature::new(4869                    &&FunctionName::new("transferFromCross"),4870                );4871                let fs = FunctionSignature::done(4872                    FunctionSignature::add_param(4873                        FunctionSignature::add_param(4874                            FunctionSignature::add_param(4875                                fs,4876                                (4877                                    <EthCrossAccount>::SIGNATURE,4878                                    <EthCrossAccount>::SIGNATURE_LEN,4879                                ),4880                            ),4881                            (4882                                <EthCrossAccount>::SIGNATURE,4883                                <EthCrossAccount>::SIGNATURE_LEN,4884                            ),4885                        ),4886                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),4887                    ),4888                    true,4889                );4890                fs4891            }4892        };4893        ///transferFromCross(EthCrossAccount,EthCrossAccount,uint256)4894        const TRANSFER_FROM_CROSS: ::evm_coder::types::bytes4 = {4895            let a = ::evm_coder::sha3_const::Keccak256::new()4896                .update_with_size(4897                    &Self::TRANSFER_FROM_CROSS_SIGNATURE.signature,4898                    Self::TRANSFER_FROM_CROSS_SIGNATURE.signature_len,4899                )4900                .finalize();4901            [a[0], a[1], a[2], a[3]]4902        };4903        const BURN_FROM_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {4904            {4905                let fs = FunctionSignature::new(&&FunctionName::new("burnFrom"));4906                let fs = FunctionSignature::done(4907                    FunctionSignature::add_param(4908                        FunctionSignature::add_param(4909                            fs,4910                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),4911                        ),4912                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),4913                    ),4914                    true,4915                );4916                fs4917            }4918        };4919        ///burnFrom(address,uint256)4920        const BURN_FROM: ::evm_coder::types::bytes4 = {4921            let a = ::evm_coder::sha3_const::Keccak256::new()4922                .update_with_size(4923                    &Self::BURN_FROM_SIGNATURE.signature,4924                    Self::BURN_FROM_SIGNATURE.signature_len,4925                )4926                .finalize();4927            [a[0], a[1], a[2], a[3]]4928        };4929        const BURN_FROM_CROSS_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {4930            {4931                let fs = FunctionSignature::new(&&FunctionName::new("burnFromCross"));4932                let fs = FunctionSignature::done(4933                    FunctionSignature::add_param(4934                        fs,4935                        (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),4936                    ),4937                    true,4938                );4939                fs4940            }4941        };4942        ///burnFromCross((address,uint256),uint256)4943        const BURN_FROM_CROSS: ::evm_coder::types::bytes4 = {4944            let a = ::evm_coder::sha3_const::Keccak256::new()4945                .update_with_size(4946                    &Self::BURN_FROM_CROSS_SIGNATURE.signature,4947                    Self::BURN_FROM_CROSS_SIGNATURE.signature_len,4948                )4949                .finalize();4950            [a[0], a[1], a[2], a[3]]4951        };4952        const NEXT_TOKEN_ID_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {4953            {4954                let fs = FunctionSignature::new(&&FunctionName::new("nextTokenId"));4955                let fs = FunctionSignature::done(fs, false);4956                fs4957            }4958        };4959        ///nextTokenId()4960        const NEXT_TOKEN_ID: ::evm_coder::types::bytes4 = {4961            let a = ::evm_coder::sha3_const::Keccak256::new()4962                .update_with_size(4963                    &Self::NEXT_TOKEN_ID_SIGNATURE.signature,4964                    Self::NEXT_TOKEN_ID_SIGNATURE.signature_len,4965                )4966                .finalize();4967            [a[0], a[1], a[2], a[3]]4968        };4969        const MINT_BULK_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {4970            {4971                let fs = FunctionSignature::new(&&FunctionName::new("mintBulk"));4972                let fs = FunctionSignature::done(4973                    FunctionSignature::add_param(4974                        fs,4975                        (<address>::SIGNATURE, <address>::SIGNATURE_LEN),4976                    ),4977                    true,4978                );4979                fs4980            }4981        };4982        ///mintBulk(address,uint256[])4983        const MINT_BULK: ::evm_coder::types::bytes4 = {4984            let a = ::evm_coder::sha3_const::Keccak256::new()4985                .update_with_size(4986                    &Self::MINT_BULK_SIGNATURE.signature,4987                    Self::MINT_BULK_SIGNATURE.signature_len,4988                )4989                .finalize();4990            [a[0], a[1], a[2], a[3]]4991        };4992        const MINT_BULK_WITH_TOKEN_URI_SIGNATURE: ::evm_coder::custom_signature::FunctionSignature = {4993            {4994                let fs = FunctionSignature::new(4995                    &&FunctionName::new("mintBulkWithTokenURI"),4996                );4997                let fs = FunctionSignature::done(4998                    FunctionSignature::add_param(4999                        fs,5000                        (<address>::SIGNATURE, <address>::SIGNATURE_LEN),5001                    ),5002                    true,5003                );5004                fs5005            }5006        };5007        ///mintBulkWithTokenURI(address,(uint256,string)[])5008        const MINT_BULK_WITH_TOKEN_URI: ::evm_coder::types::bytes4 = {5009            let a = ::evm_coder::sha3_const::Keccak256::new()5010                .update_with_size(5011                    &Self::MINT_BULK_WITH_TOKEN_URI_SIGNATURE.signature,5012                    Self::MINT_BULK_WITH_TOKEN_URI_SIGNATURE.signature_len,5013                )5014                .finalize();5015            [a[0], a[1], a[2], a[3]]5016        };5017        /// Return this call ERC165 selector5018        pub fn interface_id() -> ::evm_coder::types::bytes4 {5019            let mut interface_id = 0;5020            interface_id ^= u32::from_be_bytes(Self::APPROVE_CROSS);5021            interface_id ^= u32::from_be_bytes(Self::TRANSFER);5022            interface_id ^= u32::from_be_bytes(Self::TRANSFER_FROM_CROSS);5023            interface_id ^= u32::from_be_bytes(Self::BURN_FROM);5024            interface_id ^= u32::from_be_bytes(Self::BURN_FROM_CROSS);5025            interface_id ^= u32::from_be_bytes(Self::NEXT_TOKEN_ID);5026            interface_id ^= u32::from_be_bytes(Self::MINT_BULK);5027            interface_id ^= u32::from_be_bytes(Self::MINT_BULK_WITH_TOKEN_URI);5028            u32::to_be_bytes(interface_id)5029        }5030        /// Generate solidity definitions for methods described in this interface5031        pub fn generate_solidity_interface(5032            tc: &evm_coder::solidity::TypeCollector,5033            is_impl: bool,5034        ) {5035            use evm_coder::solidity::*;5036            use core::fmt::Write;5037            let interface = SolidityInterface {5038                docs: &[" @title Unique extensions for ERC721."],5039                name: "ERC721UniqueExtensions",5040                selector: Self::interface_id(),5041                is: &["Dummy", "ERC165"],5042                functions: (5043                    SolidityFunction {5044                        docs: &[5045                            " @notice Set or reaffirm the approved address for an NFT",5046                            " @dev The zero address indicates there is no approved address.",5047                            " @dev Throws unless `msg.sender` is the current NFT owner, or an authorized",5048                            "  operator of the current owner.",5049                            " @param approved The new substrate address approved NFT controller",5050                            " @param tokenId The NFT to approve",5051                        ],5052                        selector_str: "approveCross((address,uint256),uint256)",5053                        selector: u32::from_be_bytes(Self::APPROVE_CROSS),5054                        custom_signature: {5055                            const cs: FunctionSignature = {5056                                {5057                                    let fs = FunctionSignature::new(5058                                        &&FunctionName::new("approveCross"),5059                                    );5060                                    let fs = FunctionSignature::done(5061                                        FunctionSignature::add_param(5062                                            fs,5063                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),5064                                        ),5065                                        true,5066                                    );5067                                    fs5068                                }5069                            };5070                            cs5071                        },5072                        name: "approveCross",5073                        mutability: SolidityMutability::Mutable,5074                        is_payable: false,5075                        args: (5076                            <NamedArgument<(address, uint256)>>::new("approved"),5077                            <NamedArgument<uint256>>::new("tokenId"),5078                        ),5079                        result: <UnnamedArgument<void>>::default(),5080                    },5081                    SolidityFunction {5082                        docs: &[5083                            " @notice Transfer ownership of an NFT",5084                            " @dev Throws unless `msg.sender` is the current owner. Throws if `to`",5085                            "  is the zero address. Throws if `tokenId` is not a valid NFT.",5086                            " @param to The new owner",5087                            " @param tokenId The NFT to transfer",5088                        ],5089                        selector_str: "transfer(address,uint256)",5090                        selector: u32::from_be_bytes(Self::TRANSFER),5091                        custom_signature: {5092                            const cs: FunctionSignature = {5093                                {5094                                    let fs = FunctionSignature::new(5095                                        &&FunctionName::new("transfer"),5096                                    );5097                                    let fs = FunctionSignature::done(5098                                        FunctionSignature::add_param(5099                                            FunctionSignature::add_param(5100                                                fs,5101                                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),5102                                            ),5103                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),5104                                        ),5105                                        true,5106                                    );5107                                    fs5108                                }5109                            };5110                            cs5111                        },5112                        name: "transfer",5113                        mutability: SolidityMutability::Mutable,5114                        is_payable: false,5115                        args: (5116                            <NamedArgument<address>>::new("to"),5117                            <NamedArgument<uint256>>::new("tokenId"),5118                        ),5119                        result: <UnnamedArgument<void>>::default(),5120                    },5121                    SolidityFunction {5122                        docs: &[5123                            " @notice Transfer ownership of an NFT from cross account address to cross account address",5124                            " @dev Throws unless `msg.sender` is the current owner. Throws if `to`",5125                            "  is the zero address. Throws if `tokenId` is not a valid NFT.",5126                            " @param from Cross acccount address of current owner",5127                            " @param to Cross acccount address of new owner",5128                            " @param tokenId The NFT to transfer",5129                        ],5130                        selector_str: "transferFromCross(EthCrossAccount,EthCrossAccount,uint256)",5131                        selector: u32::from_be_bytes(Self::TRANSFER_FROM_CROSS),5132                        custom_signature: {5133                            const cs: FunctionSignature = {5134                                {5135                                    let fs = FunctionSignature::new(5136                                        &&FunctionName::new("transferFromCross"),5137                                    );5138                                    let fs = FunctionSignature::done(5139                                        FunctionSignature::add_param(5140                                            FunctionSignature::add_param(5141                                                FunctionSignature::add_param(5142                                                    fs,5143                                                    (5144                                                        <EthCrossAccount>::SIGNATURE,5145                                                        <EthCrossAccount>::SIGNATURE_LEN,5146                                                    ),5147                                                ),5148                                                (5149                                                    <EthCrossAccount>::SIGNATURE,5150                                                    <EthCrossAccount>::SIGNATURE_LEN,5151                                                ),5152                                            ),5153                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),5154                                        ),5155                                        true,5156                                    );5157                                    fs5158                                }5159                            };5160                            cs5161                        },5162                        name: "transferFromCross",5163                        mutability: SolidityMutability::Mutable,5164                        is_payable: false,5165                        args: (5166                            <NamedArgument<EthCrossAccount>>::new("from"),5167                            <NamedArgument<EthCrossAccount>>::new("to"),5168                            <NamedArgument<uint256>>::new("tokenId"),5169                        ),5170                        result: <UnnamedArgument<void>>::default(),5171                    },5172                    SolidityFunction {5173                        docs: &[5174                            " @notice Burns a specific ERC721 token.",5175                            " @dev Throws unless `msg.sender` is the current owner or an authorized",5176                            "  operator for this NFT. Throws if `from` is not the current owner. Throws",5177                            "  if `to` is the zero address. Throws if `tokenId` is not a valid NFT.",5178                            " @param from The current owner of the NFT",5179                            " @param tokenId The NFT to transfer",5180                        ],5181                        selector_str: "burnFrom(address,uint256)",5182                        selector: u32::from_be_bytes(Self::BURN_FROM),5183                        custom_signature: {5184                            const cs: FunctionSignature = {5185                                {5186                                    let fs = FunctionSignature::new(5187                                        &&FunctionName::new("burnFrom"),5188                                    );5189                                    let fs = FunctionSignature::done(5190                                        FunctionSignature::add_param(5191                                            FunctionSignature::add_param(5192                                                fs,5193                                                (<address>::SIGNATURE, <address>::SIGNATURE_LEN),5194                                            ),5195                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),5196                                        ),5197                                        true,5198                                    );5199                                    fs5200                                }5201                            };5202                            cs5203                        },5204                        name: "burnFrom",5205                        mutability: SolidityMutability::Mutable,5206                        is_payable: false,5207                        args: (5208                            <NamedArgument<address>>::new("from"),5209                            <NamedArgument<uint256>>::new("tokenId"),5210                        ),5211                        result: <UnnamedArgument<void>>::default(),5212                    },5213                    SolidityFunction {5214                        docs: &[5215                            " @notice Burns a specific ERC721 token.",5216                            " @dev Throws unless `msg.sender` is the current owner or an authorized",5217                            "  operator for this NFT. Throws if `from` is not the current owner. Throws",5218                            "  if `to` is the zero address. Throws if `tokenId` is not a valid NFT.",5219                            " @param from The current owner of the NFT",5220                            " @param tokenId The NFT to transfer",5221                        ],5222                        selector_str: "burnFromCross((address,uint256),uint256)",5223                        selector: u32::from_be_bytes(Self::BURN_FROM_CROSS),5224                        custom_signature: {5225                            const cs: FunctionSignature = {5226                                {5227                                    let fs = FunctionSignature::new(5228                                        &&FunctionName::new("burnFromCross"),5229                                    );5230                                    let fs = FunctionSignature::done(5231                                        FunctionSignature::add_param(5232                                            fs,5233                                            (<uint256>::SIGNATURE, <uint256>::SIGNATURE_LEN),5234                                        ),5235                                        true,5236                                    );5237                                    fs5238                                }5239                            };5240                            cs5241                        },5242                        name: "burnFromCross",5243                        mutability: SolidityMutability::Mutable,5244                        is_payable: false,5245                        args: (5246                            <NamedArgument<(address, uint256)>>::new("from"),5247                            <NamedArgument<uint256>>::new("tokenId"),5248                        ),5249                        result: <UnnamedArgument<void>>::default(),5250                    },5251                    SolidityFunction {5252                        docs: &[" @notice Returns next free NFT ID."],5253                        selector_str: "nextTokenId()",5254                        selector: u32::from_be_bytes(Self::NEXT_TOKEN_ID),5255                        custom_signature: {5256                            const cs: FunctionSignature = {5257                                {5258                                    let fs = FunctionSignature::new(5259                                        &&FunctionName::new("nextTokenId"),5260                                    );5261                                    let fs = FunctionSignature::done(fs, false);5262                                    fs5263                                }5264                            };5265                            cs5266                        },5267                        name: "nextTokenId",5268                        mutability: SolidityMutability::View,5269                        is_payable: false,5270                        args: (),5271                        result: <UnnamedArgument<uint256>>::default(),5272                    },5273                    SolidityFunction {5274                        docs: &[5275                            " @notice Function to mint multiple tokens.",5276                            " @dev `tokenIds` should be an array of consecutive numbers and first number",5277                            "  should be obtained with `nextTokenId` method",5278                            " @param to The new owner",5279                            " @param tokenIds IDs of the minted NFTs",5280                        ],5281                        selector_str: "mintBulk(address,uint256[])",5282                        selector: u32::from_be_bytes(Self::MINT_BULK),5283                        custom_signature: {5284                            const cs: FunctionSignature = {5285                                {5286                                    let fs = FunctionSignature::new(5287                                        &&FunctionName::new("mintBulk"),5288                                    );5289                                    let fs = FunctionSignature::done(5290                                        FunctionSignature::add_param(5291                                            fs,5292                                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),5293                                        ),5294                                        true,5295                                    );5296                                    fs5297                                }5298                            };5299                            cs5300                        },5301                        name: "mintBulk",5302                        mutability: SolidityMutability::Mutable,5303                        is_payable: false,5304                        args: (5305                            <NamedArgument<address>>::new("to"),5306                            <NamedArgument<Vec<uint256>>>::new("tokenIds"),5307                        ),5308                        result: <UnnamedArgument<bool>>::default(),5309                    },5310                    SolidityFunction {5311                        docs: &[5312                            " @notice Function to mint multiple tokens with the given tokenUris.",5313                            " @dev `tokenIds` is array of pairs of token ID and token URI. Token IDs should be consecutive",5314                            "  numbers and first number should be obtained with `nextTokenId` method",5315                            " @param to The new owner",5316                            " @param tokens array of pairs of token ID and token URI for minted tokens",5317                        ],5318                        selector_str: "mintBulkWithTokenURI(address,(uint256,string)[])",5319                        selector: u32::from_be_bytes(Self::MINT_BULK_WITH_TOKEN_URI),5320                        custom_signature: {5321                            const cs: FunctionSignature = {5322                                {5323                                    let fs = FunctionSignature::new(5324                                        &&FunctionName::new("mintBulkWithTokenURI"),5325                                    );5326                                    let fs = FunctionSignature::done(5327                                        FunctionSignature::add_param(5328                                            fs,5329                                            (<address>::SIGNATURE, <address>::SIGNATURE_LEN),5330                                        ),5331                                        true,5332                                    );5333                                    fs5334                                }5335                            };5336                            cs5337                        },5338                        name: "mintBulkWithTokenURI",5339                        mutability: SolidityMutability::Mutable,5340                        is_payable: false,5341                        args: (5342                            <NamedArgument<address>>::new("to"),5343                            <NamedArgument<Vec<(uint256, string)>>>::new("tokens"),5344                        ),5345                        result: <UnnamedArgument<bool>>::default(),5346                    },5347                ),5348            };5349            let mut out = ::evm_coder::types::string::new();5350            if "ERC721UniqueExtensions".starts_with("Inline") {5351                out.push_str("/// @dev inlined interface\n");5352            }5353            let _ = interface.format(is_impl, &mut out, tc);5354            tc.collect(out);5355            if is_impl {5356                tc.collect(5357                    "/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n"5358                        .into(),5359                );5360            } else {5361                tc.collect(5362                    "/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n"5363                        .into(),5364                );5365            }5366        }5367    }5368    impl<T> ::evm_coder::Call for ERC721UniqueExtensionsCall<T> {5369        fn parse(5370            method_id: ::evm_coder::types::bytes4,5371            reader: &mut ::evm_coder::abi::AbiReader,5372        ) -> ::evm_coder::execution::Result<Option<Self>> {5373            use ::evm_coder::abi::AbiRead;5374            match method_id {5375                ::evm_coder::ERC165Call::INTERFACE_ID => {5376                    return Ok(5377                        ::evm_coder::ERC165Call::parse(method_id, reader)?5378                            .map(|c| Self::ERC165Call(c, ::core::marker::PhantomData)),5379                    );5380                }5381                Self::APPROVE_CROSS => {5382                    return Ok(5383                        Some(Self::ApproveCross {5384                            approved: reader.abi_read()?,5385                            token_id: reader.abi_read()?,5386                        }),5387                    );5388                }5389                Self::TRANSFER => {5390                    return Ok(5391                        Some(Self::Transfer {5392                            to: reader.abi_read()?,5393                            token_id: reader.abi_read()?,5394                        }),5395                    );5396                }5397                Self::TRANSFER_FROM_CROSS => {5398                    return Ok(5399                        Some(Self::TransferFromCross {5400                            from: reader.abi_read()?,5401                            to: reader.abi_read()?,5402                            token_id: reader.abi_read()?,5403                        }),5404                    );5405                }5406                Self::BURN_FROM => {5407                    return Ok(5408                        Some(Self::BurnFrom {5409                            from: reader.abi_read()?,5410                            token_id: reader.abi_read()?,5411                        }),5412                    );5413                }5414                Self::BURN_FROM_CROSS => {5415                    return Ok(5416                        Some(Self::BurnFromCross {5417                            from: reader.abi_read()?,5418                            token_id: reader.abi_read()?,5419                        }),5420                    );5421                }5422                Self::NEXT_TOKEN_ID => return Ok(Some(Self::NextTokenId)),5423                Self::MINT_BULK => {5424                    return Ok(5425                        Some(Self::MintBulk {5426                            to: reader.abi_read()?,5427                            token_ids: reader.abi_read()?,5428                        }),5429                    );5430                }5431                Self::MINT_BULK_WITH_TOKEN_URI => {5432                    return Ok(5433                        Some(Self::MintBulkWithTokenUri {5434                            to: reader.abi_read()?,5435                            tokens: reader.abi_read()?,5436                        }),5437                    );5438                }5439                _ => {}5440            }5441            return Ok(None);5442        }5443    }5444    impl<T: Config> ERC721UniqueExtensionsCall<T>5445    where5446        T::AccountId: From<[u8; 32]>,5447    {5448        /// Is this contract implements specified ERC165 selector5449        pub fn supports_interface(5450            this: &NonfungibleHandle<T>,5451            interface_id: ::evm_coder::types::bytes4,5452        ) -> bool {5453            interface_id != u32::to_be_bytes(0xffffff)5454                && (interface_id == ::evm_coder::ERC165Call::INTERFACE_ID5455                    || interface_id == Self::interface_id())5456        }5457    }5458    impl<T: Config> ::evm_coder::Weighted for ERC721UniqueExtensionsCall<T>5459    where5460        T::AccountId: From<[u8; 32]>,5461    {5462        #[allow(unused_variables)]5463        fn weight(&self) -> ::evm_coder::execution::DispatchInfo {5464            match self {5465                Self::ERC165Call(5466                    ::evm_coder::ERC165Call::SupportsInterface { .. },5467                    _,5468                ) => ::frame_support::weights::Weight::from_ref_time(100).into(),5469                Self::ApproveCross { approved, token_id } => {5470                    (<SelfWeightOf<T>>::approve()).into()5471                }5472                Self::Transfer { to, token_id } => (<SelfWeightOf<T>>::transfer()).into(),5473                Self::TransferFromCross { from, to, token_id } => {5474                    (<SelfWeightOf<T>>::transfer()).into()5475                }5476                Self::BurnFrom { from, token_id } => {5477                    (<SelfWeightOf<T>>::burn_from()).into()5478                }5479                Self::BurnFromCross { from, token_id } => {5480                    (<SelfWeightOf<T>>::burn_from()).into()5481                }5482                Self::NextTokenId => ().into(),5483                Self::MintBulk { to, token_ids } => {5484                    (<SelfWeightOf<T>>::create_multiple_items(token_ids.len() as u32))5485                        .into()5486                }5487                Self::MintBulkWithTokenUri { to, tokens } => {5488                    (<SelfWeightOf<T>>::create_multiple_items(tokens.len() as u32))5489                        .into()5490                }5491            }5492        }5493    }5494    impl<T: Config> ::evm_coder::Callable<ERC721UniqueExtensionsCall<T>>5495    for NonfungibleHandle<T>5496    where5497        T::AccountId: From<[u8; 32]>,5498    {5499        #[allow(unreachable_code)]5500        fn call(5501            &mut self,5502            c: Msg<ERC721UniqueExtensionsCall<T>>,5503        ) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> {5504            use ::evm_coder::abi::AbiWrite;5505            match c.call {5506                ERC721UniqueExtensionsCall::ERC165Call(5507                    ::evm_coder::ERC165Call::SupportsInterface { interface_id },5508                    _,5509                ) => {5510                    let mut writer = ::evm_coder::abi::AbiWriter::default();5511                    writer5512                        .bool(5513                            &<ERC721UniqueExtensionsCall<5514                                T,5515                            >>::supports_interface(self, interface_id),5516                        );5517                    return Ok(writer.into());5518                }5519                _ => {}5520            }5521            let mut writer = ::evm_coder::abi::AbiWriter::default();5522            match c.call {5523                ERC721UniqueExtensionsCall::ApproveCross { approved, token_id } => {5524                    let result = self5525                        .approve_cross(c.caller.clone(), approved, token_id)?;5526                    (&result).to_result()5527                }5528                ERC721UniqueExtensionsCall::Transfer { to, token_id } => {5529                    let result = self.transfer(c.caller.clone(), to, token_id)?;5530                    (&result).to_result()5531                }5532                ERC721UniqueExtensionsCall::TransferFromCross { from, to, token_id } => {5533                    let result = self5534                        .transfer_from_cross(c.caller.clone(), from, to, token_id)?;5535                    (&result).to_result()5536                }5537                ERC721UniqueExtensionsCall::BurnFrom { from, token_id } => {5538                    let result = self.burn_from(c.caller.clone(), from, token_id)?;5539                    (&result).to_result()5540                }5541                ERC721UniqueExtensionsCall::BurnFromCross { from, token_id } => {5542                    let result = self.burn_from_cross(c.caller.clone(), from, token_id)?;5543                    (&result).to_result()5544                }5545                ERC721UniqueExtensionsCall::NextTokenId => {5546                    let result = self.next_token_id()?;5547                    (&result).to_result()5548                }5549                ERC721UniqueExtensionsCall::MintBulk { to, token_ids } => {5550                    let result = self.mint_bulk(c.caller.clone(), to, token_ids)?;5551                    (&result).to_result()5552                }5553                ERC721UniqueExtensionsCall::MintBulkWithTokenUri { to, tokens } => {5554                    let result = self5555                        .mint_bulk_with_token_uri(c.caller.clone(), to, tokens)?;5556                    (&result).to_result()5557                }5558                _ => {5559                    Err(5560                        ::evm_coder::execution::Error::from("method is not available")5561                            .into(),5562                    )5563                }5564            }5565        }5566    }5567    impl<T: Config> NonfungibleHandle<T>5568    where5569        T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,5570    {}5571    pub enum UniqueNFTCall<T> {5572        /// Inherited method5573        ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<T>),5574        ERC721(ERC721Call<T>),5575        ERC721Metadata(ERC721MetadataCall<T>),5576        ERC721Enumerable(ERC721EnumerableCall<T>),5577        ERC721UniqueExtensions(ERC721UniqueExtensionsCall<T>),5578        ERC721Mintable(ERC721MintableCall<T>),5579        ERC721Burnable(ERC721BurnableCall<T>),5580        Collection(CollectionCall<T>),5581        TokenProperties(TokenPropertiesCall<T>),5582    }5583    #[automatically_derived]5584    impl<T: ::core::fmt::Debug> ::core::fmt::Debug for UniqueNFTCall<T> {5585        fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {5586            match self {5587                UniqueNFTCall::ERC165Call(__self_0, __self_1) => {5588                    ::core::fmt::Formatter::debug_tuple_field2_finish(5589                        f,5590                        "ERC165Call",5591                        &__self_0,5592                        &__self_1,5593                    )5594                }5595                UniqueNFTCall::ERC721(__self_0) => {5596                    ::core::fmt::Formatter::debug_tuple_field1_finish(5597                        f,5598                        "ERC721",5599                        &__self_0,5600                    )5601                }5602                UniqueNFTCall::ERC721Metadata(__self_0) => {5603                    ::core::fmt::Formatter::debug_tuple_field1_finish(5604                        f,5605                        "ERC721Metadata",5606                        &__self_0,5607                    )5608                }5609                UniqueNFTCall::ERC721Enumerable(__self_0) => {5610                    ::core::fmt::Formatter::debug_tuple_field1_finish(5611                        f,5612                        "ERC721Enumerable",5613                        &__self_0,5614                    )5615                }5616                UniqueNFTCall::ERC721UniqueExtensions(__self_0) => {5617                    ::core::fmt::Formatter::debug_tuple_field1_finish(5618                        f,5619                        "ERC721UniqueExtensions",5620                        &__self_0,5621                    )5622                }5623                UniqueNFTCall::ERC721Mintable(__self_0) => {5624                    ::core::fmt::Formatter::debug_tuple_field1_finish(5625                        f,5626                        "ERC721Mintable",5627                        &__self_0,5628                    )5629                }5630                UniqueNFTCall::ERC721Burnable(__self_0) => {5631                    ::core::fmt::Formatter::debug_tuple_field1_finish(5632                        f,5633                        "ERC721Burnable",5634                        &__self_0,5635                    )5636                }5637                UniqueNFTCall::Collection(__self_0) => {5638                    ::core::fmt::Formatter::debug_tuple_field1_finish(5639                        f,5640                        "Collection",5641                        &__self_0,5642                    )5643                }5644                UniqueNFTCall::TokenProperties(__self_0) => {5645                    ::core::fmt::Formatter::debug_tuple_field1_finish(5646                        f,5647                        "TokenProperties",5648                        &__self_0,5649                    )5650                }5651            }5652        }5653    }5654    impl<T> UniqueNFTCall<T> {5655        /// Return this call ERC165 selector5656        pub fn interface_id() -> ::evm_coder::types::bytes4 {5657            let mut interface_id = 0;5658            u32::to_be_bytes(interface_id)5659        }5660        /// Generate solidity definitions for methods described in this interface5661        pub fn generate_solidity_interface(5662            tc: &evm_coder::solidity::TypeCollector,5663            is_impl: bool,5664        ) {5665            use evm_coder::solidity::*;5666            use core::fmt::Write;5667            let interface = SolidityInterface {5668                docs: &[],5669                name: "UniqueNFT",5670                selector: Self::interface_id(),5671                is: &[5672                    "Dummy",5673                    "ERC165",5674                    "ERC721",5675                    "ERC721Metadata",5676                    "ERC721Enumerable",5677                    "ERC721UniqueExtensions",5678                    "ERC721Mintable",5679                    "ERC721Burnable",5680                    "Collection",5681                    "TokenProperties",5682                ],5683                functions: (),5684            };5685            let mut out = ::evm_coder::types::string::new();5686            if "UniqueNFT".starts_with("Inline") {5687                out.push_str("/// @dev inlined interface\n");5688            }5689            let _ = interface.format(is_impl, &mut out, tc);5690            tc.collect(out);5691            <ERC721Call<T>>::generate_solidity_interface(tc, is_impl);5692            <ERC721MetadataCall<T>>::generate_solidity_interface(tc, is_impl);5693            <ERC721EnumerableCall<T>>::generate_solidity_interface(tc, is_impl);5694            <ERC721UniqueExtensionsCall<T>>::generate_solidity_interface(tc, is_impl);5695            <ERC721MintableCall<T>>::generate_solidity_interface(tc, is_impl);5696            <ERC721BurnableCall<T>>::generate_solidity_interface(tc, is_impl);5697            <CollectionCall<T>>::generate_solidity_interface(tc, is_impl);5698            <TokenPropertiesCall<T>>::generate_solidity_interface(tc, is_impl);5699            if is_impl {5700                tc.collect(5701                    "/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n"5702                        .into(),5703                );5704            } else {5705                tc.collect(5706                    "/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n"5707                        .into(),5708                );5709            }5710        }5711    }5712    impl<T> ::evm_coder::Call for UniqueNFTCall<T> {5713        fn parse(5714            method_id: ::evm_coder::types::bytes4,5715            reader: &mut ::evm_coder::abi::AbiReader,5716        ) -> ::evm_coder::execution::Result<Option<Self>> {5717            use ::evm_coder::abi::AbiRead;5718            match method_id {5719                ::evm_coder::ERC165Call::INTERFACE_ID => {5720                    return Ok(5721                        ::evm_coder::ERC165Call::parse(method_id, reader)?5722                            .map(|c| Self::ERC165Call(c, ::core::marker::PhantomData)),5723                    );5724                }5725                _ => {}5726            }5727            if let Some(parsed_call) = <ERC721Call<T>>::parse(method_id, reader)? {5728                return Ok(Some(Self::ERC721(parsed_call)))5729            } else if let Some(parsed_call)5730                = <ERC721MetadataCall<T>>::parse(method_id, reader)? {5731                return Ok(Some(Self::ERC721Metadata(parsed_call)))5732            } else if let Some(parsed_call)5733                = <ERC721EnumerableCall<T>>::parse(method_id, reader)? {5734                return Ok(Some(Self::ERC721Enumerable(parsed_call)))5735            } else if let Some(parsed_call)5736                = <ERC721UniqueExtensionsCall<T>>::parse(method_id, reader)? {5737                return Ok(Some(Self::ERC721UniqueExtensions(parsed_call)))5738            } else if let Some(parsed_call)5739                = <ERC721MintableCall<T>>::parse(method_id, reader)? {5740                return Ok(Some(Self::ERC721Mintable(parsed_call)))5741            } else if let Some(parsed_call)5742                = <ERC721BurnableCall<T>>::parse(method_id, reader)? {5743                return Ok(Some(Self::ERC721Burnable(parsed_call)))5744            } else if let Some(parsed_call)5745                = <CollectionCall<T>>::parse(method_id, reader)? {5746                return Ok(Some(Self::Collection(parsed_call)))5747            } else if let Some(parsed_call)5748                = <TokenPropertiesCall<T>>::parse(method_id, reader)? {5749                return Ok(Some(Self::TokenProperties(parsed_call)))5750            }5751            return Ok(None);5752        }5753    }5754    impl<T: Config> UniqueNFTCall<T>5755    where5756        T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,5757    {5758        /// Is this contract implements specified ERC165 selector5759        pub fn supports_interface(5760            this: &NonfungibleHandle<T>,5761            interface_id: ::evm_coder::types::bytes4,5762        ) -> bool {5763            interface_id != u32::to_be_bytes(0xffffff)5764                && (interface_id == ::evm_coder::ERC165Call::INTERFACE_ID5765                    || interface_id == Self::interface_id()5766                    || <ERC721Call<T>>::supports_interface(this, interface_id)5767                    || <ERC721MetadataCall<T>>::supports_interface(this, interface_id)5768                    || <ERC721EnumerableCall<T>>::supports_interface(this, interface_id)5769                    || <ERC721UniqueExtensionsCall<5770                        T,5771                    >>::supports_interface(this, interface_id)5772                    || <ERC721MintableCall<T>>::supports_interface(this, interface_id)5773                    || <ERC721BurnableCall<T>>::supports_interface(this, interface_id)5774                    || <CollectionCall<T>>::supports_interface(this, interface_id)5775                    || <TokenPropertiesCall<T>>::supports_interface(this, interface_id))5776        }5777    }5778    impl<T: Config> ::evm_coder::Weighted for UniqueNFTCall<T>5779    where5780        T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,5781    {5782        #[allow(unused_variables)]5783        fn weight(&self) -> ::evm_coder::execution::DispatchInfo {5784            match self {5785                Self::ERC721(call) => call.weight(),5786                Self::ERC721Metadata(call) => call.weight(),5787                Self::ERC721Enumerable(call) => call.weight(),5788                Self::ERC721UniqueExtensions(call) => call.weight(),5789                Self::ERC721Mintable(call) => call.weight(),5790                Self::ERC721Burnable(call) => call.weight(),5791                Self::Collection(call) => call.weight(),5792                Self::TokenProperties(call) => call.weight(),5793                Self::ERC165Call(5794                    ::evm_coder::ERC165Call::SupportsInterface { .. },5795                    _,5796                ) => ::frame_support::weights::Weight::from_ref_time(100).into(),5797            }5798        }5799    }5800    impl<T: Config> ::evm_coder::Callable<UniqueNFTCall<T>> for NonfungibleHandle<T>5801    where5802        T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,5803    {5804        #[allow(unreachable_code)]5805        fn call(5806            &mut self,5807            c: Msg<UniqueNFTCall<T>>,5808        ) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> {5809            use ::evm_coder::abi::AbiWrite;5810            match c.call {5811                UniqueNFTCall::ERC721(call) => {5812                    return <Self as ::evm_coder::Callable<5813                        ERC721Call<T>,5814                    >>::call(5815                        self,5816                        Msg {5817                            call,5818                            caller: c.caller,5819                            value: c.value,5820                        },5821                    );5822                }5823                UniqueNFTCall::ERC721Metadata(call) => {5824                    return <Self as ::evm_coder::Callable<5825                        ERC721MetadataCall<T>,5826                    >>::call(5827                        self,5828                        Msg {5829                            call,5830                            caller: c.caller,5831                            value: c.value,5832                        },5833                    );5834                }5835                UniqueNFTCall::ERC721Enumerable(call) => {5836                    return <Self as ::evm_coder::Callable<5837                        ERC721EnumerableCall<T>,5838                    >>::call(5839                        self,5840                        Msg {5841                            call,5842                            caller: c.caller,5843                            value: c.value,5844                        },5845                    );5846                }5847                UniqueNFTCall::ERC721UniqueExtensions(call) => {5848                    return <Self as ::evm_coder::Callable<5849                        ERC721UniqueExtensionsCall<T>,5850                    >>::call(5851                        self,5852                        Msg {5853                            call,5854                            caller: c.caller,5855                            value: c.value,5856                        },5857                    );5858                }5859                UniqueNFTCall::ERC721Mintable(call) => {5860                    return <Self as ::evm_coder::Callable<5861                        ERC721MintableCall<T>,5862                    >>::call(5863                        self,5864                        Msg {5865                            call,5866                            caller: c.caller,5867                            value: c.value,5868                        },5869                    );5870                }5871                UniqueNFTCall::ERC721Burnable(call) => {5872                    return <Self as ::evm_coder::Callable<5873                        ERC721BurnableCall<T>,5874                    >>::call(5875                        self,5876                        Msg {5877                            call,5878                            caller: c.caller,5879                            value: c.value,5880                        },5881                    );5882                }5883                UniqueNFTCall::Collection(call) => {5884                    return <CollectionHandle<5885                        T,5886                    > as ::evm_coder::Callable<5887                        CollectionCall<T>,5888                    >>::call(5889                        self.common_mut(),5890                        Msg {5891                            call,5892                            caller: c.caller,5893                            value: c.value,5894                        },5895                    );5896                }5897                UniqueNFTCall::TokenProperties(call) => {5898                    return <Self as ::evm_coder::Callable<5899                        TokenPropertiesCall<T>,5900                    >>::call(5901                        self,5902                        Msg {5903                            call,5904                            caller: c.caller,5905                            value: c.value,5906                        },5907                    );5908                }5909                UniqueNFTCall::ERC165Call(5910                    ::evm_coder::ERC165Call::SupportsInterface { interface_id },5911                    _,5912                ) => {5913                    let mut writer = ::evm_coder::abi::AbiWriter::default();5914                    writer5915                        .bool(5916                            &<UniqueNFTCall<T>>::supports_interface(self, interface_id),5917                        );5918                    return Ok(writer.into());5919                }5920                _ => {}5921            }5922            let mut writer = ::evm_coder::abi::AbiWriter::default();5923            match c.call {5924                _ => {5925                    Err(5926                        ::evm_coder::execution::Error::from("method is not available")5927                            .into(),5928                    )5929                }5930            }5931        }5932    }5933    impl<T: Config> CommonEvmHandler for NonfungibleHandle<T>5934    where5935        T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,5936    {5937        const CODE: &'static [u8] = b"`\xe0`@R`&`\x80\x81\x81R\x90b\x00\x138`\xa09`\x01\x90b\x00\x00\"\x90\x82b\x00\x00\xdcV[P4\x80\x15b\x00\x000W`\x00\x80\xfd[Pb\x00\x01\xa8V[cNH{q`\xe0\x1b`\x00R`A`\x04R`$`\x00\xfd[`\x01\x81\x81\x1c\x90\x82\x16\x80b\x00\x00bW`\x7f\x82\x16\x91P[` \x82\x10\x81\x03b\x00\x00\x83WcNH{q`\xe0\x1b`\x00R`\"`\x04R`$`\x00\xfd[P\x91\x90PV[`\x1f\x82\x11\x15b\x00\x00\xd7W`\x00\x81\x81R` \x81 `\x1f\x85\x01`\x05\x1c\x81\x01` \x86\x10\x15b\x00\x00\xb2WP\x80[`\x1f\x85\x01`\x05\x1c\x82\x01\x91P[\x81\x81\x10\x15b\x00\x00\xd3W\x82\x81U`\x01\x01b\x00\x00\xbeV[PPP[PPPV[\x81Q`\x01`\x01`@\x1b\x03\x81\x11\x15b\x00\x00\xf8Wb\x00\x00\xf8b\x00\x007V[b\x00\x01\x10\x81b\x00\x01\t\x84Tb\x00\x00MV[\x84b\x00\x00\x89V[` \x80`\x1f\x83\x11`\x01\x81\x14b\x00\x01HW`\x00\x84\x15b\x00\x01/WP\x85\x83\x01Q[`\x00\x19`\x03\x86\x90\x1b\x1c\x19\x16`\x01\x85\x90\x1b\x17\x85Ub\x00\x00\xd3V[`\x00\x85\x81R` \x81 `\x1f\x19\x86\x16\x91[\x82\x81\x10\x15b\x00\x01yW\x88\x86\x01Q\x82U\x94\x84\x01\x94`\x01\x90\x91\x01\x90\x84\x01b\x00\x01XV[P\x85\x82\x10\x15b\x00\x01\x98W\x87\x85\x01Q`\x00\x19`\x03\x88\x90\x1b`\xf8\x16\x1c\x19\x16\x81U[PPPPP`\x01\x90\x81\x1b\x01\x90UPV[a\x11\x80\x80b\x00\x01\xb8`\x009`\x00\xf3\xfe`\x80`@R4\x80\x15a\x00\x10W`\x00\x80\xfd[P`\x046\x10a\x03\xdaW`\x005`\xe0\x1c\x80cj8A\xdb\x11a\x02\nW\x80c\x98\x11\xb0\xc7\x11a\x01%W\x80c\xcf$\xfdm\x11a\x00\xb8W\x80c\xdfr};\x11a\x00\x87W\x80c\xdfr};\x14a\x05\xaaW\x80c\xe5\xc9\x91?\x14a\x04{W\x80c\xe9\x85\xe9\xc5\x14a\x06PW\x80c\xf6\xb4\xdf\xb4\x14a\x06^W\x80c\xfa\xfd{B\x14a\x04\x97W`\x00\x80\xfd[\x80c\xcf$\xfdm\x14a\x064W\x80c\xd3KU\xb8\x14a\x042W\x80c\xd5\xcfC\x0b\x14a\x06BW\x80c\xd6:\x8e\x11\x14a\x05\xeeW`\x00\x80\xfd[\x80c\xa9\x05\x9c\xbb\x11a\x00\xf4W\x80c\xa9\x05\x9c\xbb\x14a\x04mW\x80c\xb8\x8dO\xde\x14a\x06\x18W\x80c\xbb/ZX\x14a\x04\x89W\x80c\xc8{V\xdd\x14a\x06&W`\x00\x80\xfd[\x80c\x98\x11\xb0\xc7\x14a\x05\xeeW\x80c\x99;\x7f\xba\x14a\x05\xfcW\x80c\xa0\x18J:\x14a\x04{W\x80c\xa2,\xb4e\x14a\x06\nW`\x00\x80\xfd[\x80cy\xccg\x90\x11a\x01\x9dW\x80c\x85\x9a\xa7\xd6\x11a\x01lW\x80c\x85\x9a\xa7\xd6\x14a\x04{W\x80c\x85\xc5\x1a\xcb\x14a\x04\x97W\x80c\x92\xe4b\xc7\x14a\x04\x97W\x80c\x95\xd8\x9bA\x14a\x042W`\x00\x80\xfd[\x80cy\xccg\x90\x14a\x04mW\x80c{}\xeb\xce\x14a\x05\xe0W\x80c}d\xbc\xb4\x14a\x04\x1cW\x80c\x84\xa1\xd5\xa8\x14a\x04{W`\x00\x80\xfd[\x80cp\xa0\x821\x11a\x01\xd9W\x80cp\xa0\x821\x14a\x05\xbfW\x80cr(\xc3\'\x14a\x05\xcdW\x80cuyJ<\x14a\x04\xb3W\x80cv#@.\x14a\x04\x97W`\x00\x80\xfd[\x80cj8A\xdb\x14a\x05\x9cW\x80cl\x0c\xd1s\x14a\x04{W\x80cn\x03&\xa3\x14a\x05\x0fW\x80cn\xc0\xa9\xf1\x14a\x05\xaaW`\x00\x80\xfd[\x80c/\x07?f\x11a\x02\xfaW\x80cB\x96lh\x11a\x02\x8dW\x80cX\x13!k\x11a\x02\\W\x80cX\x13!k\x14a\x05yW\x80ccR!\x1e\x14a\x04GW\x80cd\x87#\x96\x14a\x05\x8eW\x80cg\x84O\xe6\x14a\x04\x97W`\x00\x80\xfd[\x80cB\x96lh\x14a\x05AW\x80cD\xa9\x94^\x14a\x05OW\x80cOl\xcc\xe7\x14a\x05]W\x80cP\xbbN\x7f\x14a\x05kW`\x00\x80\xfd[\x80c>u\xa9\x05\x11a\x02\xc9W\x80c>u\xa9\x05\x14a\x05\x17W\x80c@\xc1\x0f\x19\x14a\x05%W\x80cA\x83]L\x14a\x053W\x80cB\x84.\x0e\x14a\x04\xd7W`\x00\x80\xfd[\x80c/\x07?f\x14a\x04\xe5W\x80c/t\\Y\x14a\x04\xf3W\x80c6T0\x06\x14a\x05\x01W\x80c<P\xe9z\x14a\x05\x0fW`\x00\x80\xfd[\x80c\t\xbaE*\x11a\x03rW\x80c\x17R\xd6{\x11a\x03AW\x80c\x17R\xd6{\x14a\x04\xa5W\x80c\x18\x16\r\xdd\x14a\x04\xb3W\x80c\"-\x97\xfa\x14a\x04\xc9W\x80c#\xb8r\xdd\x14a\x04\xd7W`\x00\x80\xfd[\x80c\t\xbaE*\x14a\x04{W\x80c\x0e\xcd\n\xb0\x14a\x04\x89W\x80c\x11-E\x86\x14a\x03\xdfW\x80c\x13\xaf@5\x14a\x04\x97W`\x00\x80\xfd[\x80c\x06a\x11\xd1\x11a\x03\xaeW\x80c\x06a\x11\xd1\x14a\x04$W\x80c\x06\xfd\xde\x03\x14a\x042W\x80c\x08\x18\x12\xfc\x14a\x04GW\x80c\t^\xa7\xb3\x14a\x04mW`\x00\x80\xfd[\x80b\x01\x8e\x84\x14a\x03\xdfW\x80c\x01\xff\xc9\xa7\x14a\x03\xf4W\x80c\x05\x8a\xc1\x85\x14a\x04\x1cW\x80c\x05\xd2\x03[\x14a\x04\x1cW[`\x00\x80\xfd[a\x03\xf2a\x03\xed6`\x04a\x07$V[a\x06fV[\x00[a\x04\x07a\x04\x026`\x04a\x07FV[a\x06\x8aV[`@Q\x90\x15\x15\x81R` \x01[`@Q\x80\x91\x03\x90\xf3[a\x04\x07a\x06\x8aV[a\x03\xf2a\x03\xed6`\x04a\x08MV[a\x04:a\x06\xa7V[`@Qa\x04\x13\x91\x90a\x08\xd9V[a\x04Ua\x04\x026`\x04a\x08\xecV[`@Q`\x01`\x01`\xa0\x1b\x03\x90\x91\x16\x81R` \x01a\x04\x13V[a\x03\xf2a\x03\xed6`\x04a\t\x1cV[a\x03\xf2a\x03\xed6`\x04a\t\x9cV[a\x03\xf2a\x03\xed6`\x04a\t\xb8V[a\x03\xf2a\x03\xed6`\x04a\t\xe3V[a\x03\xf2a\x03\xed6`\x04a\t\xfeV[a\x04\xbba\x06\x8aV[`@Q\x90\x81R` \x01a\x04\x13V[a\x03\xf2a\x03\xed6`\x04a\njV[a\x03\xf2a\x03\xed6`\x04a\n\xd8V[a\x03\xf2a\x03\xed6`\x04a\x0b\x14V[a\x04\xbba\x04\x026`\x04a\t\x1cV[a\x04\x07a\x04\x026`\x04a\x0b\x90V[a\x03\xf2a\x06fV[a\x04\x07a\x04\x026`\x04a\t\x9cV[a\x04\x07a\x04\x026`\x04a\t\x1cV[a\x03\xf2a\x03\xed6`\x04a\x0c\x95V[a\x03\xf2a\x03\xed6`\x04a\x08\xecV[a\x04\x07a\x04\x026`\x04a\x0c\xb8V[a\x04\xbba\x04\x026`\x04a\x08\xecV[a\x04\x07a\x04\x026`\x04a\r[V[a\x05\x81a\x06\xa7V[`@Qa\x04\x13\x91\x90a\r\xa7V[a\x03\xf2a\x03\xed6`\x04a\x0e\x07V[a\x03\xf2a\x03\xed6`\x04a\x0e\xa2V[a\x05\xb2a\x06\xf6V[`@Qa\x04\x13\x91\x90a\x0e\xfcV[a\x04\xbba\x04\x026`\x04a\t\xe3V[a\x04:a\x05\xdb6`\x04a\x08MV[a\x06\xa7V[a\x03\xf2a\x03\xed6`\x04a\x0f\x1cV[a\x04\x07a\x04\x026`\x04a\t\xe3V[a\x03\xf2a\x03\xed6`\x04a\x0fXV[a\x03\xf2a\x03\xed6`\x04a\x0f\xa5V[a\x03\xf2a\x03\xed6`\x04a\x0f\xcfV[a\x04:a\x05\xdb6`\x04a\x08\xecV[a\x04:a\x05\xdb6`\x04a\x0f\x1cV[a\x03\xf2a\x03\xed6`\x04a\x106V[a\x04Ua\x04\x026`\x04a\x10tV[a\x04Ua\x06\x8aV[`\x01`@QbF\x1b\xcd`\xe5\x1b\x81R`\x04\x01a\x06\x81\x91\x90a\x10\x9eV[`@Q\x80\x91\x03\x90\xfd[`\x00`\x01`@QbF\x1b\xcd`\xe5\x1b\x81R`\x04\x01a\x06\x81\x91\x90a\x10\x9eV[```\x01`@QbF\x1b\xcd`\xe5\x1b\x81R`\x04\x01a\x06\x81\x91\x90a\x10\x9eV[\x92\x91PPV[`@\x80Q\x80\x82\x01\x90\x91R`\x00\x80\x82R` \x82\x01R\x81R` \x01\x90`\x01\x90\x03\x90\x81a\x06\xcaW\x90PP\x90P\x90V[`@\x80Q\x80\x82\x01\x90\x91R`\x00\x80\x82R` \x82\x01Ra\x06fV[\x805\x80\x15\x15\x81\x14a\x07\x1fW`\x00\x80\xfd[\x91\x90PV[`\x00` \x82\x84\x03\x12\x15a\x076W`\x00\x80\xfd[a\x07?\x82a\x07\x0fV[\x93\x92PPPV[`\x00` \x82\x84\x03\x12\x15a\x07XW`\x00\x80\xfd[\x815`\x01`\x01`\xe0\x1b\x03\x19\x81\x16\x81\x14a\x07?W`\x00\x80\xfd[cNH{q`\xe0\x1b`\x00R`A`\x04R`$`\x00\xfd[`@\x80Q\x90\x81\x01`\x01`\x01`@\x1b\x03\x81\x11\x82\x82\x10\x17\x15a\x07\xa8Wa\x07\xa8a\x07pV[`@R\x90V[`@Q`\x1f\x82\x01`\x1f\x19\x16\x81\x01`\x01`\x01`@\x1b\x03\x81\x11\x82\x82\x10\x17\x15a\x07\xd6Wa\x07\xd6a\x07pV[`@R\x91\x90PV[`\x00\x82`\x1f\x83\x01\x12a\x07\xefW`\x00\x80\xfd[\x815`\x01`\x01`@\x1b\x03\x81\x11\x15a\x08\x08Wa\x08\x08a\x07pV[a\x08\x1b`\x1f\x82\x01`\x1f\x19\x16` \x01a\x07\xaeV[\x81\x81R\x84` \x83\x86\x01\x01\x11\x15a\x080W`\x00\x80\xfd[\x81` \x85\x01` \x83\x017`\x00\x91\x81\x01` \x01\x91\x90\x91R\x93\x92PPPV[`\x00\x80`@\x83\x85\x03\x12\x15a\x08`W`\x00\x80\xfd[\x825\x91P` \x83\x015`\x01`\x01`@\x1b\x03\x81\x11\x15a\x08}W`\x00\x80\xfd[a\x08\x89\x85\x82\x86\x01a\x07\xdeV[\x91PP\x92P\x92\x90PV[`\x00\x81Q\x80\x84R`\x00[\x81\x81\x10\x15a\x08\xb9W` \x81\x85\x01\x81\x01Q\x86\x83\x01\x82\x01R\x01a\x08\x9dV[P`\x00` \x82\x86\x01\x01R` `\x1f\x19`\x1f\x83\x01\x16\x85\x01\x01\x91PP\x92\x91PPV[` \x81R`\x00a\x07?` \x83\x01\x84a\x08\x93V[`\x00` \x82\x84\x03\x12\x15a\x08\xfeW`\x00\x80\xfd[P5\x91\x90PV[\x805`\x01`\x01`\xa0\x1b\x03\x81\x16\x81\x14a\x07\x1fW`\x00\x80\xfd[`\x00\x80`@\x83\x85\x03\x12\x15a\t/W`\x00\x80\xfd[a\t8\x83a\t\x05V[\x94` \x93\x90\x93\x015\x93PPPV[`\x00`@\x82\x84\x03\x12\x15a\tXW`\x00\x80\xfd[`@Q`@\x81\x01\x81\x81\x10`\x01`\x01`@\x1b\x03\x82\x11\x17\x15a\tzWa\tza\x07pV[`@R\x90P\x80a\t\x89\x83a\t\x05V[\x81R` \x83\x015` \x82\x01RP\x92\x91PPV[`\x00`@\x82\x84\x03\x12\x15a\t\xaeW`\x00\x80\xfd[a\x07?\x83\x83a\tFV[`\x00\x80``\x83\x85\x03\x12\x15a\t\xcbW`\x00\x80\xfd[a\t\xd5\x84\x84a\tFV[\x94`@\x93\x90\x93\x015\x93PPPV[`\x00` \x82\x84\x03\x12\x15a\t\xf5W`\x00\x80\xfd[a\x07?\x82a\t\x05V[`\x00\x80`\x00``\x84\x86\x03\x12\x15a\n\x13W`\x00\x80\xfd[\x835\x92P` \x84\x015`\x01`\x01`@\x1b\x03\x80\x82\x11\x15a\n1W`\x00\x80\xfd[a\n=\x87\x83\x88\x01a\x07\xdeV[\x93P`@\x86\x015\x91P\x80\x82\x11\x15a\nSW`\x00\x80\xfd[Pa\n`\x86\x82\x87\x01a\x07\xdeV[\x91PP\x92P\x92P\x92V[`\x00\x80`\x00\x80`\x80\x85\x87\x03\x12\x15a\n\x80W`\x00\x80\xfd[\x845`\x01`\x01`@\x1b\x03\x81\x11\x15a\n\x96W`\x00\x80\xfd[a\n\xa2\x87\x82\x88\x01a\x07\xdeV[\x94PPa\n\xb1` \x86\x01a\x07\x0fV[\x92Pa\n\xbf`@\x86\x01a\x07\x0fV[\x91Pa\n\xcd``\x86\x01a\x07\x0fV[\x90P\x92\x95\x91\x94P\x92PV[`\x00\x80`\x00``\x84\x86\x03\x12\x15a\n\xedW`\x00\x80\xfd[a\n\xf6\x84a\t\x05V[\x92Pa\x0b\x04` \x85\x01a\t\x05V[\x91P`@\x84\x015\x90P\x92P\x92P\x92V[`\x00\x80`@\x83\x85\x03\x12\x15a\x0b\'W`\x00\x80\xfd[\x825`\x01`\x01`@\x1b\x03\x80\x82\x11\x15a\x0b>W`\x00\x80\xfd[a\x0bJ\x86\x83\x87\x01a\x07\xdeV[\x93P` \x85\x015\x91P\x80\x82\x11\x15a\x0b`W`\x00\x80\xfd[Pa\x08\x89\x85\x82\x86\x01a\x07\xdeV[`\x00`\x01`\x01`@\x1b\x03\x82\x11\x15a\x0b\x86Wa\x0b\x86a\x07pV[P`\x05\x1b` \x01\x90V[`\x00\x80`@\x80\x84\x86\x03\x12\x15a\x0b\xa4W`\x00\x80\xfd[a\x0b\xad\x84a\t\x05V[\x92P` \x80\x85\x015`\x01`\x01`@\x1b\x03\x80\x82\x11\x15a\x0b\xcaW`\x00\x80\xfd[\x81\x87\x01\x91P\x87`\x1f\x83\x01\x12a\x0b\xdeW`\x00\x80\xfd[\x815a\x0b\xf1a\x0b\xec\x82a\x0bmV[a\x07\xaeV[\x81\x81R`\x05\x91\x90\x91\x1b\x83\x01\x84\x01\x90\x84\x81\x01\x90\x8a\x83\x11\x15a\x0c\x10W`\x00\x80\xfd[\x85\x85\x01[\x83\x81\x10\x15a\x0c\x83W\x805\x85\x81\x11\x15a\x0c,W`\x00\x80\x81\xfd[\x86\x01\x80\x8d\x03`\x1f\x19\x01\x89\x13\x15a\x0cBW`\x00\x80\x81\xfd[a\x0cJa\x07\x86V[\x88\x82\x015\x81R\x89\x82\x015\x87\x81\x11\x15a\x0cbW`\x00\x80\x81\xfd[a\x0cp\x8f\x8b\x83\x86\x01\x01a\x07\xdeV[\x82\x8b\x01RP\x84RP\x91\x86\x01\x91\x86\x01a\x0c\x14V[P\x80\x97PPPPPPPP\x92P\x92\x90PV[`\x00` \x82\x84\x03\x12\x15a\x0c\xa7W`\x00\x80\xfd[\x815`\xff\x81\x16\x81\x14a\x07?W`\x00\x80\xfd[`\x00\x80`@\x83\x85\x03\x12\x15a\x0c\xcbW`\x00\x80\xfd[a\x0c\xd4\x83a\t\x05V[\x91P` \x80\x84\x015`\x01`\x01`@\x1b\x03\x81\x11\x15a\x0c\xf0W`\x00\x80\xfd[\x84\x01`\x1f\x81\x01\x86\x13a\r\x01W`\x00\x80\xfd[\x805a\r\x0fa\x0b\xec\x82a\x0bmV[\x81\x81R`\x05\x91\x90\x91\x1b\x82\x01\x83\x01\x90\x83\x81\x01\x90\x88\x83\x11\x15a\r.W`\x00\x80\xfd[\x92\x84\x01\x92[\x82\x84\x10\x15a\rLW\x835\x82R\x92\x84\x01\x92\x90\x84\x01\x90a\r3V[\x80\x95PPPPPP\x92P\x92\x90PV[`\x00\x80`\x00``\x84\x86\x03\x12\x15a\rpW`\x00\x80\xfd[a\ry\x84a\t\x05V[\x92P` \x84\x015\x91P`@\x84\x015`\x01`\x01`@\x1b\x03\x81\x11\x15a\r\x9bW`\x00\x80\xfd[a\n`\x86\x82\x87\x01a\x07\xdeV[` \x80\x82R\x82Q\x82\x82\x01\x81\x90R`\x00\x91\x90`@\x90\x81\x85\x01\x90\x86\x84\x01\x85[\x82\x81\x10\x15a\r\xfaWa\r\xea\x84\x83Q\x80Q`\x01`\x01`\xa0\x1b\x03\x16\x82R` \x90\x81\x01Q\x91\x01RV[\x92\x84\x01\x92\x90\x85\x01\x90`\x01\x01a\r\xc4V[P\x91\x97\x96PPPPPPPV[`\x00\x80`@\x83\x85\x03\x12\x15a\x0e\x1aW`\x00\x80\xfd[a\x0e#\x83a\x07\x0fV[\x91P` \x80\x84\x015`\x01`\x01`@\x1b\x03\x81\x11\x15a\x0e?W`\x00\x80\xfd[\x84\x01`\x1f\x81\x01\x86\x13a\x0ePW`\x00\x80\xfd[\x805a\x0e^a\x0b\xec\x82a\x0bmV[\x81\x81R`\x05\x91\x90\x91\x1b\x82\x01\x83\x01\x90\x83\x81\x01\x90\x88\x83\x11\x15a\x0e}W`\x00\x80\xfd[\x92\x84\x01\x92[\x82\x84\x10\x15a\rLWa\x0e\x93\x84a\t\x05V[\x82R\x92\x84\x01\x92\x90\x84\x01\x90a\x0e\x82V[`\x00\x80`@\x83\x85\x03\x12\x15a\x0e\xb5W`\x00\x80\xfd[\x825`\x01`\x01`@\x1b\x03\x81\x11\x15a\x0e\xcbW`\x00\x80\xfd[a\x0e\xd7\x85\x82\x86\x01a\x07\xdeV[\x92PP` \x83\x015c\xff\xff\xff\xff\x81\x16\x81\x14a\x0e\xf1W`\x00\x80\xfd[\x80\x91PP\x92P\x92\x90PV[\x81Q`\x01`\x01`\xa0\x1b\x03\x16\x81R` \x80\x83\x01Q\x90\x82\x01R`@\x81\x01a\x06\xc4V[`\x00` \x82\x84\x03\x12\x15a\x0f.W`\x00\x80\xfd[\x815`\x01`\x01`@\x1b\x03\x81\x11\x15a\x0fDW`\x00\x80\xfd[a\x0fP\x84\x82\x85\x01a\x07\xdeV[\x94\x93PPPPV[`\x00\x80`@\x83\x85\x03\x12\x15a\x0fkW`\x00\x80\xfd[\x825`\x01`\x01`@\x1b\x03\x81\x11\x15a\x0f\x81W`\x00\x80\xfd[a\x0f\x8d\x85\x82\x86\x01a\x07\xdeV[\x92PPa\x0f\x9c` \x84\x01a\x07\x0fV[\x90P\x92P\x92\x90PV[`\x00\x80`@\x83\x85\x03\x12\x15a\x0f\xb8W`\x00\x80\xfd[a\x0f\xc1\x83a\t\x05V[\x91Pa\x0f\x9c` \x84\x01a\x07\x0fV[`\x00\x80`\x00\x80`\x80\x85\x87\x03\x12\x15a\x0f\xe5W`\x00\x80\xfd[a\x0f\xee\x85a\t\x05V[\x93Pa\x0f\xfc` \x86\x01a\t\x05V[\x92P`@\x85\x015\x91P``\x85\x015`\x01`\x01`@\x1b\x03\x81\x11\x15a\x10\x1eW`\x00\x80\xfd[a\x10*\x87\x82\x88\x01a\x07\xdeV[\x91PP\x92\x95\x91\x94P\x92PV[`\x00\x80`\x00`\xa0\x84\x86\x03\x12\x15a\x10KW`\x00\x80\xfd[a\x10U\x85\x85a\tFV[\x92Pa\x10d\x85`@\x86\x01a\tFV[\x91P`\x80\x84\x015\x90P\x92P\x92P\x92V[`\x00\x80`@\x83\x85\x03\x12\x15a\x10\x87W`\x00\x80\xfd[a\x10\x90\x83a\t\x05V[\x91Pa\x0f\x9c` \x84\x01a\t\x05V[`\x00` \x80\x83R`\x00\x84T\x81`\x01\x82\x81\x1c\x91P\x80\x83\x16\x80a\x10\xc0W`\x7f\x83\x16\x92P[\x85\x83\x10\x81\x03a\x10\xddWcNH{q`\xe0\x1b\x85R`\"`\x04R`$\x85\xfd[\x87\x86\x01\x83\x81R` \x01\x81\x80\x15a\x10\xfaW`\x01\x81\x14a\x11\x10Wa\x11;V[`\xff\x19\x86\x16\x82R\x84\x15\x15`\x05\x1b\x82\x01\x96Pa\x11;V[`\x00\x8b\x81R` \x90 `\x00[\x86\x81\x10\x15a\x115W\x81T\x84\x82\x01R\x90\x85\x01\x90\x89\x01a\x11\x1cV[\x83\x01\x97PP[P\x94\x99\x98PPPPPPPPPV\xfe\xa2dipfsX\"\x12 eT\x15\xcb|u\xb1F\x80}\xaa]\xc0#\xe0\xdeO$^\x96a\xfb1\xc5\xb0\xfa\t\x12\x00>F\xa8dsolcC\x00\x08\x10\x003this contract is implemented in native";5938        fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {5939            call::<T, UniqueNFTCall<T>, _, _>(handle, self)5940        }5941    }5942}5943pub mod weights {5944    //! Autogenerated weights for pallet_nonfungible5945    //!5946    //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev5947    //! DATE: 2022-08-15, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`5948    //! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 10245949    #![allow(unused_parens)]5950    #![allow(unused_imports)]5951    #![allow(clippy::unnecessary_cast)]5952    use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};5953    use sp_std::marker::PhantomData;5954    /// Weight functions needed for pallet_nonfungible.5955    pub trait WeightInfo {5956        fn create_item() -> Weight;5957        fn create_multiple_items(b: u32) -> Weight;5958        fn create_multiple_items_ex(b: u32) -> Weight;5959        fn burn_item() -> Weight;5960        fn burn_recursively_self_raw() -> Weight;5961        fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32) -> Weight;5962        fn transfer() -> Weight;5963        fn approve() -> Weight;5964        fn transfer_from() -> Weight;5965        fn burn_from() -> Weight;5966        fn set_token_property_permissions(b: u32) -> Weight;5967        fn set_token_properties(b: u32) -> Weight;5968        fn delete_token_properties(b: u32) -> Weight;5969        fn token_owner() -> Weight;5970    }5971    /// Weights for pallet_nonfungible using the Substrate node and recommended hardware.5972    pub struct SubstrateWeight<T>(PhantomData<T>);5973    impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {5974        fn create_item() -> Weight {5975            Weight::from_ref_time(25_905_000)5976                .saturating_add(T::DbWeight::get().reads(2 as u64))5977                .saturating_add(T::DbWeight::get().writes(4 as u64))5978        }5979        fn create_multiple_items(b: u32) -> Weight {5980            Weight::from_ref_time(24_955_000)5981                .saturating_add(5982                    Weight::from_ref_time(5_340_000).saturating_mul(b as u64),5983                )5984                .saturating_add(T::DbWeight::get().reads(2 as u64))5985                .saturating_add(T::DbWeight::get().writes(2 as u64))5986                .saturating_add(5987                    T::DbWeight::get().writes((2 as u64).saturating_mul(b as u64)),5988                )5989        }5990        fn create_multiple_items_ex(b: u32) -> Weight {5991            Weight::from_ref_time(13_666_000)5992                .saturating_add(5993                    Weight::from_ref_time(8_299_000).saturating_mul(b as u64),5994                )5995                .saturating_add(T::DbWeight::get().reads(1 as u64))5996                .saturating_add(5997                    T::DbWeight::get().reads((1 as u64).saturating_mul(b as u64)),5998                )5999                .saturating_add(T::DbWeight::get().writes(1 as u64))6000                .saturating_add(6001                    T::DbWeight::get().writes((3 as u64).saturating_mul(b as u64)),6002                )6003        }6004        fn burn_item() -> Weight {6005            Weight::from_ref_time(36_205_000)6006                .saturating_add(T::DbWeight::get().reads(5 as u64))6007                .saturating_add(T::DbWeight::get().writes(5 as u64))6008        }6009        fn burn_recursively_self_raw() -> Weight {6010            Weight::from_ref_time(44_550_000)6011                .saturating_add(T::DbWeight::get().reads(5 as u64))6012                .saturating_add(T::DbWeight::get().writes(5 as u64))6013        }6014        fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32) -> Weight {6015            (Weight::from_ref_time(0))6016                .saturating_add(6017                    Weight::from_ref_time(312_125_000).saturating_mul(b as u64),6018                )6019                .saturating_add(T::DbWeight::get().reads(7 as u64))6020                .saturating_add(6021                    T::DbWeight::get().reads((4 as u64).saturating_mul(b as u64)),6022                )6023                .saturating_add(T::DbWeight::get().writes(6 as u64))6024                .saturating_add(6025                    T::DbWeight::get().writes((4 as u64).saturating_mul(b as u64)),6026                )6027        }6028        fn transfer() -> Weight {6029            Weight::from_ref_time(31_116_000)6030                .saturating_add(T::DbWeight::get().reads(4 as u64))6031                .saturating_add(T::DbWeight::get().writes(5 as u64))6032        }6033        fn approve() -> Weight {6034            Weight::from_ref_time(20_802_000)6035                .saturating_add(T::DbWeight::get().reads(2 as u64))6036                .saturating_add(T::DbWeight::get().writes(1 as u64))6037        }6038        fn transfer_from() -> Weight {6039            Weight::from_ref_time(36_083_000)6040                .saturating_add(T::DbWeight::get().reads(4 as u64))6041                .saturating_add(T::DbWeight::get().writes(6 as u64))6042        }6043        fn burn_from() -> Weight {6044            Weight::from_ref_time(41_781_000)6045                .saturating_add(T::DbWeight::get().reads(5 as u64))6046                .saturating_add(T::DbWeight::get().writes(6 as u64))6047        }6048        fn set_token_property_permissions(b: u32) -> Weight {6049            (Weight::from_ref_time(0))6050                .saturating_add(6051                    Weight::from_ref_time(15_705_000).saturating_mul(b as u64),6052                )6053                .saturating_add(T::DbWeight::get().reads(1 as u64))6054                .saturating_add(T::DbWeight::get().writes(1 as u64))6055        }6056        fn set_token_properties(b: u32) -> Weight {6057            (Weight::from_ref_time(0))6058                .saturating_add(6059                    Weight::from_ref_time(590_344_000).saturating_mul(b as u64),6060                )6061                .saturating_add(T::DbWeight::get().reads(2 as u64))6062                .saturating_add(T::DbWeight::get().writes(1 as u64))6063        }6064        fn delete_token_properties(b: u32) -> Weight {6065            (Weight::from_ref_time(0))6066                .saturating_add(6067                    Weight::from_ref_time(605_836_000).saturating_mul(b as u64),6068                )6069                .saturating_add(T::DbWeight::get().reads(2 as u64))6070                .saturating_add(T::DbWeight::get().writes(1 as u64))6071        }6072        fn token_owner() -> Weight {6073            Weight::from_ref_time(4_366_000)6074                .saturating_add(T::DbWeight::get().reads(1 as u64))6075        }6076    }6077    impl WeightInfo for () {6078        fn create_item() -> Weight {6079            Weight::from_ref_time(25_905_000)6080                .saturating_add(RocksDbWeight::get().reads(2 as u64))6081                .saturating_add(RocksDbWeight::get().writes(4 as u64))6082        }6083        fn create_multiple_items(b: u32) -> Weight {6084            Weight::from_ref_time(24_955_000)6085                .saturating_add(6086                    Weight::from_ref_time(5_340_000).saturating_mul(b as u64),6087                )6088                .saturating_add(RocksDbWeight::get().reads(2 as u64))6089                .saturating_add(RocksDbWeight::get().writes(2 as u64))6090                .saturating_add(6091                    RocksDbWeight::get().writes((2 as u64).saturating_mul(b as u64)),6092                )6093        }6094        fn create_multiple_items_ex(b: u32) -> Weight {6095            Weight::from_ref_time(13_666_000)6096                .saturating_add(6097                    Weight::from_ref_time(8_299_000).saturating_mul(b as u64),6098                )6099                .saturating_add(RocksDbWeight::get().reads(1 as u64))6100                .saturating_add(6101                    RocksDbWeight::get().reads((1 as u64).saturating_mul(b as u64)),6102                )6103                .saturating_add(RocksDbWeight::get().writes(1 as u64))6104                .saturating_add(6105                    RocksDbWeight::get().writes((3 as u64).saturating_mul(b as u64)),6106                )6107        }6108        fn burn_item() -> Weight {6109            Weight::from_ref_time(36_205_000)6110                .saturating_add(RocksDbWeight::get().reads(5 as u64))6111                .saturating_add(RocksDbWeight::get().writes(5 as u64))6112        }6113        fn burn_recursively_self_raw() -> Weight {6114            Weight::from_ref_time(44_550_000)6115                .saturating_add(RocksDbWeight::get().reads(5 as u64))6116                .saturating_add(RocksDbWeight::get().writes(5 as u64))6117        }6118        fn burn_recursively_breadth_plus_self_plus_self_per_each_raw(b: u32) -> Weight {6119            (Weight::from_ref_time(0))6120                .saturating_add(6121                    Weight::from_ref_time(312_125_000).saturating_mul(b as u64),6122                )6123                .saturating_add(RocksDbWeight::get().reads(7 as u64))6124                .saturating_add(6125                    RocksDbWeight::get().reads((4 as u64).saturating_mul(b as u64)),6126                )6127                .saturating_add(RocksDbWeight::get().writes(6 as u64))6128                .saturating_add(6129                    RocksDbWeight::get().writes((4 as u64).saturating_mul(b as u64)),6130                )6131        }6132        fn transfer() -> Weight {6133            Weight::from_ref_time(31_116_000)6134                .saturating_add(RocksDbWeight::get().reads(4 as u64))6135                .saturating_add(RocksDbWeight::get().writes(5 as u64))6136        }6137        fn approve() -> Weight {6138            Weight::from_ref_time(20_802_000)6139                .saturating_add(RocksDbWeight::get().reads(2 as u64))6140                .saturating_add(RocksDbWeight::get().writes(1 as u64))6141        }6142        fn transfer_from() -> Weight {6143            Weight::from_ref_time(36_083_000)6144                .saturating_add(RocksDbWeight::get().reads(4 as u64))6145                .saturating_add(RocksDbWeight::get().writes(6 as u64))6146        }6147        fn burn_from() -> Weight {6148            Weight::from_ref_time(41_781_000)6149                .saturating_add(RocksDbWeight::get().reads(5 as u64))6150                .saturating_add(RocksDbWeight::get().writes(6 as u64))6151        }6152        fn set_token_property_permissions(b: u32) -> Weight {6153            (Weight::from_ref_time(0))6154                .saturating_add(6155                    Weight::from_ref_time(15_705_000).saturating_mul(b as u64),6156                )6157                .saturating_add(RocksDbWeight::get().reads(1 as u64))6158                .saturating_add(RocksDbWeight::get().writes(1 as u64))6159        }6160        fn set_token_properties(b: u32) -> Weight {6161            (Weight::from_ref_time(0))6162                .saturating_add(6163                    Weight::from_ref_time(590_344_000).saturating_mul(b as u64),6164                )6165                .saturating_add(RocksDbWeight::get().reads(2 as u64))6166                .saturating_add(RocksDbWeight::get().writes(1 as u64))6167        }6168        fn delete_token_properties(b: u32) -> Weight {6169            (Weight::from_ref_time(0))6170                .saturating_add(6171                    Weight::from_ref_time(605_836_000).saturating_mul(b as u64),6172                )6173                .saturating_add(RocksDbWeight::get().reads(2 as u64))6174                .saturating_add(RocksDbWeight::get().writes(1 as u64))6175        }6176        fn token_owner() -> Weight {6177            Weight::from_ref_time(4_366_000)6178                .saturating_add(RocksDbWeight::get().reads(1 as u64))6179        }6180    }6181}6182pub type CreateItemData<T> = CreateNftExData<6183    <T as pallet_evm::account::Config>::CrossAccountId,6184>;6185pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;6186/// Token data, stored independently from other data used to describe it6187/// for the convenience of database access. Notably contains the owner account address.6188pub struct ItemDataVersion1<CrossAccountId> {6189    pub const_data: BoundedVec<u8, CustomDataLimit>,6190    pub variable_data: BoundedVec<u8, CustomDataLimit>,6191    pub owner: CrossAccountId,6192}6193#[allow(deprecated)]6194const _: () = {6195    #[automatically_derived]6196    impl<CrossAccountId> ::codec::Encode for ItemDataVersion1<CrossAccountId>6197    where6198        CrossAccountId: ::codec::Encode,6199        CrossAccountId: ::codec::Encode,6200    {6201        fn encode_to<__CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized>(6202            &self,6203            __codec_dest_edqy: &mut __CodecOutputEdqy,6204        ) {6205            ::codec::Encode::encode_to(&self.const_data, __codec_dest_edqy);6206            ::codec::Encode::encode_to(&self.variable_data, __codec_dest_edqy);6207            ::codec::Encode::encode_to(&self.owner, __codec_dest_edqy);6208        }6209    }6210    #[automatically_derived]6211    impl<CrossAccountId> ::codec::EncodeLike for ItemDataVersion1<CrossAccountId>6212    where6213        CrossAccountId: ::codec::Encode,6214        CrossAccountId: ::codec::Encode,6215    {}6216};6217#[allow(deprecated)]6218const _: () = {6219    #[automatically_derived]6220    impl<CrossAccountId> ::codec::Decode for ItemDataVersion1<CrossAccountId>6221    where6222        CrossAccountId: ::codec::Decode,6223        CrossAccountId: ::codec::Decode,6224    {6225        fn decode<__CodecInputEdqy: ::codec::Input>(6226            __codec_input_edqy: &mut __CodecInputEdqy,6227        ) -> ::core::result::Result<Self, ::codec::Error> {6228            ::core::result::Result::Ok(ItemDataVersion1::<CrossAccountId> {6229                const_data: {6230                    let __codec_res_edqy = <BoundedVec<6231                        u8,6232                        CustomDataLimit,6233                    > as ::codec::Decode>::decode(__codec_input_edqy);6234                    match __codec_res_edqy {6235                        ::core::result::Result::Err(e) => {6236                            return ::core::result::Result::Err(6237                                e.chain("Could not decode `ItemDataVersion1::const_data`"),6238                            );6239                        }6240                        ::core::result::Result::Ok(__codec_res_edqy) => __codec_res_edqy,6241                    }6242                },6243                variable_data: {6244                    let __codec_res_edqy = <BoundedVec<6245                        u8,6246                        CustomDataLimit,6247                    > as ::codec::Decode>::decode(__codec_input_edqy);6248                    match __codec_res_edqy {6249                        ::core::result::Result::Err(e) => {6250                            return ::core::result::Result::Err(6251                                e6252                                    .chain("Could not decode `ItemDataVersion1::variable_data`"),6253                            );6254                        }6255                        ::core::result::Result::Ok(__codec_res_edqy) => __codec_res_edqy,6256                    }6257                },6258                owner: {6259                    let __codec_res_edqy = <CrossAccountId as ::codec::Decode>::decode(6260                        __codec_input_edqy,6261                    );6262                    match __codec_res_edqy {6263                        ::core::result::Result::Err(e) => {6264                            return ::core::result::Result::Err(6265                                e.chain("Could not decode `ItemDataVersion1::owner`"),6266                            );6267                        }6268                        ::core::result::Result::Ok(__codec_res_edqy) => __codec_res_edqy,6269                    }6270                },6271            })6272        }6273    }6274};6275#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]6276const _: () = {6277    impl<CrossAccountId> ::scale_info::TypeInfo for ItemDataVersion1<CrossAccountId>6278    where6279        CrossAccountId: ::scale_info::TypeInfo + 'static,6280        CrossAccountId: ::scale_info::TypeInfo + 'static,6281    {6282        type Identity = Self;6283        fn type_info() -> ::scale_info::Type {6284            ::scale_info::Type::builder()6285                .path(::scale_info::Path::new("ItemDataVersion1", "pallet_nonfungible"))6286                .type_params(6287                    <[_]>::into_vec(6288                        #[rustc_box]6289                        ::alloc::boxed::Box::new([6290                            ::scale_info::TypeParameter::new(6291                                "CrossAccountId",6292                                ::core::option::Option::Some(6293                                    ::scale_info::meta_type::<CrossAccountId>(),6294                                ),6295                            ),6296                        ]),6297                    ),6298                )6299                .docs(6300                    &[6301                        "Token data, stored independently from other data used to describe it",6302                        "for the convenience of database access. Notably contains the owner account address.",6303                    ],6304                )6305                .composite(6306                    ::scale_info::build::Fields::named()6307                        .field(|f| {6308                            f6309                                .ty::<BoundedVec<u8, CustomDataLimit>>()6310                                .name("const_data")6311                                .type_name("BoundedVec<u8, CustomDataLimit>")6312                                .docs(&[])6313                        })6314                        .field(|f| {6315                            f6316                                .ty::<BoundedVec<u8, CustomDataLimit>>()6317                                .name("variable_data")6318                                .type_name("BoundedVec<u8, CustomDataLimit>")6319                                .docs(&[])6320                        })6321                        .field(|f| {6322                            f6323                                .ty::<CrossAccountId>()6324                                .name("owner")6325                                .type_name("CrossAccountId")6326                                .docs(&[])6327                        }),6328                )6329        }6330    }6331};6332const _: () = {6333    impl<CrossAccountId> ::codec::MaxEncodedLen for ItemDataVersion1<CrossAccountId>6334    where6335        CrossAccountId: ::codec::MaxEncodedLen,6336        CrossAccountId: ::codec::MaxEncodedLen,6337    {6338        fn max_encoded_len() -> ::core::primitive::usize {6339            0_usize6340                .saturating_add(<BoundedVec<u8, CustomDataLimit>>::max_encoded_len())6341                .saturating_add(<BoundedVec<u8, CustomDataLimit>>::max_encoded_len())6342                .saturating_add(<CrossAccountId>::max_encoded_len())6343        }6344    }6345};6346/// Token data, stored independently from other data used to describe it6347/// for the convenience of database access. Notably contains the owner account address.6348/// # Versioning6349/// Changes between 1 and 2:6350/// - const_data: BoundedVec < u8, CustomDataLimit > was removed6351/// - variable_data: BoundedVec < u8, CustomDataLimit > was removed6352pub struct ItemData<CrossAccountId> {6353    pub owner: CrossAccountId,6354}6355#[allow(deprecated)]6356const _: () = {6357    #[automatically_derived]6358    impl<CrossAccountId> ::codec::Encode for ItemData<CrossAccountId>6359    where6360        CrossAccountId: ::codec::Encode,6361        CrossAccountId: ::codec::Encode,6362    {6363        fn encode_to<__CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized>(6364            &self,6365            __codec_dest_edqy: &mut __CodecOutputEdqy,6366        ) {6367            ::codec::Encode::encode_to(&&self.owner, __codec_dest_edqy)6368        }6369        fn encode(&self) -> ::codec::alloc::vec::Vec<::core::primitive::u8> {6370            ::codec::Encode::encode(&&self.owner)6371        }6372        fn using_encoded<R, F: ::core::ops::FnOnce(&[::core::primitive::u8]) -> R>(6373            &self,6374            f: F,6375        ) -> R {6376            ::codec::Encode::using_encoded(&&self.owner, f)6377        }6378    }6379    #[automatically_derived]6380    impl<CrossAccountId> ::codec::EncodeLike for ItemData<CrossAccountId>6381    where6382        CrossAccountId: ::codec::Encode,6383        CrossAccountId: ::codec::Encode,6384    {}6385};6386#[allow(deprecated)]6387const _: () = {6388    #[automatically_derived]6389    impl<CrossAccountId> ::codec::Decode for ItemData<CrossAccountId>6390    where6391        CrossAccountId: ::codec::Decode,6392        CrossAccountId: ::codec::Decode,6393    {6394        fn decode<__CodecInputEdqy: ::codec::Input>(6395            __codec_input_edqy: &mut __CodecInputEdqy,6396        ) -> ::core::result::Result<Self, ::codec::Error> {6397            ::core::result::Result::Ok(ItemData::<CrossAccountId> {6398                owner: {6399                    let __codec_res_edqy = <CrossAccountId as ::codec::Decode>::decode(6400                        __codec_input_edqy,6401                    );6402                    match __codec_res_edqy {6403                        ::core::result::Result::Err(e) => {6404                            return ::core::result::Result::Err(6405                                e.chain("Could not decode `ItemData::owner`"),6406                            );6407                        }6408                        ::core::result::Result::Ok(__codec_res_edqy) => __codec_res_edqy,6409                    }6410                },6411            })6412        }6413    }6414};6415#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]6416const _: () = {6417    impl<CrossAccountId> ::scale_info::TypeInfo for ItemData<CrossAccountId>6418    where6419        CrossAccountId: ::scale_info::TypeInfo + 'static,6420        CrossAccountId: ::scale_info::TypeInfo + 'static,6421    {6422        type Identity = Self;6423        fn type_info() -> ::scale_info::Type {6424            ::scale_info::Type::builder()6425                .path(::scale_info::Path::new("ItemData", "pallet_nonfungible"))6426                .type_params(6427                    <[_]>::into_vec(6428                        #[rustc_box]6429                        ::alloc::boxed::Box::new([6430                            ::scale_info::TypeParameter::new(6431                                "CrossAccountId",6432                                ::core::option::Option::Some(6433                                    ::scale_info::meta_type::<CrossAccountId>(),6434                                ),6435                            ),6436                        ]),6437                    ),6438                )6439                .docs(6440                    &[6441                        "Token data, stored independently from other data used to describe it",6442                        "for the convenience of database access. Notably contains the owner account address.",6443                        "# Versioning",6444                        "Changes between 1 and 2:",6445                        "- const_data: BoundedVec < u8, CustomDataLimit > was removed",6446                        "- variable_data: BoundedVec < u8, CustomDataLimit > was removed",6447                    ],6448                )6449                .composite(6450                    ::scale_info::build::Fields::named()6451                        .field(|f| {6452                            f6453                                .ty::<CrossAccountId>()6454                                .name("owner")6455                                .type_name("CrossAccountId")6456                                .docs(&[])6457                        }),6458                )6459        }6460    }6461};6462const _: () = {6463    impl<CrossAccountId> ::codec::MaxEncodedLen for ItemData<CrossAccountId>6464    where6465        CrossAccountId: ::codec::MaxEncodedLen,6466        CrossAccountId: ::codec::MaxEncodedLen,6467    {6468        fn max_encoded_len() -> ::core::primitive::usize {6469            0_usize.saturating_add(<CrossAccountId>::max_encoded_len())6470        }6471    }6472};6473impl<CrossAccountId> From<ItemDataVersion1<CrossAccountId>>6474for ItemData<CrossAccountId> {6475    fn from(old: ItemDataVersion1<CrossAccountId>) -> Self {6476        let ItemDataVersion1 { const_data, variable_data, owner } = old;6477        let _ = &const_data;6478        let _ = &variable_data;6479        Self { owner }6480    }6481}6482pub type ItemDataVersion2<CrossAccountId> = ItemData<CrossAccountId>;6483/**6484			The module that hosts all the6485			[FRAME](https://docs.substrate.io/main-docs/build/events-errors/)6486			types needed to add this pallet to a6487			runtime.6488			*/6489pub mod pallet {6490    use super::*;6491    use frame_support::{6492        Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key,6493        traits::StorageVersion,6494    };6495    use frame_system::pallet_prelude::*;6496    use up_data_structs::{CollectionId, TokenId};6497    use super::weights::WeightInfo;6498    #[scale_info(skip_type_params(T), capture_docs = "always")]6499    /**6500			Custom [dispatch errors](https://docs.substrate.io/main-docs/build/events-errors/)6501			of this pallet.6502			*/6503    pub enum Error<T> {6504        #[doc(hidden)]6505        #[codec(skip)]6506        __Ignore(frame_support::sp_std::marker::PhantomData<(T)>, frame_support::Never),6507        /// Not Nonfungible item data used to mint in Nonfungible collection.6508        NotNonfungibleDataUsedToMintFungibleCollectionToken,6509        /// Used amount > 1 with NFT6510        NonfungibleItemsHaveNoAmount,6511        /// Unable to burn NFT with children6512        CantBurnNftWithChildren,6513    }6514    #[allow(deprecated)]6515    const _: () = {6516        #[automatically_derived]6517        impl<T> ::codec::Encode for Error<T> {6518            fn encode_to<__CodecOutputEdqy: ::codec::Output + ?::core::marker::Sized>(6519                &self,6520                __codec_dest_edqy: &mut __CodecOutputEdqy,6521            ) {6522                match *self {6523                    Error::NotNonfungibleDataUsedToMintFungibleCollectionToken => {6524                        __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8);6525                    }6526                    Error::NonfungibleItemsHaveNoAmount => {6527                        __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8);6528                    }6529                    Error::CantBurnNftWithChildren => {6530                        __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8);6531                    }6532                    _ => {}6533                }6534            }6535        }6536        #[automatically_derived]6537        impl<T> ::codec::EncodeLike for Error<T> {}6538    };6539    #[allow(deprecated)]6540    const _: () = {6541        #[automatically_derived]6542        impl<T> ::codec::Decode for Error<T> {6543            fn decode<__CodecInputEdqy: ::codec::Input>(6544                __codec_input_edqy: &mut __CodecInputEdqy,6545            ) -> ::core::result::Result<Self, ::codec::Error> {6546                match __codec_input_edqy6547                    .read_byte()6548                    .map_err(|e| {6549                        e.chain("Could not decode `Error`, failed to read variant byte")6550                    })?6551                {6552                    __codec_x_edqy if __codec_x_edqy6553                        == 0usize as ::core::primitive::u8 => {6554                        ::core::result::Result::Ok(6555                            Error::<6556                                T,6557                            >::NotNonfungibleDataUsedToMintFungibleCollectionToken,6558                        )6559                    }6560                    __codec_x_edqy if __codec_x_edqy6561                        == 1usize as ::core::primitive::u8 => {6562                        ::core::result::Result::Ok(6563                            Error::<T>::NonfungibleItemsHaveNoAmount,6564                        )6565                    }6566                    __codec_x_edqy if __codec_x_edqy6567                        == 2usize as ::core::primitive::u8 => {6568                        ::core::result::Result::Ok(Error::<T>::CantBurnNftWithChildren)6569                    }6570                    _ => {6571                        ::core::result::Result::Err(6572                            <_ as ::core::convert::Into<6573                                _,6574                            >>::into("Could not decode `Error`, variant doesn't exist"),6575                        )6576                    }6577                }6578            }6579        }6580    };6581    #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]6582    const _: () = {6583        impl<T> ::scale_info::TypeInfo for Error<T>6584        where6585            frame_support::sp_std::marker::PhantomData<6586                (T),6587            >: ::scale_info::TypeInfo + 'static,6588            T: 'static,6589        {6590            type Identity = Self;6591            fn type_info() -> ::scale_info::Type {6592                ::scale_info::Type::builder()6593                    .path(::scale_info::Path::new("Error", "pallet_nonfungible::pallet"))6594                    .type_params(6595                        <[_]>::into_vec(6596                            #[rustc_box]6597                            ::alloc::boxed::Box::new([6598                                ::scale_info::TypeParameter::new(6599                                    "T",6600                                    ::core::option::Option::None,6601                                ),6602                            ]),6603                        ),6604                    )6605                    .docs_always(6606                        &[6607                            "\n\t\t\tCustom [dispatch errors](https://docs.substrate.io/main-docs/build/events-errors/)\n\t\t\tof this pallet.\n\t\t\t",6608                        ],6609                    )6610                    .variant(6611                        ::scale_info::build::Variants::new()6612                            .variant(6613                                "NotNonfungibleDataUsedToMintFungibleCollectionToken",6614                                |v| {6615                                    v6616                                        .index(0usize as ::core::primitive::u8)6617                                        .docs_always(6618                                            &[6619                                                "Not Nonfungible item data used to mint in Nonfungible collection.",6620                                            ],6621                                        )6622                                },6623                            )6624                            .variant(6625                                "NonfungibleItemsHaveNoAmount",6626                                |v| {6627                                    v6628                                        .index(1usize as ::core::primitive::u8)6629                                        .docs_always(&["Used amount > 1 with NFT"])6630                                },6631                            )6632                            .variant(6633                                "CantBurnNftWithChildren",6634                                |v| {6635                                    v6636                                        .index(2usize as ::core::primitive::u8)6637                                        .docs_always(&["Unable to burn NFT with children"])6638                                },6639                            ),6640                    )6641            }6642        }6643    };6644    const _: () = {6645        impl<T> frame_support::traits::PalletError for Error<T> {6646            const MAX_ENCODED_SIZE: usize = 1;6647        }6648    };6649    /**6650			Configuration trait of this pallet.66516652			Implement this type for a runtime in order to customize this pallet.6653			*/6654    pub trait Config: frame_system::Config + pallet_common::Config + pallet_structure::Config + pallet_evm::Config {6655        type WeightInfo: WeightInfo;6656    }6657    const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);6658    /**6659			The [pallet](https://docs.substrate.io/reference/frame-pallets/#pallets) implementing6660			the on-chain logic.6661			*/6662    pub struct Pallet<T>(frame_support::sp_std::marker::PhantomData<(T)>);6663    const _: () = {6664        impl<T> core::clone::Clone for Pallet<T> {6665            fn clone(&self) -> Self {6666                Self(core::clone::Clone::clone(&self.0))6667            }6668        }6669    };6670    const _: () = {6671        impl<T> core::cmp::Eq for Pallet<T> {}6672    };6673    const _: () = {6674        impl<T> core::cmp::PartialEq for Pallet<T> {6675            fn eq(&self, other: &Self) -> bool {6676                true && self.0 == other.06677            }6678        }6679    };6680    const _: () = {6681        impl<T> core::fmt::Debug for Pallet<T> {6682            fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {6683                fmt.debug_tuple("Pallet").field(&self.0).finish()6684            }6685        }6686    };6687    /// Total amount of minted tokens in a collection.6688    #[allow(type_alias_bounds)]6689    pub type TokensMinted<T: Config> = StorageMap<6690        _GeneratedPrefixForStorageTokensMinted<T>,6691        Twox64Concat,6692        CollectionId,6693        u32,6694        ValueQuery,6695        frame_support::traits::GetDefault,6696        frame_support::traits::GetDefault,6697    >;6698    /// Amount of burnt tokens in a collection.6699    #[allow(type_alias_bounds)]6700    pub type TokensBurnt<T: Config> = StorageMap<6701        _GeneratedPrefixForStorageTokensBurnt<T>,6702        Twox64Concat,6703        CollectionId,6704        u32,6705        ValueQuery,6706        frame_support::traits::GetDefault,6707        frame_support::traits::GetDefault,6708    >;6709    /// Token data, used to partially describe a token.6710    #[allow(type_alias_bounds)]6711    pub type TokenData<T: Config> = StorageNMap<6712        _GeneratedPrefixForStorageTokenData<T>,6713        (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),6714        ItemData<T::CrossAccountId>,6715        OptionQuery,6716        frame_support::traits::GetDefault,6717        frame_support::traits::GetDefault,6718    >;6719    /// Map of key-value pairs, describing the metadata of a token.6720    #[allow(type_alias_bounds)]6721    pub type TokenProperties<T: Config> = StorageNMap<6722        _GeneratedPrefixForStorageTokenProperties<T>,6723        (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),6724        Properties,6725        ValueQuery,6726        up_data_structs::TokenProperties,6727        frame_support::traits::GetDefault,6728    >;6729    /// Custom data of a token that is serialized to bytes,6730    /// primarily reserved for on-chain operations,6731    /// normally obscured from the external users.6732    ///6733    /// Auxiliary properties are slightly different from6734    /// usual [`TokenProperties`] due to an unlimited number6735    /// and separately stored and written-to key-value pairs.6736    ///6737    /// Currently used to store RMRK data.6738    #[allow(type_alias_bounds)]6739    pub type TokenAuxProperties<T: Config> = StorageNMap<6740        _GeneratedPrefixForStorageTokenAuxProperties<T>,6741        (6742            Key<Twox64Concat, CollectionId>,6743            Key<Twox64Concat, TokenId>,6744            Key<Twox64Concat, PropertyScope>,6745            Key<Twox64Concat, PropertyKey>,6746        ),6747        AuxPropertyValue,6748        OptionQuery,6749        frame_support::traits::GetDefault,6750        frame_support::traits::GetDefault,6751    >;6752    /// Used to enumerate tokens owned by account.6753    #[allow(type_alias_bounds)]6754    pub type Owned<T: Config> = StorageNMap<6755        _GeneratedPrefixForStorageOwned<T>,6756        (6757            Key<Twox64Concat, CollectionId>,6758            Key<Blake2_128Concat, T::CrossAccountId>,6759            Key<Twox64Concat, TokenId>,6760        ),6761        bool,6762        ValueQuery,6763        frame_support::traits::GetDefault,6764        frame_support::traits::GetDefault,6765    >;6766    /// Used to enumerate token's children.6767    #[allow(type_alias_bounds)]6768    pub type TokenChildren<T: Config> = StorageNMap<6769        _GeneratedPrefixForStorageTokenChildren<T>,6770        (6771            Key<Twox64Concat, CollectionId>,6772            Key<Twox64Concat, TokenId>,6773            Key<Twox64Concat, (CollectionId, TokenId)>,6774        ),6775        bool,6776        ValueQuery,6777        frame_support::traits::GetDefault,6778        frame_support::traits::GetDefault,6779    >;6780    /// Amount of tokens owned by an account in a collection.6781    #[allow(type_alias_bounds)]6782    pub type AccountBalance<T: Config> = StorageNMap<6783        _GeneratedPrefixForStorageAccountBalance<T>,6784        (Key<Twox64Concat, CollectionId>, Key<Blake2_128Concat, T::CrossAccountId>),6785        u32,6786        ValueQuery,6787        frame_support::traits::GetDefault,6788        frame_support::traits::GetDefault,6789    >;6790    /// Allowance set by a token owner for another user to perform one of certain transactions on a token.6791    #[allow(type_alias_bounds)]6792    pub type Allowance<T: Config> = StorageNMap<6793        _GeneratedPrefixForStorageAllowance<T>,6794        (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),6795        T::CrossAccountId,6796        OptionQuery,6797        frame_support::traits::GetDefault,6798        frame_support::traits::GetDefault,6799    >;6800    /// Upgrade from the old schema to properties.6801    impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {6802        fn on_runtime_upgrade() -> Weight {6803            StorageVersion::new(1).put::<Pallet<T>>();6804            Weight::zero()6805        }6806    }6807    impl<T: Config> Pallet<T> {6808        #[doc(hidden)]6809        pub fn pallet_constants_metadata() -> frame_support::sp_std::vec::Vec<6810            frame_support::metadata::PalletConstantMetadata,6811        > {6812            ::alloc::vec::Vec::new()6813        }6814    }6815    impl<T: Config> Pallet<T> {6816        #[doc(hidden)]6817        pub fn error_metadata() -> Option<frame_support::metadata::PalletErrorMetadata> {6818            Some(frame_support::metadata::PalletErrorMetadata {6819                ty: frame_support::scale_info::meta_type::<Error<T>>(),6820            })6821        }6822    }6823    /// Type alias to `Pallet`, to be used by `construct_runtime`.6824    ///6825    /// Generated by `pallet` attribute macro.6826    #[deprecated(note = "use `Pallet` instead")]6827    #[allow(dead_code)]6828    pub type Module<T> = Pallet<T>;6829    impl<T: Config> frame_support::traits::GetStorageVersion for Pallet<T> {6830        fn current_storage_version() -> frame_support::traits::StorageVersion {6831            STORAGE_VERSION6832        }6833        fn on_chain_storage_version() -> frame_support::traits::StorageVersion {6834            frame_support::traits::StorageVersion::get::<Self>()6835        }6836    }6837    impl<T: Config> frame_support::traits::OnGenesis for Pallet<T> {6838        fn on_genesis() {6839            let storage_version = STORAGE_VERSION;6840            storage_version.put::<Self>();6841        }6842    }6843    impl<T: Config> frame_support::traits::PalletInfoAccess for Pallet<T> {6844        fn index() -> usize {6845            <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::index::<6846                Self,6847            >()6848                .expect(6849                    "Pallet is part of the runtime because pallet `Config` trait is \6850						implemented by the runtime",6851                )6852        }6853        fn name() -> &'static str {6854            <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::name::<6855                Self,6856            >()6857                .expect(6858                    "Pallet is part of the runtime because pallet `Config` trait is \6859						implemented by the runtime",6860                )6861        }6862        fn module_name() -> &'static str {6863            <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::module_name::<6864                Self,6865            >()6866                .expect(6867                    "Pallet is part of the runtime because pallet `Config` trait is \6868						implemented by the runtime",6869                )6870        }6871        fn crate_version() -> frame_support::traits::CrateVersion {6872            frame_support::traits::CrateVersion {6873                major: 0u16,6874                minor: 1u8,6875                patch: 5u8,6876            }6877        }6878    }6879    impl<T: Config> frame_support::traits::PalletsInfoAccess for Pallet<T> {6880        fn count() -> usize {6881            16882        }6883        fn infos() -> frame_support::sp_std::vec::Vec<6884            frame_support::traits::PalletInfoData,6885        > {6886            use frame_support::traits::PalletInfoAccess;6887            let item = frame_support::traits::PalletInfoData {6888                index: Self::index(),6889                name: Self::name(),6890                module_name: Self::module_name(),6891                crate_version: Self::crate_version(),6892            };6893            <[_]>::into_vec(#[rustc_box] ::alloc::boxed::Box::new([item]))6894        }6895    }6896    impl<T: Config> frame_support::traits::StorageInfoTrait for Pallet<T> {6897        fn storage_info() -> frame_support::sp_std::vec::Vec<6898            frame_support::traits::StorageInfo,6899        > {6900            #[allow(unused_mut)]6901            let mut res = ::alloc::vec::Vec::new();6902            {6903                let mut storage_info = <TokensMinted<6904                    T,6905                > as frame_support::traits::StorageInfoTrait>::storage_info();6906                res.append(&mut storage_info);6907            }6908            {6909                let mut storage_info = <TokensBurnt<6910                    T,6911                > as frame_support::traits::StorageInfoTrait>::storage_info();6912                res.append(&mut storage_info);6913            }6914            {6915                let mut storage_info = <TokenData<6916                    T,6917                > as frame_support::traits::StorageInfoTrait>::storage_info();6918                res.append(&mut storage_info);6919            }6920            {6921                let mut storage_info = <TokenProperties<6922                    T,6923                > as frame_support::traits::StorageInfoTrait>::storage_info();6924                res.append(&mut storage_info);6925            }6926            {6927                let mut storage_info = <TokenAuxProperties<6928                    T,6929                > as frame_support::traits::StorageInfoTrait>::storage_info();6930                res.append(&mut storage_info);6931            }6932            {6933                let mut storage_info = <Owned<6934                    T,6935                > as frame_support::traits::StorageInfoTrait>::storage_info();6936                res.append(&mut storage_info);6937            }6938            {6939                let mut storage_info = <TokenChildren<6940                    T,6941                > as frame_support::traits::StorageInfoTrait>::storage_info();6942                res.append(&mut storage_info);6943            }6944            {6945                let mut storage_info = <AccountBalance<6946                    T,6947                > as frame_support::traits::StorageInfoTrait>::storage_info();6948                res.append(&mut storage_info);6949            }6950            {6951                let mut storage_info = <Allowance<6952                    T,6953                > as frame_support::traits::StorageInfoTrait>::storage_info();6954                res.append(&mut storage_info);6955            }6956            res6957        }6958    }6959    #[doc(hidden)]6960    pub mod __substrate_call_check {6961        #[doc(hidden)]6962        pub use __is_call_part_defined_0 as is_call_part_defined;6963    }6964    ///Contains one variant per dispatchable that can be called by an extrinsic.6965    #[codec(encode_bound())]6966    #[codec(decode_bound())]6967    #[scale_info(skip_type_params(T), capture_docs = "always")]6968    #[allow(non_camel_case_types)]6969    pub enum Call<T: Config> {6970        #[doc(hidden)]6971        #[codec(skip)]6972        __Ignore(frame_support::sp_std::marker::PhantomData<(T,)>, frame_support::Never),6973    }6974    const _: () = {6975        impl<T: Config> core::fmt::Debug for Call<T> {6976            fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {6977                match *self {6978                    Self::__Ignore(ref _0, ref _1) => {6979                        fmt.debug_tuple("Call::__Ignore").field(&_0).field(&_1).finish()6980                    }6981                }6982            }6983        }6984    };6985    const _: () = {6986        impl<T: Config> core::clone::Clone for Call<T> {6987            fn clone(&self) -> Self {6988                match self {6989                    Self::__Ignore(ref _0, ref _1) => {6990                        Self::__Ignore(6991                            core::clone::Clone::clone(_0),6992                            core::clone::Clone::clone(_1),6993                        )6994                    }6995                }6996            }6997        }6998    };6999    const _: () = {7000        impl<T: Config> core::cmp::Eq for Call<T> {}7001    };7002    const _: () = {7003        impl<T: Config> core::cmp::PartialEq for Call<T> {7004            fn eq(&self, other: &Self) -> bool {7005                match (self, other) {7006                    (Self::__Ignore(_0, _1), Self::__Ignore(_0_other, _1_other)) => {7007                        true && _0 == _0_other && _1 == _1_other7008                    }7009                }7010            }7011        }7012    };7013    #[allow(deprecated)]7014    const _: () = {7015        #[allow(non_camel_case_types)]7016        #[automatically_derived]7017        impl<T: Config> ::codec::Encode for Call<T> {}7018        #[automatically_derived]7019        impl<T: Config> ::codec::EncodeLike for Call<T> {}7020    };7021    #[allow(deprecated)]7022    const _: () = {7023        #[allow(non_camel_case_types)]7024        #[automatically_derived]7025        impl<T: Config> ::codec::Decode for Call<T> {7026            fn decode<__CodecInputEdqy: ::codec::Input>(7027                __codec_input_edqy: &mut __CodecInputEdqy,7028            ) -> ::core::result::Result<Self, ::codec::Error> {7029                match __codec_input_edqy7030                    .read_byte()7031                    .map_err(|e| {7032                        e.chain("Could not decode `Call`, failed to read variant byte")7033                    })?7034                {7035                    _ => {7036                        ::core::result::Result::Err(7037                            <_ as ::core::convert::Into<7038                                _,7039                            >>::into("Could not decode `Call`, variant doesn't exist"),7040                        )7041                    }7042                }7043            }7044        }7045    };7046    #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]7047    const _: () = {7048        impl<T: Config> ::scale_info::TypeInfo for Call<T>7049        where7050            frame_support::sp_std::marker::PhantomData<7051                (T,),7052            >: ::scale_info::TypeInfo + 'static,7053            T: Config + 'static,7054        {7055            type Identity = Self;7056            fn type_info() -> ::scale_info::Type {7057                ::scale_info::Type::builder()7058                    .path(::scale_info::Path::new("Call", "pallet_nonfungible::pallet"))7059                    .type_params(7060                        <[_]>::into_vec(7061                            #[rustc_box]7062                            ::alloc::boxed::Box::new([7063                                ::scale_info::TypeParameter::new(7064                                    "T",7065                                    ::core::option::Option::None,7066                                ),7067                            ]),7068                        ),7069                    )7070                    .docs_always(7071                        &[7072                            "Contains one variant per dispatchable that can be called by an extrinsic.",7073                        ],7074                    )7075                    .variant(::scale_info::build::Variants::new())7076            }7077        }7078    };7079    impl<T: Config> Call<T> {}7080    impl<T: Config> frame_support::dispatch::GetDispatchInfo for Call<T> {7081        fn get_dispatch_info(&self) -> frame_support::dispatch::DispatchInfo {7082            match *self {7083                Self::__Ignore(_, _) => {7084                    ::core::panicking::panic_fmt(7085                        ::core::fmt::Arguments::new_v1(7086                            &["internal error: entered unreachable code: "],7087                            &[7088                                ::core::fmt::ArgumentV1::new_display(7089                                    &::core::fmt::Arguments::new_v1(7090                                        &["__Ignore cannot be used"],7091                                        &[],7092                                    ),7093                                ),7094                            ],7095                        ),7096                    )7097                }7098            }7099        }7100    }7101    impl<T: Config> frame_support::dispatch::GetCallName for Call<T> {7102        fn get_call_name(&self) -> &'static str {7103            match *self {7104                Self::__Ignore(_, _) => {7105                    ::core::panicking::panic_fmt(7106                        ::core::fmt::Arguments::new_v1(7107                            &["internal error: entered unreachable code: "],7108                            &[7109                                ::core::fmt::ArgumentV1::new_display(7110                                    &::core::fmt::Arguments::new_v1(7111                                        &["__PhantomItem cannot be used."],7112                                        &[],7113                                    ),7114                                ),7115                            ],7116                        ),7117                    )7118                }7119            }7120        }7121        fn get_call_names() -> &'static [&'static str] {7122            &[]7123        }7124    }7125    impl<T: Config> frame_support::traits::UnfilteredDispatchable for Call<T> {7126        type Origin = frame_system::pallet_prelude::OriginFor<T>;7127        fn dispatch_bypass_filter(7128            self,7129            origin: Self::Origin,7130        ) -> frame_support::dispatch::DispatchResultWithPostInfo {7131            match self {7132                Self::__Ignore(_, _) => {7133                    let _ = origin;7134                    ::core::panicking::panic_fmt(7135                        ::core::fmt::Arguments::new_v1(7136                            &["internal error: entered unreachable code: "],7137                            &[7138                                ::core::fmt::ArgumentV1::new_display(7139                                    &::core::fmt::Arguments::new_v1(7140                                        &["__PhantomItem cannot be used."],7141                                        &[],7142                                    ),7143                                ),7144                            ],7145                        ),7146                    );7147                }7148            }7149        }7150    }7151    impl<T: Config> frame_support::dispatch::Callable<T> for Pallet<T> {7152        type Call = Call<T>;7153    }7154    impl<T: Config> Pallet<T> {7155        #[doc(hidden)]7156        pub fn call_functions() -> frame_support::metadata::PalletCallMetadata {7157            frame_support::scale_info::meta_type::<Call<T>>().into()7158        }7159    }7160    impl<T: Config> frame_support::sp_std::fmt::Debug for Error<T> {7161        fn fmt(7162            &self,7163            f: &mut frame_support::sp_std::fmt::Formatter<'_>,7164        ) -> frame_support::sp_std::fmt::Result {7165            f.write_str(self.as_str())7166        }7167    }7168    impl<T: Config> Error<T> {7169        #[doc(hidden)]7170        pub fn as_str(&self) -> &'static str {7171            match &self {7172                Self::__Ignore(_, _) => {7173                    ::core::panicking::panic_fmt(7174                        ::core::fmt::Arguments::new_v1(7175                            &["internal error: entered unreachable code: "],7176                            &[7177                                ::core::fmt::ArgumentV1::new_display(7178                                    &::core::fmt::Arguments::new_v1(7179                                        &["`__Ignore` can never be constructed"],7180                                        &[],7181                                    ),7182                                ),7183                            ],7184                        ),7185                    )7186                }7187                Self::NotNonfungibleDataUsedToMintFungibleCollectionToken => {7188                    "NotNonfungibleDataUsedToMintFungibleCollectionToken"7189                }7190                Self::NonfungibleItemsHaveNoAmount => "NonfungibleItemsHaveNoAmount",7191                Self::CantBurnNftWithChildren => "CantBurnNftWithChildren",7192            }7193        }7194    }7195    impl<T: Config> From<Error<T>> for &'static str {7196        fn from(err: Error<T>) -> &'static str {7197            err.as_str()7198        }7199    }7200    impl<T: Config> From<Error<T>> for frame_support::sp_runtime::DispatchError {7201        fn from(err: Error<T>) -> Self {7202            use frame_support::codec::Encode;7203            let index = <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::index::<7204                Pallet<T>,7205            >()7206                .expect("Every active module has an index in the runtime; qed") as u8;7207            let mut encoded = err.encode();7208            encoded.resize(frame_support::MAX_MODULE_ERROR_ENCODED_SIZE, 0);7209            frame_support::sp_runtime::DispatchError::Module(frame_support::sp_runtime::ModuleError {7210                index,7211                error: TryInto::try_into(encoded)7212                    .expect(7213                        "encoded error is resized to be equal to the maximum encoded error size; qed",7214                    ),7215                message: Some(err.as_str()),7216            })7217        }7218    }7219    pub use __tt_error_token_1 as tt_error_token;7220    #[doc(hidden)]7221    pub mod __substrate_event_check {7222        #[doc(hidden)]7223        pub use __is_event_part_defined_2 as is_event_part_defined;7224    }7225    impl<T: Config> Pallet<T> {7226        #[doc(hidden)]7227        pub fn storage_metadata() -> frame_support::metadata::PalletStorageMetadata {7228            frame_support::metadata::PalletStorageMetadata {7229                prefix: <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::name::<7230                    Pallet<T>,7231                >()7232                    .expect("Every active pallet has a name in the runtime; qed"),7233                entries: {7234                    #[allow(unused_mut)]7235                    let mut entries = ::alloc::vec::Vec::new();7236                    {7237                        <TokensMinted<7238                            T,7239                        > as frame_support::storage::StorageEntryMetadataBuilder>::build_metadata(7240                            <[_]>::into_vec(7241                                #[rustc_box]7242                                ::alloc::boxed::Box::new([7243                                    " Total amount of minted tokens in a collection.",7244                                ]),7245                            ),7246                            &mut entries,7247                        );7248                    }7249                    {7250                        <TokensBurnt<7251                            T,7252                        > as frame_support::storage::StorageEntryMetadataBuilder>::build_metadata(7253                            <[_]>::into_vec(7254                                #[rustc_box]7255                                ::alloc::boxed::Box::new([7256                                    " Amount of burnt tokens in a collection.",7257                                ]),7258                            ),7259                            &mut entries,7260                        );7261                    }7262                    {7263                        <TokenData<7264                            T,7265                        > as frame_support::storage::StorageEntryMetadataBuilder>::build_metadata(7266                            <[_]>::into_vec(7267                                #[rustc_box]7268                                ::alloc::boxed::Box::new([7269                                    " Token data, used to partially describe a token.",7270                                ]),7271                            ),7272                            &mut entries,7273                        );7274                    }7275                    {7276                        <TokenProperties<7277                            T,7278                        > as frame_support::storage::StorageEntryMetadataBuilder>::build_metadata(7279                            <[_]>::into_vec(7280                                #[rustc_box]7281                                ::alloc::boxed::Box::new([7282                                    " Map of key-value pairs, describing the metadata of a token.",7283                                ]),7284                            ),7285                            &mut entries,7286                        );7287                    }7288                    {7289                        <TokenAuxProperties<7290                            T,7291                        > as frame_support::storage::StorageEntryMetadataBuilder>::build_metadata(7292                            <[_]>::into_vec(7293                                #[rustc_box]7294                                ::alloc::boxed::Box::new([7295                                    " Custom data of a token that is serialized to bytes,",7296                                    " primarily reserved for on-chain operations,",7297                                    " normally obscured from the external users.",7298                                    "",7299                                    " Auxiliary properties are slightly different from",7300                                    " usual [`TokenProperties`] due to an unlimited number",7301                                    " and separately stored and written-to key-value pairs.",7302                                    "",7303                                    " Currently used to store RMRK data.",7304                                ]),7305                            ),7306                            &mut entries,7307                        );7308                    }7309                    {7310                        <Owned<7311                            T,7312                        > as frame_support::storage::StorageEntryMetadataBuilder>::build_metadata(7313                            <[_]>::into_vec(7314                                #[rustc_box]7315                                ::alloc::boxed::Box::new([7316                                    " Used to enumerate tokens owned by account.",7317                                ]),7318                            ),7319                            &mut entries,7320                        );7321                    }7322                    {7323                        <TokenChildren<7324                            T,7325                        > as frame_support::storage::StorageEntryMetadataBuilder>::build_metadata(7326                            <[_]>::into_vec(7327                                #[rustc_box]7328                                ::alloc::boxed::Box::new([7329                                    " Used to enumerate token\'s children.",7330                                ]),7331                            ),7332                            &mut entries,7333                        );7334                    }7335                    {7336                        <AccountBalance<7337                            T,7338                        > as frame_support::storage::StorageEntryMetadataBuilder>::build_metadata(7339                            <[_]>::into_vec(7340                                #[rustc_box]7341                                ::alloc::boxed::Box::new([7342                                    " Amount of tokens owned by an account in a collection.",7343                                ]),7344                            ),7345                            &mut entries,7346                        );7347                    }7348                    {7349                        <Allowance<7350                            T,7351                        > as frame_support::storage::StorageEntryMetadataBuilder>::build_metadata(7352                            <[_]>::into_vec(7353                                #[rustc_box]7354                                ::alloc::boxed::Box::new([7355                                    " Allowance set by a token owner for another user to perform one of certain transactions on a token.",7356                                ]),7357                            ),7358                            &mut entries,7359                        );7360                    }7361                    entries7362                },7363            }7364        }7365    }7366    impl<T: Config> Pallet<T> {7367        /// Map of key-value pairs, describing the metadata of a token.7368        pub fn token_properties<KArg>(key: KArg) -> Properties7369        where7370            KArg: frame_support::storage::types::EncodeLikeTuple<7371                    <(7372                        Key<Twox64Concat, CollectionId>,7373                        Key<Twox64Concat, TokenId>,7374                    ) as frame_support::storage::types::KeyGenerator>::KArg,7375                > + frame_support::storage::types::TupleToEncodedIter,7376        {7377            <TokenProperties<7378                T,7379            > as frame_support::storage::StorageNMap<7380                (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),7381                Properties,7382            >>::get(key)7383        }7384    }7385    impl<T: Config> Pallet<T> {7386        /// Custom data of a token that is serialized to bytes,7387        /// primarily reserved for on-chain operations,7388        /// normally obscured from the external users.7389        ///7390        /// Auxiliary properties are slightly different from7391        /// usual [`TokenProperties`] due to an unlimited number7392        /// and separately stored and written-to key-value pairs.7393        ///7394        /// Currently used to store RMRK data.7395        pub fn token_aux_property<KArg>(key: KArg) -> Option<AuxPropertyValue>7396        where7397            KArg: frame_support::storage::types::EncodeLikeTuple<7398                    <(7399                        Key<Twox64Concat, CollectionId>,7400                        Key<Twox64Concat, TokenId>,7401                        Key<Twox64Concat, PropertyScope>,7402                        Key<Twox64Concat, PropertyKey>,7403                    ) as frame_support::storage::types::KeyGenerator>::KArg,7404                > + frame_support::storage::types::TupleToEncodedIter,7405        {7406            <TokenAuxProperties<7407                T,7408            > as frame_support::storage::StorageNMap<7409                (7410                    Key<Twox64Concat, CollectionId>,7411                    Key<Twox64Concat, TokenId>,7412                    Key<Twox64Concat, PropertyScope>,7413                    Key<Twox64Concat, PropertyKey>,7414                ),7415                AuxPropertyValue,7416            >>::get(key)7417        }7418    }7419    impl<T: Config> Pallet<T> {7420        /// Used to enumerate token's children.7421        pub fn token_children<KArg>(key: KArg) -> bool7422        where7423            KArg: frame_support::storage::types::EncodeLikeTuple<7424                    <(7425                        Key<Twox64Concat, CollectionId>,7426                        Key<Twox64Concat, TokenId>,7427                        Key<Twox64Concat, (CollectionId, TokenId)>,7428                    ) as frame_support::storage::types::KeyGenerator>::KArg,7429                > + frame_support::storage::types::TupleToEncodedIter,7430        {7431            <TokenChildren<7432                T,7433            > as frame_support::storage::StorageNMap<7434                (7435                    Key<Twox64Concat, CollectionId>,7436                    Key<Twox64Concat, TokenId>,7437                    Key<Twox64Concat, (CollectionId, TokenId)>,7438                ),7439                bool,7440            >>::get(key)7441        }7442    }7443    #[doc(hidden)]7444    pub struct _GeneratedPrefixForStorageTokensMinted<T>(7445        core::marker::PhantomData<(T,)>,7446    );7447    impl<T: Config> frame_support::traits::StorageInstance7448    for _GeneratedPrefixForStorageTokensMinted<T> {7449        fn pallet_prefix() -> &'static str {7450            <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::name::<7451                Pallet<T>,7452            >()7453                .expect("Every active pallet has a name in the runtime; qed")7454        }7455        const STORAGE_PREFIX: &'static str = "TokensMinted";7456    }7457    #[doc(hidden)]7458    pub struct _GeneratedPrefixForStorageTokensBurnt<T>(core::marker::PhantomData<(T,)>);7459    impl<T: Config> frame_support::traits::StorageInstance7460    for _GeneratedPrefixForStorageTokensBurnt<T> {7461        fn pallet_prefix() -> &'static str {7462            <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::name::<7463                Pallet<T>,7464            >()7465                .expect("Every active pallet has a name in the runtime; qed")7466        }7467        const STORAGE_PREFIX: &'static str = "TokensBurnt";7468    }7469    #[doc(hidden)]7470    pub struct _GeneratedPrefixForStorageTokenData<T>(core::marker::PhantomData<(T,)>);7471    impl<T: Config> frame_support::traits::StorageInstance7472    for _GeneratedPrefixForStorageTokenData<T> {7473        fn pallet_prefix() -> &'static str {7474            <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::name::<7475                Pallet<T>,7476            >()7477                .expect("Every active pallet has a name in the runtime; qed")7478        }7479        const STORAGE_PREFIX: &'static str = "TokenData";7480    }7481    #[doc(hidden)]7482    pub struct _GeneratedPrefixForStorageTokenProperties<T>(7483        core::marker::PhantomData<(T,)>,7484    );7485    impl<T: Config> frame_support::traits::StorageInstance7486    for _GeneratedPrefixForStorageTokenProperties<T> {7487        fn pallet_prefix() -> &'static str {7488            <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::name::<7489                Pallet<T>,7490            >()7491                .expect("Every active pallet has a name in the runtime; qed")7492        }7493        const STORAGE_PREFIX: &'static str = "TokenProperties";7494    }7495    #[doc(hidden)]7496    pub struct _GeneratedPrefixForStorageTokenAuxProperties<T>(7497        core::marker::PhantomData<(T,)>,7498    );7499    impl<T: Config> frame_support::traits::StorageInstance7500    for _GeneratedPrefixForStorageTokenAuxProperties<T> {7501        fn pallet_prefix() -> &'static str {7502            <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::name::<7503                Pallet<T>,7504            >()7505                .expect("Every active pallet has a name in the runtime; qed")7506        }7507        const STORAGE_PREFIX: &'static str = "TokenAuxProperties";7508    }7509    #[doc(hidden)]7510    pub struct _GeneratedPrefixForStorageOwned<T>(core::marker::PhantomData<(T,)>);7511    impl<T: Config> frame_support::traits::StorageInstance7512    for _GeneratedPrefixForStorageOwned<T> {7513        fn pallet_prefix() -> &'static str {7514            <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::name::<7515                Pallet<T>,7516            >()7517                .expect("Every active pallet has a name in the runtime; qed")7518        }7519        const STORAGE_PREFIX: &'static str = "Owned";7520    }7521    #[doc(hidden)]7522    pub struct _GeneratedPrefixForStorageTokenChildren<T>(7523        core::marker::PhantomData<(T,)>,7524    );7525    impl<T: Config> frame_support::traits::StorageInstance7526    for _GeneratedPrefixForStorageTokenChildren<T> {7527        fn pallet_prefix() -> &'static str {7528            <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::name::<7529                Pallet<T>,7530            >()7531                .expect("Every active pallet has a name in the runtime; qed")7532        }7533        const STORAGE_PREFIX: &'static str = "TokenChildren";7534    }7535    #[doc(hidden)]7536    pub struct _GeneratedPrefixForStorageAccountBalance<T>(7537        core::marker::PhantomData<(T,)>,7538    );7539    impl<T: Config> frame_support::traits::StorageInstance7540    for _GeneratedPrefixForStorageAccountBalance<T> {7541        fn pallet_prefix() -> &'static str {7542            <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::name::<7543                Pallet<T>,7544            >()7545                .expect("Every active pallet has a name in the runtime; qed")7546        }7547        const STORAGE_PREFIX: &'static str = "AccountBalance";7548    }7549    #[doc(hidden)]7550    pub struct _GeneratedPrefixForStorageAllowance<T>(core::marker::PhantomData<(T,)>);7551    impl<T: Config> frame_support::traits::StorageInstance7552    for _GeneratedPrefixForStorageAllowance<T> {7553        fn pallet_prefix() -> &'static str {7554            <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::name::<7555                Pallet<T>,7556            >()7557                .expect("Every active pallet has a name in the runtime; qed")7558        }7559        const STORAGE_PREFIX: &'static str = "Allowance";7560    }7561    #[doc(hidden)]7562    pub mod __substrate_inherent_check {7563        #[doc(hidden)]7564        pub use __is_inherent_part_defined_3 as is_inherent_part_defined;7565    }7566    /// Hidden instance generated to be internally used when module is used without7567    /// instance.7568    #[doc(hidden)]7569    pub type __InherentHiddenInstance = ();7570    pub(super) trait Store {7571        type TokensMinted;7572        type TokensBurnt;7573        type TokenData;7574        type TokenProperties;7575        type TokenAuxProperties;7576        type Owned;7577        type TokenChildren;7578        type AccountBalance;7579        type Allowance;7580    }7581    impl<T: Config> Store for Pallet<T> {7582        type TokensMinted = TokensMinted<T>;7583        type TokensBurnt = TokensBurnt<T>;7584        type TokenData = TokenData<T>;7585        type TokenProperties = TokenProperties<T>;7586        type TokenAuxProperties = TokenAuxProperties<T>;7587        type Owned = Owned<T>;7588        type TokenChildren = TokenChildren<T>;7589        type AccountBalance = AccountBalance<T>;7590        type Allowance = Allowance<T>;7591    }7592    impl<7593        T: Config,7594    > frame_support::traits::OnFinalize<<T as frame_system::Config>::BlockNumber>7595    for Pallet<T> {7596        fn on_finalize(n: <T as frame_system::Config>::BlockNumber) {7597            let __within_span__ = {7598                use ::tracing::__macro_support::Callsite as _;7599                static CALLSITE: ::tracing::callsite::DefaultCallsite = {7600                    static META: ::tracing::Metadata<'static> = {7601                        ::tracing_core::metadata::Metadata::new(7602                            "on_finalize",7603                            "pallet_nonfungible::pallet",7604                            ::tracing::Level::TRACE,7605                            Some("pallets/nonfungible/src/lib.rs"),7606                            Some(147u32),7607                            Some("pallet_nonfungible::pallet"),7608                            ::tracing_core::field::FieldSet::new(7609                                &[],7610                                ::tracing_core::callsite::Identifier(&CALLSITE),7611                            ),7612                            ::tracing::metadata::Kind::SPAN,7613                        )7614                    };7615                    ::tracing::callsite::DefaultCallsite::new(&META)7616                };7617                let mut interest = ::tracing::subscriber::Interest::never();7618                if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL7619                    && ::tracing::Level::TRACE7620                        <= ::tracing::level_filters::LevelFilter::current()7621                    && {7622                        interest = CALLSITE.interest();7623                        !interest.is_never()7624                    }7625                    && ::tracing::__macro_support::__is_enabled(7626                        CALLSITE.metadata(),7627                        interest,7628                    )7629                {7630                    let meta = CALLSITE.metadata();7631                    ::tracing::Span::new(meta, &{ meta.fields().value_set(&[]) })7632                } else {7633                    let span = ::tracing::__macro_support::__disabled_span(7634                        CALLSITE.metadata(),7635                    );7636                    {};7637                    span7638                }7639            };7640            let __tracing_guard__ = __within_span__.enter();7641            <Self as frame_support::traits::Hooks<7642                <T as frame_system::Config>::BlockNumber,7643            >>::on_finalize(n)7644        }7645    }7646    impl<7647        T: Config,7648    > frame_support::traits::OnIdle<<T as frame_system::Config>::BlockNumber>7649    for Pallet<T> {7650        fn on_idle(7651            n: <T as frame_system::Config>::BlockNumber,7652            remaining_weight: frame_support::weights::Weight,7653        ) -> frame_support::weights::Weight {7654            <Self as frame_support::traits::Hooks<7655                <T as frame_system::Config>::BlockNumber,7656            >>::on_idle(n, remaining_weight)7657        }7658    }7659    impl<7660        T: Config,7661    > frame_support::traits::OnInitialize<<T as frame_system::Config>::BlockNumber>7662    for Pallet<T> {7663        fn on_initialize(7664            n: <T as frame_system::Config>::BlockNumber,7665        ) -> frame_support::weights::Weight {7666            let __within_span__ = {7667                use ::tracing::__macro_support::Callsite as _;7668                static CALLSITE: ::tracing::callsite::DefaultCallsite = {7669                    static META: ::tracing::Metadata<'static> = {7670                        ::tracing_core::metadata::Metadata::new(7671                            "on_initialize",7672                            "pallet_nonfungible::pallet",7673                            ::tracing::Level::TRACE,7674                            Some("pallets/nonfungible/src/lib.rs"),7675                            Some(147u32),7676                            Some("pallet_nonfungible::pallet"),7677                            ::tracing_core::field::FieldSet::new(7678                                &[],7679                                ::tracing_core::callsite::Identifier(&CALLSITE),7680                            ),7681                            ::tracing::metadata::Kind::SPAN,7682                        )7683                    };7684                    ::tracing::callsite::DefaultCallsite::new(&META)7685                };7686                let mut interest = ::tracing::subscriber::Interest::never();7687                if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL7688                    && ::tracing::Level::TRACE7689                        <= ::tracing::level_filters::LevelFilter::current()7690                    && {7691                        interest = CALLSITE.interest();7692                        !interest.is_never()7693                    }7694                    && ::tracing::__macro_support::__is_enabled(7695                        CALLSITE.metadata(),7696                        interest,7697                    )7698                {7699                    let meta = CALLSITE.metadata();7700                    ::tracing::Span::new(meta, &{ meta.fields().value_set(&[]) })7701                } else {7702                    let span = ::tracing::__macro_support::__disabled_span(7703                        CALLSITE.metadata(),7704                    );7705                    {};7706                    span7707                }7708            };7709            let __tracing_guard__ = __within_span__.enter();7710            <Self as frame_support::traits::Hooks<7711                <T as frame_system::Config>::BlockNumber,7712            >>::on_initialize(n)7713        }7714    }7715    impl<T: Config> frame_support::traits::OnRuntimeUpgrade for Pallet<T> {7716        fn on_runtime_upgrade() -> frame_support::weights::Weight {7717            let __within_span__ = {7718                use ::tracing::__macro_support::Callsite as _;7719                static CALLSITE: ::tracing::callsite::DefaultCallsite = {7720                    static META: ::tracing::Metadata<'static> = {7721                        ::tracing_core::metadata::Metadata::new(7722                            "on_runtime_update",7723                            "pallet_nonfungible::pallet",7724                            ::tracing::Level::TRACE,7725                            Some("pallets/nonfungible/src/lib.rs"),7726                            Some(147u32),7727                            Some("pallet_nonfungible::pallet"),7728                            ::tracing_core::field::FieldSet::new(7729                                &[],7730                                ::tracing_core::callsite::Identifier(&CALLSITE),7731                            ),7732                            ::tracing::metadata::Kind::SPAN,7733                        )7734                    };7735                    ::tracing::callsite::DefaultCallsite::new(&META)7736                };7737                let mut interest = ::tracing::subscriber::Interest::never();7738                if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL7739                    && ::tracing::Level::TRACE7740                        <= ::tracing::level_filters::LevelFilter::current()7741                    && {7742                        interest = CALLSITE.interest();7743                        !interest.is_never()7744                    }7745                    && ::tracing::__macro_support::__is_enabled(7746                        CALLSITE.metadata(),7747                        interest,7748                    )7749                {7750                    let meta = CALLSITE.metadata();7751                    ::tracing::Span::new(meta, &{ meta.fields().value_set(&[]) })7752                } else {7753                    let span = ::tracing::__macro_support::__disabled_span(7754                        CALLSITE.metadata(),7755                    );7756                    {};7757                    span7758                }7759            };7760            let __tracing_guard__ = __within_span__.enter();7761            let pallet_name = <<T as frame_system::Config>::PalletInfo as frame_support::traits::PalletInfo>::name::<7762                Self,7763            >()7764                .unwrap_or("<unknown pallet name>");7765            {7766                let lvl = ::log::Level::Info;7767                if lvl <= ::log::STATIC_MAX_LEVEL && lvl <= ::log::max_level() {7768                    ::log::__private_api_log(7769                        ::core::fmt::Arguments::new_v1(7770                            &[7771                                "\u{26a0}\u{fe0f} ",7772                                " declares internal migrations (which *might* execute). On-chain `",7773                                "` vs current storage version `",7774                                "`",7775                            ],7776                            &[7777                                ::core::fmt::ArgumentV1::new_display(&pallet_name),7778                                ::core::fmt::ArgumentV1::new_debug(7779                                    &<Self as frame_support::traits::GetStorageVersion>::on_chain_storage_version(),7780                                ),7781                                ::core::fmt::ArgumentV1::new_debug(7782                                    &<Self as frame_support::traits::GetStorageVersion>::current_storage_version(),7783                                ),7784                            ],7785                        ),7786                        lvl,7787                        &(7788                            frame_support::LOG_TARGET,7789                            "pallet_nonfungible::pallet",7790                            "pallets/nonfungible/src/lib.rs",7791                            147u32,7792                        ),7793                        ::log::__private_api::Option::None,7794                    );7795                }7796            };7797            <Self as frame_support::traits::Hooks<7798                <T as frame_system::Config>::BlockNumber,7799            >>::on_runtime_upgrade()7800        }7801    }7802    impl<7803        T: Config,7804    > frame_support::traits::OffchainWorker<<T as frame_system::Config>::BlockNumber>7805    for Pallet<T> {7806        fn offchain_worker(n: <T as frame_system::Config>::BlockNumber) {7807            <Self as frame_support::traits::Hooks<7808                <T as frame_system::Config>::BlockNumber,7809            >>::offchain_worker(n)7810        }7811    }7812    impl<T: Config> frame_support::traits::IntegrityTest for Pallet<T> {7813        fn integrity_test() {7814            <Self as frame_support::traits::Hooks<7815                <T as frame_system::Config>::BlockNumber,7816            >>::integrity_test()7817        }7818    }7819    #[doc(hidden)]7820    pub mod __substrate_genesis_config_check {7821        #[doc(hidden)]7822        pub use __is_genesis_config_defined_4 as is_genesis_config_defined;7823        #[doc(hidden)]7824        pub use __is_std_enabled_for_genesis_4 as is_std_enabled_for_genesis;7825    }7826    #[doc(hidden)]7827    pub mod __substrate_origin_check {7828        #[doc(hidden)]7829        pub use __is_origin_part_defined_5 as is_origin_part_defined;7830    }7831    #[doc(hidden)]7832    pub mod __substrate_validate_unsigned_check {7833        #[doc(hidden)]7834        pub use __is_validate_unsigned_part_defined_6 as is_validate_unsigned_part_defined;7835    }7836    pub use __tt_default_parts_7 as tt_default_parts;7837}7838pub struct NonfungibleHandle<T: Config>(pallet_common::CollectionHandle<T>);7839impl<T: Config> NonfungibleHandle<T> {7840    pub fn cast(inner: pallet_common::CollectionHandle<T>) -> Self {7841        Self(inner)7842    }7843    pub fn into_inner(self) -> pallet_common::CollectionHandle<T> {7844        self.07845    }7846    pub fn common_mut(&mut self) -> &mut pallet_common::CollectionHandle<T> {7847        &mut self.07848    }7849}7850impl<T: Config> WithRecorder<T> for NonfungibleHandle<T> {7851    fn recorder(&self) -> &SubstrateRecorder<T> {7852        self.0.recorder()7853    }7854    fn into_recorder(self) -> SubstrateRecorder<T> {7855        self.0.into_recorder()7856    }7857}7858impl<T: Config> Deref for NonfungibleHandle<T> {7859    type Target = pallet_common::CollectionHandle<T>;7860    fn deref(&self) -> &Self::Target {7861        &self.07862    }7863}7864impl<T: Config> Pallet<T> {7865    /// Get number of NFT tokens in collection.7866    pub fn total_supply(collection: &NonfungibleHandle<T>) -> u32 {7867        <TokensMinted<T>>::get(collection.id) - <TokensBurnt<T>>::get(collection.id)7868    }7869    /// Check that NFT token exists.7870    ///7871    /// - `token`: Token ID.7872    pub fn token_exists(collection: &NonfungibleHandle<T>, token: TokenId) -> bool {7873        <TokenData<T>>::contains_key((collection.id, token))7874    }7875    /// Set the token property with the scope.7876    ///7877    /// - `property`: Contains key-value pair.7878    pub fn set_scoped_token_property(7879        collection_id: CollectionId,7880        token_id: TokenId,7881        scope: PropertyScope,7882        property: Property,7883    ) -> DispatchResult {7884        TokenProperties::<7885            T,7886        >::try_mutate(7887                (collection_id, token_id),7888                |properties| {7889                    properties.try_scoped_set(scope, property.key, property.value)7890                },7891            )7892            .map_err(<CommonError<T>>::from)?;7893        Ok(())7894    }7895    /// Batch operation to set multiple properties with the same scope.7896    pub fn set_scoped_token_properties(7897        collection_id: CollectionId,7898        token_id: TokenId,7899        scope: PropertyScope,7900        properties: impl Iterator<Item = Property>,7901    ) -> DispatchResult {7902        TokenProperties::<7903            T,7904        >::try_mutate(7905                (collection_id, token_id),7906                |stored_properties| {7907                    stored_properties.try_scoped_set_from_iter(scope, properties)7908                },7909            )7910            .map_err(<CommonError<T>>::from)?;7911        Ok(())7912    }7913    /// Add or edit auxiliary data for the property.7914    ///7915    /// - `f`: function that adds or edits auxiliary data.7916    pub fn try_mutate_token_aux_property<R, E>(7917        collection_id: CollectionId,7918        token_id: TokenId,7919        scope: PropertyScope,7920        key: PropertyKey,7921        f: impl FnOnce(&mut Option<AuxPropertyValue>) -> Result<R, E>,7922    ) -> Result<R, E> {7923        <TokenAuxProperties<T>>::try_mutate((collection_id, token_id, scope, key), f)7924    }7925    /// Remove auxiliary data for the property.7926    pub fn remove_token_aux_property(7927        collection_id: CollectionId,7928        token_id: TokenId,7929        scope: PropertyScope,7930        key: PropertyKey,7931    ) {7932        <TokenAuxProperties<T>>::remove((collection_id, token_id, scope, key));7933    }7934    /// Get all auxiliary data in a given scope.7935    ///7936    /// Returns iterator over Property Key - Data pairs.7937    pub fn iterate_token_aux_properties(7938        collection_id: CollectionId,7939        token_id: TokenId,7940        scope: PropertyScope,7941    ) -> impl Iterator<Item = (PropertyKey, AuxPropertyValue)> {7942        <TokenAuxProperties<T>>::iter_prefix((collection_id, token_id, scope))7943    }7944    /// Get ID of the last minted token7945    pub fn current_token_id(collection_id: CollectionId) -> TokenId {7946        TokenId(<TokensMinted<T>>::get(collection_id))7947    }7948}7949impl<T: Config> Pallet<T> {7950    /// Create NFT collection7951    ///7952    /// `init_collection` will take non-refundable deposit for collection creation.7953    ///7954    /// - `data`: Contains settings for collection limits and permissions.7955    pub fn init_collection(7956        owner: T::CrossAccountId,7957        payer: T::CrossAccountId,7958        data: CreateCollectionData<T::AccountId>,7959        is_external: bool,7960    ) -> Result<CollectionId, DispatchError> {7961        <PalletCommon<7962            T,7963        >>::init_collection(7964            owner,7965            payer,7966            data,7967            CollectionFlags {7968                external: is_external,7969                ..Default::default()7970            },7971        )7972    }7973    /// Destroy NFT collection7974    ///7975    /// `destroy_collection` will throw error if collection contains any tokens.7976    /// Only owner can destroy collection.7977    pub fn destroy_collection(7978        collection: NonfungibleHandle<T>,7979        sender: &T::CrossAccountId,7980    ) -> DispatchResult {7981        let id = collection.id;7982        if Self::collection_has_tokens(id) {7983            return Err(<CommonError<T>>::CantDestroyNotEmptyCollection.into());7984        }7985        PalletCommon::destroy_collection(collection.0, sender)?;7986        let _ = <TokenData<T>>::clear_prefix((id,), u32::MAX, None);7987        let _ = <TokenChildren<T>>::clear_prefix((id,), u32::MAX, None);7988        let _ = <Owned<T>>::clear_prefix((id,), u32::MAX, None);7989        <TokensMinted<T>>::remove(id);7990        <TokensBurnt<T>>::remove(id);7991        let _ = <Allowance<T>>::clear_prefix((id,), u32::MAX, None);7992        let _ = <AccountBalance<T>>::clear_prefix((id,), u32::MAX, None);7993        Ok(())7994    }7995    /// Burn NFT token7996    ///7997    /// `burn` removes `token` from the `collection`, from it's owner and from the parent token7998    /// if the token is nested.7999    /// Only the owner can `burn` the token. The `token` shouldn't have any nested tokens.8000    /// Also removes all corresponding properties and auxiliary properties.8001    ///8002    /// - `token`: Token that should be burned8003    /// - `collection`: Collection that contains the token8004    pub fn burn(8005        collection: &NonfungibleHandle<T>,8006        sender: &T::CrossAccountId,8007        token: TokenId,8008    ) -> DispatchResult {8009        let token_data = <TokenData<T>>::get((collection.id, token))8010            .ok_or(<CommonError<T>>::TokenNotFound)?;8011        {8012            if !(&token_data.owner == sender) {8013                { return Err(<CommonError<T>>::NoPermission.into()) };8014            }8015        };8016        if collection.permissions.access() == AccessMode::AllowList {8017            collection.check_allowlist(sender)?;8018        }8019        if Self::token_has_children(collection.id, token) {8020            return Err(<Error<T>>::CantBurnNftWithChildren.into());8021        }8022        let burnt = <TokensBurnt<T>>::get(collection.id)8023            .checked_add(1)8024            .ok_or(ArithmeticError::Overflow)?;8025        let balance = <AccountBalance<T>>::get((collection.id, token_data.owner.clone()))8026            .checked_sub(1)8027            .ok_or(ArithmeticError::Overflow)?;8028        if balance == 0 {8029            <AccountBalance<T>>::remove((collection.id, token_data.owner.clone()));8030        } else {8031            <AccountBalance<8032                T,8033            >>::insert((collection.id, token_data.owner.clone()), balance);8034        }8035        <PalletStructure<T>>::unnest_if_nested(&token_data.owner, collection.id, token);8036        <Owned<T>>::remove((collection.id, &token_data.owner, token));8037        <TokensBurnt<T>>::insert(collection.id, burnt);8038        <TokenData<T>>::remove((collection.id, token));8039        <TokenProperties<T>>::remove((collection.id, token));8040        let _ = <TokenAuxProperties<8041            T,8042        >>::clear_prefix((collection.id, token), u32::MAX, None);8043        let old_spender = <Allowance<T>>::take((collection.id, token));8044        if let Some(old_spender) = old_spender {8045            <PalletCommon<8046                T,8047            >>::deposit_event(8048                CommonEvent::Approved(8049                    collection.id,8050                    token,8051                    token_data.owner.clone(),8052                    old_spender,8053                    0,8054                ),8055            );8056        }8057        <PalletEvm<8058            T,8059        >>::deposit_log(8060            ERC721Events::Transfer {8061                from: *token_data.owner.as_eth(),8062                to: H160::default(),8063                token_id: token.into(),8064            }8065                .to_log(collection_id_to_address(collection.id)),8066        );8067        <PalletCommon<8068            T,8069        >>::deposit_event(8070            CommonEvent::ItemDestroyed(collection.id, token, token_data.owner, 1),8071        );8072        Ok(())8073    }8074    /// Same as [`burn`] but burns all the tokens that are nested in the token first8075    ///8076    /// - `self_budget`: Limit for searching children in depth.8077    /// - `breadth_budget`: Limit of breadth of searching children.8078    ///8079    /// [`burn`]: struct.Pallet.html#method.burn8080    pub fn burn_recursively(8081        collection: &NonfungibleHandle<T>,8082        sender: &T::CrossAccountId,8083        token: TokenId,8084        self_budget: &dyn Budget,8085        breadth_budget: &dyn Budget,8086    ) -> DispatchResultWithPostInfo {8087        use frame_support::storage::{with_transaction, TransactionOutcome};8088        with_transaction(|| {8089            let r = (|| {8090                {8091                    {8092                        if !self_budget.consume() {8093                            { return Err(<StructureError<T>>::DepthLimit.into()) };8094                        }8095                    };8096                    let current_token_account = T::CrossTokenAddressMapping::token_to_address(8097                        collection.id,8098                        token,8099                    );8100                    let mut weight = Weight::zero();8101                    for ((collection, token), _) in <TokenChildren<8102                        T,8103                    >>::iter_prefix((collection.id, token)) {8104                        {8105                            if !breadth_budget.consume() {8106                                { return Err(<StructureError<T>>::BreadthLimit.into()) };8107                            }8108                        };8109                        let PostDispatchInfo { actual_weight, .. } = <PalletStructure<8110                            T,8111                        >>::burn_item_recursively(8112                            current_token_account.clone(),8113                            collection,8114                            token,8115                            self_budget,8116                            breadth_budget,8117                        )?;8118                        if let Some(actual_weight) = actual_weight {8119                            weight = weight.saturating_add(actual_weight);8120                        }8121                    }8122                    Self::burn(collection, sender, token)?;8123                    DispatchResultWithPostInfo::Ok(PostDispatchInfo {8124                        actual_weight: Some(weight + <SelfWeightOf<T>>::burn_item()),8125                        pays_fee: Pays::Yes,8126                    })8127                }8128            })();8129            if r.is_ok() {8130                TransactionOutcome::Commit(r)8131            } else {8132                TransactionOutcome::Rollback(r)8133            }8134        })8135    }8136    /// Batch operation to add, edit or remove properties for the token8137    ///8138    /// All affected properties should have mutable permission and sender should have8139    /// permission to edit those properties.8140    ///8141    /// - `nesting_budget`: Limit for searching parents in depth to check ownership.8142    /// - `is_token_create`: Indicates that method is called during token initialization.8143    ///   Allows to bypass ownership check.8144    fn modify_token_properties(8145        collection: &NonfungibleHandle<T>,8146        sender: &T::CrossAccountId,8147        token_id: TokenId,8148        properties: impl Iterator<Item = (PropertyKey, Option<PropertyValue>)>,8149        is_token_create: bool,8150        nesting_budget: &dyn Budget,8151    ) -> DispatchResult {8152        use frame_support::storage::{with_transaction, TransactionOutcome};8153        with_transaction(|| {8154            let r = (|| {8155                {8156                    let mut collection_admin_status = None;8157                    let mut token_owner_result = None;8158                    let mut is_collection_admin = || {8159                        *collection_admin_status8160                            .get_or_insert_with(|| collection.is_owner_or_admin(sender))8161                    };8162                    let mut is_token_owner = || {8163                        *token_owner_result8164                            .get_or_insert_with(|| -> Result<bool, DispatchError> {8165                                let is_owned = <PalletStructure<8166                                    T,8167                                >>::check_indirectly_owned(8168                                    sender.clone(),8169                                    collection.id,8170                                    token_id,8171                                    None,8172                                    nesting_budget,8173                                )?;8174                                Ok(is_owned)8175                            })8176                    };8177                    for (key, value) in properties {8178                        let permission = <PalletCommon<8179                            T,8180                        >>::property_permissions(collection.id)8181                            .get(&key)8182                            .cloned()8183                            .unwrap_or_else(PropertyPermission::none);8184                        let is_property_exists = TokenProperties::<8185                            T,8186                        >::get((collection.id, token_id))8187                            .get(&key)8188                            .is_some();8189                        match permission {8190                            PropertyPermission {8191                                mutable: false,8192                                ..8193                            } if is_property_exists => {8194                                return Err(<CommonError<T>>::NoPermission.into());8195                            }8196                            PropertyPermission { collection_admin, token_owner, .. } => {8197                                if is_token_create && (collection_admin || token_owner)8198                                    && value.is_some()8199                                {} else if collection_admin && is_collection_admin()8200                                {} else if token_owner && is_token_owner()? {} else {8201                                    { return Err(<CommonError<T>>::NoPermission.into()) };8202                                }8203                            }8204                        }8205                        match value {8206                            Some(value) => {8207                                <TokenProperties<8208                                    T,8209                                >>::try_mutate(8210                                        (collection.id, token_id),8211                                        |properties| { properties.try_set(key.clone(), value) },8212                                    )8213                                    .map_err(<CommonError<T>>::from)?;8214                                <PalletCommon<8215                                    T,8216                                >>::deposit_event(8217                                    CommonEvent::TokenPropertySet(collection.id, token_id, key),8218                                );8219                            }8220                            None => {8221                                <TokenProperties<8222                                    T,8223                                >>::try_mutate(8224                                        (collection.id, token_id),8225                                        |properties| { properties.remove(&key) },8226                                    )8227                                    .map_err(<CommonError<T>>::from)?;8228                                <PalletCommon<8229                                    T,8230                                >>::deposit_event(8231                                    CommonEvent::TokenPropertyDeleted(8232                                        collection.id,8233                                        token_id,8234                                        key,8235                                    ),8236                                );8237                            }8238                        }8239                    }8240                    Ok(())8241                }8242            })();8243            if r.is_ok() {8244                TransactionOutcome::Commit(r)8245            } else {8246                TransactionOutcome::Rollback(r)8247            }8248        })8249    }8250    /// Batch operation to add or edit properties for the token8251    ///8252    /// Same as [`modify_token_properties`] but doesn't allow to remove properties8253    ///8254    /// [`modify_token_properties`]: struct.Pallet.html#method.modify_token_properties8255    pub fn set_token_properties(8256        collection: &NonfungibleHandle<T>,8257        sender: &T::CrossAccountId,8258        token_id: TokenId,8259        properties: impl Iterator<Item = Property>,8260        is_token_create: bool,8261        nesting_budget: &dyn Budget,8262    ) -> DispatchResult {8263        Self::modify_token_properties(8264            collection,8265            sender,8266            token_id,8267            properties.map(|p| (p.key, Some(p.value))),8268            is_token_create,8269            nesting_budget,8270        )8271    }8272    /// Add or edit single property for the token8273    ///8274    /// Calls [`set_token_properties`] internally8275    ///8276    /// [`set_token_properties`]: struct.Pallet.html#method.set_token_properties8277    pub fn set_token_property(8278        collection: &NonfungibleHandle<T>,8279        sender: &T::CrossAccountId,8280        token_id: TokenId,8281        property: Property,8282        nesting_budget: &dyn Budget,8283    ) -> DispatchResult {8284        let is_token_create = false;8285        Self::set_token_properties(8286            collection,8287            sender,8288            token_id,8289            [property].into_iter(),8290            is_token_create,8291            nesting_budget,8292        )8293    }8294    /// Batch operation to remove properties from the token8295    ///8296    /// Same as [`modify_token_properties`] but doesn't allow to add or edit properties8297    ///8298    /// [`modify_token_properties`]: struct.Pallet.html#method.modify_token_properties8299    pub fn delete_token_properties(8300        collection: &NonfungibleHandle<T>,8301        sender: &T::CrossAccountId,8302        token_id: TokenId,8303        property_keys: impl Iterator<Item = PropertyKey>,8304        nesting_budget: &dyn Budget,8305    ) -> DispatchResult {8306        let is_token_create = false;8307        Self::modify_token_properties(8308            collection,8309            sender,8310            token_id,8311            property_keys.into_iter().map(|key| (key, None)),8312            is_token_create,8313            nesting_budget,8314        )8315    }8316    /// Remove single property from the token8317    ///8318    /// Calls [`delete_token_properties`] internally8319    ///8320    /// [`delete_token_properties`]: struct.Pallet.html#method.delete_token_properties8321    pub fn delete_token_property(8322        collection: &NonfungibleHandle<T>,8323        sender: &T::CrossAccountId,8324        token_id: TokenId,8325        property_key: PropertyKey,8326        nesting_budget: &dyn Budget,8327    ) -> DispatchResult {8328        Self::delete_token_properties(8329            collection,8330            sender,8331            token_id,8332            [property_key].into_iter(),8333            nesting_budget,8334        )8335    }8336    /// Add or edit properties for the collection8337    pub fn set_collection_properties(8338        collection: &NonfungibleHandle<T>,8339        sender: &T::CrossAccountId,8340        properties: Vec<Property>,8341    ) -> DispatchResult {8342        <PalletCommon<T>>::set_collection_properties(collection, sender, properties)8343    }8344    /// Remove properties from the collection8345    pub fn delete_collection_properties(8346        collection: &CollectionHandle<T>,8347        sender: &T::CrossAccountId,8348        property_keys: Vec<PropertyKey>,8349    ) -> DispatchResult {8350        <PalletCommon<8351            T,8352        >>::delete_collection_properties(collection, sender, property_keys)8353    }8354    /// Set property permissions for the token.8355    ///8356    /// Sender should be the owner or admin of token's collection.8357    pub fn set_token_property_permissions(8358        collection: &CollectionHandle<T>,8359        sender: &T::CrossAccountId,8360        property_permissions: Vec<PropertyKeyPermission>,8361    ) -> DispatchResult {8362        <PalletCommon<8363            T,8364        >>::set_token_property_permissions(collection, sender, property_permissions)8365    }8366    /// Set property permissions for the token with scope.8367    ///8368    /// Sender should be the owner or admin of token's collection.8369    pub fn set_scoped_token_property_permissions(8370        collection: &CollectionHandle<T>,8371        sender: &T::CrossAccountId,8372        scope: PropertyScope,8373        property_permissions: Vec<PropertyKeyPermission>,8374    ) -> DispatchResult {8375        <PalletCommon<8376            T,8377        >>::set_scoped_token_property_permissions(8378            collection,8379            sender,8380            scope,8381            property_permissions,8382        )8383    }8384    /// Set property permissions for the collection.8385    ///8386    /// Sender should be the owner or admin of the collection.8387    pub fn set_property_permission(8388        collection: &CollectionHandle<T>,8389        sender: &T::CrossAccountId,8390        permission: PropertyKeyPermission,8391    ) -> DispatchResult {8392        <PalletCommon<T>>::set_property_permission(collection, sender, permission)8393    }8394    /// Transfer NFT token from one account to another.8395    ///8396    /// `from` account stops being the owner and `to` account becomes the owner of the token.8397    /// If `to` is token than `to` becomes owner of the token and the token become nested.8398    /// Unnests token from previous parent if it was nested before.8399    /// Removes allowance for the token if there was any.8400    /// Throws if transfers aren't allowed for collection or if receiver reached token ownership limit.8401    ///8402    /// - `nesting_budget`: Limit for token nesting depth8403    pub fn transfer(8404        collection: &NonfungibleHandle<T>,8405        from: &T::CrossAccountId,8406        to: &T::CrossAccountId,8407        token: TokenId,8408        nesting_budget: &dyn Budget,8409    ) -> DispatchResult {8410        {8411            if !collection.limits.transfers_enabled() {8412                { return Err(<CommonError<T>>::TransferNotAllowed.into()) };8413            }8414        };8415        let token_data = <TokenData<T>>::get((collection.id, token))8416            .ok_or(<CommonError<T>>::TokenNotFound)?;8417        {8418            if !(&token_data.owner == from) {8419                { return Err(<CommonError<T>>::NoPermission.into()) };8420            }8421        };8422        if collection.permissions.access() == AccessMode::AllowList {8423            collection.check_allowlist(from)?;8424            collection.check_allowlist(to)?;8425        }8426        <PalletCommon<T>>::ensure_correct_receiver(to)?;8427        let balance_from = <AccountBalance<T>>::get((collection.id, from))8428            .checked_sub(1)8429            .ok_or(<CommonError<T>>::TokenValueTooLow)?;8430        let balance_to = if from != to {8431            let balance_to = <AccountBalance<T>>::get((collection.id, to))8432                .checked_add(1)8433                .ok_or(ArithmeticError::Overflow)?;8434            {8435                if !(balance_to < collection.limits.account_token_ownership_limit()) {8436                    { return Err(<CommonError<T>>::AccountTokenLimitExceeded.into()) };8437                }8438            };8439            Some(balance_to)8440        } else {8441            None8442        };8443        <PalletStructure<8444            T,8445        >>::nest_if_sent_to_token(8446            from.clone(),8447            to,8448            collection.id,8449            token,8450            nesting_budget,8451        )?;8452        <PalletStructure<T>>::unnest_if_nested(&token_data.owner, collection.id, token);8453        <TokenData<8454            T,8455        >>::insert(8456            (collection.id, token),8457            ItemData {8458                owner: to.clone(),8459                ..token_data8460            },8461        );8462        if let Some(balance_to) = balance_to {8463            if balance_from == 0 {8464                <AccountBalance<T>>::remove((collection.id, from));8465            } else {8466                <AccountBalance<T>>::insert((collection.id, from), balance_from);8467            }8468            <AccountBalance<T>>::insert((collection.id, to), balance_to);8469            <Owned<T>>::remove((collection.id, from, token));8470            <Owned<T>>::insert((collection.id, to, token), true);8471        }8472        Self::set_allowance_unchecked(collection, from, token, None, true);8473        <PalletEvm<8474            T,8475        >>::deposit_log(8476            ERC721Events::Transfer {8477                from: *from.as_eth(),8478                to: *to.as_eth(),8479                token_id: token.into(),8480            }8481                .to_log(collection_id_to_address(collection.id)),8482        );8483        <PalletCommon<8484            T,8485        >>::deposit_event(8486            CommonEvent::Transfer(collection.id, token, from.clone(), to.clone(), 1),8487        );8488        Ok(())8489    }8490    /// Batch operation to mint multiple NFT tokens.8491    ///8492    /// The sender should be the owner/admin of the collection or collection should be configured8493    /// to allow public minting.8494    /// Throws if amount of tokens reached it's limit for the collection or if caller reached8495    /// token ownership limit.8496    ///8497    /// - `data`: Contains list of token properties and users who will become the owners of the8498    ///   corresponging tokens.8499    /// - `nesting_budget`: Limit for token nesting depth8500    pub fn create_multiple_items(8501        collection: &NonfungibleHandle<T>,8502        sender: &T::CrossAccountId,8503        data: Vec<CreateItemData<T>>,8504        nesting_budget: &dyn Budget,8505    ) -> DispatchResult {8506        if !collection.is_owner_or_admin(sender) {8507            {8508                if !collection.permissions.mint_mode() {8509                    { return Err(<CommonError<T>>::PublicMintingNotAllowed.into()) };8510                }8511            };8512            collection.check_allowlist(sender)?;8513            for item in data.iter() {8514                collection.check_allowlist(&item.owner)?;8515            }8516        }8517        for data in data.iter() {8518            <PalletCommon<T>>::ensure_correct_receiver(&data.owner)?;8519        }8520        let first_token = <TokensMinted<T>>::get(collection.id);8521        let tokens_minted = first_token8522            .checked_add(data.len() as u32)8523            .ok_or(ArithmeticError::Overflow)?;8524        {8525            if !(tokens_minted <= collection.limits.token_limit()) {8526                { return Err(<CommonError<T>>::CollectionTokenLimitExceeded.into()) };8527            }8528        };8529        let mut balances = BTreeMap::new();8530        for data in &data {8531            let balance = balances8532                .entry(&data.owner)8533                .or_insert_with(|| <AccountBalance<8534                    T,8535                >>::get((collection.id, &data.owner)));8536            *balance = balance.checked_add(1).ok_or(ArithmeticError::Overflow)?;8537            {8538                if !(*balance <= collection.limits.account_token_ownership_limit()) {8539                    { return Err(<CommonError<T>>::AccountTokenLimitExceeded.into()) };8540                }8541            };8542        }8543        for (i, data) in data.iter().enumerate() {8544            let token = TokenId(first_token + i as u32 + 1);8545            <PalletStructure<8546                T,8547            >>::check_nesting(8548                sender.clone(),8549                &data.owner,8550                collection.id,8551                token,8552                nesting_budget,8553            )?;8554        }8555        with_transaction(|| {8556            for (i, data) in data.iter().enumerate() {8557                let token = first_token + i as u32 + 1;8558                <TokenData<8559                    T,8560                >>::insert(8561                    (collection.id, token),8562                    ItemData {8563                        owner: data.owner.clone(),8564                    },8565                );8566                <PalletStructure<8567                    T,8568                >>::nest_if_sent_to_token_unchecked(8569                    &data.owner,8570                    collection.id,8571                    TokenId(token),8572                );8573                if let Err(e)8574                    = Self::set_token_properties(8575                        collection,8576                        sender,8577                        TokenId(token),8578                        data.properties.clone().into_iter(),8579                        true,8580                        nesting_budget,8581                    ) {8582                    return TransactionOutcome::Rollback(Err(e));8583                }8584            }8585            TransactionOutcome::Commit(Ok(()))8586        })?;8587        <TokensMinted<T>>::insert(collection.id, tokens_minted);8588        for (account, balance) in balances {8589            <AccountBalance<T>>::insert((collection.id, account), balance);8590        }8591        for (i, data) in data.into_iter().enumerate() {8592            let token = first_token + i as u32 + 1;8593            <Owned<T>>::insert((collection.id, &data.owner, token), true);8594            <PalletEvm<8595                T,8596            >>::deposit_log(8597                ERC721Events::Transfer {8598                    from: H160::default(),8599                    to: *data.owner.as_eth(),8600                    token_id: token.into(),8601                }8602                    .to_log(collection_id_to_address(collection.id)),8603            );8604            <PalletCommon<8605                T,8606            >>::deposit_event(8607                CommonEvent::ItemCreated(8608                    collection.id,8609                    TokenId(token),8610                    data.owner.clone(),8611                    1,8612                ),8613            );8614        }8615        Ok(())8616    }8617    pub fn set_allowance_unchecked(8618        collection: &NonfungibleHandle<T>,8619        sender: &T::CrossAccountId,8620        token: TokenId,8621        spender: Option<&T::CrossAccountId>,8622        assume_implicit_eth: bool,8623    ) {8624        if let Some(spender) = spender {8625            let old_spender = <Allowance<T>>::get((collection.id, token));8626            <Allowance<T>>::insert((collection.id, token), spender);8627            <PalletEvm<8628                T,8629            >>::deposit_log(8630                ERC721Events::Approval {8631                    owner: *sender.as_eth(),8632                    approved: *spender.as_eth(),8633                    token_id: token.into(),8634                }8635                    .to_log(collection_id_to_address(collection.id)),8636            );8637            if old_spender.as_ref() != Some(spender) {8638                if let Some(old_owner) = old_spender {8639                    <PalletCommon<8640                        T,8641                    >>::deposit_event(8642                        CommonEvent::Approved(8643                            collection.id,8644                            token,8645                            sender.clone(),8646                            old_owner,8647                            0,8648                        ),8649                    );8650                }8651                <PalletCommon<8652                    T,8653                >>::deposit_event(8654                    CommonEvent::Approved(8655                        collection.id,8656                        token,8657                        sender.clone(),8658                        spender.clone(),8659                        1,8660                    ),8661                );8662            }8663        } else {8664            let old_spender = <Allowance<T>>::take((collection.id, token));8665            if !assume_implicit_eth {8666                <PalletEvm<8667                    T,8668                >>::deposit_log(8669                    ERC721Events::Approval {8670                        owner: *sender.as_eth(),8671                        approved: H160::default(),8672                        token_id: token.into(),8673                    }8674                        .to_log(collection_id_to_address(collection.id)),8675                );8676            }8677            if let Some(old_spender) = old_spender {8678                <PalletCommon<8679                    T,8680                >>::deposit_event(8681                    CommonEvent::Approved(8682                        collection.id,8683                        token,8684                        sender.clone(),8685                        old_spender,8686                        0,8687                    ),8688                );8689            }8690        }8691    }8692    /// Set allowance for the spender to `transfer` or `burn` sender's token.8693    ///8694    /// - `token`: Token the spender is allowed to `transfer` or `burn`.8695    pub fn set_allowance(8696        collection: &NonfungibleHandle<T>,8697        sender: &T::CrossAccountId,8698        token: TokenId,8699        spender: Option<&T::CrossAccountId>,8700    ) -> DispatchResult {8701        if collection.permissions.access() == AccessMode::AllowList {8702            collection.check_allowlist(sender)?;8703            if let Some(spender) = spender {8704                collection.check_allowlist(spender)?;8705            }8706        }8707        if let Some(spender) = spender {8708            <PalletCommon<T>>::ensure_correct_receiver(spender)?;8709        }8710        let token_data = <TokenData<T>>::get((collection.id, token))8711            .ok_or(<CommonError<T>>::TokenNotFound)?;8712        if &token_data.owner != sender {8713            {8714                if !collection.ignores_owned_amount(sender) {8715                    { return Err(<CommonError<T>>::CantApproveMoreThanOwned.into()) };8716                }8717            };8718        }8719        Self::set_allowance_unchecked(collection, sender, token, spender, false);8720        Ok(())8721    }8722    /// Checks allowance for the spender to use the token.8723    fn check_allowed(8724        collection: &NonfungibleHandle<T>,8725        spender: &T::CrossAccountId,8726        from: &T::CrossAccountId,8727        token: TokenId,8728        nesting_budget: &dyn Budget,8729    ) -> DispatchResult {8730        if spender.conv_eq(from) {8731            return Ok(());8732        }8733        if collection.permissions.access() == AccessMode::AllowList {8734            collection.check_allowlist(spender)?;8735        }8736        if collection.limits.owner_can_transfer()8737            && collection.is_owner_or_admin(spender)8738        {8739            return Ok(());8740        }8741        if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {8742            {8743                if !<PalletStructure<8744                    T,8745                >>::check_indirectly_owned(8746                    spender.clone(),8747                    source.0,8748                    source.1,8749                    None,8750                    nesting_budget,8751                )? {8752                    { return Err(<CommonError<T>>::ApprovedValueTooLow.into()) };8753                }8754            };8755            return Ok(());8756        }8757        if <Allowance<T>>::get((collection.id, token)).as_ref() == Some(spender) {8758            return Ok(());8759        }8760        {8761            if !collection.ignores_allowance(spender) {8762                { return Err(<CommonError<T>>::ApprovedValueTooLow.into()) };8763            }8764        };8765        Ok(())8766    }8767    /// Transfer NFT token from one account to another.8768    ///8769    /// Same as the [`transfer`] but spender doesn't needs to be the owner of the token.8770    /// The owner should set allowance for the spender to transfer token.8771    ///8772    /// [`transfer`]: struct.Pallet.html#method.transfer8773    pub fn transfer_from(8774        collection: &NonfungibleHandle<T>,8775        spender: &T::CrossAccountId,8776        from: &T::CrossAccountId,8777        to: &T::CrossAccountId,8778        token: TokenId,8779        nesting_budget: &dyn Budget,8780    ) -> DispatchResult {8781        Self::check_allowed(collection, spender, from, token, nesting_budget)?;8782        Self::transfer(collection, from, to, token, nesting_budget)8783    }8784    /// Burn NFT token for `from` account.8785    ///8786    /// Same as the [`burn`] but spender doesn't need to be an owner of the token. The owner should8787    /// set allowance for the spender to burn token.8788    ///8789    /// [`burn`]: struct.Pallet.html#method.burn8790    pub fn burn_from(8791        collection: &NonfungibleHandle<T>,8792        spender: &T::CrossAccountId,8793        from: &T::CrossAccountId,8794        token: TokenId,8795        nesting_budget: &dyn Budget,8796    ) -> DispatchResult {8797        Self::check_allowed(collection, spender, from, token, nesting_budget)?;8798        Self::burn(collection, from, token)8799    }8800    /// Check that `from` token could be nested in `under` token.8801    ///8802    pub fn check_nesting(8803        handle: &NonfungibleHandle<T>,8804        sender: T::CrossAccountId,8805        from: (CollectionId, TokenId),8806        under: TokenId,8807        nesting_budget: &dyn Budget,8808    ) -> DispatchResult {8809        let nesting = handle.permissions.nesting();8810        #[cfg(not(feature = "runtime-benchmarks"))]8811        let permissive = false;8812        if permissive {} else if nesting.token_owner8813            && <PalletStructure<8814                T,8815            >>::check_indirectly_owned(8816                sender.clone(),8817                handle.id,8818                under,8819                Some(from),8820                nesting_budget,8821            )?8822        {} else if nesting.collection_admin && handle.is_owner_or_admin(&sender)8823        {} else {8824            { return Err(<CommonError<T>>::UserIsNotAllowedToNest.into()) };8825        }8826        if let Some(whitelist) = &nesting.restricted {8827            {8828                if !whitelist.contains(&from.0) {8829                    {8830                        return Err(8831                            <CommonError<T>>::SourceCollectionIsNotAllowedToNest.into(),8832                        )8833                    };8834                }8835            };8836        }8837        Ok(())8838    }8839    fn nest(under: (CollectionId, TokenId), to_nest: (CollectionId, TokenId)) {8840        <TokenChildren<T>>::insert((under.0, under.1, (to_nest.0, to_nest.1)), true);8841    }8842    fn unnest(under: (CollectionId, TokenId), to_unnest: (CollectionId, TokenId)) {8843        <TokenChildren<T>>::remove((under.0, under.1, to_unnest));8844    }8845    fn collection_has_tokens(collection_id: CollectionId) -> bool {8846        <TokenData<T>>::iter_prefix((collection_id,)).next().is_some()8847    }8848    fn token_has_children(collection_id: CollectionId, token_id: TokenId) -> bool {8849        <TokenChildren<T>>::iter_prefix((collection_id, token_id)).next().is_some()8850    }8851    pub fn token_children_ids(8852        collection_id: CollectionId,8853        token_id: TokenId,8854    ) -> Vec<TokenChild> {8855        <TokenChildren<T>>::iter_prefix((collection_id, token_id))8856            .map(|((child_collection_id, child_id), _)| TokenChild {8857                collection: child_collection_id,8858                token: child_id,8859            })8860            .collect()8861    }8862    /// Mint single NFT token.8863    ///8864    /// Delegated to [`create_multiple_items`]8865    ///8866    /// [`create_multiple_items`]: struct.Pallet.html#method.create_multiple_items8867    pub fn create_item(8868        collection: &NonfungibleHandle<T>,8869        sender: &T::CrossAccountId,8870        data: CreateItemData<T>,8871        nesting_budget: &dyn Budget,8872    ) -> DispatchResult {8873        Self::create_multiple_items(8874            collection,8875            sender,8876            <[_]>::into_vec(#[rustc_box] ::alloc::boxed::Box::new([data])),8877            nesting_budget,8878        )8879    }8880}
modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -105,10 +105,14 @@
 
 /// @title A contract that allows you to work with collections.
 <<<<<<< HEAD
+<<<<<<< HEAD
 /// @dev the ERC-165 identifier for this interface is 0xb3152af3
 =======
 /// @dev the ERC-165 identifier for this interface is 0x674be726
 >>>>>>> feat: Add custum signature with unlimited nesting.
+=======
+/// @dev the ERC-165 identifier for this interface is 0x943ee094
+>>>>>>> fix: after rebase
 contract Collection is Dummy, ERC165 {
 	/// Set collection property.
 	///
@@ -126,9 +130,9 @@
 	/// Set collection properties.
 	///
 	/// @param properties Vector of properties key/value pair.
-	/// @dev EVM selector for this function is: 0x50b26b2a,
+	/// @dev EVM selector for this function is: 0xf90c1ce9,
 	///  or in textual repr: setCollectionProperties((string,bytes)[])
-	function setCollectionProperties(Tuple19[] memory properties) public {
+	function setCollectionProperties(Tuple21[] memory properties) public {
 		require(false, stub_error);
 		properties;
 		dummy = 0;
@@ -148,7 +152,7 @@
 	/// Delete collection properties.
 	///
 	/// @param keys Properties keys.
-	/// @dev EVM selector for this function is: 0xee206ee3,
+	/// @dev EVM selector for this function is: 0x56d4684a,
 	///  or in textual repr: deleteCollectionProperties(string[])
 	function deleteCollectionProperties(string[] memory keys) public {
 		require(false, stub_error);
@@ -175,13 +179,13 @@
 	///
 	/// @param keys Properties keys. Empty keys for all propertyes.
 	/// @return Vector of properties key/value pairs.
-	/// @dev EVM selector for this function is: 0x285fb8e6,
+	/// @dev EVM selector for this function is: 0x5cad7311,
 	///  or in textual repr: collectionProperties(string[])
-	function collectionProperties(string[] memory keys) public view returns (Tuple19[] memory) {
+	function collectionProperties(string[] memory keys) public view returns (Tuple21[] memory) {
 		require(false, stub_error);
 		keys;
 		dummy;
-		return new Tuple19[](0);
+		return new Tuple21[](0);
 	}
 
 	/// Set the sponsor of the collection.
@@ -489,7 +493,7 @@
 
 	/// Get collection owner.
 	///
-	/// @return Tuble with sponsor address and his substrate mirror.
+	/// @return Tuple with sponsor address and his substrate mirror.
 	/// If address is canonical then substrate mirror is zero and vice versa.
 	/// @dev EVM selector for this function is: 0xdf727d3b,
 	///  or in textual repr: collectionOwner()
@@ -551,6 +555,7 @@
 }
 
 <<<<<<< HEAD
+<<<<<<< HEAD
 /// @dev anonymous struct
 struct Tuple19 {
 	address field_0;
@@ -602,6 +607,14 @@
 
 =======
 >>>>>>> feat: Add custum signature with unlimited nesting.
+=======
+/// @dev anonymous struct
+struct Tuple21 {
+	string field_0;
+	bytes field_1;
+}
+
+>>>>>>> fix: after rebase
 /// @title ERC721 Token that can be irreversibly burned (destroyed).
 /// @dev the ERC-165 identifier for this interface is 0x42966c68
 contract ERC721Burnable is Dummy, ERC165 {
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -71,10 +71,14 @@
 
 /// @title A contract that allows you to work with collections.
 <<<<<<< HEAD
+<<<<<<< HEAD
 /// @dev the ERC-165 identifier for this interface is 0xb3152af3
 =======
 /// @dev the ERC-165 identifier for this interface is 0x674be726
 >>>>>>> feat: Add custum signature with unlimited nesting.
+=======
+/// @dev the ERC-165 identifier for this interface is 0x943ee094
+>>>>>>> fix: after rebase
 interface Collection is Dummy, ERC165 {
 	/// Set collection property.
 	///
@@ -87,9 +91,9 @@
 	/// Set collection properties.
 	///
 	/// @param properties Vector of properties key/value pair.
-	/// @dev EVM selector for this function is: 0x50b26b2a,
+	/// @dev EVM selector for this function is: 0xf90c1ce9,
 	///  or in textual repr: setCollectionProperties((string,bytes)[])
-	function setCollectionProperties(Tuple19[] memory properties) external;
+	function setCollectionProperties(Tuple21[] memory properties) external;
 
 	/// Delete collection property.
 	///
@@ -101,7 +105,7 @@
 	/// Delete collection properties.
 	///
 	/// @param keys Properties keys.
-	/// @dev EVM selector for this function is: 0xee206ee3,
+	/// @dev EVM selector for this function is: 0x56d4684a,
 	///  or in textual repr: deleteCollectionProperties(string[])
 	function deleteCollectionProperties(string[] memory keys) external;
 
@@ -119,9 +123,9 @@
 	///
 	/// @param keys Properties keys. Empty keys for all propertyes.
 	/// @return Vector of properties key/value pairs.
-	/// @dev EVM selector for this function is: 0x285fb8e6,
+	/// @dev EVM selector for this function is: 0x5cad7311,
 	///  or in textual repr: collectionProperties(string[])
-	function collectionProperties(string[] memory keys) external view returns (Tuple19[] memory);
+	function collectionProperties(string[] memory keys) external view returns (Tuple21[] memory);
 
 	/// Set the sponsor of the collection.
 	///
@@ -310,7 +314,7 @@
 
 	/// Get collection owner.
 	///
-	/// @return Tuble with sponsor address and his substrate mirror.
+	/// @return Tuple with sponsor address and his substrate mirror.
 	/// If address is canonical then substrate mirror is zero and vice versa.
 	/// @dev EVM selector for this function is: 0xdf727d3b,
 	///  or in textual repr: collectionOwner()
@@ -348,6 +352,7 @@
 	uint256 field_1;
 }
 
+<<<<<<< HEAD
 /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 /// @dev See https://eips.ethereum.org/EIPS/eip-721
 /// @dev the ERC-165 identifier for this interface is 0x5b5e139f
@@ -380,6 +385,14 @@
 
 =======
 >>>>>>> feat: Add custum signature with unlimited nesting.
+=======
+/// @dev anonymous struct
+struct Tuple21 {
+	string field_0;
+	bytes field_1;
+}
+
+>>>>>>> fix: after rebase
 /// @title ERC721 Token that can be irreversibly burned (destroyed).
 /// @dev the ERC-165 identifier for this interface is 0x42966c68
 interface ERC721Burnable is Dummy, ERC165 {
modifiedtests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth
--- a/tests/src/eth/nonFungibleAbi.json
+++ b/tests/src/eth/nonFungibleAbi.json
@@ -268,6 +268,9 @@
   },
   {
 <<<<<<< HEAD
+<<<<<<< HEAD
+=======
+>>>>>>> fix: after rebase
     "inputs": [
       { "internalType": "string[]", "name": "keys", "type": "string[]" }
     ],
@@ -278,16 +281,23 @@
           { "internalType": "string", "name": "field_0", "type": "string" },
           { "internalType": "bytes", "name": "field_1", "type": "bytes" }
         ],
+<<<<<<< HEAD
         "internalType": "struct Tuple19[]",
+=======
+        "internalType": "struct Tuple21[]",
+>>>>>>> fix: after rebase
         "name": "",
         "type": "tuple[]"
       }
     ],
+<<<<<<< HEAD
 =======
     "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
     "name": "collectionProperty",
     "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],
 >>>>>>> feat: Add custum signature with unlimited nesting.
+=======
+>>>>>>> fix: after rebase
     "stateMutability": "view",
     "type": "function"
   },
@@ -339,6 +349,9 @@
   },
   {
 <<<<<<< HEAD
+<<<<<<< HEAD
+=======
+>>>>>>> fix: after rebase
     "inputs": [
       { "internalType": "string[]", "name": "keys", "type": "string[]" }
     ],
@@ -348,8 +361,11 @@
     "type": "function"
   },
   {
+<<<<<<< HEAD
 =======
 >>>>>>> feat: Add custum signature with unlimited nesting.
+=======
+>>>>>>> fix: after rebase
     "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],
     "name": "deleteCollectionProperty",
     "outputs": [],
@@ -677,11 +693,15 @@
   {
     "inputs": [
 <<<<<<< HEAD
+<<<<<<< HEAD
+=======
+>>>>>>> fix: after rebase
       {
         "components": [
           { "internalType": "string", "name": "field_0", "type": "string" },
           { "internalType": "bytes", "name": "field_1", "type": "bytes" }
         ],
+<<<<<<< HEAD
         "internalType": "struct Tuple19[]",
         "name": "properties",
         "type": "tuple[]"
@@ -690,6 +710,12 @@
       { "internalType": "string", "name": "key", "type": "string" },
       { "internalType": "bytes", "name": "value", "type": "bytes" }
 >>>>>>> feat: Add custum signature with unlimited nesting.
+=======
+        "internalType": "struct Tuple21[]",
+        "name": "properties",
+        "type": "tuple[]"
+      }
+>>>>>>> fix: after rebase
     ],
     "name": "setCollectionProperties",
     "outputs": [],