> ## Documentation Index
> Fetch the complete documentation index at: https://hedera-0c6e0218-docs-smart-contract-pectra-updates-v2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Gas and Fees

> Understanding gas costs, throttling, and fee calculation for Hiero Contracts

## Gas

When executing smart contracts, the **EVM** requires the amount of work paid in **gas**. The "work" includes computation, state transitions, and storage. Gas is the unit of measurement used to charge a fee per opcode executed by the EVM. Each opcode has a defined gas cost. Gas reflects the cost necessary to pay for the computational resources used to process transactions.

<Note>
  Following **[HIP-1249](https://hips.hedera.com/hip/hip-1249)**, Hedera has implemented **operational-based throttling** and eliminated **minimum gas charges**, providing more predictable resource management and fairer billing for smart contract operations.
</Note>

## Weibar

Gas information for EVM operations is returned in **weibar** (introduced in [HIP-410](https://hips.hedera.com/hip/hip-410)).

* `1 weibar = 10^-18 HBAR`
* `1 tinybar = 10^10 weibar`

As noted in [HIP-410](https://hips.hedera.com/hip/hip-410), this maximizes compatibility with third-party tools that expect ether units to be operated on in fractions of `10^18`, also known as a **Wei**.

## Gas Schedule and Fee Calculation

Gas charges apply to `ContractCall`, `ContractCreate`, and `EthereumTransaction`. Other smart contract-related transactions (e.g., `ContractDelete`, `ContractGetInfo`) use the standard [Fee Model](/learn/core-concepts/fee-model), a base fee plus extras for node, network, and service components, paid in HBAR.

For gas-consuming transactions (`ContractCall`, `ContractCreate`, `EthereumTransaction`), gas is an "extra" in the service fee component. The gas extra covers EVM execution costs. All other fee components (node fee, network fee, and the non-gas portion of the service fee) follow the base-fee-plus-extras model.

Gas fees for EVM transactions consist of:

* **Intrinsic Gas**: The minimum amount of gas required to execute a transaction
* **EVM Opcode Gas**: The gas required to execute the defined opcodes for the smart contract call
* **Hedera System Contract Gas**: The required gas associated with Hedera-defined transactions, such as using the Hedera Token Service system contract

<Note>
  **High-volume contract creation.** `ContractCreateTransaction` supports the
  `high_volume` flag ([HIP-1313](https://hips.hedera.com/hip/hip-1313)), which routes
  the transaction through dedicated high-volume throttle capacity with variable-rate
  pricing. This applies to **HAPI-based contract creation only**; contract deployments
  via EVM `CREATE` / `CREATE2` opcodes are not included. See the
  [High-Volume Entity Creation](/learn/core-concepts/high-volume-entity-creation) guide
  for details.
</Note>

### Intrinsic Gas

A transaction submitted to the smart contract service must be sent with enough gas to cover **intrinsic gas**. Under the **Pectra hard fork** (Prague EVM execution layer), intrinsic gas is calculated as:

```bash theme={null}
21000 + 4 × (number of zero bytes) + 16 × (number of non-zero bytes) = intrinsic gas
```

* **21,000**: The base gas cost for any transaction
* **4 × (zero bytes)**: The cost of each zero byte in the transaction payload
* **16 × (non-zero bytes)**: The cost for each non-zero byte in the transaction payload

If insufficient gas is submitted, the transaction will **fail during precheck** and no record will be created.

<Note>
  **Pectra calldata floor ([EIP-7623](https://eips.ethereum.org/EIPS/eip-7623)).** Under Pectra, transactions must additionally satisfy a calldata floor:

  ```bash theme={null}
  floor = 21000 + 10 × (zero bytes + 4 × non-zero bytes)
  ```

  The transaction pays `MAX(standard intrinsic + execution gas, floor)`. The floor primarily affects calldata-heavy transactions with low execution cost; most contract calls are unaffected. See [HIP-1341](https://hips.hedera.com/hip/hip-1341) for Pectra adoption details on Hedera.
</Note>

<Note>
  This applies to both standard transactions and **jumbo EthereumTransactions** introduced by **[HIP-1086](https://hips.hedera.com/hip/hip-1086)**, which allow larger `callData` payloads.
</Note>

<Note>
  **Type 4 (EIP-7702) authorization gas.** Each entry in a Type 4 EthereumTransaction's `authorization_list` costs **25,000 gas** if it creates a new account, or **12,500 gas** if the authorizing account already exists. Hedera additionally charges its usual hollow-account creation cost for any newly created accounts. See the [EOA Code Delegation](/evm/development/eoa-code-delegation) page and [HIP-1340](https://hips.hedera.com/hip/hip-1340).
</Note>

### EVM Opcode Gas

Execution costs in the EVM include both **fixed** and **dynamic** costs:

* **Fixed Cost**: Base cost per opcode execution
* **Dynamic Cost**: Varies by parameters (e.g., cold vs warm storage access)

**Example**: For the `SLOAD` opcode, which loads data from storage:

* **Fixed Cost**: `100 gas` units (base cost per execution)
* **Dynamic Cost (Cold Access)**: `2,100 gas` units (first-time access to the storage slot)
* **Dynamic Cost (Warm Access)**: `100 gas` units (subsequent access within the transaction)

If `SLOAD` accesses a storage slot twice within the same transaction, the total gas cost would be calculated as follows:

* **First Access (Cold)** = `100 + 2,100 = 2,200 gas`
* **Second Access (Warm)** = `100 + 100 = 200 gas`
* **Final Gas Cost Total** = `2,400 gas`

📣 *Explore [opcodes in Pectra (Prague) fork](https://www.evm.codes/?fork=prague).*

### Hedera System Contract Gas

Hedera system contract gas fees apply only when using a native Hedera service. They are calculated by converting the transaction cost in **USD** to gas using a set conversion rate, then adding a **20% surcharge** for overhead and variations in gas usage.

**Example**: For a **\$0.10 transaction** with a conversion rate of `1,000,000 gas per USD`:

* **Base Gas Cost** = `0.10 × 1,000,000 = 100,000 gas`
* **Total Gas Cost** = `100,000 × 1.2 = 120,000 gas`
* **Final gas cost total** = `120,000 gas`

<Note>
  Following **[HIP-1249](https://hips.hedera.com/hip/hip-1249)**, system contract operations also contribute to **operational throttling** through measured ops costs, providing layered resource protection alongside gas-based billing.
</Note>

#### System Contract View Functions

The gas requirements for **HTS view functions** can be calculated in a slightly modified manner. The transaction type of `getTokenInfo` can be used and a nominal price need not be calculated. This implies that converting the fee into HBAR is not necessary as the canonical price (`$0.0001`) can be directly converted into gas by using the conversion factor of **852 tinycents**. Add **20% markup**. Thus gas cost is:

* **Base gas cost** = `(1000000 + 852000 - 1) × 1000 / 852000 = 2173 gas`
* **Total Gas Cost** = `2173 × 1.2 = 2607 gas`

**Final gas cost total** = `2607 gas`

<Info>
  **Example System Contracts:**

  * **[Hedera Token Service (HTS)](https://github.com/hiero-ledger/hiero-contracts/blob/main/contracts/token-service/HederaTokenService.sol)**
  * **[Pseudo Random Number Generator (PRNG)](https://github.com/hiero-ledger/hiero-contracts/blob/main/contracts/prng/PrngSystemContract.sol)**
  * **[Exchange Rate](https://github.com/hiero-ledger/hiero-contracts/blob/main/contracts/exchange-rate/ExchangeRateSystemContract.sol)**

  **Learn More**: Our detailed gas calculation [reference](https://github.com/hashgraph/hedera-services/blob/develop/hedera-node/docs/design/services/smart-contract-service/system-contract-gas-calc.md#system-contracts) explains the precise steps for calculating gas fees on Hedera.
</Info>

## Gas for Jumbo Transactions

**Jumbo EthereumTransactions** that include large `callData` under **[HIP-1086](https://hips.hedera.com/hip/hip-1086)** follow the same gas model as standard EVM transactions. This gas pricing applies only to [EthereumTransaction](/native/smart-contracts/ethereum-transaction) type; standard HAPI transactions are unaffected.

### Formula

The gas cost for `callData` is based on byte content:

```
callData gas = (4 × zero bytes) + (16 × non-zero bytes)
```

This is added to the base gas and execution gas to calculate the total gas required.

*📣 [Learn more about Ethereum jumbo transactions](/native/smart-contracts/ethereum-transaction#handling-large-calldata-payloads)*

### Example Calculation

For **100KB of `callData`** with `10,000 zero bytes` and `90,000 non-zero bytes`:

* **Zero byte gas**: `4 × 10,000 = 40,000`
* **Non-zero byte gas**: `16 × 90,000 = 1,440,000`
* **Total callData gas** = `1,480,000`

Ensure both `gasLimit` (RLP) and `maxGasAllowance` (wrapper) are set high enough to cover the total.

<Note>
  🔹 **Size Caps**: Jumbo EthereumTransactions are capped at **24KB** (creation) and **128KB** (call). Larger payloads require `callDataFileId`.\
  🔹 **Throttling**: Jumbo transactions are subject to dedicated **operational throttling** based on transaction type and complexity.
</Note>

## Gas Limit

The **gas limit** is the maximum amount of gas you are willing to pay for an operation.

The current opcode gas fees are reflective as of the **[0.22 Hedera Service release](/learn/release-notes/services#v0.22)**.

| Operation                                                                 | Pectra Cost (Gas)                              | Current Hedera (Gas)                           |
| ------------------------------------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- |
| Code deposit                                                              | 200 \* bytes                                   | 200 \* bytes                                   |
| <p><code>BALANCE</code><br />(cold account)</p>                           | 2600                                           | 2600                                           |
| <p><code>BALANCE</code><br />(warm account)</p>                           | 100                                            | 100                                            |
| `EXP`                                                                     | 10 + 50/byte                                   | 10 + 50/byte                                   |
| <p><code>EXTCODECOPY</code><br />(cold account)</p>                       | 2600 + Mem                                     | 2600 + Mem                                     |
| <p><code>EXTCODECOPY</code><br />(warm account)</p>                       | 100 + Mem                                      | 100 + Mem                                      |
| <p><code>EXTCODEHASH</code><br />(cold account)</p>                       | 2600                                           | 2600                                           |
| <p><code>EXTCODEHASH</code><br />(warm account)</p>                       | 100                                            | 100                                            |
| <p><code>EXTCODESIZE</code><br />(cold account)</p>                       | 2600                                           | 2600                                           |
| <p><code>EXTCODESIZE</code><br />(warm account)</p>                       | 100                                            | 100                                            |
| <p><code>LOG0, LOG1, LOG2,</code><br /><code>LOG3, LOG4</code></p>        | <p>375 + 375\*topics<br />+ data Mem</p>       | <p>375 + 375\*topics<br />+ data Mem</p>       |
| <p><code>SLOAD</code><br />(cold slot)</p>                                | 2100                                           | 2100                                           |
| <p><code>SLOAD</code><br />(warm slot)</p>                                | 100                                            | 100                                            |
| <p><code>SSTORE</code><br />(new slot)</p>                                | 22,100                                         | 22,100                                         |
| <p><code>SSTORE</code><br />(existing slot,<br />cold access)</p>         | 2,900                                          | 2,900                                          |
| <p><code>SSTORE</code><br />(existing slot,<br />warm access)</p>         | 100                                            | 100                                            |
| <p><code>SSTORE</code><br />refund</p>                                    | As specified by the EVM                        | As specified by the EVM                        |
| <p><code>CALL</code> <em>et al</em>.<br />(cold recipient)</p>            | 2,600                                          | 2,600                                          |
| <p><code>CALL</code> <em>et al</em>.<br />(warm recipient)</p>            | 100                                            | 100                                            |
| <p><code>CALL</code> <em>et al</em>.<br />HBAR/ETH Transfer Surcharge</p> | 9,000                                          | 9,000                                          |
| <p><code>SELFDESTRUCT</code><br />(cold beneficiary)</p>                  | 2600                                           | 2600                                           |
| <p><code>SELFDESTRUCT</code><br />(warm beneficiary)</p>                  | 0                                              | 0                                              |
| `TSTORE`                                                                  | 100                                            | 100                                            |
| `TLOAD`                                                                   | 100                                            | 100                                            |
| `MCOPY`                                                                   | 3 + 3\*words\_copied + memory\_expansion\_cost | 3 + 3\*words\_copied + memory\_expansion\_cost |

The terms **'warm'** and **'cold'** in the above table correspond with whether the account or storage slot has been read or written to within the current smart contract transaction, even within a child call frame.

**'CALL et al.'** includes with limitation: `CALL`, `CALLCODE`, `DELEGATECALL`, and `STATICCALL`

**BLS12-381 precompiles ([EIP-2537](https://eips.ethereum.org/EIPS/eip-2537))** are available under Pectra at the following addresses, callable via `call` / `staticcall`:

| Function              | Address | Input size (bytes) | Purpose                                                                       |
| --------------------- | ------- | ------------------ | ----------------------------------------------------------------------------- |
| `BLS12_G1ADD`         | `0x0b`  | 256                | Add two G1 points.                                                            |
| `BLS12_G1MSM`         | `0x0c`  | 160 × k slices     | Multi-scalar multiplication on G1 (sum of `scalar[i] × point[i]`).            |
| `BLS12_G2ADD`         | `0x0d`  | 512                | Add two G2 points.                                                            |
| `BLS12_G2MSM`         | `0x0e`  | 288 × k slices     | Multi-scalar multiplication on G2.                                            |
| `BLS12_PAIRING_CHECK` | `0x0f`  | 384 × k slices     | Verify `Π e(G1_i, G2_i) == 1`, the core check for BLS signature verification. |
| `BLS12_MAP_FP_TO_G1`  | `0x10`  | 64                 | Map a field element (`Fp`) onto the G1 curve.                                 |
| `BLS12_MAP_FP2_TO_G2` | `0x11`  | 128                | Map a field element (`Fp2`) onto the G2 curve (used in hash-to-curve).        |

**Input encoding** (per EIP-2537):

* `Fp` element: 64 bytes, a 48-byte field element left-padded to 64 bytes (16 bytes of leading zeros).
* `G1` point: 128 bytes, two `Fp` elements (`x`, `y`).
* `G2` point: 256 bytes, two `Fp2` elements, each `Fp2 = (c0, c1)` written as two `Fp` values.
* Scalar (for MSM): 32 bytes, big-endian, full 256-bit width.

Each MSM input is `point ‖ scalar`, repeated `k` times. The pairing check input is `(G1_i ‖ G2_i)` tuples of 384 bytes each, repeated `k` times.

### Example: BLS signature verification

The most common use case is verifying a BLS signature against a public key and message hash. The pairing check verifies `e(signature, G2_generator) == e(H(m), public_key)`, which the precompile expresses as `Π e(G1, G2) == 1` by including the second pair with a negated G1 generator.

```solidity Solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

/// @title BLSVerifier
/// @notice Verifies a single BLS signature using EIP-2537 precompiles on Hedera/Ethereum.
contract BLSVerifier {
    /// Address of BLS12_PAIRING_CHECK precompile.
    address constant BLS12_PAIRING_CHECK = address(0x0f);

    /// Address of BLS12_MAP_FP2_TO_G2 (used for hash-to-curve message encoding).
    address constant BLS12_MAP_FP2_TO_G2 = address(0x11);

    /// Verifies that `signature` (G2 point, 256 bytes) was produced by the holder of
    /// `publicKey` (G1 point, 128 bytes) over the G2-encoded message `messagePoint`
    /// (256 bytes, typically produced by hash-to-curve onto G2 off-chain or via
    /// BLS12_MAP_FP2_TO_G2 on-chain).
    ///
    /// Pairing check: e(-G1_generator, signature) · e(publicKey, messagePoint) == 1
    function verify(
        bytes calldata publicKey,        // 128 bytes, G1 point
        bytes calldata messagePoint,     // 256 bytes, G2 point
        bytes calldata signature         // 256 bytes, G2 point
    ) external view returns (bool valid) {
        require(publicKey.length    == 128, "bad pubkey len");
        require(messagePoint.length == 256, "bad msg len");
        require(signature.length    == 256, "bad sig len");

        // Negated G1 generator (-G1) in EIP-2537's 128-byte encoding: the canonical
        // BLS12-381 generator's x coordinate, then (p - y), each left-padded to 64 bytes.
        // As with any cryptographic constant, exercise this contract against the
        // EIP-2537 test vectors before production use.
        bytes memory negG1 = hex"0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0f"
                             hex"c3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"
                             hex"00000000000000000000000000000000114d1d6855d545a8aa7d76c8cf2e21f2"
                             hex"67816aef1db507c96655b9d5caac42364e6f38ba0ecb751bad54dcd6b939c2ca";

        // Build pairing input: (negG1 ‖ signature) ‖ (publicKey ‖ messagePoint) = 768 bytes
        bytes memory input = bytes.concat(negG1, signature, publicKey, messagePoint);

        bytes memory output = new bytes(32);
        bool ok;
        assembly {
            ok := staticcall(
                gas(),
                BLS12_PAIRING_CHECK,
                add(input, 0x20),
                768,
                add(output, 0x20),
                32
            )
        }
        require(ok, "precompile failed");

        // Pairing check returns 32 bytes: 0x00..01 = valid, 0x00..00 = invalid.
        valid = (uint256(bytes32(output)) == 1);
    }
}
```

### Example: aggregate two G1 public keys

BLS aggregation is the canonical reason to want native curve precompiles. Adding two G1 public keys lets you combine signatures over the same message into a single signature that verifies against the sum of the keys.

```solidity Solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

contract BLSAggregator {
    address constant BLS12_G1ADD = address(0x0b);

    /// Adds two G1 points (each 128 bytes). Returns the 128-byte sum.
    function aggregate(bytes calldata a, bytes calldata b) external view returns (bytes memory sum) {
        require(a.length == 128 && b.length == 128, "bad point len");

        bytes memory input = bytes.concat(a, b);  // 256 bytes
        sum = new bytes(128);

        bool ok;
        assembly {
            ok := staticcall(gas(), BLS12_G1ADD, add(input, 0x20), 256, add(sum, 0x20), 128)
        }
        require(ok, "G1ADD failed");
    }
}
```

> See the [EIP-2537 specification](https://eips.ethereum.org/EIPS/eip-2537) for the full input format of each precompile and the test vectors used to validate implementations.

Reference: [HIP-206](https://hips.hedera.com/hip/hip-206), [HIP-865](https://hips.hedera.com/hip/hip-865), [HIP-1341](https://hips.hedera.com/hip/hip-1341)

## Operational-Based Throttling

While most **EVM-compatible networks** use per-block gas limits for resource control, Hedera uses **time-based throttling**. Following **[HIP-1249](https://hips.hedera.com/hip/hip-1249)**, Hedera has transitioned from **gas-per-second** to **operations-per-second (ops/sec) throttling**, controlling network throughput based on actual computational demands rather than gas estimates. This potentially supports **significantly higher throughput** while maintaining EVM compatibility.

**Ops costs** are derived from **nanosecond performance benchmarks** with safety margins, covering **EVM opcodes**, **precompiles**, and **system contracts**. Gas continues for user billing and per-transaction limits, separating cost calculation from throttling.

<Note>
  **Performance**: Real-world testing shows substantial improvements, with **Uniswap** achieving over **150 million gas/sec** compared to the previous **15 million gas/sec** limit.
</Note>

### Transaction Execution Outcomes

With **operational-based throttling**, transaction processing follows specific patterns based on resource availability:

**Ops Throttle Exhausted**: When the operations-per-second throttle is exhausted either before execution begins or during execution, transactions fail with a `THROTTLED_AT_CONSENSUS` error and are charged only the **[intrinsic gas fee](/evm/development/gas-fees#intrinsic-gas)**.

**Gas Limit Exhausted**: If a transaction's gas limit is exhausted before the ops throttle, it fails with an **out-of-gas error** and users are charged for the full gas used, with ops deducted for work completed.

**Successful Execution**: For successful transactions, users are charged for the **exact gas used** and the corresponding ops units are deducted from the throttle bucket.

## Gas Reservation and Unused Gas Refund

Hedera throttles transactions **before consensus**, and nodes limit the number of transactions they can submit to the network. At **consensus time**, if the maximum number of transactions is exceeded, the excess transactions are not evaluated and are canceled with a **busy state**. Throttling by variable gas amounts provides challenges to this system, where the nodes only submit a share of their transaction limit.

To address this, Hedera now uses **operational-based throttling** that applies only at **consensus**. The system operates with:

* **Frontend (ingest/precheck)**: Uses **TPS limits** only with no gas-based throttling
* **Backend (consensus)**: Applies **operations-per-second (ops) throttling** based on actual computational work performed

It is impossible to know the actual evaluated gas pre-consensus because the network state can directly impact the flow of the transaction, which is why pre-consensus uses the `gasLimit` field and will be referred to as the **gas reservation**.

**Contract query requests** are unique and bypass the consensus stage altogether. These requests are executed solely on the local node that receives them and only influence that specific node's precheck throttle.

To ensure transactions can execute properly, setting a **higher gas reservation** than will be used by execution is common. On **Ethereum mainnet**, the entire reservation is charged to the account before execution, and the unused portion is credited back. However, Ethereum utilizes a **[memory pool (mempool)](/support/glossary#mempool)** and does transaction ordering at block production time, allowing the block limit to be based only on used and not reserved gas.

Users are charged only for the **actual gas used** during transaction execution, with **unused gas being fully refunded**. This aligns with Ethereum's billing model and eliminates the previous minimum charge requirements.

## Maximum Gas Per Transaction

Each transaction on Hedera is capped by a **per-transaction gas limit**. If a transaction's `gasLimit` exceeds this cap, it is rejected during precheck with the `INDIVIDUAL_TX_GAS_LIMIT_EXCEEDED` error and does not proceed to consensus. This gas metering approach ensures efficient resource use, preventing excessive consumption while allowing flexibility for larger, more complex smart contracts.

Per-transaction gas limits remain unchanged (e.g., **15 million gas per transaction**), while network throughput is now managed through **operational-based throttling**. Refer to [HIP‑1249](https://hips.hedera.com/hip/hip-1249) for implementation details.

**Reference**: [HIP-185](https://hips.hedera.com/hip/hip-185)
