git.delta.rocks / unique-network / refs/commits / 251ea62d352e

difftreelog

fix unbroke ink contract build substrate v0.9.8

Yaroslav Bolyukin2021-08-06parent: #d49b9b4.patch.diff
in: master

7 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4935,12 +4935,15 @@
 name = "nft-data-structs"
 version = "0.9.0"
 dependencies = [
+ "derivative",
  "frame-support",
  "frame-system",
+ "max-encoded-len",
  "parity-scale-codec",
  "serde",
  "sp-core",
  "sp-runtime",
+ "sp-std",
 ]
 
 [[package]]
@@ -4999,6 +5002,7 @@
  "cumulus-primitives-core",
  "cumulus-primitives-timestamp",
  "cumulus-primitives-utility",
+ "derivative",
  "fp-rpc",
  "frame-benchmarking",
  "frame-executive",
@@ -5007,6 +5011,7 @@
  "frame-system-benchmarking",
  "frame-system-rpc-runtime-api",
  "hex-literal",
+ "max-encoded-len",
  "nft-data-structs",
  "pallet-aura",
  "pallet-balances",
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -1675,8 +1675,8 @@
 			CreateItemData::NFT(data) => {
 				let item = NftItemType {
 					owner: owner.clone(),
-					const_data: data.const_data,
-					variable_data: data.variable_data,
+					const_data: data.const_data.into_inner(),
+					variable_data: data.variable_data.into_inner(),
 				};
 
 				Self::add_nft_item(collection, item)?;
@@ -1692,8 +1692,8 @@
 
 				let item = ReFungibleItemType {
 					owner: owner_list,
-					const_data: data.const_data,
-					variable_data: data.variable_data,
+					const_data: data.const_data.into_inner(),
+					variable_data: data.variable_data.into_inner(),
 				};
 
 				Self::add_refungible_item(collection, item)?;
modifiedprimitives/nft/Cargo.tomldiffbeforeafterboth
--- a/primitives/nft/Cargo.toml
+++ b/primitives/nft/Cargo.toml
@@ -9,20 +9,25 @@
 version = '0.9.0'
 
 [dependencies]
-codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ['derive'] }
+codec = { package = "parity-scale-codec", version = "2.2.0", default-features = false, features = ['derive'] }
 serde = { version = "1.0.119", features = ['derive'], default-features = false }
+max-encoded-len = { default-features = false, features = ['derive'], version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 sp-core = { version = "3.0.0", default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-std = { version = "3.0.0", default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 sp-runtime = { version = "3.0.0", default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+derivative = "2.2.0"
 
 [features]
 default = ["std"]
 std = [
   "serde/std",
   "codec/std",
+  "max-encoded-len/std",
   "frame-system/std",
   "frame-support/std",
   "sp-runtime/std",
   "sp-core/std",
+  "sp-std/std",
 ]
\ No newline at end of file
modifiedprimitives/nft/src/lib.rsdiffbeforeafterboth
--- a/primitives/nft/src/lib.rs
+++ b/primitives/nft/src/lib.rs
@@ -4,8 +4,9 @@
 
 use sp_runtime::sp_std::prelude::Vec;
 use codec::{Decode, Encode};
+use max_encoded_len::MaxEncodedLen;
 pub use frame_support::{
-	construct_runtime, decl_event, decl_module, decl_storage, decl_error,
+	BoundedVec, construct_runtime, decl_event, decl_module, decl_storage, decl_error,
 	dispatch::DispatchResult,
 	ensure, fail, parameter_types,
 	traits::{
@@ -19,18 +20,26 @@
 	},
 	StorageValue, transactional,
 };
+use derivative::Derivative;
 
 pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;
 pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;
 pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;
 pub const MAX_TOKEN_OWNERSHIP: u32 = 10_000_000;
 
+// TODO: Somehow use ChainLimits for BoundedVec len calculation?
+// Do we need ChainLimits anyway, if we can change them via forkless upgrades?
+parameter_types! {
+pub const MaxDataSize: u32 = 2048;
+// TODO: This limit isn't checked for substrate create_multiple_items call
+pub const MaxItemsPerBatch: u32 = 200;
+}
+
 pub type CollectionId = u32;
 pub type TokenId = u32;
 pub type DecimalPoints = u8;
 
-#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum CollectionMode {
 	Invalid,
 	NFT,
@@ -60,8 +69,7 @@
 	fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>;
 }
 
-#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum AccessMode {
 	Normal,
 	WhiteList,
@@ -72,8 +80,7 @@
 	}
 }
 
-#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum SchemaVersion {
 	ImageURL,
 	Unique,
@@ -84,15 +91,13 @@
 	}
 }
 
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct Ownership<AccountId> {
 	pub owner: AccountId,
 	pub fraction: u128,
 }
 
