Skip to content

Gas and fees

Users need to pay fees to submit transactions on the Daodst network. Since fees are handled differently in Ethereum and Cosmos, it is important to understand how the Daodst blockchain implements Ethereum-type fee calculations that are compatible with the Cosmos SDK.

Thus, this overview explains the basics of gas calculations, how fees are provided for transactions, and how Ethereum-style fee calculations use the fee market (EIP1559) to prioritize transactions.

Also note that fees paid for interacting with smart contracts on Daodst can earn revenue for smart contract deployers. For information on this, go to develop.

Prerequisites to read

Base

Why is there a transaction fee?

If anyone could submit transactions to the network for free, the network could be overwhelmed by a small number of participants sending fraudulent transactions to clog the network and make it non-functional.

The solution to this problem is a concept called gas, which is the resource consumed throughout the execution of a transaction.

In practice, each step of code execution consumes a small amount of gas, effectively charging validator resource usage and preventing malicious actors from disrupting the network at will.

What is Gas?

In general, gas is a unit of measure for the computational intensity of a particular transaction — in other words, how much work is required to evaluate and execute it.

Complex multi-step transactions, such as a Cosmos transaction that delegates to a dozen validators, require more gas than simple single-step transactions (such as a Cosmos transaction that sends tokens to another address).

When referring to a transaction, gas refers to the total amount of gas required for the transaction.

For example, a transaction may require 300,000 units of gas to execute.

Think of gas as electricity (kWh) in a house or factory, or as fuel for a car.

The idea is that it costs some money to get somewhere.

More Gas introduction:

How to calculate Gas

In general, there is no way to know exactly how much gas a transaction will cost without simply running it.

Using the Cosmos SDK, this can be done with Simulating a Tx.

Otherwise, there are ways to estimate the gas a transaction will require based on details of the transaction fields and data.

For example, in the case of the EVM, each bytecode operation has a corresponding amount of gas.

More about Gas calculation:

The relationship between Gas and handling fee?

Gas refers to the computational work required to perform it, while the fee refers to the amount of tokens you actually spend to execute the transaction.

They are derived using the following formulas:

Total Fees = Gas * Gas Price (the price per unit of gas)

If gas is in kWh, then "gas price" will be the rate determined by your energy supplier in USD/kWh, and fees will be your bill.

Like electricity, gas prices can fluctuate on a given day, depending on network traffic.

More about Gas and Fees:

How does Cosmos handle transaction fees?

Gas fees in Cosmos are relatively simple. As a user, you specify two fields:

  1. Corresponding to GasLimit of the execution gas limit, defined as GasWanted
  2. One of Fees or GasPrice, which will be used to specify or calculate the transaction fee

The node will fully consume the provided fee and then start executing the transaction. If the GasLimit is found to be insufficient during execution, the transaction will fail and any changes will be rolled back, the provided fee will not be refunded.

Validators of Cosmos SDK-based chains can specify a "minimum gas price" that they will enforce when selecting transactions to include in a block.

As a result, transactions with insufficient fees will experience delays or fail outright.

At the beginning of each block, the previous block's fees are distributed to validators and delegators, after which they can be withdrawn and spent.

How to handle fees on Ethereum?

Ethereum fees include multiple implementations introduced over time.

Initially, the user will specify the GasPrice and GasLimit in the transaction - much like a Cosmos SDK transaction.

Block proposers will receive the full gas fee from each transaction in the block, and they will choose which transactions to include accordingly.

With the proposal EIP-1559 and the London hard fork, the gas calculation has changed.

The above GasPrice is now split into two separate parts: BaseFee and PriorityFee.

BaseFee is automatically calculated based on the block size and will be destroyed once the block is mined.

PriorityFee is given to the proposer and represents a tip, or incentive for the proposer to include the transaction in a block.

Gas Price = Base Fee + Priority Fee

In a transaction, in addition to specifying a gas_limit as before, the user can specify a max_fee_per_gas corresponding to the total GasPrice and a max_priority_fee_per_gas corresponding to the maximum PriorityFee.

All excess gas not required for execution is returned to the user.

More about Ethereum fees:

Implementation

How to deal with Gas and fees on Daodst?

Fundamentally, Daodst is a Cosmos SDK chain that enables EVM compatibility as part of a Cosmos SDK module. Due to this architecture, all EVM transactions are ultimately encoded as Cosmos SDK transactions and update the state managed by the Cosmos SDK. Since all transactions are represented as Cosmos SDK transactions, transaction fees can be at different execution layers.

