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

Add nft module #296

Merged
merged 11 commits into from
Sep 28, 2020
Merged

Add nft module #296

merged 11 commits into from
Sep 28, 2020

Conversation

zjb0807
Copy link
Contributor

@zjb0807 zjb0807 commented Sep 25, 2020

No description provided.

@zjb0807 zjb0807 requested a review from xlc September 25, 2020 02:34
impl<T: Trait> Module<T> {
/// Create NFT(non fungible token) class
pub fn create_class(owner: &T::AccountId, metadata: CID, data: T::ClassData) -> Result<T::ClassId, DispatchError> {
let class_id = Self::next_class_id();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let class_id = NextClassId::<T>::try_mutate(|id| {
  let currentId = *id;
  *id = id.checked_add(One::one()).ok_or(Error::<T>::NoAvailableClassId);
  currentId
})?;

info.owner = to.clone();
}
});
TokensByOwner::<T>::remove(from.clone(), token);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TokensByOwner::<T>::remove(from.clone(), token);
TokensByOwner::<T>::remove(from, token);

the key can be a reference so never need to clone the key. take a reference if needed.

}
});
TokensByOwner::<T>::remove(from.clone(), token);
TokensByOwner::<T>::insert(to.clone(), token, ());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TokensByOwner::<T>::insert(to.clone(), token, ());
TokensByOwner::<T>::insert(to, token, ());


/// Transfer NFT(non fungible token) from `from` account to `to` account
pub fn transfer(from: &T::AccountId, to: &T::AccountId, token: (T::ClassId, T::TokenId)) -> DispatchResult {
ensure!(Tokens::<T>::contains_key(token.0, token.1), Error::<T>::TokenNotFound);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be able to combine the contains_key and mutate with try_mutate_exists, same for TokensByOwner

One example

<Auctions<T>>::try_mutate_exists(id, |auction| -> DispatchResult {
let mut auction = auction.as_mut().ok_or(Error::<T>::AuctionNotExist)?;

Ok(())
})?;
Tokens::<T>::insert(class_id, token_id, token_info);
TokensByOwner::<T>::insert(owner.clone(), (class_id, token_id), ());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TokensByOwner::<T>::insert(owner.clone(), (class_id, token_id), ());
TokensByOwner::<T>::insert(owner, (class_id, token_id), ());

data: T::TokenData,
) -> Result<T::TokenId, DispatchError> {
let token_id = Self::next_token_id();
ensure!(token_id != T::TokenId::max_value(), Error::<T>::NoAvailableTokenId);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing update next token id?

if let Some(info) = class_info {
info.total_issuance = info
.total_issuance
.checked_sub(&1.into())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use One::one() over 1.into(). Learn from Gav paritytech/substrate#5715 (comment)

}
Ok(())
})?;
Tokens::<T>::remove(token.0, token.1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be able to use take().ok_or(Error::<T>::TokenNotFound) to combine remove and check.


/// Destroy NFT(non fungible token) class
pub fn destroy_class(owner: &T::AccountId, class_id: T::ClassId) -> DispatchResult {
ensure!(Classes::<T>::contains_key(class_id), Error::<T>::ClassNotFound);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use try_mutate_exists to avoid multiple access

@xlc
Copy link
Member

xlc commented Sep 25, 2020

Looks good. Just needs some small optimizations and improvements.

@zjb0807 zjb0807 requested a review from xlc September 25, 2020 07:27
Ok(current_id)
})?;

Classes::<T>::try_mutate(class_id, |class_info| -> DispatchResult {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could fail and NextTokenId still get updated.

Should put rest of the method into the NextTokenId::try_mutate closure

ensure!(token_info.take().is_some(), Error::<T>::TokenNotFound);
Ok(())
})?;
TokensByOwner::<T>::try_mutate_exists(owner, token, |info| -> DispatchResult {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could fail and Tokens still get updates.

Should put rest of the method into the Tokens:: try_mutate_exists closure

@xlc xlc merged commit 4892257 into master Sep 28, 2020
@xlc xlc deleted the nft branch September 28, 2020 03:13
@zjb0807 zjb0807 mentioned this pull request Sep 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants