Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement changeissuer for base #126

Merged
merged 1 commit into from
May 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/pallets/rmrk-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ Rejects an NFT sent from another account to self or owned NFT
nft_id: NftId
```

### **change_issuer**
changing the issuer of a collection or base
### **change_collection_issuer**
changing the issuer of a collection
```rust
collection_id: CollectionId,
new_issuer: <T::Lookup as StaticLookup>::Source
Expand Down
9 changes: 7 additions & 2 deletions pallets/rmrk-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,10 +487,15 @@ pub mod pallet {
Ok(())
}

/// changing the issuer of a collection or a base
/// Change the issuer of a collection
///
/// Parameters:
/// - `origin`: sender of the transaction
/// - `collection_id`: collection id of the nft to change issuer of
/// - `new_issuer`: Collection's new issuer
#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
#[transactional]
pub fn change_issuer(
pub fn change_collection_issuer(
origin: OriginFor<T>,
collection_id: CollectionId,
new_issuer: <T::Lookup as StaticLookup>::Source,
Expand Down
6 changes: 3 additions & 3 deletions pallets/rmrk-core/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,17 +175,17 @@ fn destroy_collection_works() {

/// Collection: Change issuer tests (RMRK2.0 spec: CHANGEISSUER)=
#[test]
fn change_issuer_works() {
fn change_collection_issuer_works() {
ExtBuilder::default().build().execute_with(|| {
// Create a basic collection
assert_ok!(basic_collection());
// BOB can't change issuer because he is not the current issuer
assert_noop!(
RMRKCore::change_issuer(Origin::signed(BOB), 0, BOB),
RMRKCore::change_collection_issuer(Origin::signed(BOB), 0, BOB),
Error::<Test>::NoPermission
);
// Change issuer from ALICE to BOB
assert_ok!(RMRKCore::change_issuer(Origin::signed(ALICE), 0, BOB));
assert_ok!(RMRKCore::change_collection_issuer(Origin::signed(ALICE), 0, BOB));
// Changing issuer should trigger IssuerChanged event
System::assert_last_event(MockEvent::RmrkCore(crate::Event::IssuerChanged {
old_issuer: ALICE,
Expand Down
22 changes: 22 additions & 0 deletions pallets/rmrk-equip/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,28 @@ where
Ok(base_id)
}

/// Implementation of the base_change_issuer function for the Base trait
/// Called by the change_base_issuer extrinsic to change the issuer of a base
///
/// Parameters:
/// - base_id: The Base ID to change the issuer of
/// - new_issuer: The Account to become the new issuer
fn base_change_issuer(
base_id: BaseId,
new_issuer: T::AccountId,
) -> Result<(T::AccountId, CollectionId), DispatchError> {
ensure!(Bases::<T>::contains_key(base_id), Error::<T>::NoAvailableBaseId);

Bases::<T>::try_mutate_exists(base_id, |base| -> DispatchResult {
if let Some(b) = base {
b.issuer = new_issuer.clone();
}
Ok(())
})?;

Ok((new_issuer, base_id))
}

/// Implementation of the do_equip function for the Base trait
/// Called by the equip extrinsic to equip a child NFT's resource to a parent's slot, if all are available.
/// Also can be called to unequip, which can be successful if
Expand Down
41 changes: 41 additions & 0 deletions pallets/rmrk-equip/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use frame_support::{
};
use sp_std::vec::Vec;

use sp_runtime::{traits::StaticLookup};

pub use pallet::*;

use rmrk_traits::{
Expand Down Expand Up @@ -136,6 +138,12 @@ pub mod pallet {
base_id: BaseId,
slot_id: SlotId,
},
// Base's issuer has changed
BaseIssuerChanged {
old_issuer: T::AccountId,
new_issuer: T::AccountId,
base_id: BaseId,
},
}

#[pallet::error]
Expand Down Expand Up @@ -188,6 +196,39 @@ pub mod pallet {
where
T: pallet_uniques::Config<ClassId = CollectionId, InstanceId = NftId>,
{
/// Change the issuer of a Base
///
/// Parameters:
/// - `origin`: sender of the transaction
/// - `base_id`: base_id to change issuer of
/// - `new_issuer`: Base's new issuer
#[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
pub fn change_base_issuer(
origin: OriginFor<T>,
base_id: BaseId,
new_issuer: <T::Lookup as StaticLookup>::Source,
) -> DispatchResult {
let sender = ensure_signed(origin.clone())?;
let base =
Self::bases(base_id).ok_or(Error::<T>::BaseDoesntExist)?;
ensure!(base.issuer == sender, Error::<T>::PermissionError);
let new_owner = T::Lookup::lookup(new_issuer.clone())?;

ensure!(
Bases::<T>::contains_key(base_id),
Error::<T>::NoAvailableBaseId
);

let (new_owner, base_id) =
Self::base_change_issuer(base_id, new_owner)?;

Self::deposit_event(Event::BaseIssuerChanged {
old_issuer: sender,
new_issuer: new_owner,
base_id,
});
Ok(())
}
/// Equips a child NFT's resource to a parent's slot, if all are available.
/// Also can be called to unequip, which can be successful if
/// - Item has beeen burned
Expand Down
31 changes: 31 additions & 0 deletions pallets/rmrk-equip/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,37 @@ fn create_base_works() {
});
}

/// Base: Change issuer tests (RMRK2.0 spec: CHANGEISSUER)=
#[test]
fn change_base_issuer_works() {
ExtBuilder::default().build().execute_with(|| {
// Create a base
assert_ok!(RmrkEquip::create_base(
Origin::signed(ALICE), // origin
bvec![0u8; 20], // base_type
bvec![0u8; 20], // symbol
vec![], // parts
));
// Issuer should be Alice
assert_eq!(RmrkEquip::bases(0).unwrap().issuer, ALICE);
// Bob can't change issuer (no permission)
assert_noop!(
RmrkEquip::change_base_issuer(Origin::signed(BOB), 0, BOB),
Error::<Test>::PermissionError);
// Changing Base Issuer should be Alice
assert_ok!(RmrkEquip::change_base_issuer(Origin::signed(ALICE), 0, BOB));
// Issuer should be Bob
assert_eq!(RmrkEquip::bases(0).unwrap().issuer, BOB);
// Last event should be BaseIssuerChanged
System::assert_last_event(MockEvent::RmrkEquip(crate::Event::BaseIssuerChanged {
old_issuer: ALICE,
new_issuer: BOB,
base_id: 0,
}));

});
}

/// Base: Attempting to create a base with more the max parts fails
#[test]
fn exceeding_max_parts_per_base_fails() {
Expand Down
4 changes: 4 additions & 0 deletions traits/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ pub trait Base<AccountId, CollectionId, NftId, BoundedString> {
symbol: BoundedString,
parts: Vec<PartType<BoundedString>>,
) -> Result<BaseId, DispatchError>;
fn base_change_issuer(
base_id: BaseId,
new_issuer: AccountId,
) -> Result<(AccountId, CollectionId), DispatchError>;
fn do_equip(
issuer: AccountId, // Maybe don't need?
item: (CollectionId, NftId),
Expand Down