# How Acton Handles Gas Estimation for TON Smart Contracts

> Learn how Acton estimates TON smart contract gas usage. Discover methods like Transaction.getUsedGas() and calculateGasFee() for accurate fee projections.

- Repository: [TON - The Open Network/acton](https://github.com/ton-blockchain/acton)
- Tags: how-to-guide
- Published: 2026-05-14

---

**Acton estimates gas consumption through `Transaction.getUsedGas()` for executed transactions and provides pure standard library functions like `calculateGasFee()` to project fees for hypothetical gas amounts using VM opcodes.**

Acton, the comprehensive testing framework for The Open Network (TON), implements a dual-layer approach to gas estimation for TON smart contracts within the `ton-blockchain/acton` repository. By combining runtime telemetry from transaction execution with static fee-calculation primitives, the framework enables developers to audit historical consumption and forecast future costs with nanoton precision. This analysis examines the specific source implementations in `crates/ton-retrace` and the Tolk standard library that power these capabilities.

## Retrieving Actual Gas Consumption with Transaction.getUsedGas()

When Acton's emulator or TonCenter API returns a transaction, the framework wraps the raw response in a `Transaction` object that exposes granular execution metrics. The `getUsedGas()` method reads directly from the transaction's compute phase data to return the exact amount of gas consumed.

In [`crates/ton-retrace/src/types.rs`](https://github.com/ton-blockchain/acton/blob/main/crates/ton-retrace/src/types.rs), the `Transaction` struct deserializes fields including `gas_used` and `gas_fees` from the underlying TON data. The method accesses these through the `ComputeInfo` enum, which distinguishes between successful execution and skipped phases.

### The ComputeInfo Enum Structure

The `ComputeInfo` enum defines two primary variants:

- **Skipped**: Indicates the compute phase did not run, such as when targeting an undeployed contract
- **Success**: Contains `gas_used: u64` and `gas_fees` fields reflecting actual VM consumption

When `getUsedGas()` encounters the `Success` variant, it returns the raw `gas_used` value as reported by the TVM. This integer represents the exact gas units consumed during the contract's execution cycle.

### Handling Skipped Compute Phases

If the transaction's compute phase was skipped, calling `getUsedGas()` triggers an exception. The test suite validates this behavior in [`tests/integration/test_runner/transaction_load_body_and_load_in_msg_extract_typed_payload_and_endpoints_tests.rs`](https://github.com/ton-blockchain/acton/blob/main/tests/integration/test_runner/transaction_load_body_and_load_in_msg_extract_typed_payload_and_endpoints_tests.rs) using `expectToEndWithExitCode(567)`.

This mechanism safeguards developers from accidentally reading gas metrics from transactions that never executed code, such as messages sent to undeployed addresses.

## Projecting Fees with Standard Library Functions

Beyond inspecting historical transactions, Acton provides pure functions to calculate theoretical fees based on hypothetical gas amounts. These functions reside in `crates/tolk-compiler/assets/tolk-stdlib/gas-payments.tolk`.

### GETGASFEE and GETGASFEESIMPLE Opcodes

The standard library exposes two primary fee-calculation primitives:

- **`calculateGasFee(workchain, gasUsed)`**: Invokes the `GETGASFEE` VM opcode to determine the total fee for a specified gas amount on a specific workchain
- **`calculateGasFeeWithoutFlatPrice`**: Invokes `GETGASFEESIMPLE` to calculate fees excluding flat-rate components

Both functions are marked with the `@pure` annotation, meaning they perform no state modifications and can be called safely from any Tolk or Func script to estimate costs before execution.

```rust
// gas-payments.tolk (standard library)
@pure
fun calculateGasFee(workchain: int8, gasUsed: int): coins
    asm(gasUsed workchain) "GETGASFEE"
    
// User script
val fee = calculateGasFee(MASTERCHAIN, 150_000); // fee in nanoton-coins

```

## Integration Workflow: From Execution to Fee Calculation

The complete gas estimation flow combines both mechanisms into a coherent pipeline:

1. **Send** a message to a smart contract
2. **Receive** a `Transaction` object from the emulator or API
3. **Extract** actual consumption via `tx.getUsedGas()`
4. **Project** costs using `calculateGasFee(workchain, gasUnits)` to receive nanoton-coin values

This separation of concerns allows developers to verify actual resource usage against theoretical models, identifying discrepancies between expected and realized gas consumption.

```rust
// In a Tolk/Func test script
val tx = txs.findTransaction<Ping>({ from: sender.address, to: workerAddress })!;
val used_gas: int = tx.getUsedGas();          // ← reads ComputeInfo.Success.gas_used

```

## Validation Through Integration Tests

Acton's test suite validates gas estimation accuracy in [`tests/integration/test_runner/transaction_load_body_and_load_in_msg_extract_typed_payload_and_endpoints_tests.rs`](https://github.com/ton-blockchain/acton/blob/main/tests/integration/test_runner/transaction_load_body_and_load_in_msg_extract_typed_payload_and_endpoints_tests.rs).

The test `transaction_get_used_gas_matches_send_result_for_root_and_child_transactions` confirms that `rootTx.getUsedGas()` aligns with the `gasUsed` field from transaction lists and exceeds the baseline of 255 units for non-trivial operations.

A separate test function, `transaction_get_used_gas_reports_skipped_compute_phase_for_undeployed_destination`, sends messages to undeployed addresses and verifies the exit code 567 exception, ensuring the framework correctly identifies skipped compute phases.

```rust
// In a test that targets an undeployed destination
val tx = txs.findTransaction<Ping>({ from: sender.address, to: undeployed })!;
expectToEndWithExitCode(567); // Acton reports "compute phase skipped"
tx.getUsedGas();               // throws because the phase was skipped

```

## Summary

- **Runtime inspection**: `Transaction.getUsedGas()` extracts `gas_used: u64` from `ComputeInfo.Success` in executed transactions
- **Static calculation**: Pure functions `calculateGasFee` and `calculateGasFeeWithoutFlatPrice` wrap `GETGASFEE` and `GETGASFEESIMPLE` opcodes for hypothetical fee projection
- **Safety mechanisms**: The framework throws exit code 567 when attempting to read gas from skipped compute phases targeting undeployed contracts
- **Source locations**: Implementation resides in [`crates/ton-retrace/src/types.rs`](https://github.com/ton-blockchain/acton/blob/main/crates/ton-retrace/src/types.rs) and `crates/tolk-compiler/assets/tolk-stdlib/gas-payments.tolk`
- **Test coverage**: Integration tests verify both successful gas retrieval and proper error handling for skipped phases at [`tests/integration/test_runner/transaction_load_body_and_load_in_msg_extract_typed_payload_and_endpoints_tests.rs`](https://github.com/ton-blockchain/acton/blob/main/tests/integration/test_runner/transaction_load_body_and_load_in_msg_extract_typed_payload_and_endpoints_tests.rs)

## Frequently Asked Questions

### What happens if I call getUsedGas() on a transaction with a skipped compute phase?

Acton throws an exception with exit code 567. This occurs when the target contract was not deployed or the compute phase was otherwise skipped, preventing invalid gas readings from non-executed code.

### How does Acton calculate the actual fee cost from gas units?

The framework maps gas units to nanoton fees using the `calculateGasFee(workchain, gasUsed)` function, which invokes the `GETGASFEE` VM opcode. This accounts for workchain-specific pricing parameters and flat-rate components defined in the TON configuration.

### Can I use Acton's gas estimation for transactions that haven't been executed yet?

Yes. While `getUsedGas()` requires an executed transaction, the `@pure` functions `calculateGasFee` and `calculateGasFeeWithoutFlatPrice` can project fees for any hypothetical gas amount without requiring runtime execution or state changes.

### Where are the gas estimation primitives defined in the Acton codebase?

Runtime gas data structures reside in [`crates/ton-retrace/src/types.rs`](https://github.com/ton-blockchain/acton/blob/main/crates/ton-retrace/src/types.rs), defining `Transaction` and `ComputeInfo`. The fee-calculation standard library is located at `crates/tolk-compiler/assets/tolk-stdlib/gas-payments.tolk`.