difftreelog
refactor! rewrite collections accessors
in: master
Squashed from multiple
4 files changed
node/src/chain_spec.rsdiffbeforeafterboth--- a/node/src/chain_spec.rs
+++ b/node/src/chain_spec.rs
@@ -179,9 +179,10 @@
.collect(),
}),
pallet_nft: Some(NftConfig {
- collection: vec![(
+ collection_id: vec![(
1,
- CollectionType {
+ Collection {
+ id: 1,
owner: get_account_id_from_seed::<sr25519::Public>("Alice"),
mode: CollectionMode::NFT,
access: AccessMode::Normal,
pallets/nft/src/lib.rsdiffbeforeafterboth--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -125,7 +125,8 @@
#[derive(Encode, Decode, Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-pub struct CollectionType<T: Config> {
+pub struct Collection<T: Config> {
+ pub id: CollectionId,
pub owner: T::AccountId,
pub mode: CollectionMode,
pub access: AccessMode,
@@ -426,7 +427,7 @@
pub AccountItemCount get(fn account_item_count): map hasher(twox_64_concat) T::AccountId => u32;
// Basic collections
- pub Collection get(fn collection) config(): map hasher(identity) CollectionId => Option<CollectionType<T>> = None;
+ pub CollectionById get(fn collection_id) config(): map hasher(identity) CollectionId => Option<Collection<T>> = None;
pub AdminList get(fn admin_list_collection): map hasher(identity) CollectionId => Vec<T::AccountId>;
pub WhiteList get(fn white_list): double_map hasher(identity) CollectionId, hasher(twox_64_concat) T::AccountId => bool;
@@ -464,7 +465,7 @@
add_extra_genesis {
build(|config: &GenesisConfig<T>| {
// Modification of storage
- for (_num, _c) in &config.collection {
+ for (_num, _c) in &config.collection_id {
<Module<T>>::init_collection(_c);
}
@@ -615,7 +616,8 @@
};
// Create new collection
- let new_collection = CollectionType {
+ let new_collection = Collection {
+ id: next_id,
owner: who.clone(),
name: collection_name,
mode: mode.clone(),
@@ -634,7 +636,7 @@
};
// Add new collection to map
- <Collection<T>>::insert(next_id, new_collection);
+ <CollectionById<T>>::insert(next_id, new_collection);
// call event
Self::deposit_event(RawEvent::Created(next_id, mode.into(), who.clone()));
@@ -655,10 +657,9 @@
pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {
let sender = ensure_signed(origin)?;
- Self::check_owner_permissions(collection_id, sender)?;
-
- let target_collection = <Collection<T>>::get(collection_id);
- if !target_collection.limits.owner_can_destroy {
+ let collection = Self::get_collection(collection_id)?;
+ Self::check_owner_permissions(&collection, sender)?;
+ if !collection.limits.owner_can_destroy {
fail!(Error::<T>::NoPermission);
}
@@ -667,7 +668,7 @@
<Balance<T>>::remove_prefix(collection_id);
<ItemListIndex>::remove(collection_id);
<AdminList<T>>::remove(collection_id);
- <Collection<T>>::remove(collection_id);
+ <CollectionById<T>>::remove(collection_id);
<WhiteList<T>>::remove_prefix(collection_id);
<NftItemList<T>>::remove_prefix(collection_id);
@@ -709,7 +710,8 @@
pub fn add_to_white_list(origin, collection_id: CollectionId, address: T::AccountId) -> DispatchResult{
let sender = ensure_signed(origin)?;
- Self::check_owner_or_admin_permissions(collection_id, sender)?;
+ let collection = Self::get_collection(collection_id)?;
+ Self::check_owner_or_admin_permissions(&collection, sender)?;
<WhiteList<T>>::insert(collection_id, address, true);
@@ -732,7 +734,8 @@
pub fn remove_from_white_list(origin, collection_id: CollectionId, address: T::AccountId) -> DispatchResult{
let sender = ensure_signed(origin)?;
- Self::check_owner_or_admin_permissions(collection_id, sender)?;
+ let collection = Self::get_collection(collection_id)?;
+ Self::check_owner_or_admin_permissions(&collection, sender)?;
<WhiteList<T>>::remove(collection_id, address);
@@ -755,10 +758,10 @@
{
let sender = ensure_signed(origin)?;
- Self::check_owner_permissions(collection_id, sender)?;
- let mut target_collection = <Collection<T>>::get(collection_id).unwrap();
+ let mut target_collection = Self::get_collection(collection_id)?;
+ Self::check_owner_permissions(&target_collection, sender)?;
target_collection.access = mode;
- <Collection<T>>::insert(collection_id, target_collection);
+ Self::save_collection(target_collection);
Ok(())
}
@@ -781,10 +784,10 @@
{
let sender = ensure_signed(origin)?;
- Self::check_owner_permissions(collection_id, sender)?;
- let mut target_collection = <Collection<T>>::get(collection_id).unwrap();
+ let mut target_collection = Self::get_collection(collection_id)?;
+ Self::check_owner_permissions(&target_collection, sender)?;
target_collection.mint_mode = mint_permission;
- <Collection<T>>::insert(collection_id, target_collection);
+ Self::save_collection(target_collection);
Ok(())
}
@@ -804,10 +807,10 @@
pub fn change_collection_owner(origin, collection_id: CollectionId, new_owner: T::AccountId) -> DispatchResult {
let sender = ensure_signed(origin)?;
- Self::check_owner_permissions(collection_id, sender)?;
- let mut target_collection = <Collection<T>>::get(collection_id).unwrap();
+ let mut target_collection = Self::get_collection(collection_id)?;
+ Self::check_owner_permissions(&target_collection, sender)?;
target_collection.owner = new_owner;
- <Collection<T>>::insert(collection_id, target_collection);
+ Self::save_collection(target_collection);
Ok(())
}
@@ -829,7 +832,8 @@
pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::AccountId) -> DispatchResult {
let sender = ensure_signed(origin)?;
- Self::check_owner_or_admin_permissions(collection_id, sender)?;
+ let collection = Self::get_collection(collection_id)?;
+ Self::check_owner_or_admin_permissions(&collection, sender)?;
let mut admin_arr: Vec<T::AccountId> = Vec::new();
if <AdminList<T>>::contains_key(collection_id)
@@ -863,7 +867,8 @@
pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::AccountId) -> DispatchResult {
let sender = ensure_signed(origin)?;
- Self::check_owner_or_admin_permissions(collection_id, sender)?;
+ let collection = Self::get_collection(collection_id)?;
+ Self::check_owner_or_admin_permissions(&collection, sender)?;
ensure!(<AdminList<T>>::contains_key(collection_id), Error::<T>::AdminNotFound);
let mut admin_arr = <AdminList<T>>::get(collection_id);
@@ -886,13 +891,12 @@
pub fn set_collection_sponsor(origin, collection_id: CollectionId, new_sponsor: T::AccountId) -> DispatchResult {
let sender = ensure_signed(origin)?;
-
- let mut target_collection = <Collection<T>>::get(collection_id).ok_or(Error::<T>::CollectionNotFound)?;
- ensure!(sender == target_collection.owner, Error::<T>::NoPermission);
+ let mut target_collection = Self::get_collection(collection_id)?;
+ Self::check_owner_permissions(&target_collection, sender)?;
target_collection.sponsor = new_sponsor;
target_collection.sponsor_confirmed = false;
- <Collection<T>>::insert(collection_id, target_collection);
+ Self::save_collection(target_collection);
Ok(())
}
@@ -909,11 +913,11 @@
let sender = ensure_signed(origin)?;
- let mut target_collection = <Collection<T>>::get(collection_id).ok_or(Error::<T>::CollectionNotFound)?;
+ let mut target_collection = Self::get_collection(collection_id)?;
ensure!(sender == target_collection.sponsor, Error::<T>::ConfirmUnsetSponsorFail);
target_collection.sponsor_confirmed = true;
- <Collection<T>>::insert(collection_id, target_collection);
+ Self::save_collection(target_collection);
Ok(())
}
@@ -932,12 +936,12 @@
let sender = ensure_signed(origin)?;
- let mut target_collection = <Collection<T>>::get(collection_id).ok_or(Error::<T>::CollectionNotFound)?;
- ensure!(sender == target_collection.owner, Error::<T>::NoPermission);
+ let mut target_collection = Self::get_collection(collection_id)?;
+ Self::check_owner_permissions(&target_collection, sender)?;
target_collection.sponsor = T::AccountId::default();
target_collection.sponsor_confirmed = false;
- <Collection<T>>::insert(collection_id, target_collection);
+ Self::save_collection(target_collection);
Ok(())
}
@@ -971,13 +975,11 @@
let sender = ensure_signed(origin)?;
- Self::collection_exists(collection_id)?;
+ let target_collection = Self::get_collection(collection_id)?;
- let target_collection = <Collection<T>>::get(collection_id).unwrap();
-
- Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;
+ Self::can_create_items_in_collection(&target_collection, &sender, &owner)?;
Self::validate_create_item_args(&target_collection, &data)?;
- Self::create_item_no_validation(collection_id, owner, data)?;
+ Self::create_item_no_validation(&target_collection, owner, data)?;
Ok(())
}
@@ -1008,16 +1010,15 @@
ensure!(items_data.len() > 0, Error::<T>::EmptyArgument);
let sender = ensure_signed(origin)?;
- Self::collection_exists(collection_id)?;
- let target_collection = <Collection<T>>::get(collection_id).unwrap();
+ let target_collection = Self::get_collection(collection_id)?;
- Self::can_create_items_in_collection(collection_id, &target_collection, &sender, &owner)?;
+ Self::can_create_items_in_collection(&target_collection, &sender, &owner)?;
for data in &items_data {
Self::validate_create_item_args(&target_collection, data)?;
}
for data in &items_data {
- Self::create_item_no_validation(collection_id, owner.clone(), data.clone())?;
+ Self::create_item_no_validation(&target_collection, owner.clone(), data.clone())?;
}
Ok(())
@@ -1040,33 +1041,32 @@
pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {
let sender = ensure_signed(origin)?;
- Self::collection_exists(collection_id)?;
// Transfer permissions check
- let target_collection = <Collection<T>>::get(collection_id).unwrap();
+ let target_collection = Self::get_collection(collection_id)?;
ensure!(
- Self::is_item_owner(sender.clone(), collection_id, item_id) ||
+ Self::is_item_owner(sender.clone(), &target_collection, item_id) ||
(
target_collection.limits.owner_can_transfer &&
- Self::is_owner_or_admin_permissions(collection_id, sender.clone())
+ Self::is_owner_or_admin_permissions(&target_collection, sender.clone())
),
Error::<T>::NoPermission
);
if target_collection.access == AccessMode::WhiteList {
- Self::check_white_list(collection_id, &sender)?;
+ Self::check_white_list(&target_collection, &sender)?;
}
match target_collection.mode
{
- CollectionMode::NFT => Self::burn_nft_item(collection_id, item_id)?,
- CollectionMode::Fungible(_) => Self::burn_fungible_item(&sender, collection_id, value)?,
- CollectionMode::ReFungible => Self::burn_refungible_item(collection_id, item_id, &sender)?,
+ CollectionMode::NFT => Self::burn_nft_item(&target_collection, item_id)?,
+ CollectionMode::Fungible(_) => Self::burn_fungible_item(&sender, &target_collection, value)?,
+ CollectionMode::ReFungible => Self::burn_refungible_item(&target_collection, item_id, &sender)?,
_ => ()
};
// call event
- Self::deposit_event(RawEvent::ItemDestroyed(collection_id, item_id));
+ Self::deposit_event(RawEvent::ItemDestroyed(target_collection.id, item_id));
Ok(())
}
@@ -1097,7 +1097,9 @@
#[weight = <T as Config>::WeightInfo::transfer()]
pub fn transfer(origin, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {
let sender = ensure_signed(origin)?;
- Self::transfer_internal(sender, recipient, collection_id, item_id, value)
+ let collection = Self::get_collection(collection_id)?;
+
+ Self::transfer_internal(sender, recipient, &collection, item_id, value)
}
/// Set, change, or remove approved address to transfer the ownership of the NFT.
@@ -1119,23 +1121,22 @@
pub fn approve(origin, spender: T::AccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResult {
let sender = ensure_signed(origin)?;
+ let target_collection = Self::get_collection(collection_id)?;
- Self::collection_exists(collection_id)?;
- Self::token_exists(collection_id, item_id, &sender)?;
+ Self::token_exists(&target_collection, item_id, &sender)?;
// Transfer permissions check
- let target_collection = <Collection<T>>::get(collection_id).unwrap();
let allowance_limit = if (
target_collection.limits.owner_can_transfer &&
Self::is_owner_or_admin_permissions(
- collection_id,
+ &target_collection,
sender.clone(),
)
) {
None
} else if let Some(amount) = Self::owned_amount(
sender.clone(),
- collection_id,
+ &target_collection,
item_id,
) {
Some(amount)
@@ -1144,8 +1145,8 @@
};
if target_collection.access == AccessMode::WhiteList {
- Self::check_white_list(collection_id, &sender)?;
- Self::check_white_list(collection_id, &spender)?;
+ Self::check_white_list(&target_collection, &sender)?;
+ Self::check_white_list(&target_collection, &spender)?;
}
let allowance_exists = <Allowances<T>>::contains_key(collection_id, (item_id, &sender, &spender));
@@ -1184,6 +1185,8 @@
pub fn transfer_from(origin, from: T::AccountId, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResult {
let sender = ensure_signed(origin)?;
+ let target_collection = Self::get_collection(collection_id)?;
+
let mut appoved_transfer = false;
// Check approval
@@ -1193,25 +1196,23 @@
ensure!(approval >= value, Error::<T>::TokenValueNotEnough);
appoved_transfer = true;
}
-
- let target_collection = <Collection<T>>::get(collection_id).unwrap();
// Limits check
- Self::is_correct_transfer(collection_id, &target_collection, &recipient)?;
+ Self::is_correct_transfer(&target_collection, &recipient)?;
// Transfer permissions check
ensure!(
appoved_transfer ||
(
target_collection.limits.owner_can_transfer &&
- Self::is_owner_or_admin_permissions(collection_id, sender.clone())
+ Self::is_owner_or_admin_permissions(&target_collection, sender.clone())
),
Error::<T>::NoPermission
);
if target_collection.access == AccessMode::WhiteList {
- Self::check_white_list(collection_id, &sender)?;
- Self::check_white_list(collection_id, &recipient)?;
+ Self::check_white_list(&target_collection, &sender)?;
+ Self::check_white_list(&target_collection, &recipient)?;
}
// Reduce approval by transferred amount or remove if remaining approval drops to 0
@@ -1224,9 +1225,9 @@
match target_collection.mode
{
- CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, from, recipient)?,
- CollectionMode::Fungible(_) => Self::transfer_fungible(collection_id, value, &from, &recipient)?,
- CollectionMode::ReFungible => Self::transfer_refungible(collection_id, item_id, value, from.clone(), recipient)?,
+ CollectionMode::NFT => Self::transfer_nft(&target_collection, item_id, from, recipient)?,
+ CollectionMode::Fungible(_) => Self::transfer_fungible(&target_collection, value, &from, &recipient)?,
+ CollectionMode::ReFungible => Self::transfer_refungible(&target_collection, item_id, value, from.clone(), recipient)?,
_ => ()
};
@@ -1269,21 +1270,20 @@
) -> DispatchResult {
let sender = ensure_signed(origin)?;
- Self::collection_exists(collection_id)?;
- Self::token_exists(collection_id, item_id, &sender)?;
+ let target_collection = Self::get_collection(collection_id)?;
+ Self::token_exists(&target_collection, item_id, &sender)?;
ensure!(ChainLimit::get().custom_data_limit >= data.len() as u32, Error::<T>::TokenVariableDataLimitExceeded);
// Modify permissions check
- let target_collection = <Collection<T>>::get(collection_id).unwrap();
- ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||
- Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
+ ensure!(Self::is_item_owner(sender.clone(), &target_collection, item_id) ||
+ Self::is_owner_or_admin_permissions(&target_collection, sender.clone()),
Error::<T>::NoPermission);
match target_collection.mode
{
- CollectionMode::NFT => Self::set_nft_variable_data(collection_id, item_id, data)?,
- CollectionMode::ReFungible => Self::set_re_fungible_variable_data(collection_id, item_id, data)?,
+ CollectionMode::NFT => Self::set_nft_variable_data(&target_collection, item_id, data)?,
+ CollectionMode::ReFungible => Self::set_re_fungible_variable_data(&target_collection, item_id, data)?,
CollectionMode::Fungible(_) => fail!(Error::<T>::CantStoreMetadataInFungibleTokens),
_ => fail!(Error::<T>::UnexpectedCollectionType)
};
@@ -1312,10 +1312,10 @@
version: SchemaVersion
) -> DispatchResult {
let sender = ensure_signed(origin)?;
- Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;
- let mut target_collection = <Collection<T>>::get(collection_id).unwrap();
+ let mut target_collection = Self::get_collection(collection_id)?;
+ Self::check_owner_or_admin_permissions(&target_collection, sender.clone())?;
target_collection.schema_version = version;
- <Collection<T>>::insert(collection_id, target_collection);
+ Self::save_collection(target_collection);
Ok(())
}
@@ -1339,14 +1339,14 @@
schema: Vec<u8>
) -> DispatchResult {
let sender = ensure_signed(origin)?;
- Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;
+ let mut target_collection = Self::get_collection(collection_id)?;
+ Self::check_owner_or_admin_permissions(&target_collection, sender.clone())?;
// check schema limit
ensure!(schema.len() as u32 <= ChainLimit::get().offchain_schema_limit, "");
- let mut target_collection = <Collection<T>>::get(collection_id).unwrap();
target_collection.offchain_schema = schema;
- <Collection<T>>::insert(collection_id, target_collection);
+ Self::save_collection(target_collection);
Ok(())
}
@@ -1370,14 +1370,14 @@
schema: Vec<u8>
) -> DispatchResult {
let sender = ensure_signed(origin)?;
- Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;
+ let mut target_collection = Self::get_collection(collection_id)?;
+ Self::check_owner_or_admin_permissions(&target_collection, sender.clone())?;
// check schema limit
ensure!(schema.len() as u32 <= ChainLimit::get().const_on_chain_schema_limit, "");
- let mut target_collection = <Collection<T>>::get(collection_id).unwrap();
target_collection.const_on_chain_schema = schema;
- <Collection<T>>::insert(collection_id, target_collection);
+ Self::save_collection(target_collection);
Ok(())
}
@@ -1401,14 +1401,14 @@
schema: Vec<u8>
) -> DispatchResult {
let sender = ensure_signed(origin)?;
- Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;
+ let mut target_collection = Self::get_collection(collection_id)?;
+ Self::check_owner_or_admin_permissions(&target_collection, sender.clone())?;
// check schema limit
ensure!(schema.len() as u32 <= ChainLimit::get().variable_on_chain_schema_limit, "");
- let mut target_collection = <Collection<T>>::get(collection_id).unwrap();
target_collection.variable_on_chain_schema = schema;
- <Collection<T>>::insert(collection_id, target_collection);
+ Self::save_collection(target_collection);
Ok(())
}
@@ -1577,8 +1577,8 @@
new_limits: CollectionLimits<T::BlockNumber>,
) -> DispatchResult {
let sender = ensure_signed(origin)?;
- Self::check_owner_permissions(collection_id, sender.clone())?;
- let mut target_collection = <Collection<T>>::get(collection_id).unwrap();
+ let mut target_collection = Self::get_collection(collection_id)?;
+ Self::check_owner_permissions(&target_collection, sender.clone())?;
let old_limits = target_collection.limits;
let chain_limits = ChainLimit::get();
@@ -1599,7 +1599,7 @@
);
target_collection.limits = new_limits;
- <Collection<T>>::insert(collection_id, target_collection);
+ Self::save_collection(target_collection);
Ok(())
}
@@ -1607,39 +1607,37 @@
}
impl<T: Config> Module<T> {
-
- pub fn transfer_internal(sender: T::AccountId, recipient: T::AccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResult {
- let target_collection = <Collection<T>>::get(collection_id).unwrap();
-
+ pub fn transfer_internal(sender: T::AccountId, recipient: T::AccountId, target_collection: &Collection<T>, item_id: TokenId, value: u128) -> DispatchResult {
// Limits check
- Self::is_correct_transfer(collection_id, &target_collection, &recipient)?;
+ Self::is_correct_transfer(target_collection, &recipient)?;
// Transfer permissions check
- ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) ||
- Self::is_owner_or_admin_permissions(collection_id, sender.clone()),
+ ensure!(Self::is_item_owner(sender.clone(), target_collection, item_id) ||
+ Self::is_owner_or_admin_permissions(target_collection, sender.clone()),
Error::<T>::NoPermission);
if target_collection.access == AccessMode::WhiteList {
- Self::check_white_list(collection_id, &sender)?;
- Self::check_white_list(collection_id, &recipient)?;
+ Self::check_white_list(target_collection, &sender)?;
+ Self::check_white_list(target_collection, &recipient)?;
}
match target_collection.mode
{
- CollectionMode::NFT => Self::transfer_nft(collection_id, item_id, sender.clone(), recipient.clone())?,
- CollectionMode::Fungible(_) => Self::transfer_fungible(collection_id, value, &sender, &recipient)?,
- CollectionMode::ReFungible => Self::transfer_refungible(collection_id, item_id, value, sender.clone(), recipient.clone())?,
+ CollectionMode::NFT => Self::transfer_nft(target_collection, item_id, sender.clone(), recipient.clone())?,
+ CollectionMode::Fungible(_) => Self::transfer_fungible(target_collection, value, &sender, &recipient)?,
+ CollectionMode::ReFungible => Self::transfer_refungible(target_collection, item_id, value, sender.clone(), recipient.clone())?,
_ => ()
};
- Self::deposit_event(RawEvent::Transfer(collection_id, item_id, sender, recipient, value));
+ Self::deposit_event(RawEvent::Transfer(target_collection.id, item_id, sender, recipient, value));
Ok(())
}
- fn is_correct_transfer(collection_id: CollectionId, collection: &CollectionType<T>, recipient: &T::AccountId) -> DispatchResult {
+ fn is_correct_transfer(collection: &Collection<T>, recipient: &T::AccountId) -> DispatchResult {
+ let collection_id = collection.id;
// check token limit and account token limit
let account_items: u32 = <AddressTokens<T>>::get(collection_id, recipient).len() as u32;
@@ -1648,7 +1646,8 @@
Ok(())
}
- fn can_create_items_in_collection(collection_id: CollectionId, collection: &CollectionType<T>, sender: &T::AccountId, owner: &T::AccountId) -> DispatchResult {
+ fn can_create_items_in_collection(collection: &Collection<T>, sender: &T::AccountId, owner: &T::AccountId) -> DispatchResult {
+ let collection_id = collection.id;
// check token limit and account token limit
let total_items: u32 = ItemListIndex::get(collection_id);
@@ -1656,16 +1655,16 @@
ensure!(collection.limits.token_limit > total_items, Error::<T>::CollectionTokenLimitExceeded);
ensure!(collection.limits.account_token_ownership_limit > account_items, Error::<T>::AccountTokenLimitExceeded);
- if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) {
+ if !Self::is_owner_or_admin_permissions(collection, sender.clone()) {
ensure!(collection.mint_mode == true, Error::<T>::PublicMintingNotAllowed);
- Self::check_white_list(collection_id, owner)?;
- Self::check_white_list(collection_id, sender)?;
+ Self::check_white_list(collection, owner)?;
+ Self::check_white_list(collection, sender)?;
}
Ok(())
}
- fn validate_create_item_args(target_collection: &CollectionType<T>, data: &CreateItemData) -> DispatchResult {
+ fn validate_create_item_args(target_collection: &Collection<T>, data: &CreateItemData) -> DispatchResult {
match target_collection.mode
{
CollectionMode::NFT => {
@@ -1703,7 +1702,9 @@
Ok(())
}
- fn create_item_no_validation(collection_id: CollectionId, owner: T::AccountId, data: CreateItemData) -> DispatchResult {
+ fn create_item_no_validation(collection: &Collection<T>, owner: T::AccountId, data: CreateItemData) -> DispatchResult {
+ let collection_id = collection.id;
+
match data
{
CreateItemData::NFT(data) => {
@@ -1713,10 +1714,10 @@
variable_data: data.variable_data
};
- Self::add_nft_item(collection_id, item)?;
+ Self::add_nft_item(collection, item)?;
},
CreateItemData::Fungible(data) => {
- Self::add_fungible_item(collection_id, &owner, data.value)?;
+ Self::add_fungible_item(collection, &owner, data.value)?;
},
CreateItemData::ReFungible(data) => {
let mut owner_list = Vec::new();
@@ -1728,7 +1729,7 @@
variable_data: data.variable_data
};
- Self::add_refungible_item(collection_id, item)?;
+ Self::add_refungible_item(collection, item)?;
}
};
@@ -1738,7 +1739,8 @@
Ok(())
}
- fn add_fungible_item(collection_id: CollectionId, owner: &T::AccountId, value: u128) -> DispatchResult {
+ fn add_fungible_item(collection: &Collection<T>, owner: &T::AccountId, value: u128) -> DispatchResult {
+ let collection_id = collection.id;
// Does new owner already have an account?
let mut balance: u128 = 0;
@@ -1761,7 +1763,9 @@
Ok(())
}
- fn add_refungible_item(collection_id: CollectionId, item: ReFungibleItemType<T::AccountId>) -> DispatchResult {
+ fn add_refungible_item(collection: &Collection<T>, item: ReFungibleItemType<T::AccountId>) -> DispatchResult {
+ let collection_id = collection.id;
+
let current_index = <ItemListIndex>::get(collection_id)
.checked_add(1)
.ok_or(Error::<T>::NumOverflow)?;
@@ -1784,7 +1788,9 @@
Ok(())
}
- fn add_nft_item(collection_id: CollectionId, item: NftItemType<T::AccountId>) -> DispatchResult {
+ fn add_nft_item(collection: &Collection<T>, item: NftItemType<T::AccountId>) -> DispatchResult {
+ let collection_id = collection.id;
+
let current_index = <ItemListIndex>::get(collection_id)
.checked_add(1)
.ok_or(Error::<T>::NumOverflow)?;
@@ -1805,10 +1811,12 @@
}
fn burn_refungible_item(
- collection_id: CollectionId,
+ collection: &Collection<T>,
item_id: TokenId,
owner: &T::AccountId,
) -> DispatchResult {
+ let collection_id = collection.id;
+
ensure!(
<ReFungibleItemList<T>>::contains_key(collection_id, item_id),
Error::<T>::TokenNotFound
@@ -1849,7 +1857,9 @@
Ok(())
}
- fn burn_nft_item(collection_id: CollectionId, item_id: TokenId) -> DispatchResult {
+ fn burn_nft_item(collection: &Collection<T>, item_id: TokenId) -> DispatchResult {
+ let collection_id = collection.id;
+
ensure!(
<NftItemList<T>>::contains_key(collection_id, item_id),
Error::<T>::TokenNotFound
@@ -1868,7 +1878,9 @@
Ok(())
}
- fn burn_fungible_item(owner: &T::AccountId, collection_id: CollectionId, value: u128) -> DispatchResult {
+ fn burn_fungible_item(owner: &T::AccountId, collection: &Collection<T>, value: u128) -> DispatchResult {
+ let collection_id = collection.id;
+
ensure!(
<FungibleItemList<T>>::contains_key(collection_id, owner),
Error::<T>::TokenNotFound
@@ -1893,18 +1905,16 @@
Ok(())
}
- fn collection_exists(collection_id: CollectionId) -> DispatchResult {
- ensure!(
- <Collection<T>>::contains_key(collection_id),
- Error::<T>::CollectionNotFound
- );
- Ok(())
+ pub fn get_collection(collection_id: CollectionId) -> Result<Collection<T>, sp_runtime::DispatchError> {
+ Ok(<CollectionById<T>>::get(collection_id)
+ .ok_or(Error::<T>::CollectionNotFound)?)
}
- fn check_owner_permissions(collection_id: CollectionId, subject: T::AccountId) -> DispatchResult {
- Self::collection_exists(collection_id)?;
+ fn save_collection(collection: Collection<T>) {
+ <CollectionById<T>>::insert(collection.id, collection);
+ }
- let target_collection = <Collection<T>>::get(collection_id).unwrap();
+ fn check_owner_permissions(target_collection: &Collection<T>, subject: T::AccountId) -> DispatchResult {
ensure!(
subject == target_collection.owner,
Error::<T>::NoPermission
@@ -1913,13 +1923,12 @@
Ok(())
}
- fn is_owner_or_admin_permissions(collection_id: CollectionId, subject: T::AccountId) -> bool {
- let target_collection = <Collection<T>>::get(collection_id).unwrap();
- let mut result: bool = subject == target_collection.owner;
- let exists = <AdminList<T>>::contains_key(collection_id);
+ fn is_owner_or_admin_permissions(collection: &Collection<T>, subject: T::AccountId) -> bool {
+ let mut result: bool = subject == collection.owner;
+ let exists = <AdminList<T>>::contains_key(collection.id);
if !result & exists {
- if <AdminList<T>>::get(collection_id).contains(&subject) {
+ if <AdminList<T>>::get(collection.id).contains(&subject) {
result = true
}
}
@@ -1928,11 +1937,10 @@
}
fn check_owner_or_admin_permissions(
- collection_id: CollectionId,
+ collection: &Collection<T>,
subject: T::AccountId,
) -> DispatchResult {
- Self::collection_exists(collection_id)?;
- let result = Self::is_owner_or_admin_permissions(collection_id, subject.clone());
+ let result = Self::is_owner_or_admin_permissions(collection, subject.clone());
ensure!(
result,
@@ -1943,10 +1951,10 @@
fn owned_amount(
subject: T::AccountId,
- collection_id: CollectionId,
+ target_collection: &Collection<T>,
item_id: TokenId,
) -> Option<u128> {
- let target_collection = <Collection<T>>::get(collection_id);
+ let collection_id = target_collection.id;
match target_collection.mode {
CollectionMode::NFT => {
@@ -1971,8 +1979,8 @@
}
}
- fn is_item_owner(subject: T::AccountId, collection_id: CollectionId, item_id: TokenId) -> bool {
- let target_collection = <Collection<T>>::get(collection_id).unwrap();
+ fn is_item_owner(subject: T::AccountId, target_collection: &Collection<T>, item_id: TokenId) -> bool {
+ let collection_id = target_collection.id;
match target_collection.mode {
CollectionMode::NFT => {
@@ -1991,7 +1999,9 @@
}
}
- fn check_white_list(collection_id: CollectionId, address: &T::AccountId) -> DispatchResult {
+ fn check_white_list(collection: &Collection<T>, address: &T::AccountId) -> DispatchResult {
+ let collection_id = collection.id;
+
let mes = Error::<T>::AddresNotInWhiteList;
ensure!(<WhiteList<T>>::contains_key(collection_id, address), mes);
@@ -2001,11 +2011,11 @@
/// Check if token exists. In case of Fungible, check if there is an entry for
/// the owner in fungible balances double map
fn token_exists(
- collection_id: CollectionId,
+ target_collection: &Collection<T>,
item_id: TokenId,
owner: &T::AccountId
) -> DispatchResult {
- let target_collection = <Collection<T>>::get(collection_id).unwrap();
+ let collection_id = target_collection.id;
let exists = match target_collection.mode
{
CollectionMode::NFT => <NftItemList<T>>::contains_key(collection_id, item_id),
@@ -2019,18 +2029,19 @@
}
fn transfer_fungible(
- collection_id: CollectionId,
+ collection: &Collection<T>,
value: u128,
owner: &T::AccountId,
recipient: &T::AccountId,
) -> DispatchResult {
- Self::token_exists(collection_id, 0, owner)?;
+ let collection_id = collection.id;
+ Self::token_exists(&collection, 0, owner)?;
let mut balance = <FungibleItemList<T>>::get(collection_id, owner);
ensure!(balance.value >= value, Error::<T>::TokenValueTooLow);
// Send balance to recipient (updates balanceOf of recipient)
- Self::add_fungible_item(collection_id, recipient, value)?;
+ Self::add_fungible_item(collection, recipient, value)?;
// update balanceOf of sender
<Balance<T>>::insert(collection_id, (*owner).clone(), balance.value - value);
@@ -2048,13 +2059,14 @@
}
fn transfer_refungible(
- collection_id: CollectionId,
+ collection: &Collection<T>,
item_id: TokenId,
value: u128,
owner: T::AccountId,
new_owner: T::AccountId,
) -> DispatchResult {
- Self::token_exists(collection_id, item_id, &owner)?;
+ let collection_id = collection.id;
+ Self::token_exists(collection, item_id, &owner)?;
let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id);
let item = full_item
@@ -2130,12 +2142,13 @@
}
fn transfer_nft(
- collection_id: CollectionId,
+ collection: &Collection<T>,
item_id: TokenId,
sender: T::AccountId,
new_owner: T::AccountId,
) -> DispatchResult {
- Self::token_exists(collection_id, item_id, &sender)?;
+ let collection_id = collection.id;
+ Self::token_exists(&collection, item_id, &sender)?;
let mut item = <NftItemList<T>>::get(collection_id, item_id);
@@ -2167,10 +2180,11 @@
}
fn set_re_fungible_variable_data(
- collection_id: CollectionId,
+ collection: &Collection<T>,
item_id: TokenId,
data: Vec<u8>
) -> DispatchResult {
+ let collection_id = collection.id;
let mut item = <ReFungibleItemList<T>>::get(collection_id, item_id);
item.variable_data = data;
@@ -2181,10 +2195,11 @@
}
fn set_nft_variable_data(
- collection_id: CollectionId,
+ collection: &Collection<T>,
item_id: TokenId,
data: Vec<u8>
) -> DispatchResult {
+ let collection_id = collection.id;
let mut item = <NftItemList<T>>::get(collection_id, item_id);
item.variable_data = data;
@@ -2194,7 +2209,7 @@
Ok(())
}
- fn init_collection(item: &CollectionType<T>) {
+ fn init_collection(item: &Collection<T>) {
// check params
assert!(
item.decimal_points <= MAX_DECIMAL_POINTS,
@@ -2274,7 +2289,6 @@
}
fn add_token_index(collection_id: CollectionId, item_index: TokenId, owner: &T::AccountId) -> DispatchResult {
-
// add to account limit
if <AccountItemCount<T>>::contains_key(owner) {
@@ -2449,38 +2463,34 @@
// Determine who is paying transaction fee based on ecnomic model
// Parse call to extract collection ID and access collection sponsor
- let mut sponsor: T::AccountId = match IsSubType::<Call<T>>::is_sub_type(call) {
+ let mut sponsor: Option<T::AccountId> = (|| match IsSubType::<Call<T>>::is_sub_type(call) {
Some(Call::create_item(collection_id, _owner, _properties)) => {
- let collection = <Collection<T>>::get(collection_id).unwrap();
+ let collection = <CollectionById<T>>::get(collection_id)?;
// sponsor timeout
let block_number = <system::Module<T>>::block_number() as T::BlockNumber;
let limit = collection.limits.sponsor_transfer_timeout;
- let mut sponsored = true;
if <CreateItemBasket<T>>::contains_key((collection_id, &who)) {
let last_tx_block = <CreateItemBasket<T>>::get((collection_id, &who));
let limit_time = last_tx_block + limit.into();
if block_number <= limit_time {
- sponsored = false;
+ return None;
}
- }
- if sponsored {
- <CreateItemBasket<T>>::insert((collection_id, who.clone()), block_number);
}
+ <CreateItemBasket<T>>::insert((collection_id, who.clone()), block_number);
// check free create limit
if (collection.limits.sponsored_data_size >= (_properties.len() as u32)) &&
- (collection.sponsor_confirmed) &&
- (sponsored)
+ (collection.sponsor_confirmed)
{
- collection.sponsor
+ Some(collection.sponsor)
} else {
- T::AccountId::default()
+ None
}
}
Some(Call::transfer(_new_owner, collection_id, item_id, _value)) => {
- let collection = <Collection<T>>::get(collection_id).unwrap();
+ let collection = <CollectionById<T>>::get(collection_id)?;
let mut sponsor_transfer = false;
if collection.sponsor_confirmed {
@@ -2568,16 +2578,16 @@
}
if !sponsor_transfer {
- T::AccountId::default()
+ None
} else {
- collection.sponsor
+ Some(collection.sponsor)
}
}
Some(Call::set_variable_meta_data(collection_id, item_id, data)) => {
let mut sponsor_metadata_changes = false;
- let collection = <Collection<T>>::get(collection_id).unwrap();
+ let collection = <CollectionById<T>>::get(collection_id)?;
if
collection.sponsor_confirmed &&
@@ -2600,17 +2610,35 @@
}
if !sponsor_metadata_changes {
- T::AccountId::default()
+ None
} else {
- collection.sponsor
+ Some(collection.sponsor)
}
}
- _ => T::AccountId::default(),
- };
+ _ => None,
+ })();
+
+ match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {
+ Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {
+ let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());
+
+ let owned_contract = <ContractOwner<T>>::contains_key(called_contract.clone())
+ && <ContractOwner<T>>::get(called_contract.clone()) == *who;
+ let white_list_enabled = <ContractWhiteListEnabled<T>>::contains_key(called_contract.clone()) && <ContractWhiteListEnabled<T>>::get(called_contract.clone());
+
+ if !owned_contract && white_list_enabled {
+ if !<ContractWhiteList<T>>::contains_key(called_contract.clone(), who) {
+ return Err(InvalidTransaction::Call.into());
+ }
+ }
+ },
+ _ => {},
+ }
+
// Sponsor smart contracts
- sponsor = match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {
+ sponsor = sponsor.or_else(|| match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {
// On instantiation: set the contract owner
Some(pallet_contracts::Call::instantiate(_endowment, _gas_limit, code_hash, _data, salt)) => {
@@ -2622,7 +2650,7 @@
);
<ContractOwner<T>>::insert(new_contract_address.clone(), who.clone());
- T::AccountId::default()
+ None
},
// When the contract is called, check if the sponsoring is enabled and pay fees from contract endowment if it is
@@ -2630,16 +2658,6 @@
let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());
- let owned_contract = <ContractOwner<T>>::contains_key(called_contract.clone())
- && <ContractOwner<T>>::get(called_contract.clone()) == *who;
- let white_list_enabled = <ContractWhiteListEnabled<T>>::contains_key(called_contract.clone()) && <ContractWhiteListEnabled<T>>::get(called_contract.clone());
-
- if !owned_contract && white_list_enabled {
- if !<ContractWhiteList<T>>::contains_key(called_contract.clone(), who) {
- return Err(InvalidTransaction::Call.into());
- }
- }
-
let mut sponsor_transfer = false;
if <ContractSponsoringRateLimit<T>>::contains_key(called_contract.clone()) {
let last_tx_block = <ContractSponsorBasket<T>>::get((&called_contract, &who));
@@ -2655,26 +2673,21 @@
sponsor_transfer = false;
}
-
- let mut sp = T::AccountId::default();
if sponsor_transfer {
if <ContractSelfSponsoring<T>>::contains_key(called_contract.clone()) {
if <ContractSelfSponsoring<T>>::get(called_contract.clone()) {
- sp = called_contract;
+ return Some(called_contract);
}
}
}
- sp
+ None
},
- _ => sponsor,
- };
+ _ => None,
+ });
- let mut who_pays_fee: T::AccountId = sponsor.clone();
- if sponsor == T::AccountId::default() {
- who_pays_fee = who.clone();
- }
+ let who_pays_fee = sponsor.unwrap_or_else(|| who.clone());
<<T as transaction_payment::Config>::OnChargeTransaction as transaction_payment::OnChargeTransaction<T>>::withdraw_fee(&who_pays_fee, call, info, fee, tip)
.map(|i| (fee, i))
runtime/src/chain_extension.rsdiffbeforeafterboth--- a/runtime/src/chain_extension.rs
+++ b/runtime/src/chain_extension.rs
@@ -60,7 +60,9 @@
}
let recipient = AccountId32::from(bytes_rec);
- match pallet_nft::Module::<Runtime>::transfer_internal(sender, recipient, input.collection_id, input.token_id, input.amount) {
+ let collection = pallet_nft::Module::<Runtime>::get_collection(input.collection_id)?;
+
+ match pallet_nft::Module::<Runtime>::transfer_internal(sender, recipient, &collection, input.token_id, input.amount) {
Ok(_) => Ok(RetVal::Converging(func_id)),
_ => Err(DispatchError::Other("Transfer error"))
}
runtime_types.jsondiffbeforeafterboth31 "ConstData": "Vec<u8>",31 "ConstData": "Vec<u8>",32 "VariableData": "Vec<u8>"32 "VariableData": "Vec<u8>"33 },33 },34 "CollectionType": {34 "Collection": {35 "Id": "CollectionId",35 "Owner": "AccountId",36 "Owner": "AccountId",36 "Mode": "CollectionMode",37 "Mode": "CollectionMode",37 "Access": "AccessMode",38 "Access": "AccessMode",