difftreelog
Merge pull request #14 from usetech-llc/feature/NFTPAR-109-110_contract_sponsoring
in: master
Feature/nftpar 109 110 contract sponsoring
4 files changed
Cargo.lockdiffbeforeafterboth3737 "frame-support",3737 "frame-support",3738 "frame-system",3738 "frame-system",3739 "log",3739 "log",3740 "pallet-contracts",3740 "pallet-transaction-payment",3741 "pallet-transaction-payment",3741 "parity-scale-codec",3742 "parity-scale-codec",3742 "serde",3743 "serde",pallets/nft/Cargo.tomldiffbeforeafterboth73branch = 'v2.0.0_release'73branch = 'v2.0.0_release'74optional = true74optional = true7576[dependencies.pallet-contracts]77default-features = false78git = 'https://github.com/usetech-llc/substrate.git'79package = 'pallet-contracts'80branch = 'v2.0.0_release'81version = '2.0.0'758276[features]83[features]77default = ['std']84default = ['std']pallets/nft/src/default_weights.rsdiffbeforeafterboth92 .saturating_add(DbWeight::get().reads(2 as Weight))92 .saturating_add(DbWeight::get().reads(2 as Weight))93 .saturating_add(DbWeight::get().writes(1 as Weight))93 .saturating_add(DbWeight::get().writes(1 as Weight))94 }94 }95 // fn enable_contract_sponsoring() -> Weight {96 // (0 as Weight)97 // .saturating_add(DbWeight::get().reads(1 as Weight))98 // .saturating_add(DbWeight::get().writes(1 as Weight))99 // }95}100}96101pallets/nft/src/lib.rsdiffbeforeafterboth28use sp_runtime::sp_std::prelude::Vec;28use sp_runtime::sp_std::prelude::Vec;29use sp_runtime::{29use sp_runtime::{30 traits::{30 traits::{31 DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SaturatedConversion, Saturating,31 DispatchInfoOf, Dispatchable, PostDispatchInfoOf, Saturating, SignedExtension, Zero,32 SignedExtension, Zero,33 },32 },34 transaction_validity::{33 transaction_validity::{35 InvalidTransaction, TransactionPriority, TransactionValidity, TransactionValidityError,34 InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,36 ValidTransaction,37 },35 },38 FixedPointOperand, FixedU128,36 FixedPointOperand, FixedU128,39};37};38use pallet_contracts::ContractAddressFor;39use sp_runtime::traits::StaticLookup;404041#[cfg(test)]41#[cfg(test)]42mod mock;42mod mock;203 fn approve() -> Weight;203 fn approve() -> Weight;204 fn transfer_from() -> Weight;204 fn transfer_from() -> Weight;205 fn set_offchain_schema() -> Weight;205 fn set_offchain_schema() -> Weight;206 // fn enable_contract_sponsoring() -> Weight;206}207}207208208pub trait Trait: system::Trait + Sized {209pub trait Trait: system::Trait + Sized + transaction_payment::Trait + pallet_contracts::Trait {209 type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;210 type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;210211211 /// Weight information for extrinsics in this pallet.212 /// Weight information for extrinsics in this pallet.257 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => Vec<BasketItem<T::AccountId, T::BlockNumber>>;258 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => Vec<BasketItem<T::AccountId, T::BlockNumber>>;258 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => T::BlockNumber;259 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => T::BlockNumber;259260260 // Sponsorship261 // Contract Sponsorship and Ownership261 pub ContractSponsor get(fn contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;262 pub ContractOwner get(fn contract_owner): map hasher(identity) T::AccountId => T::AccountId;262 pub UnconfirmedContractSponsor get(fn unconfirmed_contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;263 pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(identity) T::AccountId => bool;263 }264 }264 add_extra_genesis {265 add_extra_genesis {265 build(|config: &GenesisConfig<T>| {266 build(|config: &GenesisConfig<T>| {1114 Ok(())1115 Ok(())1115 } 1116 }11171118 /// Enable smart contract self-sponsoring.1119 /// 1120 /// # Permissions1121 /// 1122 /// * Contract Owner1123 /// 1124 /// # Arguments1125 /// 1126 /// * contract address1127 /// * enable flag1128 /// 1129 #[weight = 0]1130 pub fn enable_contract_sponsoring(1131 origin,1132 contract_address: T::AccountId,1133 enable: bool1134 ) -> DispatchResult {1135 let sender = ensure_signed(origin)?;1136 let mut is_owner = false;1137 if <ContractOwner<T>>::contains_key(contract_address.clone()) {1138 let owner = <ContractOwner<T>>::get(&contract_address);1139 is_owner = sender == owner;1140 }1141 ensure!(is_owner, "Only contract owner may call this method");11421143 <ContractSelfSponsoring<T>>::insert(contract_address, enable);1144 Ok(())1145 }11461116 }1147 }1117}1148}1737/// Require the transactor pay for themselves and maybe include a tip to gain additional priority1768/// Require the transactor pay for themselves and maybe include a tip to gain additional priority1738/// in the queue.1769/// in the queue.1739#[derive(Encode, Decode, Clone, Eq, PartialEq)]1770#[derive(Encode, Decode, Clone, Eq, PartialEq)]1740pub struct ChargeTransactionPayment<T: transaction_payment::Trait + Send + Sync>(1771pub struct ChargeTransactionPayment<T: Trait + Send + Sync>(1741 #[codec(compact)] BalanceOf<T>,1772 #[codec(compact)] BalanceOf<T>1742);1773);174317741744impl<T: Trait + transaction_payment::Trait + Send + Sync> sp_std::fmt::Debug1775impl<T: Trait + Send + Sync> sp_std::fmt::Debug1745 for ChargeTransactionPayment<T>1776 for ChargeTransactionPayment<T>1746{1777{1747 #[cfg(feature = "std")]1778 #[cfg(feature = "std")]1754 }1785 }1755}1786}175617871757impl<T: Trait + transaction_payment::Trait + Send + Sync> ChargeTransactionPayment<T>1788impl<T: Trait + Send + Sync> ChargeTransactionPayment<T>1758where1789where1759 T::Call:1790 T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<Call<T>> + IsSubType<pallet_contracts::Call<T>>,1760 Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<Call<T>>,1761 BalanceOf<T>: Send + Sync + FixedPointOperand,1791 BalanceOf<T>: Send + Sync + FixedPointOperand,1762{1792{178718171788 // Set fee based on call type. Creating collection costs 1 Unique.1818 // Set fee based on call type. Creating collection costs 1 Unique.1789 // All other transactions have traditional fees so far1819 // All other transactions have traditional fees so far1820 // let fee = match call.is_sub_type() {1821 // Some(Call::create_collection(..)) => <BalanceOf<T>>::from(1_000_000_000),1822 // _ => Self::traditional_fee(len, info, tip), // Flat fee model, use only for testing purposes1823 // // _ => <BalanceOf<T>>::from(100)1824 // };1790 let fee = match call.is_sub_type() {1825 let fee = Self::traditional_fee(len, info, tip);1791 Some(Call::create_collection(..)) => <BalanceOf<T>>::from(1_000_000_000),1792 _ => Self::traditional_fee(len, info, tip), // Flat fee model, use only for testing purposes1793 // _ => <BalanceOf<T>>::from(100)1794 };179518261796 // Determine who is paying transaction fee based on ecnomic model1827 // Determine who is paying transaction fee based on ecnomic model1797 // Parse call to extract collection ID and access collection sponsor1828 // Parse call to extract collection ID and access collection sponsor1798 let sponsor: T::AccountId = match call.is_sub_type() {1829 let mut sponsor: T::AccountId = match IsSubType::<Call<T>>::is_sub_type(call) {1799 Some(Call::create_item(collection_id, _properties, _owner)) => {1830 Some(Call::create_item(collection_id, _properties, _owner)) => {1800 <Collection<T>>::get(collection_id).sponsor1831 <Collection<T>>::get(collection_id).sponsor1801 }1832 }1864 _ => T::AccountId::default(),1895 _ => T::AccountId::default(),1865 };1896 };18971898 // Sponsor smart contracts1899 sponsor = match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {19001901 // On instantiation: set the contract owner1902 Some(pallet_contracts::Call::instantiate(_endowment, _gas_limit, code_hash, data)) => {19031904 let new_contract_address = <T as pallet_contracts::Trait>::DetermineContractAddress::contract_address_for(1905 code_hash,1906 &data,1907 &who,1908 );1909 <ContractOwner<T>>::insert(new_contract_address.clone(), who.clone());19101911 T::AccountId::default()1912 },19131914 // When the contract is called, check if the sponsoring is enabled and pay fees from contract endowment if it is1915 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {19161917 let mut sp = T::AccountId::default();1918 let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());1919 if <ContractSelfSponsoring<T>>::contains_key(called_contract.clone()) {1920 if <ContractSelfSponsoring<T>>::get(called_contract.clone()) {1921 sp = called_contract;1922 }1923 }19241925 sp1926 },19271928 _ => sponsor,1929 };186619301867 let mut who_pays_fee: T::AccountId = sponsor.clone();1931 let mut who_pays_fee: T::AccountId = sponsor.clone();1868 if sponsor == T::AccountId::default() {1932 if sponsor == T::AccountId::default() {1891}1955}1956189219571893impl<T: Trait + transaction_payment::Trait + Send + Sync> SignedExtension1958impl<T: Trait + Send + Sync> SignedExtension1894 for ChargeTransactionPayment<T>1959 for ChargeTransactionPayment<T>1895where1960where1896 BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,1961 BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,1897 T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<Call<T>>,1962 T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<Call<T>> + IsSubType<pallet_contracts::Call<T>>,1898{1963{1899 const IDENTIFIER: &'static str = "ChargeTransactionPayment";1964 const IDENTIFIER: &'static str = "ChargeTransactionPayment";1900 type AccountId = T::AccountId;1965 type AccountId = T::AccountId;191219771913 fn validate(1978 fn validate(1914 &self,1979 &self,1915 who: &Self::AccountId,1980 _who: &Self::AccountId,1916 call: &Self::Call,1981 _call: &Self::Call,1917 info: &DispatchInfoOf<Self::Call>,1982 _info: &DispatchInfoOf<Self::Call>,1918 len: usize,1983 _len: usize,1919 ) -> TransactionValidity {1984 ) -> TransactionValidity {1920 let (fee, _) = self.withdraw_fee(who, call, info, len)?;19211922 let mut r = ValidTransaction::default();1985 Ok(ValidTransaction::default())1923 // NOTE: we probably want to maximize the _fee (of any type) per weight unit_ here, which1924 // will be a bit more than setting the priority to tip. For now, this is enough.1925 r.priority = fee.saturated_into::<TransactionPriority>();1926 Ok(r)1927 }1986 }192819871929 fn pre_dispatch(1988 fn pre_dispatch(