Endless
  • 🚀README
  • Discovery
    • 🚀Endless Web3 Genesis Cloud
    • 💎Business Model
    • 🎯Vision
    • ✈️Roadmap
    • 🪙Economics
    • 👤Team
      • Yu Xiong
      • Amit Kumar Jaiswal
      • Ned
      • 0xfun
      • Scott Trowbridge
      • Neeraj Sharma LLB
      • Amjad Suleman
      • Binu Paul
      • Eduard Romulus GOEAN
    • ❤️Developer Community
  • Endless Chain
    • Tech Docs
      • Account Address Format
      • Endless Account
      • Endless Coin(EDS)
      • Sponsored Transaction
      • On-Chain Multisig
      • Randomness
      • Safety Transaction
      • Token Locking & Distribution
    • Start
      • Learn about Endless
        • Accounts
        • Resources
        • Events
        • Transactions and States
        • Gas and Storage Fees
        • Computing Transaction Gas
        • Blocks
        • Staking
          • Delegated Staking
        • Governance
        • Endless Blockchain Deep Dive
          • Validator Nodes Overview
          • Fullnodes Overview
          • Node Networks and Synchronization
        • Move - A Web3 Language and Runtime
      • Explore Endless
      • Latest Endless Releases
      • Networks
    • Build
      • Tutorials
        • Your First Transaction
        • Your First Fungible Asset
        • Your First NFT
        • Your First Move Module
        • Your First Multisig
      • Learn the Move Language
        • The Move Book
          • Getting Started
            • Introduction
            • Modules and Scripts
          • Primitive Types
            • Move Tutorial
            • Integers
            • Bool
            • Address
            • Vector
            • Signer
            • References
            • Tuples and Unit
          • Basic Concepts
            • Local Variables and Scope
            • Equality
            • Abort and Assert
            • Conditionals
            • While, For, and Loop
            • Functions
            • Structs and Resources
            • Constants
            • Generics
            • Abilities
            • Uses and Aliases
            • Friends
            • Packages
            • Package Upgrades
            • Unit Tests
          • Global Storage
            • Global Storage - Structure
            • Global Storage - Operators
          • Reference
            • Libraries
            • Move Coding Conventions
        • Advanced Move Guides
          • Objects
            • Creating Objects
            • Configuring objects
            • Using objects
          • Move Scripts
            • Writing Move Scripts
            • Compiling Move Scripts
            • Running Move Scripts
            • Move Scripts Tutorial
          • Resource Accounts
          • Modules on Endless
          • Cryptography
          • Gas Profiling
          • Security
      • Endless Standards
        • Object
        • Endless Fungible Asset Standard
        • Endless Digital Asset Standard
        • Endless Wallet Standard
      • Endless APIs
        • Fullnode Rest API
        • Indexer Restful API
          • Indexer Installation
        • GRPC Transaction Stream
          • Running Locally
          • Custom Processors
            • End-to-End Tutorial
            • Parsing Transactions
          • Self-Hosted Transaction Stream Service
      • Endless SDKs
        • TypeScript SDK
          • Account
          • SDK Configuration
          • Fetch data from chain
          • Transaction Builder
          • HTTP Client
          • Move Types
          • Testing
          • Typescript
        • Rust SDK
        • Go SDK
      • Endless CLI
        • Install the Endless CLI
          • Install On Mac
          • Install On Alibaba Cloud
          • Install On Linux
          • Install On Windows
        • CLI Configuration
        • Use Endless CLI
          • Working With Move Contracts
            • Arguments in JSON Tutorial
          • Trying Things On-Chain
            • Look Up On-Chain Account Info
            • Create Test Accounts
          • Running A Local Network
            • Running a Public Network
          • Managing a Network Node
      • Integrate with Endless
        • Endless Token Overview
        • Application Integration Guide
      • Endless VSCode extension
      • Advanced Builder Guides
        • Develop Locally
          • Running a Local Network
          • Run a Localnet with Validator
    • Nodes
      • Learn about Nodes
      • Run a Validator and VFN
        • Node Requirements
        • Deploy Nodes
          • Using Docker
          • Using AWS
          • Using Azure
          • Using GCP
        • Connect Nodes
          • Connect to a Network
        • Verify Nodes
          • Node Health
          • Validator Leaderboard
      • Run a Public Fullnode
        • PFN Requirements
        • Deploy a PFN
          • Using Pre-compiled Binary
          • Using Docker
          • Using GCP 🚧 (under_construction)
        • Verify a PFN
        • Modify a PFN
          • Upgrade your PFN
          • Generate a PFN Identity
          • Customize PFN Networks
      • Bootstrap a Node
        • Bootstrap from a Snapshot
        • Bootstrap from a Backup
      • Configure a Node
        • State Synchronization
        • Data Pruning
        • Telemetry
        • Locating Node Files
          • Files For Mainnet
          • Files For Testnet
          • Files For Devnet
      • Monitor a Node
        • Node Inspection Service
        • Important Node Metrics
        • Node Health Checker
    • Reference
      • Endless Error Codes
      • Move Reference Documentation
      • Endless Glossary
    • FAQs
  • Endless Bridge
    • Intro to Endless Bridge
    • How to use bridge
    • Liquidity Management
    • Faucet
    • Developer Integration
      • Contract Integration
        • Message Contract
        • Execute Contract
      • Server-Side Integration
        • Message Sender
        • Example of Message Listener Service (Rust)
        • Example of Token Cross-Chain (JS)
  • Endless Wallet
    • User Guide
    • Basic Tutorial
    • FAQs
    • MultiAccount
    • SDK
      • Functions
      • Events
  • GameFi
    • Intro
    • GameFi & Endless
  • Endless Modules
    • Stacks
    • Storage
    • Module List
  • Endless Ecosystem
    • Intro
    • Show Cases
    • App Demo
  • Whitepaper
  • Endless SCAN
    • User Guide
  • MULTI-SIGNATURE
    • Multi-Signature User Guide
  • Regulations
    • Privacy Policy
    • Terms of Service
    • Funding Terms - Disclaimer
