git.delta.rocks / unique-network / refs/commits / 1aac61d1c876

difftreelog

source

runtime/src/chain_extension.rs6.8 KiBsourcehistory
1//! NFT Chain Extension23//4// This file is subject to the terms and conditions defined in5// file 'LICENSE', which is part of this source code package.6//78use codec::{Decode, Encode};9use max_encoded_len::MaxEncodedLen;10use derivative::Derivative;1112pub use pallet_contracts::chain_extension::RetVal;13use pallet_contracts::chain_extension::{14	ChainExtension, Environment, Ext, InitState, SysConfig, UncheckedFrom,15};1617pub use frame_support::debug;18use frame_support::dispatch::DispatchError;1920extern crate pallet_nft;21pub use pallet_nft::*;22use pallet_nft::CrossAccountId;23use nft_data_structs::*;2425/// Create item parameters26#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)]27pub struct NFTExtCreateItem<AccountId> {28	pub owner: AccountId,29	pub collection_id: u32,30	pub data: CreateItemData,31}3233/// Transfer parameters34#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)]35pub struct NFTExtTransfer<AccountId> {36	pub recipient: AccountId,37	pub collection_id: u32,38	pub token_id: u32,39	pub amount: u128,40}4142#[derive(Derivative, PartialEq, Encode, Decode, MaxEncodedLen)]43#[derivative(Debug)]44pub struct NFTExtCreateMultipleItems<AccountId> {45	pub owner: AccountId,46	pub collection_id: u32,47	#[derivative(Debug = "ignore")]48	pub data: BoundedVec<CreateItemData, MaxItemsPerBatch>,49}5051#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)]52pub struct NFTExtApprove<AccountId> {53	pub spender: AccountId,54	pub collection_id: u32,55	pub item_id: u32,56	pub amount: u128,57}5859#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)]60pub struct NFTExtTransferFrom<AccountId> {61	pub owner: AccountId,62	pub recipient: AccountId,63	pub collection_id: u32,64	pub item_id: u32,65	pub amount: u128,66}6768#[derive(Derivative, PartialEq, Encode, Decode, MaxEncodedLen)]69#[derivative(Debug)]70pub struct NFTExtSetVariableMetaData {71	pub collection_id: u32,72	pub item_id: u32,73	#[derivative(Debug = "ignore")]74	pub data: BoundedVec<u8, MaxDataSize>,75}7677#[derive(Debug, PartialEq, Encode, Decode, MaxEncodedLen)]78pub struct NFTExtToggleWhiteList<AccountId> {79	pub collection_id: u32,80	pub address: AccountId,81	pub whitelisted: bool,82}8384/// The chain Extension of NFT pallet85pub struct NFTExtension;8687pub type NftWeightInfoOf<C> = <C as pallet_nft::Config>::WeightInfo;8889pub type AccountIdOf<C> = <C as SysConfig>::AccountId;9091impl<C: Config + pallet_contracts::Config> ChainExtension<C> for NFTExtension {92	fn call<E: Ext>(func_id: u32, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>93	where94		E: Ext<T = C>,95		C: pallet_nft::Config,96		<E::T as SysConfig>::AccountId: UncheckedFrom<<E::T as SysConfig>::Hash> + AsRef<[u8]>,97	{98		// The memory of the vm stores buf in scale-codec99		match func_id {100			0 => {101				let mut env = env.buf_in_buf_out();102				let input: NFTExtTransfer<AccountIdOf<C>> = env.read_as()?;103				env.charge_weight(NftWeightInfoOf::<C>::transfer())?;104105				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;106107				pallet_nft::Module::<C>::transfer_internal(108					&C::CrossAccountId::from_sub(env.ext().address().clone()),109					&C::CrossAccountId::from_sub(input.recipient),110					&collection,111					input.token_id,112					input.amount,113				)?;114115				collection.submit_logs()?;116				Ok(RetVal::Converging(0))117			}118			1 => {119				// Create Item120				let mut env = env.buf_in_buf_out();121				let input: NFTExtCreateItem<AccountIdOf<C>> = env.read_as()?;122				env.charge_weight(NftWeightInfoOf::<C>::create_item(input.data.data_size()))?;123124				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;125126				pallet_nft::Module::<C>::create_item_internal(127					&C::CrossAccountId::from_sub(env.ext().address().clone()),128					&collection,129					&C::CrossAccountId::from_sub(input.owner),130					input.data,131				)?;132133				collection.submit_logs()?;134				Ok(RetVal::Converging(0))135			}136			2 => {137				// Create multiple items138				let mut env = env.buf_in_buf_out();139				let input: NFTExtCreateMultipleItems<AccountIdOf<C>> = env.read_as()?;140				env.charge_weight(NftWeightInfoOf::<C>::create_item(141					input.data.iter().map(|i| i.data_size()).sum(),142				))?;143144				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;145146				pallet_nft::Module::<C>::create_multiple_items_internal(147					&C::CrossAccountId::from_sub(env.ext().address().clone()),148					&collection,149					&C::CrossAccountId::from_sub(input.owner),150					input.data.into_inner(),151				)?;152153				collection.submit_logs()?;154				Ok(RetVal::Converging(0))155			}156			3 => {157				// Approve158				let mut env = env.buf_in_buf_out();159				let input: NFTExtApprove<AccountIdOf<C>> = env.read_as()?;160				env.charge_weight(NftWeightInfoOf::<C>::approve())?;161162				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;163164				pallet_nft::Module::<C>::approve_internal(165					&C::CrossAccountId::from_sub(env.ext().address().clone()),166					&C::CrossAccountId::from_sub(input.spender),167					&collection,168					input.item_id,169					input.amount,170				)?;171172				collection.submit_logs()?;173				Ok(RetVal::Converging(0))174			}175			4 => {176				// Transfer from177				let mut env = env.buf_in_buf_out();178				let input: NFTExtTransferFrom<AccountIdOf<C>> = env.read_as()?;179				env.charge_weight(NftWeightInfoOf::<C>::transfer_from())?;180181				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;182183				pallet_nft::Module::<C>::transfer_from_internal(184					&C::CrossAccountId::from_sub(env.ext().address().clone()),185					&C::CrossAccountId::from_sub(input.owner),186					&C::CrossAccountId::from_sub(input.recipient),187					&collection,188					input.item_id,189					input.amount,190				)?;191192				collection.submit_logs()?;193				Ok(RetVal::Converging(0))194			}195			5 => {196				// Set variable metadata197				let mut env = env.buf_in_buf_out();198				let input: NFTExtSetVariableMetaData = env.read_as()?;199				env.charge_weight(NftWeightInfoOf::<C>::set_variable_meta_data())?;200201				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;202203				pallet_nft::Module::<C>::set_variable_meta_data_internal(204					&C::CrossAccountId::from_sub(env.ext().address().clone()),205					&collection,206					input.item_id,207					input.data.into_inner(),208				)?;209210				collection.submit_logs()?;211				Ok(RetVal::Converging(0))212			}213			6 => {214				// Toggle whitelist215				let mut env = env.buf_in_buf_out();216				let input: NFTExtToggleWhiteList<AccountIdOf<C>> = env.read_as()?;217				env.charge_weight(NftWeightInfoOf::<C>::add_to_white_list())?;218219				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;220221				pallet_nft::Module::<C>::toggle_white_list_internal(222					&C::CrossAccountId::from_sub(env.ext().address().clone()),223					&collection,224					&C::CrossAccountId::from_sub(input.address),225					input.whitelisted,226				)?;227228				collection.submit_logs()?;229				Ok(RetVal::Converging(0))230			}231			_ => Err(DispatchError::Other("unknown chain_extension func_id")),232		}233	}234}