difftreelog
refunfible transfer
in: master
1 file changed
pallets/nft/src/lib.rsdiffbeforeafterboth42 Invalid,42 Invalid,43 // custom data size43 // custom data size44 NFT(u32),44 NFT(u32),45 // amount45 // decimal points46 Fungible(u32),46 Fungible(u32),47 // custom data size47 ReFungible,48 ReFungible(u32),48}49}495050impl Into<u8> for CollectionMode {51impl Into<u8> for CollectionMode {53 CollectionMode::Invalid => 0,54 CollectionMode::Invalid => 0,54 CollectionMode::NFT(_) => 1,55 CollectionMode::NFT(_) => 1,55 CollectionMode::Fungible(_) => 2,56 CollectionMode::Fungible(_) => 2,56 CollectionMode::ReFungible => 3,57 CollectionMode::ReFungible(_) => 3,57 }58 }58 }59 }59}60}110#[cfg_attr(feature = "std", derive(Debug))]111#[cfg_attr(feature = "std", derive(Debug))]111pub struct FungibleItemType<AccountId> {112pub struct FungibleItemType<AccountId> {112 pub collection: u64,113 pub collection: u64,113 pub owner: Vec<AccountId>,114 pub owner: AccountId,114 pub data: Vec<u64>,115 pub value: u128,115}116}116117117#[derive(Encode, Decode, Default, Clone, PartialEq)]118#[derive(Encode, Decode, Default, Clone, PartialEq)]118#[cfg_attr(feature = "std", derive(Debug))]119#[cfg_attr(feature = "std", derive(Debug))]119pub struct ReFungibleItemType<AccountId> {120pub struct ReFungibleItemType<AccountId> {120 pub collection: u64,121 pub collection: u64,121 pub owner: Vec<Ownership<AccountId>>,122 pub owner: Vec<Ownership<AccountId>>,123 pub data: Vec<u8>,122}124}123125124pub trait Trait: system::Trait {126pub trait Trait: system::Trait {181 let who = ensure_signed(origin)?;183 let who = ensure_signed(origin)?;182 let custom_data_size = match mode {184 let custom_data_size = match mode {183 CollectionMode::NFT(size) => size,185 CollectionMode::NFT(size) => size,186 CollectionMode::ReFungible(size) => size,184 _ => 0187 _ => 0185 };188 };186189190 };193 };191194192 // check params195 // check params193 ensure!(decimal_points < 100, "decimal_points parameter must be lower than 100"); 196 ensure!(decimal_points <= 4, "decimal_points parameter must be lower than 4"); 194197195 let mut name = collection_name.to_vec();198 let mut name = collection_name.to_vec();196 name.push(0);199 name.push(0);357360358 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;361 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;359362360 let new_balance = <Balance<T>>::get(collection_id, owner.clone()) + 1;363 let new_balance = <Balance<T>>::get(collection_id, owner.clone()).checked_add(1).unwrap();361 <Balance<T>>::insert(collection_id, owner.clone(), new_balance);364 <Balance<T>>::insert(collection_id, owner.clone(), new_balance);362365363 // TODO: implement other modes366 // TODO: implement other modes374 Self::add_nft_item(item)?;377 Self::add_nft_item(item)?;375 378 376 },379 },380 CollectionMode::ReFungible(_) => {381 let mut owner_list = Vec::new();382 let value = (10 as u128).pow(target_collection.decimal_points);383 owner_list.push(Ownership {owner: owner, fraction: value});384385 let item = ReFungibleItemType {386 collection: collection_id,387 owner: owner_list,388 data: properties389 };390 391 Self::add_refungible_item(item)?;392 },377 _ => ()393 _ => ()378 };394 };379395392 {408 {393 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;409 Self::check_owner_or_admin_permissions(collection_id, sender.clone())?;394 }410 }395 411 let target_collection = <Collection<T>>::get(collection_id);412413 match target_collection.mode 414 {396 Self::burn_nft_item(collection_id, item_id)?;415 CollectionMode::NFT(_) => Self::burn_nft_item(collection_id, item_id)?,416 CollectionMode::ReFungible(_) => Self::burn_refungible_item(collection_id, item_id, sender.clone())?,417 _ => ()418 };397419398 // call event420 // call event399 Self::deposit_event(RawEvent::ItemDestroyed(collection_id, item_id));421 Self::deposit_event(RawEvent::ItemDestroyed(collection_id, item_id));417 match target_collection.mode 439 match target_collection.mode 418 {440 {419 CollectionMode::NFT(_) => Self::transfer_nft(collection_id, item_id, recipient)?,441 CollectionMode::NFT(_) => Self::transfer_nft(collection_id, item_id, recipient)?,442 CollectionMode::ReFungible(_) => Self::transfer_refungible(collection_id, item_id, value, sender.clone(), recipient)?,420 _ => ()443 _ => ()421 };444 };422445556579557 match target_collection.mode {580 match target_collection.mode {558 CollectionMode::NFT(_) => <NftItemList<T>>::get(collection_id, item_id).owner == subject,581 CollectionMode::NFT(_) => <NftItemList<T>>::get(collection_id, item_id).owner == subject,559 CollectionMode::Fungible(_) => <FungibleItemList<T>>::get(collection_id, item_id).owner.contains(&subject),582 CollectionMode::Fungible(_) => <FungibleItemList<T>>::get(collection_id, item_id).owner == subject,560 CollectionMode::ReFungible => <ReFungibleItemList<T>>::get(collection_id, item_id).owner.iter().any(|i| i.owner == subject),583 CollectionMode::ReFungible(_) => <ReFungibleItemList<T>>::get(collection_id, item_id).owner.iter().any(|i| i.owner == subject),561 CollectionMode::Invalid => false584 CollectionMode::Invalid => false562 }585 }563 }586 }564587588 fn add_refungible_item(item: ReFungibleItemType<T::AccountId>) -> DispatchResult {589590 let current_index = <ItemListIndex>::get(item.collection)591 .checked_add(1)592 .expect("Item list index id error");593594 Self::add_token_index(item.collection, current_index, item.owner.first().unwrap().owner.clone())?;595596 <ItemListIndex>::insert(item.collection, current_index);597 <ReFungibleItemList<T>>::insert(item.collection, current_index, item); 598599 Ok(())600 }601602 fn burn_refungible_item(collection_id: u64, item_id: u64, owner: T::AccountId) -> DispatchResult {603 604 let collection = <ReFungibleItemList<T>>::get(collection_id, item_id);605 let item = collection.owner.iter().filter(|&i| i.owner == owner).next().unwrap();606 Self::remove_token_index(collection_id, item_id, owner)?;607608 // update balance609 let new_balance = <Balance<T>>::get(collection_id, item.owner.clone()).checked_sub(item.fraction as u64).unwrap();610 <Balance<T>>::insert(collection_id, item.owner.clone(), new_balance);611612 // TODO613 <ReFungibleItemList<T>>::remove(collection_id, item_id);614615 Ok(())616 }617618 fn transfer_refungible(collection_id: u64, item_id: u64, value: u64, owner: T::AccountId, new_owner: T::AccountId) -> DispatchResult {619620 let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id);621 let item = full_item.owner.iter().filter(|i| i.owner == owner).next().unwrap();622 let amount = item.fraction;623624 ensure!(amount < value.into(),"Item balance not enouth");625626 // update balance627 let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.clone()).checked_sub(value).unwrap();628 <Balance<T>>::insert(collection_id, item.owner.clone(), balance_old_owner);629630 let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.clone()).checked_add(value).unwrap();631 <Balance<T>>::insert(collection_id, new_owner.clone(), balance_new_owner);632633 let old_owner = item.owner.clone();634 let new_owner_has_account = full_item.owner.iter().any(|i| i.owner == new_owner);635636 // transfer637 if amount == value.into() && !new_owner_has_account638 {639 // change owner640 // new owner do not have account641 let mut new_full_item = full_item.clone();642 new_full_item.owner.iter_mut().find(|i| i.owner == owner).unwrap().owner = new_owner.clone();643 <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);644645 // update index collection646 Self::move_token_index(collection_id, item_id, old_owner.clone(), new_owner.clone())?;647 }648 else649 {650 let mut new_full_item = full_item.clone();651 new_full_item.owner.iter_mut().find(|i| i.owner == owner).unwrap().fraction -= amount;652653 // separate amount654 if new_owner_has_account {655 // new owner has account656 new_full_item.owner.iter_mut().find(|i| i.owner == new_owner).unwrap().fraction += amount;657 }658 else659 {660 // new owner do not have account661 new_full_item.owner.push(Ownership { owner: new_owner.clone(), fraction: amount});662 Self::add_token_index(collection_id, item_id, new_owner.clone())?;663 }664665 <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);666 }667668 Ok(())669 }670 565 fn add_nft_item(item: NftItemType<T::AccountId>) -> DispatchResult {671 fn add_nft_item(item: NftItemType<T::AccountId>) -> DispatchResult {566672