-#[derive(Encode, Decode, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum SponsorshipState<AccountId> {
 	/// The fees are applied to the transaction sender
 	Disabled,
@@ -147,30 +152,26 @@
 	pub transfers_enabled: bool,
 }
 
-#[derive(Encode, Decode, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct NftItemType<AccountId> {
 	pub owner: AccountId,
 	pub const_data: Vec<u8>,
 	pub variable_data: Vec<u8>,
 }
 
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct FungibleItemType {
 	pub value: u128,
 }
 
-#[derive(Encode, Decode, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct ReFungibleItemType<AccountId> {
 	pub owner: Vec<Ownership<AccountId>>,
 	pub const_data: Vec<u8>,
 	pub variable_data: Vec<u8>,
 }
 
-#[derive(Encode, Decode, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct CollectionLimits<BlockNumber: Encode + Decode> {
 	pub account_token_ownership_limit: u32,
 	pub sponsored_data_size: u32,
@@ -200,8 +201,7 @@
 	}
 }
 
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub struct ChainLimits {
 	pub collection_numbers_limit: u32,
 	pub account_token_ownership_limit: u32,
@@ -219,29 +219,73 @@
 	pub const_on_chain_schema_limit: u32,
 }
 
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+/// BoundedVec doesn't supports serde
+mod bounded_serde {
+	use core::convert::TryFrom;
+	use frame_support::{BoundedVec, traits::Get};
+	use serde::{
+		ser::{self, Serialize},
+		de::{self, Deserialize, Error},
+	};
+	use sp_std::vec::Vec;
+
+	pub fn serialize<D, V, S>(value: &BoundedVec<V, S>, serializer: D) -> Result<D::Ok, D::Error>
+	where
+		D: ser::Serializer,
+		V: Serialize,
+	{
+		let vec: &Vec<_> = &value;
+		vec.serialize(serializer)
+	}
+
+	pub fn deserialize<'de, D, V, S>(deserializer: D) -> Result<BoundedVec<V, S>, D::Error>
+	where
+		D: de::Deserializer<'de>,
+		V: de::Deserialize<'de>,
+		S: Get<u32>,
+	{
+		// TODO: Implement custom visitor, which will limit vec size at parse time? Will serde only be used by chainspec?
+		let vec = <Vec<V>>::deserialize(deserializer)?;
+		let len = vec.len();
+		TryFrom::try_from(vec).map_err(|_| D::Error::invalid_length(len, &"lesser size"))
+	}
+}
+
+#[derive(
+	Encode, Decode, MaxEncodedLen, Default, Derivative, Clone, PartialEq, Serialize, Deserialize,
+)]
+#[derivative(Debug)]
 pub struct CreateNftData {
-	pub const_data: Vec<u8>,
-	pub variable_data: Vec<u8>,
+	#[serde(with = "bounded_serde")]
+	#[derivative(Debug="ignore")]
+	pub const_data: BoundedVec<u8, MaxDataSize>,
+	#[serde(with = "bounded_serde")]
+	#[derivative(Debug="ignore")]
+	pub variable_data: BoundedVec<u8, MaxDataSize>,
 }
 
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(
+	Encode, Decode, MaxEncodedLen, Default, Debug, Clone, PartialEq, Serialize, Deserialize,
+)]
 pub struct CreateFungibleData {
 	pub value: u128,
 }
 
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(
+	Encode, Decode, MaxEncodedLen, Default, Derivative, Clone, PartialEq, Serialize, Deserialize,
+)]
+#[derivative(Debug)]
 pub struct CreateReFungibleData {
-	pub const_data: Vec<u8>,
-	pub variable_data: Vec<u8>,
+	#[serde(with = "bounded_serde")]
+	#[derivative(Debug="ignore")]
+	pub const_data: BoundedVec<u8, MaxDataSize>,
+	#[serde(with = "bounded_serde")]
+	#[derivative(Debug="ignore")]
+	pub variable_data: BoundedVec<u8, MaxDataSize>,
 	pub pieces: u128,
 }
 
