# Transaction Fees

Substrate provides the
`transaction_payment`

pallet for
calculating and collecting fees for executing transactions. Fees are broken down into two
components:

- Byte fee - A fee proportional to the transaction's length in bytes. The proportionality constant
is a parameter in the
`transaction_payment`

pallet. - Weight fee - A fee calculated from the transaction's weight. Weights quantify the time spent executing the transaction. Learn more in the recipe on weights. The conversion doesn't need to be linear, although it often is. The same conversion function is applied across all transactions from all pallets in the runtime.
- Fee Multiplier - A multiplier for the computed fee, that can change as the chain progresses. This topic is not (yet) covered further in the recipes.

```
total_fee = transaction_length * length_fee + weight_to_fee(total_weight)
```

## Setting the Parameters

Each of the parameters described above is set in the
transaction payment pallet's
configuration trait. For example, the `super-runtime`

sets these parameters as follows.

src:
`runtimes/super-runtime/src/lib.rs`

```
parameter_types! {
pub const TransactionByteFee: u128 = 1;
}
impl transaction_payment::Config for Runtime {
type Currency = balances::Module<Runtime>;
type OnTransactionPayment = ();
type TransactionByteFee = TransactionByteFee;
type WeightToFee = IdentityFee<Balance>;
type FeeMultiplierUpdate = ();
}
```

## 1 to 1 Conversion

In many cases converting weight to fees one-to-one, as shown above, will suffice and can be
accomplished with
`IdentityFee`

. This
approach is also taken in the
node template.
It is also possible to provide a type that makes a more complex calculation. Any type that
implements
`WeightToFeePolynomial`

will suffice.

## Linear Conversion

Another common way to convert weight to fees is linearly. When converting linearly, the weight is
multiplied by a constant coefficient to determine the fee to charge. This is demonstrated in the
`weight-fee-runtime`

with the `LinearWeightToFee`

struct.

We declare the struct with an associated type `C`

, which will provide the coefficient.

```
pub struct LinearWeightToFee<C>(sp_std::marker::PhantomData<C>);
```

Then we implement `WeightToFeePolynomial`

for it. When implementing this trait, your main job is to
return a set of
`WeightToFeeCoefficient`

s.
These coefficients can have integer and fractional parts and be positive or negative. In our
`LinearWeightToFee`

there is a single integer coefficient supplied by the associated type.

```
impl<C> WeightToFeePolynomial for LinearWeightToFee<C>
where
C: Get<Balance>,
{
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
let coefficient = WeightToFeeCoefficient {
coeff_integer: C::get(),
coeff_frac: Perbill::zero(),
negative: false,
degree: 1,
};
// Return a smallvec of coefficients. Order does not need to match degrees
// because each coefficient has an explicit degree annotation.
smallvec!(coefficient)
}
}
```

This struct is reusable, and works with different coefficients. Using it looks like this.

```
parameter_types! {
// Used with LinearWeightToFee conversion. Leaving this constant intact when using other
// conversion techniques is harmless.
pub const FeeWeightRatio: u128 = 1_000;
// --snip--
}
impl transaction_payment::Config for Runtime {
// Convert dispatch weight to a chargeable fee.
type WeightToFee = LinearWeightToFee<FeeWeightRatio>;
// --snip--
}
```

## Quadratic Conversion

More complex polynomials can also be used. When using complex polynomials, it is unlikely that your
logic will be reused among multiple chains, so it is generally not worth the overhead of making the
coefficients configurable. The `QuadraticWeightToFee`

demonstrates a 2nd-degree polynomial with
hard-coded non-integer signed coefficients.

```
pub struct QuadraticWeightToFee;
impl WeightToFeePolynomial for QuadraticWeightToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
let linear = WeightToFeeCoefficient {
coeff_integer: 2,
coeff_frac: Perbill::from_percent(40),
negative: true,
degree: 1,
};
let quadratic = WeightToFeeCoefficient {
coeff_integer: 3,
coeff_frac: Perbill::zero(),
negative: false,
degree: 2,
};
// Return a smallvec of coefficients. Order does not need to match degrees
// because each coefficient has an explicit degree annotation. In fact, any
// negative coefficients should be saved for last regardless of their degree
// because large negative coefficients will likely cause saturation (to zero)
// if they happen early on.
smallvec![quadratic, linear]
}
}
```

## Collecting Fees

Having calculated the amount of fees due, runtime authors must decide which asset the fees should be
paid in. A common choice is the use the
`Balances`

pallet, but any type that
implements the `Currency`

trait
can be used.

src:
`runtimes/weight-fee-runtime/src/lib.rs`

```
impl transaction_payment::Config for Runtime {
// A generic asset whose ID is stored in the generic_asset pallet's runtime storage
type Currency = SpendingAssetCurrency<Self>;
// --snip--
}
```