1

I want to set a single fee for every transaction happening in substrate either its transfer or any other transaction I want the transfer fee to be 1 unit.

Thanks

2 Answers 2

2

Manually specifying fee

First thing that came to my mind is doing:

/// How much is exactly one unit in your node?
const UNIT: u32 = 10_000_000;

#[pallet::weight(UNIT.into())]
fn call_one(..) -> _ {}

#[pallet::weight(UNIT.into())]
fn call_two(..) -> {}

Using WeightInfo trait

Another one is to have a seperate weight file and define weight there:

weights.rs

use frame_support::{traits::Get, weights::Weight};
use sp_std::marker::PhantomData;

pub trait WeightInfo {
    fn common_weight() -> Weight;
}

pub struct PalletWeightInfo<T>(PhantomData<T>);

impl<T: frame_system::Config> WeightInfo for PalletWeightInfo<T>{
    fn set_airdrop_server_account() -> Weight {
        ONE_UNIT as Weight
    }

In config:

pub trait Config: frame_system::Config {
   /// -- other configs
   PalletWeightInfo: WeightInfo,
}

In extrinsic call

#[pallet::weight(T::PalletWeightInfo::common_weight())]
fn call_one(..) -> _ {}

#[pallet::weight(T::PalletWeightInfo::common_weight())]
fn call_two(..) -> _ {}

Pallet specific through config trait

If you want that pallet to use constant fee in all extrinsic but also be configured from runtime, you can add weight field in Config as well.

Global to runtime

If you want to use same weight in every pallet you create & link, you can set minimum fee weight to UNIT while creating runtime and put #[pallet::weight(0)] to every call. This will set the weight to minimum amount specified which will be outside pallet i.e in runtime creation


But depending on usage, it is very unlikely that it requires same weight for different calls since weight are measure of resource consumed by given extrinsic. Nevertheless, you are free to do so but make sure it is absolute desired and planned.

2

You should simply adjust the WeightToFee calculation from the Pallet Transaction Payment Configuration:

impl pallet_transaction_payment::Config for Runtime {
    type Event = Event;
    type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees>;
    type OperationalFeeMultiplier = OperationalFeeMultiplier;
    type WeightToFee = ConstantFee<Balance>;
    type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
    type FeeMultiplierUpdate =
        TargetedFeeAdjustment<Self, TargetBlockFullness, AdjustmentVariable, MinimumMultiplier>;
}

You could create an use a struct like:

/// Implementor of `WeightToFee` that always returns the same fee.
pub struct ConstantFee<T>(sp_std::marker::PhantomData<T>);

impl<T> WeightToFee for ConstantFee<T>
where
    T: BaseArithmetic + From<u32> + Copy + Unsigned,
{
    type Balance = T;

    fn weight_to_fee(weight: &Weight) -> Self::Balance {
        1_000_000u32.into()
    }
}

This would make it so that the fee taken from the user is always a constant value you control.

1
  • 1
    hi @Shawn i tried using this solution but in my case the gas fee is reduced after every transaction suppose if i have done 1st transaction and fees in 10 milli then for 2nd transaction the fee is reduced to 10 micro ,then nano then femto and it keeps on reducing .. how can i fix this... Jan 5, 2023 at 11:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.