In fact, processing fees include standard Cosmos SDK logic, some Ethereum logic, and customDaodst logic. In most cases, fees are collected by the fee_collector module and then paid to validators and delegators. Some key differences are as follows:

1.Fee Market Module

To support EIP-1559 gas and fee calculations on Daodst's EVM layer, Daodst tracks the gas supplied for each block and uses it to calculate the base fee for future EVM transactions, enabling EIP-specified EVM dynamic fees and transaction prioritization Level -1559.

For EVM transactions, each node bypasses its local min-gas-prices configuration and instead applies EIP-1559 fee logic - the gas price must simply be greater than the global min-gas-price and the block's BaseFee, the remainder is considered the priority tip.

This allows validators to calculate Ethereum fees without applying the Cosmos SDK fee logic.

Unlike Ethereum, the BaseFee on Daodst will not be destroyed, but distributed to validators and delegators

Additionally, BaseFee is bounded by the global min-gas-price (currently, the global min-gas-price parameter is set to zero, although it can be updated via governance).

2. EVM Gas refund

Daodst refunds a small portion (at least 50% by default) of unspent gas for EVM transactions to approximate the current behavior on Ethereum.

3. Income module

Daodst develops the revenue module as a way to reward developers for creating useful dApps - any contract that registers with the Daodst revenue module rewards the contract developer with a small portion of transaction fees (currently 95% ). Validators and delegators earn the remainder.