Powered by GitBook
On this page
  • Unit of gas
  • The Fee Statement
  • Gas price and prioritizing transactions
  • Specifying gas fees within a transaction
  • Gas parameters set by governance
  • Calculating Storage Fees
  • Calculating Storage Deletion Refund
  • Examples
  • Estimating gas consumption via simulation
Export as PDF
  1. Endless Chain
  2. Start
  3. Learn about Endless

Gas and Storage Fees

Any transaction execution on the Endless blockchain requires a processing fee. As of today, this fee comprises two components:

  1. Execution & IO costs

  • This covers your usage of transient computation resources, such as processing your transactions and propagating the validated record throughout the distributed network of the mainnet.

  • It is measured in Gas Units whose price may fluctuate according to the load of the network. This allows execution and IO costs to be low when the network is less busy.

  • This portion of gas is burned permanently upon the execution of a transaction.

  1. Storage fees

  • This covers the cost to persistently store validated record in the distributed blockchain storage.

  • It is measured in fixed EDS prices, so the permanent storage cost stays stable even as the gas unit price fluctuates with the network's transient load.

  • The storage fee can be refunded when the allocated storage slot is deleted. Currently, the network is configured to refund the entirety of the storage fee paid over the lifetime of a state storage slot.

  • To keep system implementation simple, this portion of gas is burned and minted again upon refund.

Conceptually, this fee can be thought of as quite similar to how we pay for our home electric or water utilities.

Unit of gas

Transactions can range from simple and inexpensive to complicated based upon what they do. In the Endless blockchain, a unit of gas represents a basic unit of consumption for transient resources, such as doing computation or accessing the storage. The latter should not be conflated with the long-term storage aspect of such operations, as that is covered by the storage fees separately.

See How Base Gas Works for a detailed description of gas fee types and available optimizations.

Unit of gas

A unit of gas is a dimensionless number or a unit that is not associated with any one item such as a coin, expressed as an integer. The total gas units consumed by your transaction depend on the complexity of your transaction. The gas price, on the other hand, is expressed in terms of Endless blockchain's native coin (Octas). Also see Transactions and States for how a transaction submitted to the Endless blockchain looks like.

The Fee Statement

