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