difftreelog
refactor return CrossAccountId in backing storages
in: master
14 files changed
client/rpc/src/lib.rsdiffbeforeafterboth--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -75,9 +75,17 @@
) -> Result<String>;
#[rpc(name = "nft_adminlist")]
- fn adminlist(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<Vec<AccountId>>;
+ fn adminlist(
+ &self,
+ collection: CollectionId,
+ at: Option<BlockHash>,
+ ) -> Result<Vec<CrossAccountId>>;
#[rpc(name = "nft_allowlist")]
- fn allowlist(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<Vec<AccountId>>;
+ fn allowlist(
+ &self,
+ collection: CollectionId,
+ at: Option<BlockHash>,
+ ) -> Result<Vec<CrossAccountId>>;
#[rpc(name = "nft_lastTokenId")]
fn last_token_id(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<TokenId>;
}
@@ -150,7 +158,7 @@
pass_method!(balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> String => |v| v.to_string());
pass_method!(allowance(collection: CollectionId, sender: CrossAccountId, spender: CrossAccountId, token: TokenId) -> String => |v| v.to_string());
- pass_method!(adminlist(collection: CollectionId) -> Vec<AccountId>);
- pass_method!(allowlist(collection: CollectionId) -> Vec<AccountId>);
+ pass_method!(adminlist(collection: CollectionId) -> Vec<CrossAccountId>);
+ pass_method!(allowlist(collection: CollectionId) -> Vec<CrossAccountId>);
pass_method!(last_token_id(collection: CollectionId) -> TokenId);
}
pallets/common/src/account.rsdiffbeforeafterboth--- a/pallets/common/src/account.rs
+++ b/pallets/common/src/account.rs
@@ -19,6 +19,8 @@
fn from_sub(account: AccountId) -> Self;
fn from_eth(account: H160) -> Self;
+
+ fn conv_eq(&self, other: &Self) -> bool;
}
#[derive(Encode, Decode, Serialize, Deserialize, TypeInfo)]
@@ -28,7 +30,7 @@
Ethereum(H160),
}
-#[derive(Eq)]
+#[derive(PartialEq, Eq)]
pub struct BasicCrossAccountId<T: Config> {
/// If true - then ethereum is canonical encoding
from_ethereum: bool,
@@ -77,18 +79,6 @@
}
}
-impl<T: Config> PartialEq for BasicCrossAccountId<T> {
- fn eq(&self, other: &Self) -> bool {
- if self.from_ethereum == other.from_ethereum {
- self.substrate == other.substrate && self.ethereum == other.ethereum
- } else if self.from_ethereum {
- // ethereum is canonical encoding, but we need to compare derived address
- self.substrate == other.substrate
- } else {
- self.ethereum == other.ethereum
- }
- }
-}
impl<T: Config> Clone for BasicCrossAccountId<T> {
fn clone(&self) -> Self {
Self {
@@ -158,6 +148,16 @@
from_ethereum: true,
}
}
+ fn conv_eq(&self, other: &Self) -> bool {
+ if self.from_ethereum == other.from_ethereum {
+ self.substrate == other.substrate && self.ethereum == other.ethereum
+ } else if self.from_ethereum {
+ // ethereum is canonical encoding, but we need to compare derived address
+ self.substrate == other.substrate
+ } else {
+ self.ethereum == other.ethereum
+ }
+ }
}
impl<T: Config> From<BasicCrossAccountIdRepr<T::AccountId>> for BasicCrossAccountId<T> {
fn from(repr: BasicCrossAccountIdRepr<T::AccountId>) -> Self {
pallets/common/src/lib.rsdiffbeforeafterboth1#![cfg_attr(not(feature = "std"), no_std)]23use core::ops::{Deref, DerefMut};4use sp_std::vec::Vec;5use account::CrossAccountId;6use frame_support::{7 dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo},8 ensure, fail,9 traits::{Imbalance, Get, Currency},10};11use nft_data_structs::{12 COLLECTION_NUMBER_LIMIT, Collection, CollectionId, CreateItemData, ExistenceRequirement,13 MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_COLLECTION_NAME_LENGTH, MAX_TOKEN_PREFIX_LENGTH,14 MetaUpdatePermission, Pays, PostDispatchInfo, TokenId, Weight, WithdrawReasons,15};16pub use pallet::*;17use sp_core::H160;18use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};19pub mod account;20#[cfg(feature = "runtime-benchmarks")]21pub mod benchmarking;22pub mod erc;23pub mod eth;2425#[must_use = "Should call submit_logs or save, otherwise some data will be lost for evm side"]26pub struct CollectionHandle<T: Config> {27 pub id: CollectionId,28 collection: Collection<T>,29 pub recorder: pallet_evm_coder_substrate::SubstrateRecorder<T>,30}31impl<T: Config> CollectionHandle<T> {32 pub fn new_with_gas_limit(id: CollectionId, gas_limit: u64) -> Option<Self> {33 <CollectionById<T>>::get(id).map(|collection| Self {34 id,35 collection,36 recorder: pallet_evm_coder_substrate::SubstrateRecorder::new(37 eth::collection_id_to_address(id),38 gas_limit,39 ),40 })41 }42 pub fn new(id: CollectionId) -> Option<Self> {43 Self::new_with_gas_limit(id, u64::MAX)44 }45 pub fn try_get(id: CollectionId) -> Result<Self, DispatchError> {46 Ok(Self::new(id).ok_or_else(|| <Error<T>>::CollectionNotFound)?)47 }48 pub fn log(&self, log: impl evm_coder::ToLog) -> DispatchResult {49 self.recorder.log_sub(log)50 }51 pub fn log_infallible(&self, log: impl evm_coder::ToLog) {52 self.recorder.log_infallible(log)53 }54 #[allow(dead_code)]55 fn consume_gas(&self, gas: u64) -> DispatchResult {56 self.recorder.consume_gas_sub(gas)57 }58 pub fn consume_sload(&self) -> DispatchResult {59 self.recorder.consume_sload_sub()60 }61 pub fn consume_sstores(&self, amount: usize) -> DispatchResult {62 self.recorder.consume_sstores_sub(amount)63 }64 pub fn consume_sstore(&self) -> DispatchResult {65 self.recorder.consume_sstore_sub()66 }67 pub fn consume_log(&self, topics: usize, data: usize) -> DispatchResult {68 self.recorder.consume_log_sub(topics, data)69 }70 pub fn submit_logs(self) -> DispatchResult {71 self.recorder.submit_logs()72 }73 pub fn save(self) -> DispatchResult {74 self.recorder.submit_logs()?;75 <CollectionById<T>>::insert(self.id, self.collection);76 Ok(())77 }78}79impl<T: Config> Deref for CollectionHandle<T> {80 type Target = Collection<T>;8182 fn deref(&self) -> &Self::Target {83 &self.collection84 }85}8687impl<T: Config> DerefMut for CollectionHandle<T> {88 fn deref_mut(&mut self) -> &mut Self::Target {89 &mut self.collection90 }91}9293impl<T: Config> CollectionHandle<T> {94 pub fn check_is_owner(&self, subject: &T::CrossAccountId) -> DispatchResult {95 ensure!(*subject.as_sub() == self.owner, <Error<T>>::NoPermission);96 Ok(())97 }98 pub fn is_owner_or_admin(&self, subject: &T::CrossAccountId) -> Result<bool, DispatchError> {99 self.consume_sload()?;100101 Ok(*subject.as_sub() == self.owner || <IsAdmin<T>>::get((self.id, subject.as_sub())))102 }103 pub fn check_is_owner_or_admin(&self, subject: &T::CrossAccountId) -> DispatchResult {104 ensure!(self.is_owner_or_admin(subject)?, <Error<T>>::NoPermission);105 Ok(())106 }107 pub fn ignores_allowance(&self, user: &T::CrossAccountId) -> Result<bool, DispatchError> {108 Ok(self.limits.owner_can_transfer() && self.is_owner_or_admin(user)?)109 }110 pub fn ignores_owned_amount(&self, user: &T::CrossAccountId) -> Result<bool, DispatchError> {111 Ok(self.limits.owner_can_transfer() && self.is_owner_or_admin(user)?)112 }113 pub fn check_allowlist(&self, user: &T::CrossAccountId) -> DispatchResult {114 self.consume_sload()?;115116 ensure!(117 <Allowlist<T>>::get((self.id, user.as_sub())),118 <Error<T>>::AddressNotInAllowlist119 );120 Ok(())121 }122123 pub fn check_can_update_meta(124 &self,125 subject: &T::CrossAccountId,126 item_owner: &T::CrossAccountId,127 ) -> DispatchResult {128 match self.meta_update_permission {129 MetaUpdatePermission::ItemOwner => {130 ensure!(subject == item_owner, <Error<T>>::NoPermission);131 Ok(())132 }133 MetaUpdatePermission::Admin => self.check_is_owner_or_admin(subject),134 MetaUpdatePermission::None => fail!(<Error<T>>::NoPermission),135 }136 }137}138139#[frame_support::pallet]140pub mod pallet {141 use super::*;142 use frame_support::{pallet_prelude::*};143 use frame_support::{Blake2_128Concat, storage::Key};144 use account::{EvmBackwardsAddressMapping, CrossAccountId};145 use frame_support::traits::Currency;146 use nft_data_structs::TokenId;147 use scale_info::TypeInfo;148149 #[pallet::config]150 pub trait Config: frame_system::Config + pallet_evm_coder_substrate::Config + TypeInfo {151 type Event: IsType<<Self as frame_system::Config>::Event> + From<Event<Self>>;152153 type CrossAccountId: CrossAccountId<Self::AccountId>;154155 type EvmAddressMapping: pallet_evm::AddressMapping<Self::AccountId>;156 type EvmBackwardsAddressMapping: EvmBackwardsAddressMapping<Self::AccountId>;157158 type Currency: Currency<Self::AccountId>;159 type CollectionCreationPrice: Get<160 <<Self as Config>::Currency as Currency<Self::AccountId>>::Balance,161 >;162 type TreasuryAccountId: Get<Self::AccountId>;163 }164165 #[pallet::pallet]166 #[pallet::generate_store(pub(super) trait Store)]167 pub struct Pallet<T>(_);168169 #[pallet::event]170 #[pallet::generate_deposit(pub fn deposit_event)]171 pub enum Event<T: Config> {172 /// New collection was created173 ///174 /// # Arguments175 ///176 /// * collection_id: Globally unique identifier of newly created collection.177 ///178 /// * mode: [CollectionMode] converted into u8.179 ///180 /// * account_id: Collection owner.181 CollectionCreated(CollectionId, u8, T::AccountId),182183 /// New item was created.184 ///185 /// # Arguments186 ///187 /// * collection_id: Id of the collection where item was created.188 ///189 /// * item_id: Id of an item. Unique within the collection.190 ///191 /// * recipient: Owner of newly created item192 ///193 /// * amount: Always 1 for NFT194 ItemCreated(CollectionId, TokenId, T::CrossAccountId, u128),195196 /// Collection item was burned.197 ///198 /// # Arguments199 ///200 /// * collection_id.201 ///202 /// * item_id: Identifier of burned NFT.203 ///204 /// * owner: which user has destroyed its tokens205 ///206 /// * amount: Always 1 for NFT207 ItemDestroyed(CollectionId, TokenId, T::CrossAccountId, u128),208209 /// Item was transferred210 ///211 /// * collection_id: Id of collection to which item is belong212 ///213 /// * item_id: Id of an item214 ///215 /// * sender: Original owner of item216 ///217 /// * recipient: New owner of item218 ///219 /// * amount: Always 1 for NFT220 Transfer(221 CollectionId,222 TokenId,223 T::CrossAccountId,224 T::CrossAccountId,225 u128,226 ),227228 /// * collection_id229 ///230 /// * item_id231 ///232 /// * sender233 ///234 /// * spender235 ///236 /// * amount237 Approved(238 CollectionId,239 TokenId,240 T::CrossAccountId,241 T::CrossAccountId,242 u128,243 ),244 }245246 #[pallet::error]247 pub enum Error<T> {248 /// This collection does not exist.249 CollectionNotFound,250 /// Sender parameter and item owner must be equal.251 MustBeTokenOwner,252 /// No permission to perform action253 NoPermission,254 /// Collection is not in mint mode.255 PublicMintingNotAllowed,256 /// Address is not in white list.257 AddressNotInAllowlist,258259 /// Collection name can not be longer than 63 char.260 CollectionNameLimitExceeded,261 /// Collection description can not be longer than 255 char.262 CollectionDescriptionLimitExceeded,263 /// Token prefix can not be longer than 15 char.264 CollectionTokenPrefixLimitExceeded,265 /// Total collections bound exceeded.266 TotalCollectionsLimitExceeded,267 /// variable_data exceeded data limit.268 TokenVariableDataLimitExceeded,269270 /// Collection settings not allowing items transferring271 TransferNotAllowed,272 /// Account token limit exceeded per collection273 AccountTokenLimitExceeded,274 /// Collection token limit exceeded275 CollectionTokenLimitExceeded,276 /// Metadata flag frozen277 MetadataFlagFrozen,278279 /// Item not exists.280 TokenNotFound,281 /// Item balance not enough.282 TokenValueTooLow,283 /// Requested value more than approved.284 TokenValueNotEnough,285 /// Tried to approve more than owned286 CantApproveMoreThanOwned,287288 /// Can't transfer tokens to ethereum zero address289 AddressIsZero,290 /// Target collection doesn't supports this operation291 UnsupportedOperation,292 }293294 #[pallet::storage]295 pub type CreatedCollectionCount<T> = StorageValue<Value = CollectionId, QueryKind = ValueQuery>;296 #[pallet::storage]297 pub type DestroyedCollectionCount<T> =298 StorageValue<Value = CollectionId, QueryKind = ValueQuery>;299300 /// Collection info301 #[pallet::storage]302 pub type CollectionById<T> = StorageMap<303 Hasher = Blake2_128Concat,304 Key = CollectionId,305 Value = Collection<T>,306 QueryKind = OptionQuery,307 >;308309 /// List of collection admins310 #[pallet::storage]311 pub type IsAdmin<T: Config> = StorageNMap<312 Key = (313 Key<Blake2_128Concat, CollectionId>,314 Key<Blake2_128Concat, T::AccountId>,315 ),316 Value = bool,317 QueryKind = ValueQuery,318 >;319320 /// Allowlisted collection users321 #[pallet::storage]322 pub type Allowlist<T: Config> = StorageNMap<323 Key = (324 Key<Blake2_128Concat, CollectionId>,325 Key<Blake2_128Concat, T::AccountId>,326 ),327 Value = bool,328 QueryKind = ValueQuery,329 >;330}331332impl<T: Config> Pallet<T> {333 /// Ethereum receiver 0x0000000000000000000000000000000000000000 is reserved, and shouldn't own tokens334 pub fn ensure_correct_receiver(receiver: &T::CrossAccountId) -> DispatchResult {335 ensure!(336 &T::CrossAccountId::from_eth(H160([0; 20])) != receiver,337 <Error<T>>::AddressIsZero338 );339 Ok(())340 }341}342343impl<T: Config> Pallet<T> {344 pub fn init_collection(data: Collection<T>) -> Result<CollectionId, DispatchError> {345 {346 ensure!(347 data.name.len() <= MAX_COLLECTION_NAME_LENGTH,348 Error::<T>::CollectionNameLimitExceeded349 );350 ensure!(351 data.description.len() <= MAX_COLLECTION_DESCRIPTION_LENGTH,352 Error::<T>::CollectionDescriptionLimitExceeded353 );354 ensure!(355 data.token_prefix.len() <= MAX_TOKEN_PREFIX_LENGTH,356 Error::<T>::CollectionTokenPrefixLimitExceeded357 );358 }359360 let created_count = <CreatedCollectionCount<T>>::get()361 .0362 .checked_add(1)363 .ok_or(ArithmeticError::Overflow)?;364 let destroyed_count = <DestroyedCollectionCount<T>>::get().0;365 let id = CollectionId(created_count);366367 // bound Total number of collections368 ensure!(369 created_count - destroyed_count < COLLECTION_NUMBER_LIMIT,370 <Error<T>>::TotalCollectionsLimitExceeded371 );372373 // =========374375 // Take a (non-refundable) deposit of collection creation376 {377 let mut imbalance =378 <<<T as Config>::Currency as Currency<T::AccountId>>::PositiveImbalance>::zero();379 imbalance.subsume(380 <<T as Config>::Currency as Currency<T::AccountId>>::deposit_creating(381 &T::TreasuryAccountId::get(),382 T::CollectionCreationPrice::get(),383 ),384 );385 <T as Config>::Currency::settle(386 &data.owner,387 imbalance,388 WithdrawReasons::TRANSFER,389 ExistenceRequirement::KeepAlive,390 )391 .map_err(|_| Error::<T>::NoPermission)?;392 }393394 <CreatedCollectionCount<T>>::put(created_count);395 <Pallet<T>>::deposit_event(Event::CollectionCreated(396 id,397 data.mode.id(),398 data.owner.clone(),399 ));400 <CollectionById<T>>::insert(id, data);401 Ok(id)402 }403404 pub fn destroy_collection(405 collection: CollectionHandle<T>,406 sender: &T::CrossAccountId,407 ) -> DispatchResult {408 ensure!(409 collection.limits.owner_can_destroy(),410 <Error<T>>::NoPermission,411 );412 collection.check_is_owner(&sender)?;413414 let destroyed_collections = <DestroyedCollectionCount<T>>::get()415 .0416 .checked_add(1)417 .ok_or(ArithmeticError::Overflow)?;418419 // =========420421 <DestroyedCollectionCount<T>>::put(destroyed_collections);422 <CollectionById<T>>::remove(collection.id);423 <IsAdmin<T>>::remove_prefix((collection.id,), None);424 <Allowlist<T>>::remove_prefix((collection.id,), None);425 Ok(())426 }427428 pub fn toggle_allowlist(429 collection: &CollectionHandle<T>,430 sender: &T::CrossAccountId,431 user: &T::CrossAccountId,432 allowed: bool,433 ) -> DispatchResult {434 collection.check_is_owner_or_admin(&sender)?;435436 // =========437438 if allowed {439 <Allowlist<T>>::insert((collection.id, user.as_sub()), true);440 } else {441 <Allowlist<T>>::remove((collection.id, user.as_sub()));442 }443444 Ok(())445 }446}447448#[macro_export]449macro_rules! unsupported {450 () => {451 Err(<Error<T>>::UnsupportedOperation.into())452 };453}454455/// Worst cases456pub trait CommonWeightInfo {457 fn create_item() -> Weight;458 fn create_multiple_items(amount: u32) -> Weight;459 fn burn_item() -> Weight;460 fn transfer() -> Weight;461 fn approve() -> Weight;462 fn transfer_from() -> Weight;463 fn burn_from() -> Weight;464 fn set_variable_metadata(bytes: u32) -> Weight;465}466467pub trait CommonCollectionOperations<T: Config> {468 fn create_item(469 &self,470 sender: T::CrossAccountId,471 to: T::CrossAccountId,472 data: CreateItemData,473 ) -> DispatchResultWithPostInfo;474 fn create_multiple_items(475 &self,476 sender: T::CrossAccountId,477 to: T::CrossAccountId,478 data: Vec<CreateItemData>,479 ) -> DispatchResultWithPostInfo;480 fn burn_item(481 &self,482 sender: T::CrossAccountId,483 token: TokenId,484 amount: u128,485 ) -> DispatchResultWithPostInfo;486487 fn transfer(488 &self,489 sender: T::CrossAccountId,490 to: T::CrossAccountId,491 token: TokenId,492 amount: u128,493 ) -> DispatchResultWithPostInfo;494 fn approve(495 &self,496 sender: T::CrossAccountId,497 spender: T::CrossAccountId,498 token: TokenId,499 amount: u128,500 ) -> DispatchResultWithPostInfo;501 fn transfer_from(502 &self,503 sender: T::CrossAccountId,504 from: T::CrossAccountId,505 to: T::CrossAccountId,506 token: TokenId,507 amount: u128,508 ) -> DispatchResultWithPostInfo;509 fn burn_from(510 &self,511 sender: T::CrossAccountId,512 from: T::CrossAccountId,513 token: TokenId,514 amount: u128,515 ) -> DispatchResultWithPostInfo;516517 fn set_variable_metadata(518 &self,519 sender: T::CrossAccountId,520 token: TokenId,521 data: Vec<u8>,522 ) -> DispatchResultWithPostInfo;523524 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId>;525 fn token_exists(&self, token: TokenId) -> bool;526 fn last_token_id(&self) -> TokenId;527528 fn token_owner(&self, token: TokenId) -> T::CrossAccountId;529 fn const_metadata(&self, token: TokenId) -> Vec<u8>;530 fn variable_metadata(&self, token: TokenId) -> Vec<u8>;531532 /// How many tokens collection contains (Applicable to nonfungible/refungible)533 fn collection_tokens(&self) -> u32;534 /// Amount of different tokens account has (Applicable to nonfungible/refungible)535 fn account_balance(&self, account: T::CrossAccountId) -> u32;536 /// Amount of specific token account have (Applicable to fungible/refungible)537 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128;538 fn allowance(539 &self,540 sender: T::CrossAccountId,541 spender: T::CrossAccountId,542 token: TokenId,543 ) -> u128;544}545546// Flexible enough for implementing CommonCollectionOperations547pub fn with_weight(res: DispatchResult, weight: Weight) -> DispatchResultWithPostInfo {548 let post_info = PostDispatchInfo {549 actual_weight: Some(weight),550 pays_fee: Pays::Yes,551 };552 match res {553 Ok(()) => Ok(post_info),554 Err(error) => Err(DispatchErrorWithPostInfo { post_info, error }),555 }556}1#![cfg_attr(not(feature = "std"), no_std)]23use core::ops::{Deref, DerefMut};4use sp_std::vec::Vec;5use account::CrossAccountId;6use frame_support::{7 dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo},8 ensure, fail,9 traits::{Imbalance, Get, Currency},10};11use nft_data_structs::{12 COLLECTION_NUMBER_LIMIT, Collection, CollectionId, CreateItemData, ExistenceRequirement,13 MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_COLLECTION_NAME_LENGTH, MAX_TOKEN_PREFIX_LENGTH,14 MetaUpdatePermission, Pays, PostDispatchInfo, TokenId, Weight, WithdrawReasons,15};16pub use pallet::*;17use sp_core::H160;18use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};19pub mod account;20#[cfg(feature = "runtime-benchmarks")]21pub mod benchmarking;22pub mod erc;23pub mod eth;2425#[must_use = "Should call submit_logs or save, otherwise some data will be lost for evm side"]26pub struct CollectionHandle<T: Config> {27 pub id: CollectionId,28 collection: Collection<T>,29 pub recorder: pallet_evm_coder_substrate::SubstrateRecorder<T>,30}31impl<T: Config> CollectionHandle<T> {32 pub fn new_with_gas_limit(id: CollectionId, gas_limit: u64) -> Option<Self> {33 <CollectionById<T>>::get(id).map(|collection| Self {34 id,35 collection,36 recorder: pallet_evm_coder_substrate::SubstrateRecorder::new(37 eth::collection_id_to_address(id),38 gas_limit,39 ),40 })41 }42 pub fn new(id: CollectionId) -> Option<Self> {43 Self::new_with_gas_limit(id, u64::MAX)44 }45 pub fn try_get(id: CollectionId) -> Result<Self, DispatchError> {46 Ok(Self::new(id).ok_or_else(|| <Error<T>>::CollectionNotFound)?)47 }48 pub fn log(&self, log: impl evm_coder::ToLog) -> DispatchResult {49 self.recorder.log_sub(log)50 }51 pub fn log_infallible(&self, log: impl evm_coder::ToLog) {52 self.recorder.log_infallible(log)53 }54 #[allow(dead_code)]55 fn consume_gas(&self, gas: u64) -> DispatchResult {56 self.recorder.consume_gas_sub(gas)57 }58 pub fn consume_sload(&self) -> DispatchResult {59 self.recorder.consume_sload_sub()60 }61 pub fn consume_sstores(&self, amount: usize) -> DispatchResult {62 self.recorder.consume_sstores_sub(amount)63 }64 pub fn consume_sstore(&self) -> DispatchResult {65 self.recorder.consume_sstore_sub()66 }67 pub fn consume_log(&self, topics: usize, data: usize) -> DispatchResult {68 self.recorder.consume_log_sub(topics, data)69 }70 pub fn submit_logs(self) -> DispatchResult {71 self.recorder.submit_logs()72 }73 pub fn save(self) -> DispatchResult {74 self.recorder.submit_logs()?;75 <CollectionById<T>>::insert(self.id, self.collection);76 Ok(())77 }78}79impl<T: Config> Deref for CollectionHandle<T> {80 type Target = Collection<T>;8182 fn deref(&self) -> &Self::Target {83 &self.collection84 }85}8687impl<T: Config> DerefMut for CollectionHandle<T> {88 fn deref_mut(&mut self) -> &mut Self::Target {89 &mut self.collection90 }91}9293impl<T: Config> CollectionHandle<T> {94 pub fn check_is_owner(&self, subject: &T::CrossAccountId) -> DispatchResult {95 ensure!(*subject.as_sub() == self.owner, <Error<T>>::NoPermission);96 Ok(())97 }98 pub fn is_owner_or_admin(&self, subject: &T::CrossAccountId) -> Result<bool, DispatchError> {99 self.consume_sload()?;100101 Ok(*subject.as_sub() == self.owner || <IsAdmin<T>>::get((self.id, subject)))102 }103 pub fn check_is_owner_or_admin(&self, subject: &T::CrossAccountId) -> DispatchResult {104 ensure!(self.is_owner_or_admin(subject)?, <Error<T>>::NoPermission);105 Ok(())106 }107 pub fn ignores_allowance(&self, user: &T::CrossAccountId) -> Result<bool, DispatchError> {108 Ok(self.limits.owner_can_transfer() && self.is_owner_or_admin(user)?)109 }110 pub fn ignores_owned_amount(&self, user: &T::CrossAccountId) -> Result<bool, DispatchError> {111 Ok(self.limits.owner_can_transfer() && self.is_owner_or_admin(user)?)112 }113 pub fn check_allowlist(&self, user: &T::CrossAccountId) -> DispatchResult {114 self.consume_sload()?;115116 ensure!(117 <Allowlist<T>>::get((self.id, user)),118 <Error<T>>::AddressNotInAllowlist119 );120 Ok(())121 }122123 pub fn check_can_update_meta(124 &self,125 subject: &T::CrossAccountId,126 item_owner: &T::CrossAccountId,127 ) -> DispatchResult {128 match self.meta_update_permission {129 MetaUpdatePermission::ItemOwner => {130 ensure!(subject == item_owner, <Error<T>>::NoPermission);131 Ok(())132 }133 MetaUpdatePermission::Admin => self.check_is_owner_or_admin(subject),134 MetaUpdatePermission::None => fail!(<Error<T>>::NoPermission),135 }136 }137}138139#[frame_support::pallet]140pub mod pallet {141 use super::*;142 use frame_support::{Blake2_128Concat, pallet_prelude::*, storage::Key};143 use account::{EvmBackwardsAddressMapping, CrossAccountId};144 use frame_support::traits::Currency;145 use nft_data_structs::TokenId;146 use scale_info::TypeInfo;147148 #[pallet::config]149 pub trait Config: frame_system::Config + pallet_evm_coder_substrate::Config + TypeInfo {150 type Event: IsType<<Self as frame_system::Config>::Event> + From<Event<Self>>;151152 type CrossAccountId: CrossAccountId<Self::AccountId>;153154 type EvmAddressMapping: pallet_evm::AddressMapping<Self::AccountId>;155 type EvmBackwardsAddressMapping: EvmBackwardsAddressMapping<Self::AccountId>;156157 type Currency: Currency<Self::AccountId>;158 type CollectionCreationPrice: Get<159 <<Self as Config>::Currency as Currency<Self::AccountId>>::Balance,160 >;161 type TreasuryAccountId: Get<Self::AccountId>;162 }163164 #[pallet::pallet]165 #[pallet::generate_store(pub(super) trait Store)]166 pub struct Pallet<T>(_);167168 #[pallet::event]169 #[pallet::generate_deposit(pub fn deposit_event)]170 pub enum Event<T: Config> {171 /// New collection was created172 ///173 /// # Arguments174 ///175 /// * collection_id: Globally unique identifier of newly created collection.176 ///177 /// * mode: [CollectionMode] converted into u8.178 ///179 /// * account_id: Collection owner.180 CollectionCreated(CollectionId, u8, T::AccountId),181182 /// New item was created.183 ///184 /// # Arguments185 ///186 /// * collection_id: Id of the collection where item was created.187 ///188 /// * item_id: Id of an item. Unique within the collection.189 ///190 /// * recipient: Owner of newly created item191 ///192 /// * amount: Always 1 for NFT193 ItemCreated(CollectionId, TokenId, T::CrossAccountId, u128),194195 /// Collection item was burned.196 ///197 /// # Arguments198 ///199 /// * collection_id.200 ///201 /// * item_id: Identifier of burned NFT.202 ///203 /// * owner: which user has destroyed its tokens204 ///205 /// * amount: Always 1 for NFT206 ItemDestroyed(CollectionId, TokenId, T::CrossAccountId, u128),207208 /// Item was transferred209 ///210 /// * collection_id: Id of collection to which item is belong211 ///212 /// * item_id: Id of an item213 ///214 /// * sender: Original owner of item215 ///216 /// * recipient: New owner of item217 ///218 /// * amount: Always 1 for NFT219 Transfer(220 CollectionId,221 TokenId,222 T::CrossAccountId,223 T::CrossAccountId,224 u128,225 ),226227 /// * collection_id228 ///229 /// * item_id230 ///231 /// * sender232 ///233 /// * spender234 ///235 /// * amount236 Approved(237 CollectionId,238 TokenId,239 T::CrossAccountId,240 T::CrossAccountId,241 u128,242 ),243 }244245 #[pallet::error]246 pub enum Error<T> {247 /// This collection does not exist.248 CollectionNotFound,249 /// Sender parameter and item owner must be equal.250 MustBeTokenOwner,251 /// No permission to perform action252 NoPermission,253 /// Collection is not in mint mode.254 PublicMintingNotAllowed,255 /// Address is not in white list.256 AddressNotInAllowlist,257258 /// Collection name can not be longer than 63 char.259 CollectionNameLimitExceeded,260 /// Collection description can not be longer than 255 char.261 CollectionDescriptionLimitExceeded,262 /// Token prefix can not be longer than 15 char.263 CollectionTokenPrefixLimitExceeded,264 /// Total collections bound exceeded.265 TotalCollectionsLimitExceeded,266 /// variable_data exceeded data limit.267 TokenVariableDataLimitExceeded,268269 /// Collection settings not allowing items transferring270 TransferNotAllowed,271 /// Account token limit exceeded per collection272 AccountTokenLimitExceeded,273 /// Collection token limit exceeded274 CollectionTokenLimitExceeded,275 /// Metadata flag frozen276 MetadataFlagFrozen,277278 /// Item not exists.279 TokenNotFound,280 /// Item balance not enough.281 TokenValueTooLow,282 /// Requested value more than approved.283 TokenValueNotEnough,284 /// Tried to approve more than owned285 CantApproveMoreThanOwned,286287 /// Can't transfer tokens to ethereum zero address288 AddressIsZero,289 /// Target collection doesn't supports this operation290 UnsupportedOperation,291 }292293 #[pallet::storage]294 pub type CreatedCollectionCount<T> = StorageValue<Value = CollectionId, QueryKind = ValueQuery>;295 #[pallet::storage]296 pub type DestroyedCollectionCount<T> =297 StorageValue<Value = CollectionId, QueryKind = ValueQuery>;298299 /// Collection info300 #[pallet::storage]301 pub type CollectionById<T> = StorageMap<302 Hasher = Blake2_128Concat,303 Key = CollectionId,304 Value = Collection<T>,305 QueryKind = OptionQuery,306 >;307308 /// List of collection admins309 #[pallet::storage]310 pub type IsAdmin<T: Config> = StorageNMap<311 Key = (312 Key<Blake2_128Concat, CollectionId>,313 Key<Blake2_128Concat, T::CrossAccountId>,314 ),315 Value = bool,316 QueryKind = ValueQuery,317 >;318319 /// Allowlisted collection users320 #[pallet::storage]321 pub type Allowlist<T: Config> = StorageNMap<322 Key = (323 Key<Blake2_128Concat, CollectionId>,324 Key<Blake2_128Concat, T::CrossAccountId>,325 ),326 Value = bool,327 QueryKind = ValueQuery,328 >;329}330331impl<T: Config> Pallet<T> {332 /// Ethereum receiver 0x0000000000000000000000000000000000000000 is reserved, and shouldn't own tokens333 pub fn ensure_correct_receiver(receiver: &T::CrossAccountId) -> DispatchResult {334 ensure!(335 &T::CrossAccountId::from_eth(H160([0; 20])) != receiver,336 <Error<T>>::AddressIsZero337 );338 Ok(())339 }340}341342impl<T: Config> Pallet<T> {343 pub fn init_collection(data: Collection<T>) -> Result<CollectionId, DispatchError> {344 {345 ensure!(346 data.name.len() <= MAX_COLLECTION_NAME_LENGTH,347 Error::<T>::CollectionNameLimitExceeded348 );349 ensure!(350 data.description.len() <= MAX_COLLECTION_DESCRIPTION_LENGTH,351 Error::<T>::CollectionDescriptionLimitExceeded352 );353 ensure!(354 data.token_prefix.len() <= MAX_TOKEN_PREFIX_LENGTH,355 Error::<T>::CollectionTokenPrefixLimitExceeded356 );357 }358359 let created_count = <CreatedCollectionCount<T>>::get()360 .0361 .checked_add(1)362 .ok_or(ArithmeticError::Overflow)?;363 let destroyed_count = <DestroyedCollectionCount<T>>::get().0;364 let id = CollectionId(created_count);365366 // bound Total number of collections367 ensure!(368 created_count - destroyed_count < COLLECTION_NUMBER_LIMIT,369 <Error<T>>::TotalCollectionsLimitExceeded370 );371372 // =========373374 // Take a (non-refundable) deposit of collection creation375 {376 let mut imbalance =377 <<<T as Config>::Currency as Currency<T::AccountId>>::PositiveImbalance>::zero();378 imbalance.subsume(379 <<T as Config>::Currency as Currency<T::AccountId>>::deposit_creating(380 &T::TreasuryAccountId::get(),381 T::CollectionCreationPrice::get(),382 ),383 );384 <T as Config>::Currency::settle(385 &data.owner,386 imbalance,387 WithdrawReasons::TRANSFER,388 ExistenceRequirement::KeepAlive,389 )390 .map_err(|_| Error::<T>::NoPermission)?;391 }392393 <CreatedCollectionCount<T>>::put(created_count);394 <Pallet<T>>::deposit_event(Event::CollectionCreated(395 id,396 data.mode.id(),397 data.owner.clone(),398 ));399 <CollectionById<T>>::insert(id, data);400 Ok(id)401 }402403 pub fn destroy_collection(404 collection: CollectionHandle<T>,405 sender: &T::CrossAccountId,406 ) -> DispatchResult {407 ensure!(408 collection.limits.owner_can_destroy(),409 <Error<T>>::NoPermission,410 );411 collection.check_is_owner(&sender)?;412413 let destroyed_collections = <DestroyedCollectionCount<T>>::get()414 .0415 .checked_add(1)416 .ok_or(ArithmeticError::Overflow)?;417418 // =========419420 <DestroyedCollectionCount<T>>::put(destroyed_collections);421 <CollectionById<T>>::remove(collection.id);422 <IsAdmin<T>>::remove_prefix((collection.id,), None);423 <Allowlist<T>>::remove_prefix((collection.id,), None);424 Ok(())425 }426427 pub fn toggle_allowlist(428 collection: &CollectionHandle<T>,429 sender: &T::CrossAccountId,430 user: &T::CrossAccountId,431 allowed: bool,432 ) -> DispatchResult {433 collection.check_is_owner_or_admin(&sender)?;434435 // =========436437 if allowed {438 <Allowlist<T>>::insert((collection.id, user.as_sub()), true);439 } else {440 <Allowlist<T>>::remove((collection.id, user.as_sub()));441 }442443 Ok(())444 }445}446447#[macro_export]448macro_rules! unsupported {449 () => {450 Err(<Error<T>>::UnsupportedOperation.into())451 };452}453454/// Worst cases455pub trait CommonWeightInfo {456 fn create_item() -> Weight;457 fn create_multiple_items(amount: u32) -> Weight;458 fn burn_item() -> Weight;459 fn transfer() -> Weight;460 fn approve() -> Weight;461 fn transfer_from() -> Weight;462 fn burn_from() -> Weight;463 fn set_variable_metadata(bytes: u32) -> Weight;464}465466pub trait CommonCollectionOperations<T: Config> {467 fn create_item(468 &self,469 sender: T::CrossAccountId,470 to: T::CrossAccountId,471 data: CreateItemData,472 ) -> DispatchResultWithPostInfo;473 fn create_multiple_items(474 &self,475 sender: T::CrossAccountId,476 to: T::CrossAccountId,477 data: Vec<CreateItemData>,478 ) -> DispatchResultWithPostInfo;479 fn burn_item(480 &self,481 sender: T::CrossAccountId,482 token: TokenId,483 amount: u128,484 ) -> DispatchResultWithPostInfo;485486 fn transfer(487 &self,488 sender: T::CrossAccountId,489 to: T::CrossAccountId,490 token: TokenId,491 amount: u128,492 ) -> DispatchResultWithPostInfo;493 fn approve(494 &self,495 sender: T::CrossAccountId,496 spender: T::CrossAccountId,497 token: TokenId,498 amount: u128,499 ) -> DispatchResultWithPostInfo;500 fn transfer_from(501 &self,502 sender: T::CrossAccountId,503 from: T::CrossAccountId,504 to: T::CrossAccountId,505 token: TokenId,506 amount: u128,507 ) -> DispatchResultWithPostInfo;508 fn burn_from(509 &self,510 sender: T::CrossAccountId,511 from: T::CrossAccountId,512 token: TokenId,513 amount: u128,514 ) -> DispatchResultWithPostInfo;515516 fn set_variable_metadata(517 &self,518 sender: T::CrossAccountId,519 token: TokenId,520 data: Vec<u8>,521 ) -> DispatchResultWithPostInfo;522523 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId>;524 fn token_exists(&self, token: TokenId) -> bool;525 fn last_token_id(&self) -> TokenId;526527 fn token_owner(&self, token: TokenId) -> T::CrossAccountId;528 fn const_metadata(&self, token: TokenId) -> Vec<u8>;529 fn variable_metadata(&self, token: TokenId) -> Vec<u8>;530531 /// How many tokens collection contains (Applicable to nonfungible/refungible)532 fn collection_tokens(&self) -> u32;533 /// Amount of different tokens account has (Applicable to nonfungible/refungible)534 fn account_balance(&self, account: T::CrossAccountId) -> u32;535 /// Amount of specific token account have (Applicable to fungible/refungible)536 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128;537 fn allowance(538 &self,539 sender: T::CrossAccountId,540 spender: T::CrossAccountId,541 token: TokenId,542 ) -> u128;543}544545// Flexible enough for implementing CommonCollectionOperations546pub fn with_weight(res: DispatchResult, weight: Weight) -> DispatchResultWithPostInfo {547 let post_info = PostDispatchInfo {548 actual_weight: Some(weight),549 pays_fee: Pays::Yes,550 };551 match res {552 Ok(()) => Ok(post_info),553 Err(error) => Err(DispatchErrorWithPostInfo { post_info, error }),554 }555}pallets/fungible/src/common.rsdiffbeforeafterboth--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -2,9 +2,7 @@
use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};
use nft_data_structs::TokenId;
-use pallet_common::{
- CommonCollectionOperations, CommonWeightInfo, account::CrossAccountId, with_weight,
-};
+use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
use sp_runtime::ArithmeticError;
use sp_std::{vec::Vec, vec};
@@ -188,7 +186,7 @@
}
fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {
- if <Balance<T>>::get((self.id, account.as_sub())) != 0 {
+ if <Balance<T>>::get((self.id, account)) != 0 {
vec![TokenId::default()]
} else {
vec![]
@@ -218,7 +216,7 @@
}
fn account_balance(&self, account: T::CrossAccountId) -> u32 {
- if <Balance<T>>::get((self.id, account.as_sub())) != 0 {
+ if <Balance<T>>::get((self.id, account)) != 0 {
1
} else {
0
@@ -229,7 +227,7 @@
if token != TokenId::default() {
return 0;
}
- <Balance<T>>::get((self.id, account.as_sub()))
+ <Balance<T>>::get((self.id, account))
}
fn allowance(
@@ -241,6 +239,6 @@
if token != TokenId::default() {
return 0;
}
- <Allowance<T>>::get((self.id, sender.as_sub(), spender.as_sub()))
+ <Allowance<T>>::get((self.id, sender, spender))
}
}
pallets/fungible/src/erc.rsdiffbeforeafterboth--- a/pallets/fungible/src/erc.rs
+++ b/pallets/fungible/src/erc.rs
@@ -52,7 +52,7 @@
}
fn balance_of(&self, owner: address) -> Result<uint256> {
let owner = T::CrossAccountId::from_eth(owner);
- let balance = <Balance<T>>::get((self.id, owner.as_sub()));
+ let balance = <Balance<T>>::get((self.id, owner));
Ok(balance.into())
}
fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result<bool> {
@@ -92,7 +92,7 @@
let owner = T::CrossAccountId::from_eth(owner);
let spender = T::CrossAccountId::from_eth(spender);
- Ok(<Allowance<T>>::get((self.id, owner.as_sub(), spender.as_sub())).into())
+ Ok(<Allowance<T>>::get((self.id, owner, spender)).into())
}
}
pallets/fungible/src/lib.rsdiffbeforeafterboth--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -55,7 +55,7 @@
pub(super) type Balance<T: Config> = StorageNMap<
Key = (
Key<Twox64Concat, CollectionId>,
- Key<Blake2_128Concat, T::AccountId>,
+ Key<Blake2_128Concat, T::CrossAccountId>,
),
Value = u128,
QueryKind = ValueQuery,
@@ -65,8 +65,8 @@
pub(super) type Allowance<T: Config> = StorageNMap<
Key = (
Key<Twox64Concat, CollectionId>,
- Key<Blake2_128, T::AccountId>,
- Key<Blake2_128Concat, T::AccountId>,
+ Key<Blake2_128, T::CrossAccountId>,
+ Key<Blake2_128Concat, T::CrossAccountId>,
),
Value = u128,
QueryKind = ValueQuery,
@@ -119,7 +119,7 @@
.checked_sub(amount)
.ok_or(<CommonError<T>>::TokenValueTooLow)?;
- let balance = <Balance<T>>::get((collection.id, owner.as_sub()))
+ let balance = <Balance<T>>::get((collection.id, owner))
.checked_sub(amount)
.ok_or(<CommonError<T>>::TokenValueTooLow)?;
@@ -130,9 +130,9 @@
// =========
if balance == 0 {
- <Balance<T>>::remove((collection.id, owner.as_sub()));
+ <Balance<T>>::remove((collection.id, owner));
} else {
- <Balance<T>>::insert((collection.id, owner.as_sub()), balance);
+ <Balance<T>>::insert((collection.id, owner), balance);
}
<TotalSupply<T>>::insert(collection.id, total_supply);
@@ -167,12 +167,12 @@
}
<PalletCommon<T>>::ensure_correct_receiver(to)?;
- let balance_from = <Balance<T>>::get((collection.id, from.as_sub()))
+ let balance_from = <Balance<T>>::get((collection.id, from))
.checked_sub(amount)
.ok_or(<CommonError<T>>::TokenValueTooLow)?;
let balance_to = if from != to {
Some(
- <Balance<T>>::get((collection.id, to.as_sub()))
+ <Balance<T>>::get((collection.id, to))
.checked_add(amount)
.ok_or(ArithmeticError::Overflow)?,
)
@@ -190,11 +190,11 @@
if let Some(balance_to) = balance_to {
// from != to
if balance_from == 0 {
- <Balance<T>>::remove((collection.id, from.as_sub()));
+ <Balance<T>>::remove((collection.id, from));
} else {
- <Balance<T>>::insert((collection.id, from.as_sub()), balance_from);
+ <Balance<T>>::insert((collection.id, from), balance_from);
}
- <Balance<T>>::insert((collection.id, to.as_sub()), balance_to);
+ <Balance<T>>::insert((collection.id, to), balance_to);
}
collection.log_infallible(ERC20Events::Transfer {
@@ -242,7 +242,7 @@
collection.consume_sload()?;
let balance = balances
.entry(user.clone())
- .or_insert_with(|| <Balance<T>>::get((collection.id, user.as_sub())));
+ .or_insert_with(|| <Balance<T>>::get((collection.id, user)));
*balance = (*balance)
.checked_add(amount)
.ok_or(ArithmeticError::Overflow)?;
@@ -259,7 +259,7 @@
<TotalSupply<T>>::insert(collection.id, total_supply);
for (user, amount) in balances {
- <Balance<T>>::insert((collection.id, user.as_sub()), amount);
+ <Balance<T>>::insert((collection.id, &user), amount);
collection.log_infallible(ERC20Events::Transfer {
from: H160::default(),
@@ -283,7 +283,7 @@
spender: &T::CrossAccountId,
amount: u128,
) {
- <Allowance<T>>::insert((collection.id, owner.as_sub(), spender.as_sub()), amount);
+ <Allowance<T>>::insert((collection.id, owner, spender), amount);
collection.log_infallible(ERC20Events::Approval {
owner: *owner.as_eth(),
@@ -310,7 +310,7 @@
collection.check_allowlist(&spender)?;
}
- if <Balance<T>>::get((collection.id, owner.as_sub())) < amount {
+ if <Balance<T>>::get((collection.id, owner)) < amount {
ensure!(
collection.ignores_owned_amount(owner)?,
<CommonError<T>>::CantApproveMoreThanOwned
@@ -330,7 +330,7 @@
to: &T::CrossAccountId,
amount: u128,
) -> DispatchResult {
- if spender == from {
+ if spender.conv_eq(from) {
return Self::transfer(collection, from, to, amount);
}
if collection.access == AccessMode::WhiteList {
@@ -338,8 +338,7 @@
collection.check_allowlist(spender)?;
}
- let allowance = <Allowance<T>>::get((collection.id, from.as_sub(), spender.as_sub()))
- .checked_sub(amount);
+ let allowance = <Allowance<T>>::get((collection.id, from, spender)).checked_sub(amount);
if allowance.is_none() {
ensure!(
collection.ignores_allowance(spender)?,
@@ -362,7 +361,7 @@
from: &T::CrossAccountId,
amount: u128,
) -> DispatchResult {
- if spender == from {
+ if spender.conv_eq(from) {
return Self::burn(collection, from, amount);
}
if collection.access == AccessMode::WhiteList {
@@ -370,8 +369,7 @@
collection.check_allowlist(spender)?;
}
- let allowance = <Allowance<T>>::get((collection.id, from.as_sub(), spender.as_sub()))
- .checked_sub(amount);
+ let allowance = <Allowance<T>>::get((collection.id, from, spender)).checked_sub(amount);
if allowance.is_none() {
ensure!(
collection.ignores_allowance(spender)?,
pallets/nft/src/lib.rsdiffbeforeafterboth--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -948,12 +948,12 @@
// TODO: limit returned entries?
impl<T: Config> Pallet<T> {
- pub fn adminlist(collection: CollectionId) -> Vec<T::AccountId> {
+ pub fn adminlist(collection: CollectionId) -> Vec<T::CrossAccountId> {
<IsAdmin<T>>::iter_prefix((collection,))
.map(|(a, _)| a)
.collect()
}
- pub fn allowlist(collection: CollectionId) -> Vec<T::AccountId> {
+ pub fn allowlist(collection: CollectionId) -> Vec<T::CrossAccountId> {
<Allowlist<T>>::iter_prefix((collection,))
.map(|(a, _)| a)
.collect()
pallets/nonfungible/src/common.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -2,9 +2,7 @@
use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};
use nft_data_structs::TokenId;
-use pallet_common::{
- CommonCollectionOperations, CommonWeightInfo, account::CrossAccountId, with_weight,
-};
+use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
use sp_runtime::DispatchError;
use sp_std::vec::Vec;
@@ -200,7 +198,7 @@
}
fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {
- <Owned<T>>::iter_prefix((self.id, account.as_sub()))
+ <Owned<T>>::iter_prefix((self.id, account))
.map(|(id, _)| id)
.collect()
}
@@ -234,7 +232,7 @@
}
fn account_balance(&self, account: T::CrossAccountId) -> u32 {
- <AccountBalance<T>>::get((self.id, account.as_sub()))
+ <AccountBalance<T>>::get((self.id, account))
}
fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -93,7 +93,7 @@
impl<T: Config> NonfungibleHandle<T> {
fn balance_of(&self, owner: address) -> Result<uint256> {
let owner = T::CrossAccountId::from_eth(owner);
- let balance = <AccountBalance<T>>::get((self.id, owner.as_sub()));
+ let balance = <AccountBalance<T>>::get((self.id, owner));
Ok(balance.into())
}
fn owner_of(&self, token_id: uint256) -> Result<address> {
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -80,7 +80,7 @@
pub(super) type Owned<T: Config> = StorageNMap<
Key = (
Key<Twox64Concat, CollectionId>,
- Key<Blake2_128Concat, T::AccountId>,
+ Key<Blake2_128Concat, T::CrossAccountId>,
Key<Twox64Concat, TokenId>,
),
Value = bool,
@@ -91,7 +91,7 @@
pub(super) type AccountBalance<T: Config> = StorageNMap<
Key = (
Key<Twox64Concat, CollectionId>,
- Key<Blake2_128Concat, T::AccountId>,
+ Key<Blake2_128Concat, T::CrossAccountId>,
),
Value = u32,
QueryKind = ValueQuery,
@@ -179,7 +179,7 @@
// =========
- <Owned<T>>::remove((collection.id, token_data.owner.as_sub(), token));
+ <Owned<T>>::remove((collection.id, &token_data.owner, token));
<TokensBurnt<T>>::insert(collection.id, burnt);
<TokenData<T>>::remove((collection.id, token));
let old_spender = <Allowance<T>>::take((collection.id, token));
@@ -234,11 +234,11 @@
}
<PalletCommon<T>>::ensure_correct_receiver(to)?;
- let balance_from = <AccountBalance<T>>::get((collection.id, from.as_sub()))
+ let balance_from = <AccountBalance<T>>::get((collection.id, from))
.checked_sub(1)
.ok_or(<CommonError<T>>::TokenValueTooLow)?;
let balance_to = if from != to {
- let balance_to = <AccountBalance<T>>::get((collection.id, to.as_sub()))
+ let balance_to = <AccountBalance<T>>::get((collection.id, to))
.checked_add(1)
.ok_or(ArithmeticError::Overflow)?;
@@ -268,13 +268,13 @@
if let Some(balance_to) = balance_to {
// from != to
if balance_from == 0 {
- <AccountBalance<T>>::remove((collection.id, from.as_sub()));
+ <AccountBalance<T>>::remove((collection.id, from));
} else {
- <AccountBalance<T>>::insert((collection.id, from.as_sub()), balance_from);
+ <AccountBalance<T>>::insert((collection.id, from), balance_from);
}
- <AccountBalance<T>>::insert((collection.id, to.as_sub()), balance_to);
- <Owned<T>>::remove((collection.id, from.as_sub(), token));
- <Owned<T>>::insert((collection.id, to.as_sub(), token), true);
+ <AccountBalance<T>>::insert((collection.id, to), balance_to);
+ <Owned<T>>::remove((collection.id, from, token));
+ <Owned<T>>::insert((collection.id, to, token), true);
}
Self::set_allowance_unchecked(collection, from, token, None, true);
@@ -336,8 +336,8 @@
let mut balances = BTreeMap::new();
for data in &data {
let balance = balances
- .entry(data.owner.as_sub())
- .or_insert_with(|| <AccountBalance<T>>::get((collection.id, data.owner.as_sub())));
+ .entry(&data.owner)
+ .or_insert_with(|| <AccountBalance<T>>::get((collection.id, &data.owner)));
*balance = balance.checked_add(1).ok_or(ArithmeticError::Overflow)?;
ensure!(
@@ -364,7 +364,7 @@
owner: data.owner.clone(),
},
);
- <Owned<T>>::insert((collection.id, data.owner.as_sub(), token), true);
+ <Owned<T>>::insert((collection.id, &data.owner, token), true);
collection.log_infallible(ERC721Events::Transfer {
from: H160::default(),
@@ -481,7 +481,7 @@
to: &T::CrossAccountId,
token: TokenId,
) -> DispatchResult {
- if spender == from {
+ if spender.conv_eq(from) {
return Self::transfer(collection, from, to, token);
}
if collection.access == AccessMode::WhiteList {
@@ -509,7 +509,7 @@
from: &T::CrossAccountId,
token: TokenId,
) -> DispatchResult {
- if spender == from {
+ if spender.conv_eq(from) {
return Self::burn(collection, from, token);
}
if collection.access == AccessMode::WhiteList {
pallets/refungible/src/common.rsdiffbeforeafterboth--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -3,9 +3,7 @@
use sp_std::collections::btree_map::BTreeMap;
use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight};
use nft_data_structs::TokenId;
-use pallet_common::{
- CommonCollectionOperations, CommonWeightInfo, account::CrossAccountId, with_weight,
-};
+use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
use sp_runtime::DispatchError;
use sp_std::vec::Vec;
@@ -196,7 +194,7 @@
}
fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {
- <Owned<T>>::iter_prefix((self.id, account.as_sub()))
+ <Owned<T>>::iter_prefix((self.id, account))
.map(|(id, _)| id)
.collect()
}
@@ -224,11 +222,11 @@
}
fn account_balance(&self, account: T::CrossAccountId) -> u32 {
- <AccountBalance<T>>::get((self.id, account.as_sub()))
+ <AccountBalance<T>>::get((self.id, account))
}
fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {
- <Balance<T>>::get((self.id, token, account.as_sub()))
+ <Balance<T>>::get((self.id, token, account))
}
fn allowance(
@@ -237,6 +235,6 @@
spender: T::CrossAccountId,
token: TokenId,
) -> u128 {
- <Allowance<T>>::get((self.id, token, sender.as_sub(), spender))
+ <Allowance<T>>::get((self.id, token, sender, spender))
}
}
pallets/refungible/src/lib.rsdiffbeforeafterboth--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -83,7 +83,7 @@
pub(super) type Owned<T: Config> = StorageNMap<
Key = (
Key<Twox64Concat, CollectionId>,
- Key<Blake2_128Concat, T::AccountId>,
+ Key<Blake2_128Concat, T::CrossAccountId>,
Key<Twox64Concat, TokenId>,
),
Value = bool,
@@ -95,7 +95,7 @@
Key = (
Key<Twox64Concat, CollectionId>,
// Owner
- Key<Blake2_128Concat, T::AccountId>,
+ Key<Blake2_128Concat, T::CrossAccountId>,
),
Value = u32,
QueryKind = ValueQuery,
@@ -107,7 +107,7 @@
Key<Twox64Concat, CollectionId>,
Key<Twox64Concat, TokenId>,
// Owner
- Key<Blake2_128Concat, T::AccountId>,
+ Key<Blake2_128Concat, T::CrossAccountId>,
),
Value = u128,
QueryKind = ValueQuery,
@@ -119,7 +119,7 @@
Key<Twox64Concat, CollectionId>,
Key<Twox64Concat, TokenId>,
// Owner
- Key<Blake2_128, T::AccountId>,
+ Key<Blake2_128, T::CrossAccountId>,
// Spender
Key<Blake2_128Concat, T::CrossAccountId>,
),
@@ -206,18 +206,18 @@
if total_supply == 0 {
// Ensure user actually owns this amount
ensure!(
- <Balance<T>>::get((collection.id, token, owner.as_sub())) == amount,
+ <Balance<T>>::get((collection.id, token, owner)) == amount,
<CommonError<T>>::TokenValueTooLow
);
- let account_balance = <AccountBalance<T>>::get((collection.id, owner.as_sub()))
+ let account_balance = <AccountBalance<T>>::get((collection.id, owner))
.checked_sub(1)
// Should not occur
.ok_or(ArithmeticError::Underflow)?;
// =========
- <Owned<T>>::remove((collection.id, owner.as_sub(), token));
- <AccountBalance<T>>::insert((collection.id, owner.as_sub()), account_balance);
+ <Owned<T>>::remove((collection.id, owner, token));
+ <AccountBalance<T>>::insert((collection.id, owner), account_balance);
Self::burn_token(collection, token)?;
<PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(
collection.id,
@@ -228,11 +228,11 @@
return Ok(());
}
- let balance = <Balance<T>>::get((collection.id, token, owner.as_sub()))
+ let balance = <Balance<T>>::get((collection.id, token, owner))
.checked_sub(amount)
.ok_or(<CommonError<T>>::TokenValueTooLow)?;
let account_balance = if balance == 0 {
- <AccountBalance<T>>::get((collection.id, owner.as_sub()))
+ <AccountBalance<T>>::get((collection.id, owner))
.checked_sub(1)
// Should not occur
.ok_or(ArithmeticError::Underflow)?
@@ -243,11 +243,11 @@
// =========
if balance == 0 {
- <Owned<T>>::remove((collection.id, owner.as_sub(), token));
- <Balance<T>>::remove((collection.id, token, owner.as_sub()));
- <AccountBalance<T>>::insert((collection.id, owner.as_sub()), account_balance);
+ <Owned<T>>::remove((collection.id, owner, token));
+ <Balance<T>>::remove((collection.id, token, owner));
+ <AccountBalance<T>>::insert((collection.id, owner), account_balance);
} else {
- <Balance<T>>::insert((collection.id, token, owner.as_sub()), balance);
+ <Balance<T>>::insert((collection.id, token, owner), balance);
}
<TotalSupply<T>>::insert((collection.id, token), total_supply);
// TODO: ERC20 transfer event
@@ -278,13 +278,13 @@
}
<PalletCommon<T>>::ensure_correct_receiver(to)?;
- let balance_from = <Balance<T>>::get((collection.id, token, from.as_sub()))
+ let balance_from = <Balance<T>>::get((collection.id, token, from))
.checked_sub(amount)
.ok_or(<CommonError<T>>::TokenValueTooLow)?;
let mut create_target = false;
let from_to_differ = from != to;
let balance_to = if from != to {
- let old_balance = <Balance<T>>::get((collection.id, token, to.as_sub()));
+ let old_balance = <Balance<T>>::get((collection.id, token, to));
if old_balance == 0 {
create_target = true;
}
@@ -299,7 +299,7 @@
let account_balance_from = if balance_from == 0 {
Some(
- <AccountBalance<T>>::get((collection.id, from.as_sub()))
+ <AccountBalance<T>>::get((collection.id, from))
.checked_sub(1)
// Should not occur
.ok_or(ArithmeticError::Underflow)?,
@@ -310,7 +310,7 @@
// Account data is created in token, AccountBalance should be increased
// But only if from != to as we shouldn't check overflow in this case
let account_balance_to = if create_target && from_to_differ {
- let account_balance_to = <AccountBalance<T>>::get((collection.id, to.as_sub()))
+ let account_balance_to = <AccountBalance<T>>::get((collection.id, to))
.checked_add(1)
.ok_or(ArithmeticError::Overflow)?;
ensure!(
@@ -328,18 +328,18 @@
if let Some(balance_to) = balance_to {
// from != to
if balance_from == 0 {
- <Balance<T>>::remove((collection.id, token, from.as_sub()));
+ <Balance<T>>::remove((collection.id, token, from));
} else {
- <Balance<T>>::insert((collection.id, token, from.as_sub()), balance_from);
+ <Balance<T>>::insert((collection.id, token, from), balance_from);
}
- <Balance<T>>::insert((collection.id, token, to.as_sub()), balance_to);
+ <Balance<T>>::insert((collection.id, token, to), balance_to);
if let Some(account_balance_from) = account_balance_from {
- <AccountBalance<T>>::insert((collection.id, from.as_sub()), account_balance_from);
- <Owned<T>>::remove((collection.id, from.as_sub(), token));
+ <AccountBalance<T>>::insert((collection.id, from), account_balance_from);
+ <Owned<T>>::remove((collection.id, from, token));
}
if let Some(account_balance_to) = account_balance_to {
- <AccountBalance<T>>::insert((collection.id, to.as_sub()), account_balance_to);
- <Owned<T>>::insert((collection.id, to.as_sub(), token), true);
+ <AccountBalance<T>>::insert((collection.id, to), account_balance_to);
+ <Owned<T>>::insert((collection.id, to, token), true);
}
}
@@ -412,8 +412,8 @@
for data in &data {
for (owner, _) in &data.users {
let balance = balances
- .entry(owner.as_sub())
- .or_insert_with(|| <AccountBalance<T>>::get((collection.id, owner.as_sub())));
+ .entry(owner)
+ .or_insert_with(|| <AccountBalance<T>>::get((collection.id, owner)));
*balance = balance.checked_add(1).ok_or(ArithmeticError::Overflow)?;
ensure!(
@@ -444,8 +444,8 @@
if amount == 0 {
continue;
}
- <Balance<T>>::insert((collection.id, token_id, user.as_sub()), amount);
- <Owned<T>>::insert((collection.id, user.as_sub(), TokenId(token_id)), true);
+ <Balance<T>>::insert((collection.id, token_id, &user), amount);
+ <Owned<T>>::insert((collection.id, &user, TokenId(token_id)), true);
// TODO: ERC20 transfer event
<PalletCommon<T>>::deposit_event(CommonEvent::ItemCreated(
collection.id,
@@ -465,7 +465,7 @@
token: TokenId,
amount: u128,
) {
- <Allowance<T>>::insert((collection.id, token, sender.as_sub(), spender), amount);
+ <Allowance<T>>::insert((collection.id, token, sender, spender), amount);
// TODO: ERC20 approval event
<PalletCommon<T>>::deposit_event(CommonEvent::Approved(
collection.id,
@@ -490,7 +490,7 @@
<PalletCommon<T>>::ensure_correct_receiver(spender)?;
- if <Balance<T>>::get((collection.id, token, sender.as_sub())) < amount {
+ if <Balance<T>>::get((collection.id, token, sender)) < amount {
ensure!(
collection.ignores_owned_amount(sender)? && Self::token_exists(collection, token),
<CommonError<T>>::CantApproveMoreThanOwned
@@ -511,7 +511,7 @@
token: TokenId,
amount: u128,
) -> DispatchResult {
- if spender == from {
+ if spender.conv_eq(from) {
return Self::transfer(collection, from, to, token, amount);
}
if collection.access == AccessMode::WhiteList {
@@ -519,8 +519,8 @@
collection.check_allowlist(spender)?;
}
- let allowance = <Allowance<T>>::get((collection.id, token, from.as_sub(), &spender))
- .checked_sub(amount);
+ let allowance =
+ <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);
if allowance.is_none() {
ensure!(
collection.ignores_allowance(spender)?,
@@ -544,7 +544,7 @@
token: TokenId,
amount: u128,
) -> DispatchResult {
- if spender == from {
+ if spender.conv_eq(from) {
return Self::burn(collection, from, token, amount);
}
if collection.access == AccessMode::WhiteList {
@@ -552,8 +552,8 @@
collection.check_allowlist(spender)?;
}
- let allowance = <Allowance<T>>::get((collection.id, token, from.as_sub(), &spender))
- .checked_sub(amount);
+ let allowance =
+ <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);
if allowance.is_none() {
ensure!(
collection.ignores_allowance(spender)?,
primitives/rpc/src/lib.rsdiffbeforeafterboth--- a/primitives/rpc/src/lib.rs
+++ b/primitives/rpc/src/lib.rs
@@ -30,8 +30,8 @@
/// Used for ethereum integration
fn eth_contract_code(account: H160) -> Option<Vec<u8>>;
- fn adminlist(collection: CollectionId) -> Vec<AccountId>;
- fn allowlist(collection: CollectionId) -> Vec<AccountId>;
+ fn adminlist(collection: CollectionId) -> Vec<CrossAccountId>;
+ fn allowlist(collection: CollectionId) -> Vec<CrossAccountId>;
fn last_token_id(collection: CollectionId) -> TokenId;
}
}
runtime/src/lib.rsdiffbeforeafterboth--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -1033,12 +1033,14 @@
}
fn eth_contract_code(account: H160) -> Option<Vec<u8>> {
- <pallet_nft::NftErcSupport<Runtime>>::get_code(&account).or_else(|| <pallet_evm_migration::OnMethodCall<Runtime>>::get_code(&account)).or_else(|| <pallet_evm_contract_helpers::HelpersOnMethodCall<Self>>::get_code(&account))
+ <pallet_nft::NftErcSupport<Runtime>>::get_code(&account)
+ .or_else(|| <pallet_evm_migration::OnMethodCall<Runtime>>::get_code(&account))
+ .or_else(|| <pallet_evm_contract_helpers::HelpersOnMethodCall<Self>>::get_code(&account))
}
- fn adminlist(collection: CollectionId) -> Vec<AccountId> {
+ fn adminlist(collection: CollectionId) -> Vec<CrossAccountId> {
<pallet_nft::Pallet<Runtime>>::adminlist(collection)
}
- fn allowlist(collection: CollectionId) -> Vec<AccountId> {
+ fn allowlist(collection: CollectionId) -> Vec<CrossAccountId> {
<pallet_nft::Pallet<Runtime>>::allowlist(collection)
}
fn last_token_id(collection: CollectionId) -> TokenId {