Detailed schedule

  1. The node executes the previous block and runs the EndBlock hook * As part of this hook, the FeeMarket (EIP-1559) module tracks the total TransientGasWanted from transactions on that block. This will be used for the BaseFee of the next block.

  2. Nodes receive transactions for subsequent blocks and gossip about these transactions to their peers *These can be sorted and prioritized by included fee price (EVM transactions using the EIP-1559 fee priority mechanism will be included in the next block

  3. The node runs the BeginBlock * FeeMarket module for the subsequent block to calculate the BaseFee to apply to this block using the total GasWanted from the previous block.

  4. Distribution module distributes The previous block's fee rewards to validators and delegators

  5. For each valid transaction to be included in this block, the node does the following:

** They run an AnteHandler corresponding to the transaction type **.

This process:

  1. Perform basic transaction validation
  2. Verify that the provided fee is greater than the global and local minimum validator values and greater than the computed BaseFee
    1. (For Ethereum transactions) Preempting EVM transaction consumption gas
  3. Deduct the user's transaction fee and transfer it to the fee_collector module
  4. Increase the TransientGasWanted in the current block to calculate the BaseFee of the next block

Then, for standard Cosmos transactions, nodes

  • Execute transactions and update status
  • Transaction consumes gas

For Ethereum transactions, nodes:

  • Execute transactions and update status
  • Calculates the gas used and compares it to the supplied gas, then refunds the remainder of the specified portion
  • If the transaction interacts with a registered smart contract, a small portion of the fee used as revenue is sent to the contract developer as part of the revenue module

  • The node runs EndBlock for this block and stores the GasWanted of the block

Detailed practice

Cosmos Gas

In the Cosmos SDK, gas is mainly tracked in GasMeter and BlockGasMeter:

  • GasMeter: Tracks gas consumed during executions that lead to state transitions. It is reset every time a transaction is executed.
  • BlockGasMeter: Tracks gas consumed in a block and enforces gas not exceeding a predefined limit. This limit is defined in the Tendermint consensus parameters and can be changed through governance parameter change proposals.

Since gas is priced in bytes, the same interaction with larger parameter values will cost more gas than smaller parameter values (unlike Ethereum's uint256 values, Cosmos SDK values use Big.Int types, which are dynamically resized).

More information on gas as part of the Cosmos SDK can be found here.

Match EVM Gas consumption

Daodst is an EVM compatible chain that supports Ethereum Web3 tools. For this reason, gas consumption must be comparable to other EVMs, most importantly Ethereum.

The main difference between EVM and Cosmos state transitions is that the EVM uses a gas table for each opcode, Instead, Cosmos uses GasConfig to charge gas for each CRUD operation by setting a fixed per-byte cost for accessing the database.

To match the gas consumed by the EVM, the gas consumption logic in the SDK is ignored, instead the gas consumed is calculated by subtracting the state transition remaining gas plus the refund from the gas limit defined on the message.

To ignore the SDK's gas consumption, we reset the transaction GasMeter count to 0 and manually set it to the gasUsed value calculated by the EVM module at the end of execution.

AnteHandler

The Cosmos SDK AnteHandler performs basic checks before transaction execution.

These checks are typically signature verification, transaction field verification, transaction fees, etc.

Regarding gas consumption and fees, AnteHandler checks that the user has enough balance to cover the tx cost (amount plus the fee), and checks that the gas limit defined in the message is greater than or equal to the computed intrinsic gas message.

Gas Return

In EVM, gas can be specified before execution. The full amount of gas specified is consumed at the start of execution (during the AnteHandler step), if any gas remains after execution, the remaining gas will be refunded to the user.

Additionally, the EVM can also define gas to be returned to the user, but these will be limited to a fraction of the gas used, depending on the fork/version used.

Zero Fee Transactions

In Cosmos, AnteHandler does not enforce minimum gas prices, because min-gas-prices are checked against local nodes/validators.

In other words, the minimum fee accepted is determined by the validators of the network, and each validator can specify a different minimum value for their fee.

This may allow end users to submit 0-fee transactions if at least one validator is willing to include a 0 gas price transaction in their proposed block.

For the same reason, in Daodst it is possible to send transactions with a 0 fee for transaction types other than those defined by the evm module.

EVM module transactions cannot have a "0" fee because the EVM itself requires gas.

This check is done by the EVM transaction stateless validation (i.e. ValidateBasic) function as well as a custom AnteHandler defined by Daodst.

Gas Estimate

Ethereum provides a JSON-RPC endpoint eth_estimateGas to help users set the correct gas limit in their transactions.

Therefore, a specific query API EstimateGas is implemented in Daodst. It will apply the transaction against the current block/state and perform a binary search to find the best gas value to return to the user (the same transaction will be applied over and over until we find the minimum gas required before failing).

The reason we need to use binary search is that the gas required by the transaction may be higher than the value returned by the EVM after applying the transaction, so we need to try until we find the optimal value.

A cached context will be used throughout execution to avoid persisting changes in state.

For Cosmos Tx, developers can use Cosmos SDK's transaction simulation to create accurate estimates.

Use Daodst CLI to process Gas and transaction fees

Users should consider the available options when broadcasting transactions using the Daodst CLI client. There are three flags to consider when sending a transaction to the network:

  • --fees: Fees to pay with the transaction; eg: 10dst. Defaults to required fee.
  • --gas: Gas limit to set per transaction; default is 200000.
  • --gas-prices: gas prices to determine transaction fees (e.g. 10dst).

However, not all of these need to be defined in every transaction. The correct combination is:

  • --fees=auto: Automatically estimate fees and gas (same behavior as --gas=auto ). An error is thrown if any other fee-related flags are used (e.g. --gas-prices, --fees)
  • --gas=auto: Same behavior as --fees=auto. An error is thrown if any other fee-related flags are used (e.g. --gas-prices, --fees)
  • --gas={int}: use the specified amount of gas and the transaction fee
  • --fees={int}{denom}: use the specified fee for tx. Use the gas default (200000) for tx.
  • --fees={int}{denom} --gas={int}: Use the specified gas and fee. Computes the gas-price using the provided parameters
  • --gas-prices={int}{denom}: Use provided gas prices and default gas amount (200000)
  • --gas-prices={int}{denom} --gas={int}: Use the gas specified for tx and calculate the price with the corresponding parameters.

Readers should note that the first two options provide a more user-friendly experience for new users, while the latter are intended for more advanced users who want more control over these parameters.

The team introduced the 'auto' flag option, which automatically calculates the gas and fees required to execute a transaction. In this way, new users or developers can execute transactions without defining specific gas and fee values.

Using the auto flag may sometimes not estimate the correct gas and fees based on network traffic. To overcome this, you can use a higher value for the --gas-adjustment flag. By default it is set to 1.2. When the estimate is insufficient, retry a higher gas adjustment, such as --gas-adjustment 1.3.

The --gas-prices and --fees flags cannot be combined. If so, the user will receive an error message stating that fees and gas prices cannot be provided at the same time.

Keep in mind that the above combo may fail if the fee or gas amount offered is insufficient. If this is the case, the CLI will return an error message with the specific reason. For example:

raw_log: 'out of gas in location: submit proposal; gasWanted: 200000, gasUsed: 263940.
  Please retry with a gas (--gas flag) amount higher than gasUsed: out of gas'