From f279e0ad5f85dcabe73597f8eafedfe61c7c4678 Mon Sep 17 00:00:00 2001
From: Novus Nota <68142933+novusnota@users.noreply.github.com>
Date: Tue, 14 Oct 2025 12:04:23 +0200
Subject: [PATCH] chore: title Tact code blocks and add a corresponding notice
---
ecosystem/blueprint/coverage.mdx | 5 +-
ton/proofs/basic-proof-concepts.mdx | 34 +++---
tvm/exit-codes.mdx | 163 ++++++++++++++--------------
3 files changed, 99 insertions(+), 103 deletions(-)
diff --git a/ecosystem/blueprint/coverage.mdx b/ecosystem/blueprint/coverage.mdx
index 66cb5ae1..a0084b81 100644
--- a/ecosystem/blueprint/coverage.mdx
+++ b/ecosystem/blueprint/coverage.mdx
@@ -201,7 +201,7 @@ Note that when code of other contracts is stored directly in the code of contrac
To mitigate this effect in coverage estimation, add a circular dependency. For example, import a file with the following content.
-```tact
+```tact title="Tact"
contract A {
receive() {
let x = initOf B();
@@ -209,8 +209,7 @@ contract A {
}
}
-contract B(
-) {
+contract B() {
receive() {
let x = initOf A();
drop2(x);
diff --git a/ton/proofs/basic-proof-concepts.mdx b/ton/proofs/basic-proof-concepts.mdx
index ccb92cd4..a1a4d76d 100644
--- a/ton/proofs/basic-proof-concepts.mdx
+++ b/ton/proofs/basic-proof-concepts.mdx
@@ -8,7 +8,7 @@ A **proof** is a tree-based structure that contains the necessary data and can b
To prove something means to construct such a structure. The exact structure may differ depending on the use case. For example, suppose a proof is to be validated off-chain and requires multiple cell trees; the native TON approach is to construct a Bag of Cells (BoC) containing all the necessary cells. This is precisely what a liteserver does when data is requested from the blockchain.
There are several key points to consider when proving anything on-chain.
@@ -19,12 +19,12 @@ There are several key points to consider when proving anything on-chain.
- **Blocks** serve as diffs that reflect changes to the **state** over time. Think of **blocks** as Git commits and the **state** as your repository.
- Latest TL-B schemas can be found in the [TON Monorepo](https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb). They may evolve, typically in backwards-compatible ways.
-
## More about blocks
We need to examine the block layout to determine what we can prove and how to do it.
Each block (ShardChain block, MasterChain block) has a unique block ID:
+
```tlb
block_id_ext$_ shard_id:ShardIdent seq_no:uint32
root_hash:bits256 file_hash:bits256 = BlockIdExt;
@@ -36,6 +36,7 @@ block_id_ext$_ shard_id:ShardIdent seq_no:uint32
- `file_hash` helps validators optimize processes; typically, you don’t need it.
A full block structure is as follows:
+
```tlb
block#11ef55aa global_id:int32
info:^BlockInfo value_flow:^ValueFlow
@@ -81,27 +82,27 @@ For detailed inspections, it is convenient to use the [official explorer](https:
To prove a transaction's existence in the **MasterChain**:
1. Obtain a trusted MasterChain block `root_hash` using TVM instructions (`PREVMCBLOCKS`, `PREVMCBLOCKS_100`, `PREVKEYBLOCKS`).
-2. User provides a complete MasterChain block that should be validated against the trusted hash.
-3. Parse the block to extract the transaction.
+1. User provides a complete MasterChain block that should be validated against the trusted hash.
+1. Parse the block to extract the transaction.
### Prove a transaction in BaseChain
For **BaseChain** transactions:
-1. Follow *steps 1-2* above to get a trusted `MasterChain` block.
-2. Extract the `shard_hashes` field from the MasterChain block.
-3. User provides the full ShardChain block that should be validated against the trusted hash.
-4. Parse the ShardChain block to find the transaction.
+1. Follow _steps 1-2_ above to get a trusted `MasterChain` block.
+1. Extract the `shard_hashes` field from the MasterChain block.
+1. User provides the full ShardChain block that should be validated against the trusted hash.
+1. Parse the ShardChain block to find the transaction.
### Prove account states
Sometimes, data is not in block diffs but within the ShardState itself. To prove an account's state in the **BaseChain**:
1. Parse the ShardChain block’s `state_update` field. This exotic cell contains two ShardState hashes (before and after the block).
-2. The user provides a ShardState that must be validated against the hash obtained in *step 1*.
+1. The user provides a ShardState that must be validated against the hash obtained in _step 1_.
## Understanding pruned branch cells
@@ -121,13 +122,13 @@ graph TD
end
```
-*v1* is a regular cell tree; in *v2*, the cell *c1* becomes a pruned branch, removing its content and references. However, if you only need *c0*, there’s no practical difference, as `$hash_0(v1) == hash_0(v2)$`.
+_v1_ is a regular cell tree; in _v2_, the cell _c1_ becomes a pruned branch, removing its content and references. However, if you only need _c0_, there’s no practical difference, as `$hash_0(v1) == hash_0(v2)$`.
- `hash0(cell)` ignores pruned branches, returning the original tree’s hash.
- `reprHash(cell)` accounts for everything. Matching `reprHashes` ensures cell path equivalency.
## Composing proofs
@@ -159,9 +160,9 @@ graph TD
```
## Real-world example
@@ -172,6 +173,7 @@ In this particular example, we want to prove the state of a JettonMaster and the
The [full example](https://github.com/tact-lang/dex/blob/main/sources/contracts/vaults/proofs/block-proof.tact) is too large for this article, but let's cover some key points.
This is an example of the proof composition technique described above. It is convenient because for `getRawAccountState`, the [liteserver](/ecosystem/node/overview) returns two items:
+
- the account state itself
- a BoC containing two proofs
@@ -200,7 +202,7 @@ const patchedShardState = rebuild(newShardState, path, accountState) // And repl
Another interesting point is how we access the hash of the last known `ShardBlock`.
-```tact
+```tact title="Tact"
inline fun findShardInBinTree(root: Cell, address: Address, shardBitLen: Int): ShardDescr {
let curCs = root.beginParse();
// It's std address, but we parse it as VarAddress to get hash part as Slice, not as Int
diff --git a/tvm/exit-codes.mdx b/tvm/exit-codes.mdx
index 3bd0615f..e8db5645 100644
--- a/tvm/exit-codes.mdx
+++ b/tvm/exit-codes.mdx
@@ -6,6 +6,10 @@ description: "An exit code is a 32-bit signed integer, which indicates whether t
import { Aside } from '/snippets/aside.jsx';
+
+
Each transaction on TON Blockchain consists of multiple phases. An _exit code_ is a 32-bit signed integer that indicates whether the [compute](#compute) or [action](#action) phase of the transaction was successful, and if not — holds the code of the exception that occurred. Each exit code represents its own exception or resulting state of the transaction.
Exit codes 0 and 1 indicate normal (successful) execution of the [compute phase](#compute). Exit (or [result](#action)) code 0 indicates normal (successful) execution of the [action phase](#action). Any other exit code indicates that a certain exception has occurred and that the transaction was not successful in one way or another, i.e. the transaction was reverted or the inbound message has bounced back.
@@ -13,60 +17,57 @@ Exit codes 0 and 1 indicate normal (successful) execution of the [compute phase]
TON Blockchain reserves exit code values from 0 to 127. The range from 256 to 65535 is free for developer-defined exit codes.
## Table of exit codes
The following table lists exit codes with their origin (where they can occur) and a short description for each.
-| Exit code | Origin | Brief description
-| :----------------------------------------------------------- | :---------------------------------- | :----------------
-| [0](#0%3A-normal-termination) | [Compute][c] and [action][a] phases | Standard successful execution exit code.
-| [1](#1%3A-alternative-termination) | [Compute phase][c] | Alternative successful execution exit code. Reserved, but does not occur.
-| [2](#2%3A-stack-underflow) | [Compute phase][c] | Stack underflow.
-| [3](#3%3A-stack-overflow) | [Compute phase][c] | Stack overflow.
-| [4](#4%3A-integer-overflow) | [Compute phase][c] | Integer overflow.
-| [5](#5%3A-integer-out-of-expected-range) | [Compute phase][c] | Range check error — an integer is out of its expected range.
-| [6](#6%3A-invalid-opcode) | [Compute phase][c] | Invalid [TVM][tvm] opcode.
-| [7](#7%3A-type-check-error) | [Compute phase][c] | Type check error.
-| [8](#8%3A-cell-overflow) | [Compute phase][c] | Cell overflow.
-| [9](#9%3A-cell-underflow) | [Compute phase][c] | Cell underflow.
-| [10](#10%3A-dictionary-error) | [Compute phase][c] | Dictionary error.
-| [11](#11%3A-%22unknown%22-error) | [Compute phase][c] | Described in [TVM][tvm] docs as "Unknown error, may be thrown by user programs."
-| [12](#12%3A-fatal-error) | [Compute phase][c] | Fatal error. Thrown by [TVM][tvm] in situations deemed impossible.
-| [13](#13%3A-out-of-gas-error) | [Compute phase][c] | Out of gas error.
-| [-14](#-14%3A-out-of-gas-error) | [Compute phase][c] | Same as 13. Negative, so that it [cannot be faked](#13%3A-out-of-gas-error).
-| [14](#14%3A-virtualization-error) | [Compute phase][c] | VM virtualization error. Reserved, but never thrown.
-| [32](#32%3A-action-list-is-invalid) | [Action phase][a] | Action list is invalid.
-| [33](#33%3A-action-list-is-too-long) | [Action phase][a] | Action list is too long.
-| [34](#34%3A-invalid-or-unsupported-action) | [Action phase][a] | Action is invalid or not supported.
-| [35](#35%3A-invalid-source-address-in-outbound-message) | [Action phase][a] | Invalid source address in outbound message.
-| [36](#36%3A-invalid-destination-address-in-outbound-message) | [Action phase][a] | Invalid destination address in outbound message.
-| [37](#37%3A-not-enough-toncoin) | [Action phase][a] | Not enough Toncoin.
-| [38](#38%3A-not-enough-extra-currencies) | [Action phase][a] | Not enough extra currencies.
-| [39](#39%3A-outbound-message-does-not-fit-into-cell) | [Action phase][a] | Outbound message does not fit into a cell after rewriting.
-| [40](#40%3A-cannot-process-message) | [Action phase][a] | Cannot process a message — not enough funds, the message is too large, or its Merkle depth is too big.
-| [41](#41%3A-library-reference-is-null) | [Action phase][a] | Library reference is null during library change action.
-| [42](#42%3A-library-change-action-error) | [Action phase][a] | Library change action error.
-| [43](#43%3A-library-limits-exceeded) | [Action phase][a] | Exceeded the maximum number of cells in the library or the maximum depth of the Merkle tree.
-| [50](#50%3A-account-state-size-exceeded-limits) | [Action phase][a] | Account state size exceeded limits.
+| Exit code | Origin | Brief description |
+| :----------------------------------------------------------- | :---------------------------------- | :----------------------------------------------------------------------------------------------------- |
+| [0](#0%3A-normal-termination) | [Compute][c] and [action][a] phases | Standard successful execution exit code. |
+| [1](#1%3A-alternative-termination) | [Compute phase][c] | Alternative successful execution exit code. Reserved, but does not occur. |
+| [2](#2%3A-stack-underflow) | [Compute phase][c] | Stack underflow. |
+| [3](#3%3A-stack-overflow) | [Compute phase][c] | Stack overflow. |
+| [4](#4%3A-integer-overflow) | [Compute phase][c] | Integer overflow. |
+| [5](#5%3A-integer-out-of-expected-range) | [Compute phase][c] | Range check error — an integer is out of its expected range. |
+| [6](#6%3A-invalid-opcode) | [Compute phase][c] | Invalid [TVM][tvm] opcode. |
+| [7](#7%3A-type-check-error) | [Compute phase][c] | Type check error. |
+| [8](#8%3A-cell-overflow) | [Compute phase][c] | Cell overflow. |
+| [9](#9%3A-cell-underflow) | [Compute phase][c] | Cell underflow. |
+| [10](#10%3A-dictionary-error) | [Compute phase][c] | Dictionary error. |
+| [11](#11%3A-%22unknown%22-error) | [Compute phase][c] | Described in [TVM][tvm] docs as "Unknown error, may be thrown by user programs." |
+| [12](#12%3A-fatal-error) | [Compute phase][c] | Fatal error. Thrown by [TVM][tvm] in situations deemed impossible. |
+| [13](#13%3A-out-of-gas-error) | [Compute phase][c] | Out of gas error. |
+| [-14](#-14%3A-out-of-gas-error) | [Compute phase][c] | Same as 13. Negative, so that it [cannot be faked](#13%3A-out-of-gas-error). |
+| [14](#14%3A-virtualization-error) | [Compute phase][c] | VM virtualization error. Reserved, but never thrown. |
+| [32](#32%3A-action-list-is-invalid) | [Action phase][a] | Action list is invalid. |
+| [33](#33%3A-action-list-is-too-long) | [Action phase][a] | Action list is too long. |
+| [34](#34%3A-invalid-or-unsupported-action) | [Action phase][a] | Action is invalid or not supported. |
+| [35](#35%3A-invalid-source-address-in-outbound-message) | [Action phase][a] | Invalid source address in outbound message. |
+| [36](#36%3A-invalid-destination-address-in-outbound-message) | [Action phase][a] | Invalid destination address in outbound message. |
+| [37](#37%3A-not-enough-toncoin) | [Action phase][a] | Not enough Toncoin. |
+| [38](#38%3A-not-enough-extra-currencies) | [Action phase][a] | Not enough extra currencies. |
+| [39](#39%3A-outbound-message-does-not-fit-into-cell) | [Action phase][a] | Outbound message does not fit into a cell after rewriting. |
+| [40](#40%3A-cannot-process-message) | [Action phase][a] | Cannot process a message — not enough funds, the message is too large, or its Merkle depth is too big. |
+| [41](#41%3A-library-reference-is-null) | [Action phase][a] | Library reference is null during library change action. |
+| [42](#42%3A-library-change-action-error) | [Action phase][a] | Library change action error. |
+| [43](#43%3A-library-limits-exceeded) | [Action phase][a] | Exceeded the maximum number of cells in the library or the maximum depth of the Merkle tree. |
+| [50](#50%3A-account-state-size-exceeded-limits) | [Action phase][a] | Account state size exceeded limits. |
{/* NOTE: Some might depend on a phase, in such cases the table entry might be:
-| number | [Compute][c] and [action][a] phases | Depends on the phase.
+ | number | [Compute][c] and [action][a] phases | Depends on the phase.
-*/}
+ */}
[c]: /tvm/overview#compute-phase
+
[a]: /tvm/overview#action-phase
## Exit codes in Blueprint projects
@@ -74,12 +75,12 @@ The following table lists exit codes with their origin (where they can occur) an
In [Blueprint][bp] tests, exit codes from the [compute phase](#compute) are specified in the `exitCode` field of the object argument for the `toHaveTransaction()` method of the `expect()` matcher. The field for the [result](#action) codes (exit codes from the [action phase](#action)) in the same `toHaveTransaction()` method is called `actionResultCode`.
{/*
-
+ */}
Additionally, one can examine the result of sending a message to a contract and discover the phases of each transaction and their values, including exit (or result) codes for the [compute phase](#compute) (or [action phase](#action)).
@@ -125,7 +126,7 @@ This is an alternative exit code for the successful execution of the [compute ph
If an operation consumes more elements than exist on the stack, an error with exit code 2 is thrown: `Stack underflow`.
-```tact
+```tact title="Tact"
asm fun drop() { DROP }
contract Loot {
@@ -140,17 +141,17 @@ contract Loot {
}
```
- */}
### 39: Outbound message does not fit into cell
When processing the message, TON Blockchain tries to pack it according to the relevant TL-B schemas, and if it cannot, an error with exit code 39 is thrown: `Outbound message doesn't fit into a cell`.
### 40: Cannot process message
@@ -492,9 +485,7 @@ When processing the message, TON Blockchain tries to pack it according to the re
If there are not enough funds to process all the cells in a message, the message is too large, or its Merkle depth is too big, an error with exit code 40 is thrown: `Cannot process a message`.
### 41: Library reference is null
@@ -515,26 +506,30 @@ If the account state (contract storage, essentially) exceeds any of the limits s
If the configuration is absent, the default values are:
-* `max_msg_bits` is equal to $2^{21}$ — maximum message size in bits.
-* `max_msg_cells` is equal to $2^{13}$ — maximum number of cells a message can occupy.
-* `max_library_cells` is equal to 1000 — maximum number of cells that can be used as library reference cells.
-* `max_vm_data_depth` is equal to $2^{9}$ — maximum cells depth in messages and account state.
-* `ext_msg_limits.max_size` is equal to 65535 — maximum external message size in bits.
-* `ext_msg_limits.max_depth` is equal to $2^{9}$ — maximum external message depth.
-* `max_acc_state_cells` is equal to $2^{16}$ — maximum number of cells that an account state can occupy.
-* `max_acc_state_bits` is equal to $2^{16} \times 1023$ — maximum account state size in bits.
-* `max_acc_public_libraries` is equal to $2^{8}$ — maximum number of library reference cells that an account state can use on the masterchain.
-* `defer_out_queue_size_limit` is equal to $2^{8}$ — maximum number of outbound messages to be queued (regarding validators and collators).
+- `max_msg_bits` is equal to $2^{21}$ — maximum message size in bits.
+- `max_msg_cells` is equal to $2^{13}$ — maximum number of cells a message can occupy.
+- `max_library_cells` is equal to 1000 — maximum number of cells that can be used as library reference cells.
+- `max_vm_data_depth` is equal to $2^{9}$ — maximum cells depth in messages and account state.
+- `ext_msg_limits.max_size` is equal to 65535 — maximum external message size in bits.
+- `ext_msg_limits.max_depth` is equal to $2^{9}$ — maximum external message depth.
+- `max_acc_state_cells` is equal to $2^{16}$ — maximum number of cells that an account state can occupy.
+- `max_acc_state_bits` is equal to $2^{16} \times 1023$ — maximum account state size in bits.
+- `max_acc_public_libraries` is equal to $2^{8}$ — maximum number of library reference cells that an account state can use on the masterchain.
+- `defer_out_queue_size_limit` is equal to $2^{8}$ — maximum number of outbound messages to be queued (regarding validators and collators).
-{/* NOTE: Reserved a section until when Tolk introduces any custom exit codes.
+{/* NOTE: Reserved a section until Tolk introduces any custom exit codes.
-## Tolk compiler
+ ## Tolk compiler
-Tolk utilizes exit codes from 128 to 255. Note that exit codes used by Tolk indicate contract errors which can occur when using Tolk-generated code and are therefore thrown in the transaction's [compute phase](#compute), not during compilation.
-*/}
+ Tolk utilizes exit codes from 128 to 255. Note that exit codes used by Tolk indicate contract errors which can occur when using Tolk-generated code and are therefore thrown in the transaction's [compute phase](#compute), not during compilation.
+ */}
[tlb]: /language/TL-B/overview
+
[tvm]: /tvm/overview
+
[bp]: /ecosystem/blueprint/overview
+
[sb]: https://github.com/ton-org/sandbox
+
[jest]: https://jestjs.io