As of Endless Framework release 1.7, the breakdown of fee charges and refunds is emitted as a module event represented by struct 0x1::transaction_fee::FeeStatement.

    #[event]
    /// Breakdown of fee charge and refund for a transaction.
    /// The structure is:
    ///
    /// - Net charge or refund (not in the statement)
    ///    - total charge: total_charge_gas_units, matches `gas_used` in the on-chain `TransactionInfo`.
    ///      This is the sum of the sub-items below. Notice that there's potential precision loss when
    ///      the conversion between internal and external gas units and between native token and gas
    ///      units, so it's possible that the numbers don't add up exactly. -- This number is the final
    ///      charge, while the break down is merely informational.
    ///        - gas charge for execution (CPU time): `execution_gas_units`
    ///        - gas charge for IO (storage random access): `io_gas_units`
    ///        - storage fee charge (storage space): `storage_fee_octas`, to be included in
    ///          `total_charge_gas_unit`, this number is converted to gas units according to the user
    ///          specified `gas_unit_price` on the transaction.
    ///    - storage deletion refund: `storage_fee_refund_octas`, this is not included in `gas_used` or
    ///      `total_charge_gas_units`, the net charge / refund is calculated by
    ///      `total_charge_gas_units` * `gas_unit_price` - `storage_fee_refund_octas`.
    ///
    /// This is meant to be emitted as a module event.
    struct FeeStatement has drop, store {
        /// Total gas charge.
        total_charge_gas_units: u64,
        /// Execution gas charge.
        execution_gas_units: u64,
        /// IO gas charge.
        io_gas_units: u64,
        /// Storage fee charge.
        storage_fee_octas: u64,
        /// Storage fee refund.
        storage_fee_refund_octas: u64,
    }

Gas price and prioritizing transactions

By specifying a higher gas unit price than the current market price, you can increase the priority level for your transaction on the blockchain by paying a larger processing fee. As part of consensus, when the leader selects transactions from its mempool to propose as part of the next block, it will prioritize selecting transactions with a higher gas unit price. Please note that higher gas fees only prioritize transaction selection for the next block.

Increasing gas unit price with in-flight transactions

If you are increasing gas unit price, but have in-flight (uncommitted) transactions for the same account, you should resubmit all of those transactions with the higher gas unit price. This is because transactions within the same account always have to respect sequence number, so effectively the higher gas unit price transaction will increase priority only after the in-flight transactions are included in a block.

Specifying gas fees within a transaction

When a transaction is submitted to the Endless blockchain, the transaction must contain the following mandatory gas fields:

  • max_gas_amount: The maximum number of gas units that the transaction sender is willing to spend to execute the transaction. This determines the maximum computational resources that can be consumed by the transaction.

  • gas_price: The gas price the transaction sender is willing to pay. It is expressed in Octa units, where 1 Octa equals 10-8 Endless utility token.

    During the transaction execution, the total gas amount, expressed as:

  • (total gas units consumed) * (gas_price)

    must not exceed max_gas_amount, or else the transaction will abort the execution.

The transaction fee charged to the client will be at the most gas_price * max_gas_amount.

Gas parameters set by governance

The following gas parameters are set by Endless governance.

On-chain gas schedule

These on-chain gas parameters are published on the Endless blockchain at 0x1::gas_schedule::GasScheduleV2.

  • txn.maximum_number_of_gas_units: Maximum number of gas units that can be spent (this is the maximum allowed value for the max_gas_amount gas parameter in the transaction). This is to ensure that the dynamic pricing adjustments do not exceed how much you are willing to pay in total.

  • txn.min_transaction_gas_units: Minimum number of gas units that can be spent. The max_gas_amount value in the transaction must be set to greater than this parameter鈥檚 value.

There also exists some global per-category limits:

  • txn.max_execution_gas: The maximum number of gas units a transaction can spend on execution.

  • txn.max_io_gas: The maximum number of gas units a transaction can spend on IO.

  • txn.max_storage_fee: The maximum amount of EDS a transaction can spend on persistent storage. These limits help decouple one category from another, allowing us to set txn.maximum_number_of_gas_units generously without having to worry about abuses.

Calculating Storage Fees

The storage fee for a transaction is charged according to the number of new slots allocated in the global state and the size increase in the existing slots.

There are some nuances with regard to price changing and legacy slots which didn't pay for the size of the slot below a historical "free quota".

It should also be noted that due to some backward compatibility reasons, the total storage fee of a transaction is currently presented to the client as part of the total gas_used. This means, this amount could vary based on the gas unit price even for the same transaction.

Here is an example. Suppose we have a transaction that costs 100 gas units in execution & IO, and 5000 Octa in storage fees. The network will show that you have used

  • 100 + 5000 / 100 = 150 gas units if the gas unit price is 100, or

  • 100 + 5000 / 200 = 125 gas units if the unit price is 200.

We are aware of the confusion this might create, and plan to present these as separate items in the future. However, this will require some changes to the transaction output format and downstream clients, so please be patient while we work hard to make this happen.

Calculating Storage Deletion Refund

If a transaction deletes state items, a refund is issued to the transaction payer for the released storage slots. Currently, a full refund is issued -- that is, all storage fee paid for the slot and bytes of the item over the lifetime of it.