-#[derive(Encode, Decode, Debug, Clone, PartialEq)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(Encode, Decode, MaxEncodedLen, Debug, Clone, PartialEq, Serialize, Deserialize)]
 pub enum CreateItemData {
 	NFT(CreateNftData),
 	Fungible(CreateFungibleData),
modifiedruntime/Cargo.tomldiffbeforeafterboth
--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -31,6 +31,7 @@
 ]
 std = [
     'codec/std',
+    'max-encoded-len/std',
     'cumulus-pallet-aura-ext/std',
     'cumulus-pallet-parachain-system/std',
     'cumulus-pallet-xcm/std',
@@ -378,6 +379,8 @@
 # local dependencies
 
 [dependencies]
+max-encoded-len = { default-features = false, features = ['derive'], version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+derivative = "2.2.0"
 pallet-nft = { path = '../pallets/nft', default-features = false, version = '3.0.0' }
 pallet-inflation = { path = '../pallets/inflation', default-features = false, version = '3.0.0' }
 nft-data-structs = { path = '../primitives/nft', default-features = false, version = '0.9.0' }
modifiedruntime/src/chain_extension.rsdiffbeforeafterboth
before · runtime/src/chain_extension.rs
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};910pub use pallet_contracts::chain_extension::RetVal;11use pallet_contracts::chain_extension::{12	ChainExtension, Environment, Ext, InitState, SysConfig, UncheckedFrom,13};1415pub use frame_support::debug;16use frame_support::dispatch::DispatchError;1718extern crate pallet_nft;19pub use pallet_nft::*;20use pallet_nft::CrossAccountId;21use nft_data_structs::*;2223use crate::Vec;2425/// Create item parameters26#[derive(Debug, PartialEq, Encode, Decode)]27pub struct NFTExtCreateItem<E: Ext> {28	pub owner: <E::T as SysConfig>::AccountId,29	pub collection_id: u32,30	pub data: CreateItemData,31}3233/// Transfer parameters34#[derive(Debug, PartialEq, Encode, Decode)]35pub struct NFTExtTransfer<E: Ext> {36	pub recipient: <E::T as SysConfig>::AccountId,37	pub collection_id: u32,38	pub token_id: u32,39	pub amount: u128,40}4142#[derive(Debug, PartialEq, Encode, Decode)]43pub struct NFTExtCreateMultipleItems<E: Ext> {44	pub owner: <E::T as SysConfig>::AccountId,45	pub collection_id: u32,46	pub data: Vec<CreateItemData>,47}4849#[derive(Debug, PartialEq, Encode, Decode)]50pub struct NFTExtApprove<E: Ext> {51	pub spender: <E::T as SysConfig>::AccountId,52	pub collection_id: u32,53	pub item_id: u32,54	pub amount: u128,55}5657#[derive(Debug, PartialEq, Encode, Decode)]58pub struct NFTExtTransferFrom<E: Ext> {59	pub owner: <E::T as SysConfig>::AccountId,60	pub recipient: <E::T as SysConfig>::AccountId,61	pub collection_id: u32,62	pub item_id: u32,63	pub amount: u128,64}6566#[derive(Debug, PartialEq, Encode, Decode)]67pub struct NFTExtSetVariableMetaData {68	pub collection_id: u32,69	pub item_id: u32,70	pub data: Vec<u8>,71}7273#[derive(Debug, PartialEq, Encode, Decode)]74pub struct NFTExtToggleWhiteList<E: Ext> {75	pub collection_id: u32,76	pub address: <E::T as SysConfig>::AccountId,77	pub whitelisted: bool,78}7980/// The chain Extension of NFT pallet81pub struct NFTExtension;8283pub type NftWeightInfoOf<C> = <C as pallet_nft::Config>::WeightInfo;8485impl<C: Config + pallet_contracts::Config> ChainExtension<C> for NFTExtension {86	fn call<E: Ext>(func_id: u32, env: Environment<E, InitState>) -> Result<RetVal, DispatchError>87	where88		E: Ext<T = C>,89		C: pallet_nft::Config,90		<E::T as SysConfig>::AccountId: UncheckedFrom<<E::T as SysConfig>::Hash> + AsRef<[u8]>,91	{92		// The memory of the vm stores buf in scale-codec93		match func_id {94			0 => {95				let mut env = env.buf_in_buf_out();96				let input: NFTExtTransfer<E> = env.read_as()?;97				env.charge_weight(NftWeightInfoOf::<C>::transfer())?;9899				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;100101				pallet_nft::Module::<C>::transfer_internal(102					&C::CrossAccountId::from_sub(env.ext().address().clone()),103					&C::CrossAccountId::from_sub(input.recipient),104					&collection,105					input.token_id,106					input.amount,107				)?;108109				pallet_nft::Module::<C>::submit_logs(collection)?;110				Ok(RetVal::Converging(0))111			}112			1 => {113				// Create Item114				let mut env = env.buf_in_buf_out();115				let input: NFTExtCreateItem<E> = env.read_as()?;116				env.charge_weight(NftWeightInfoOf::<C>::create_item(input.data.data_size()))?;117118				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;119120				pallet_nft::Module::<C>::create_item_internal(121					&C::CrossAccountId::from_sub(env.ext().address().clone()),122					&collection,123					&C::CrossAccountId::from_sub(input.owner),124					input.data,125				)?;126127				pallet_nft::Module::<C>::submit_logs(collection)?;128				Ok(RetVal::Converging(0))129			}130			2 => {131				// Create multiple items132				let mut env = env.buf_in_buf_out();133				let input: NFTExtCreateMultipleItems<E> = env.read_as()?;134				env.charge_weight(NftWeightInfoOf::<C>::create_item(135					input.data.iter().map(|i| i.data_size()).sum(),136				))?;137138				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;139140				pallet_nft::Module::<C>::create_multiple_items_internal(141					&C::CrossAccountId::from_sub(env.ext().address().clone()),142					&collection,143					&C::CrossAccountId::from_sub(input.owner),144					input.data,145				)?;146147				pallet_nft::Module::<C>::submit_logs(collection)?;148				Ok(RetVal::Converging(0))149			}150			3 => {151				// Approve152				let mut env = env.buf_in_buf_out();153				let input: NFTExtApprove<E> = env.read_as()?;154				env.charge_weight(NftWeightInfoOf::<C>::approve())?;155156				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;157158				pallet_nft::Module::<C>::approve_internal(159					&C::CrossAccountId::from_sub(env.ext().address().clone()),160					&C::CrossAccountId::from_sub(input.spender),161					&collection,162					input.item_id,163					input.amount,164				)?;165166				pallet_nft::Module::<C>::submit_logs(collection)?;167				Ok(RetVal::Converging(0))168			}169			4 => {170				// Transfer from171				let mut env = env.buf_in_buf_out();172				let input: NFTExtTransferFrom<E> = env.read_as()?;173				env.charge_weight(NftWeightInfoOf::<C>::transfer_from())?;174175				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;176177				pallet_nft::Module::<C>::transfer_from_internal(178					&C::CrossAccountId::from_sub(env.ext().address().clone()),179					&C::CrossAccountId::from_sub(input.owner),180					&C::CrossAccountId::from_sub(input.recipient),181					&collection,182					input.item_id,183					input.amount,184				)?;185186				pallet_nft::Module::<C>::submit_logs(collection)?;187				Ok(RetVal::Converging(0))188			}189			5 => {190				// Set variable metadata191				let mut env = env.buf_in_buf_out();192				let input: NFTExtSetVariableMetaData = env.read_as()?;193				env.charge_weight(NftWeightInfoOf::<C>::set_variable_meta_data())?;194195				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;196197				pallet_nft::Module::<C>::set_variable_meta_data_internal(198					&C::CrossAccountId::from_sub(env.ext().address().clone()),199					&collection,200					input.item_id,201					input.data,202				)?;203204				pallet_nft::Module::<C>::submit_logs(collection)?;205				Ok(RetVal::Converging(0))206			}207			6 => {208				// Toggle whitelist209				let mut env = env.buf_in_buf_out();210				let input: NFTExtToggleWhiteList<E> = env.read_as()?;211				env.charge_weight(NftWeightInfoOf::<C>::add_to_white_list())?;212213				let collection = pallet_nft::Module::<C>::get_collection(input.collection_id)?;214215				pallet_nft::Module::<C>::toggle_white_list_internal(216					&C::CrossAccountId::from_sub(env.ext().address().clone()),217					&collection,218					&C::CrossAccountId::from_sub(input.address),219					input.whitelisted,220				)?;221222				pallet_nft::Module::<C>::submit_logs(collection)?;223				Ok(RetVal::Converging(0))224			}225			_ => Err(DispatchError::Other("unknown chain_extension func_id")),226		}227	}228}
after · runtime/src/chain_extension.rs
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}
modifiedruntime/src/lib.rsdiffbeforeafterboth
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -72,7 +72,6 @@
 use sp_runtime::{
 	traits::{Dispatchable},
 };
-// use pallet_contracts::chain_extension::UncheckedFrom;
 
 // pub use pallet_timestamp::Call as TimestampCall;
 pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
@@ -419,7 +418,7 @@
 	type DepositPerStorageItem = DepositPerStorageItem;
 	type RentFraction = RentFraction;
 	type SurchargeReward = SurchargeReward;
-	type WeightPrice = pallet_transaction_payment::Module<Self>;
+	type WeightPrice = pallet_transaction_payment::Pallet<Self>;
 	type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
 	type ChainExtension = NFTExtension;
 	type DeletionQueueDepth = DeletionQueueDepth;