The refund amount is denominated in EDS and is not converted to gas units or included in the total gas_used. Instead, this refund amount is specifically detailed in the storage_fee_refund_octas field of the FeeStatement. As a result, the transaction's net effect on the payer's EDS balance is determined by gas_used * gas_unit_price - storage_refund. If the result is positive, there is a deduction from the account balance; if negative, there is a deposit.

Examples

Example 1: Account balance vs transaction fee

The sender's account must have sufficient funds to pay for the transaction fee.

If, let's say, you transfer all the money out of your account so that you have no remaining balance to pay for the transaction fee. In such case the Endless blockchain would let you know that the transaction will fail, and your transfer wouldn't succeed either.

Example 2: Transaction amounts vs transaction fee

Transaction fee is independent of transfer amounts in the transaction.

In a transaction, for example, transaction A, you are transferring 1000 coins from one account to another account. In a second transaction B, with the same gas field values of transaction A, you now transfer 100,000 coins from one account to another one account. Assuming that both the transactions A and B are sent roughly at the same time, then the gas costs for transactions A and B would be near-identical.

Estimating gas consumption via simulation

The gas used for a transaction can be estimated by simulating the transaction on chain as described here or locally via the gas profiling feature of the Endless CLI. The results of the simulated transaction represent the exact amount that is needed at the exact state of the blockchain at the time of the simulation. These gas units used may change based on the state of the chain. For this reason, any amount coming out of the simulation is only an estimate, and when setting the max gas amount, it should include an appropriate amount of headroom based upon your comfort-level and historical behaviors. Setting the max gas amount too low will result in the transaction aborting and the account being charged for whatever gas was consumed.

To simulate the transaction locally, use the gas profiler, which is integrated into the Endless CLI. This will generate a web-based report to help you understand the precise gas usage of your transaction. See Gas Profiling for more details.

Note that the Signature

provided on the transaction must be all zeros. This is to prevent someone from using the valid signature.

To simulate the transaction, there are two flags:

  1. estimate_max_gas_amount: This flag will find the maximum possible gas you can use, and it will simulate the transaction to tell you the actual gas_used.

Simulation steps

The simulation steps for finding the correct amount of gas for a transaction are as follows:

  1. Estimate the gas via simulation with both estimate_gas_unit_price and estimate_max_gas_amount set to true.

  2. Use the gas_unit_price in the returned transaction as your new transaction鈥檚 gas_unit_price.

  3. View the gas_used * gas_unit_price values in the returned transaction as the lower bound for the cost of the transaction.

  4. To calculate the upper bound of the cost, take the minimum of the max_gas_amount in the returned transaction, and the gas_used * safety factor. In the CLI a value of 1.5 is used for safety factor. Use this value as max_gas_amount for the transaction you want to submit. Note that the upper bound for the cost of the transaction is max_gas_amount * gas_unit_price, i.e., this is the most the sender of the transaction is charged.

  5. At this point you now have your gas_unit_price and max_gas_amount to submit your transaction as follows:

    1. gas_unit_price from the returned simulated transaction.

    2. max_gas_amount as the minimum of the gas_used * a safety factor or the max_gas_amount from the transaction.

  6. If you feel the need to prioritize or deprioritize your transaction, adjust the gas_unit_price of the transaction. Increase the value for higher priority, and decrease the value for lower priority.

tip

tip

Note that the safety factor only takes into consideration changes related to execution and IO. Unexpected creation of storage slots may not be sufficiently covered.

PreviousTransactions and StatesNextComputing Transaction Gas

Last updated 2 months ago

In the Endless network, the Endless governance sets the absolute minimum gas unit price. However, the market determines how quickly a transaction with a particular gas unit price is processed. See , for example, which shows the market price movements of Ethereum gas price.

However, within a block, the order of transaction execution is determined by the system. This order is based on , which makes parallel execution more efficient by considering conflict patterns. While in most cases this is unnecessary, if the network is under load this measure can ensure your transaction is processed more quickly. See the gas_unit_price entry under Estimating the gas units via simulation for details.

To simulate transactions on chain, used the API. This API will run the exact transaction that you plan to run.

estimate_gas_unit_price: This flag will estimate the gas unit price in the transaction using the same algorithm as the API.

Prioritization is based upon buckets of gas_unit_price. The buckets are defined in . The current buckets are [0, 150, 300, 500, 1000, 3000, 5000, 10000, 100000, 1000000]. Therefore, a gas_unit_price of 150 and 299 would be prioritized nearly the same.

Ethereum Gas Tracker
transaction shuffling
SimulateTransaction
estimate_gas_price
mempool_config.rs