diff --git a/contract-dev/blueprint/debug.mdx b/contract-dev/blueprint/debug.mdx
index 98f5e23eb..4eff538eb 100644
--- a/contract-dev/blueprint/debug.mdx
+++ b/contract-dev/blueprint/debug.mdx
@@ -68,7 +68,7 @@ it('should deploy correctly', async () => {
## Dump values from a contract
-There are three TVM debug [instructions](/tvm/instructions#fe-debug): `DUMPSTK`, `STRDUMP`, and `DUMP`.
+There are three TVM debug [instructions](/tvm/instructions#feij-debug): `DUMPSTK`, `STRDUMP`, and `DUMP`.
These instructions are wrapped in functions with different names in each language:
@@ -127,7 +127,7 @@ default exception handler, terminating vm with exit code 9
diff --git a/contract-dev/techniques/on-chain-jetton-processing.mdx b/contract-dev/techniques/on-chain-jetton-processing.mdx
index 228ef1636..9be03cc03 100644
--- a/contract-dev/techniques/on-chain-jetton-processing.mdx
+++ b/contract-dev/techniques/on-chain-jetton-processing.mdx
@@ -32,7 +32,7 @@ There are three approaches to verify `JettonNotify` messages, depending on the l
## Manual wallet management
-If the jetton type is known in advance, [calculate the corresponding jetton wallet address off-chain](https://docs.ton.org/standard/tokens/jettons/find) and set it via a message after deployment. It is impossible to hardcode the jetton wallet address in the contract’s [`StateInit`](/foundations/messages/deploy) because the wallet address depends on the contract address and creates a circular dependency. This is the most efficient approach, because it only requires one address comparison.
+If the jetton type is known in advance, [calculate the corresponding jetton wallet address off-chain](/standard/tokens/jettons/find) and set it via a message after deployment. It is impossible to hardcode the jetton wallet address in the contract’s [`StateInit`](/foundations/messages/deploy) because the wallet address depends on the contract address and creates a circular dependency. This is the most efficient approach, because it only requires one address comparison.
The following example of a receiving contract handles `JettonNotify` messages for a trusted jetton wallet address that can be set by the owner of the contract.
@@ -228,7 +228,7 @@ If a jetton contract doesn't implement TEP-89, it is possible to compute the jet
Jettons that do not implement the TEP-89 messages for computing a wallet address on-chain are rare. [TONCO DEX](https://tonco.io/) rejects them, while platforms such as [DeDust](https://dedust.io/) only allow them after a manual approval.
-With the state of a jetton minter, the [RUNVM](/tvm/instructions#db4-runvm) instruction can emulate the execution of the `get_wallet_address` [get-method](/tvm/get-method) to derive the wallet address for any owner.
+With the state of a jetton minter, the [`RUNVM`](/tvm/instructions#db4fff-runvm) instruction can emulate the execution of the `get_wallet_address` [get-method](/tvm/get-method) to derive the wallet address for any owner.
Use the following helper function. It relies on [Fift](/languages/fift/overview) because it's impossible to assign a type to `c7`. It executes the `get_wallet_address` method of a jetton minter on-chain, and calculates the corresponding wallet address for a given owner.
diff --git a/contribute/snippets/filetree.mdx b/contribute/snippets/filetree.mdx
index cc8780e95..15e94cbca 100644
--- a/contribute/snippets/filetree.mdx
+++ b/contribute/snippets/filetree.mdx
@@ -22,7 +22,7 @@ import { FileTree } from '/snippets/filetree.jsx';
## Usage
-Specify the structure of files and directories inside the [`items` property](#items) as a JavaScript list of strings, objects, and nested lists.
+Specify the structure of files and directories inside the [`items` property](#items-required) as a JavaScript list of strings, objects, and nested lists.
```mdx
import { FileTree } from '/snippets/filetree.jsx';
diff --git a/contribute/snippets/image.mdx b/contribute/snippets/image.mdx
index 6adb2ba53..9c453bf78 100644
--- a/contribute/snippets/image.mdx
+++ b/contribute/snippets/image.mdx
@@ -6,13 +6,13 @@ sidebarTitle: "Image"
import { Aside } from '/snippets/aside.jsx';
import { Image } from '/snippets/image.jsx';
-To display an image, use the `` component. It allows displaying either a single image for all themes ([`src`](#src)) or one image per light theme (`src`) and one image for the dark theme ([`darkSrc`](#darksrc)).
+To display an image, use the `` component. It allows displaying either a single image for all themes ([`src`](#src-required)) or one image per light theme (`src`) and one image for the dark theme ([`darkSrc`](#darksrc)).
-Additionally, you can specify the [`href`](#href) property, making an image double as a clickable link. When doing so, the [`target`](#href) property allows to change the browsing context of the link.
+Additionally, you can specify the [`href`](#href) property, making an image double as a clickable link. When doing so, the [`target`](#href) property allows changing the browsing context of the link.
----
-
### `subwallet_id` (32 bits)
**Purpose:**\
@@ -105,8 +99,6 @@ One private key manages multiple "virtual" wallets for organizational or account
**Recommendation:**\
Use `subwallet_id: 0x10ad` (4269) to avoid conflicts with other wallet types (standard wallets or vesting wallets) derived from the same keypair. See [How to create Highload Wallet v3](/standard/wallets/highload/v3/create) for details.
----
-
### `old_queries` (HashmapE 13 ^Cell)
**Purpose:**\
@@ -120,8 +112,6 @@ Provides a second layer of replay protection. During cleanup, `queries` → `old
**Details:** See [Replay protection mechanism](#replay-protection-mechanism).
----
-
### `queries` (HashmapE 13 ^Cell)
**Purpose:**\
@@ -135,8 +125,6 @@ When a message arrives, the contract checks if its `query_id` is already marked
**Details:** See [Replay protection mechanism](#replay-protection-mechanism).
----
-
### `last_clean_time` (64 bits)
**Purpose:**\
@@ -147,8 +135,6 @@ Tracks when the contract last rotated `queries` → `old_queries`. Cleanup trigg
**Details:** See [Replay protection mechanism](#replay-protection-mechanism).
----
-
### `timeout` (22 bits)
**Purpose:**\
@@ -166,8 +152,6 @@ Messages are valid if `created_at > now() - timeout` and `created_at <= now()`.
- [Replay protection mechanism](#replay-protection-mechanism) — how timeout is used
- [Timeout constraints](#timeout-constraints) — choosing the right value
----
-
## Replay protection mechanism
Highload v3 uses a dual-hashmap system (`queries` and `old_queries`) combined with timestamps to prevent replay attacks.
@@ -191,7 +175,7 @@ The contract stores processed `query_id` values in two hashmaps:
- Each value is a cell containing a bitmap of processed `bit_number` values
- Stores recently processed query IDs
-### How query\_id is checked
+### How `query_id` is checked
When an external message arrives, the contract:
@@ -286,8 +270,6 @@ Even if Transaction 2 fails in the action phase, Transaction 1 has already succe
This architecture solves a fundamental problem present in all standard external message wallets, including seqno-based wallets and earlier highload designs.
----
-
## External message structure
External messages sent to Highload v3 have a specific layout.
@@ -311,8 +293,6 @@ The signature is in the **root cell** (512 bits); all other parameters are in a
**Gas optimization:** This structure saves \~500 gas units during signature verification. If the signature were in the same cell as the message body, the contract would need to use `slice_hash()` (which rebuilds the cell internally, costing extra gas) instead of simply taking `cell_hash()` of the reference.
----
-
### `signature` (512 bits)
**Type:**\
@@ -333,8 +313,6 @@ Exit code `33`.
**Link:** [Ed25519 signature scheme](https://en.wikipedia.org/wiki/EdDSA#Ed25519)
----
-
### `subwallet_id` (32 bits)
**Purpose:**\
@@ -346,8 +324,6 @@ Must match the `subwallet_id` stored in contract storage.
**On mismatch:**\
Exit code `34`.
----
-
### `query_id` (composite structure)
The `query_id` follows the `QueryId` TL-B structure and is split into two parts:
@@ -370,8 +346,6 @@ The contract checks if bit `bit_number` is set in the cell stored at `hashmap[sh
**Recommendation:**\
Increment `query_id` sequentially using a counter-based strategy.
----
-
### `created_at` (64 bits)
**Purpose:**\
@@ -391,8 +365,6 @@ Exit code `35`.
**Why it matters:**\
Prevents replay of expired messages. Even if a `query_id` is eventually forgotten, stale messages are rejected based on `created_at`. See [Timestamp validation](#timestamp-validation) for important time lag considerations.
----
-
### `timeout` (22 bits)
**Purpose:**\
@@ -408,8 +380,6 @@ Exit code `38`.
22 bits allows timeout values up to \~4.8 million seconds (\~55 days).
----
-
### `send_mode` (8 bits)
**Purpose:**\
@@ -417,8 +387,6 @@ Specifies the [send mode](/foundations/messages/modes) for the internal message.
**Link:** [send\_raw\_message modes](/languages/func/stdlib#send_raw_message)
----
-
### `message_to_send` (reference cell)
**Structure:**\
@@ -450,8 +418,6 @@ The contract validates `message_to_send` **after committing storage** to prevent
**Critical limitation:**\
Highload v3 can send **only ONE internal message** per external message. For batch transfers, use the [internal\_transfer pattern](#single-message-per-external) with an action list (up to 254 messages).
----
-
## Message sending flow
Highload v3 uses a two-transaction pattern to safely send messages:
@@ -472,8 +438,6 @@ Highload v3 uses a two-transaction pattern to safely send messages:
See [Single message per external](#single-message-per-external) for details on this limitation and the batch transfer workaround.
----
-
## Exit codes
| Exit code | Name | Description | How to fix |
@@ -486,8 +450,6 @@ See [Single message per external](#single-message-per-external) for details on t
| `37` | Invalid message | The `message_to_send` structure is invalid or cannot be processed | Verify the message cell structure and contents |
| `38` | Invalid timeout | The `timeout` in the message does not match storage timeout | Verify you are using the correct `timeout` value for this wallet |
----
-
## Limitations and constraints
### Single message per external
@@ -502,15 +464,13 @@ Manually validating message structure is expensive in gas costs. The contract va
State-init validation is complex and gas-intensive, while deploying contracts from a highload wallet is rarely needed. The feature was intentionally excluded to reduce gas costs.
**Workaround for batch transfers:**\
-Send an internal message to the wallet itself with opcode `0xae42e5a4` (`internal_transfer`) and an action list containing up to **254 outgoing messages** (not 255, because one action slot is reserved for [`set_code` protection](#protection-against-set-code)).
+Send an internal message to the wallet itself with opcode `0xae42e5a4` (`internal_transfer`) and an action list containing up to **254 outgoing messages** (not 255, because one action slot is reserved for [`set_code` protection](#protection-against-set_code)).
**How to implement:** [Send batch transfers](/standard/wallets/highload/v3/send-batch-transfers)
----
-
### Query ID space limitations
-Highload v3 supports up to **8,380,416 unique query IDs** (see [`query_id` structure](#query-id-composite-structure) for details).
+Highload v3 supports up to **8,380,416 unique query IDs** (see [`query_id` structure](#query-id-structure) for details).
**Impact on throughput:**\
If you send messages faster than `timeout`, you may exhaust available query IDs. After `timeout`, old IDs can be reused.
@@ -518,8 +478,6 @@ If you send messages faster than `timeout`, you may exhaust available query IDs.
**Recommended strategy:**\
Use a counter-based approach, incrementing `query_id` for each message.
----
-
### Timeout constraints
The `timeout` value affects message validity, storage costs, and operational behavior:
@@ -535,8 +493,6 @@ Processed `query_id` values remain in storage for up to `2 × timeout` (across `
- Short timeout (seconds/minutes): Fast expiration certainty, but messages may expire during network congestion
- Long timeout (hours): Messages survive congestion, but slow failure detection and higher storage costs
----
-
### Gas consumption
Gas costs vary depending on the number of outgoing messages sent:
@@ -560,8 +516,6 @@ Forward fees scale with:
- Number of outgoing messages
- Size and complexity of message content
----
-
## Get methods
Highload Wallet v3 provides several read-only methods for monitoring and verification.
@@ -591,8 +545,6 @@ Before sending a message, check if a `query_id` was already used to avoid replay
**Link:** [How to verify if a message is processed](/standard/wallets/highload/v3/verify-is-processed)
----
-
## Protection against `set_code`
**Why this protection is needed:**
@@ -614,8 +566,6 @@ This pattern **prevents any `set_code` action in the action list from taking eff
**Action list limitation:**\
Because the contract calls `set_code(old_code)` as a protection mechanism, one action slot is consumed. This is why the maximum number of outgoing messages in a batch is **254** (not 255) — one slot is reserved for the `set_code` protection.
----
-
## Implementation
**Source code:** [`ton-blockchain/highload-wallet-contract-v3`](https://github.com/ton-blockchain/highload-wallet-contract-v3)
@@ -630,8 +580,6 @@ Because the contract calls `set_code(old_code)` as a protection mechanism, one a
**Link:** [How-to guides](/standard/wallets/highload/v3/create)
----
-
## See also
- [How to create Highload Wallet v3](/standard/wallets/highload/v3/create)
diff --git a/standard/wallets/highload/v3/verify-is-processed.mdx b/standard/wallets/highload/v3/verify-is-processed.mdx
index 29aa73032..2e0b7feac 100644
--- a/standard/wallets/highload/v3/verify-is-processed.mdx
+++ b/standard/wallets/highload/v3/verify-is-processed.mdx
@@ -291,7 +291,7 @@ if (messagesFailed > 0) {
>
**Partial failures:** Even if the action phase succeeds overall, some individual messages may fail. Check `skippedActions` to detect partial failures. If `skippedActions > 0`, some messages in the batch were not sent.
- The `totalActions - 1` calculation accounts for the [`set_code` protection](/standard/wallets/highload/v3/specification#protection-against-set-code) action.
+ The `totalActions - 1` calculation accounts for the [`set_code` protection](/standard/wallets/highload/v3/specification#protection-against-set_code) action.
## Expected outputs
diff --git a/standard/wallets/v5-api.mdx b/standard/wallets/v5-api.mdx
index 983aa96d0..3b3207445 100644
--- a/standard/wallets/v5-api.mdx
+++ b/standard/wallets/v5-api.mdx
@@ -189,7 +189,7 @@ graph LR
Signed message is a message that was signed using owners private key from his dedicated keypair, method from asymmetric cryptography. Later this message will be verified on-chain using public key stored in wallet smart contract - [read more](/standard/wallets/how-it-works#how-ownership-verification-works) about how ownership verification works.
-Before V5 standard, there was only one way to deliver signed message to wallet contract - via external-in message. However, external messages has certain limitations, e.g. you can only send external-out messages from the smart contracts themselves. This means that it wasn't possible to deliver signed message from inside the blockchain, from another smart contract. V5 standard adds this functionality, partially enabling [gasless transaction](/standard/wallets/v5#preparing-for-gasless-transactions).
+Before V5 standard, there was only one way to deliver signed message to wallet contract - via external-in message. However, external messages has certain limitations, e.g. you can only send external-out messages from the smart contracts themselves. This means that it wasn't possible to deliver signed message from inside the blockchain, from another smart contract. V5 standard adds this functionality, partially enabling [gasless transaction](/standard/wallets/gasless).
Besides `W5InnerRequest` field that contains actual actions that will be performed, `W5SignedRequest` structure contains usual wallet message fields that were in-place in previous versions, read more about them [here](/standard/wallets/how-it-works).
diff --git a/start-here.mdx b/start-here.mdx
index 08bb692ed..758f5438e 100644
--- a/start-here.mdx
+++ b/start-here.mdx
@@ -75,7 +75,7 @@ Over its lifetime, an account changes its [status](/foundations/status) among fo
- `nonexist`: There wasn't a single operation with the account, or it was removed. It has neither a balance, nor code.
- `uninit`: If some Toncoin is transferred to an account, it now exists, but there is still no smart contract code on it. It now has a balance.
- `active`: After a deploy message (see below) with code and initial data is sent to an account, it becomes active and can process other messages. It now has a balance, code, and internal state.
-- `frozen`: If an account is overdue on its [storage fees](/foundations/fees#storage-fee), it will be frozen until the fees are paid. If the overdue amount reaches a maximum limit specified by the blockchain, the account goes completely bankrupt, is removed, and ceases to exist.
+- `frozen`: If an account is overdue on its [storage fees](/foundations/fees#storage-fees), it will be frozen until the fees are paid. If the overdue amount reaches a maximum limit specified by the blockchain, the account goes completely bankrupt, is removed, and ceases to exist.
### Smart contracts
diff --git a/tolk/features/message-handling.mdx b/tolk/features/message-handling.mdx
index 1986b12cd..d7e840d71 100644
--- a/tolk/features/message-handling.mdx
+++ b/tolk/features/message-handling.mdx
@@ -8,7 +8,7 @@ A contract file typically begins with a [`contract` declaration](/languages/tolk
## `onInternalMessage`
-Contracts primarily handle [internal messages](/foundations/messages/internal#internal-messages). Users interact with contracts through their wallets, which send internal messages to the contract. The entrypoint is declared as follows:
+Contracts primarily handle [internal messages](/foundations/messages/internal). Users interact with contracts through their wallets, which send internal messages to the contract. The entrypoint is declared as follows:
```tolk
fun onInternalMessage(in: InMessage) {
diff --git a/tolk/features/message-sending.mdx b/tolk/features/message-sending.mdx
index 22df44577..41ada57c7 100644
--- a/tolk/features/message-sending.mdx
+++ b/tolk/features/message-sending.mdx
@@ -78,7 +78,7 @@ val walletInitialState: ContractState = {
};
```
-When sending a message to the wallet, it may not yet exist on-chain. In this case, the message must include the wallet's code and initial data. The message destination is therefore defined by the wallet's [`StateInit`](/foundations/messages/deploy#deploy-message).
+When sending a message to the wallet, it may not yet exist on-chain. In this case, the message must include the wallet's code and initial data. The message destination is therefore defined by the wallet's [`StateInit`](/foundations/messages/deploy).
```tolk
// address auto-calculated, code+data auto-attached
@@ -232,7 +232,7 @@ A struct is declared as `CreateMessageOptions`. By convention, fie
## Sending modes
-A message created with `createMessage()` is typically sent using [`msg.send(mode)`](/foundations/messages/modes#sending-modes).
+A message created with `createMessage()` is typically sent using [`msg.send(mode)`](/foundations/messages/modes).
## `ContractState` and `StateInit`
diff --git a/tolk/types/tuples.mdx b/tolk/types/tuples.mdx
index 915e2ee3b..ff9de51ab 100644
--- a/tolk/types/tuples.mdx
+++ b/tolk/types/tuples.mdx
@@ -328,4 +328,4 @@ fun demo(p: Point3d) {
Arrays can be [serialized to cells](/languages/tolk/types/overall-serialization) when `T` is serializable. The binary format uses snake references: a `uint8` length followed by chained cell references containing the elements.
-Raw tuples are not serializable to cells, because `unknown` is unserializable. But they can be returned from [get methods](/tvm/get-method#get-methods), since contract getters operate directly on the stack.
+Raw tuples are not serializable to cells, because `unknown` is unserializable. But they can be returned from [get methods](/tolk/features/contract-getters), since contract getters operate directly on the stack.
diff --git a/tvm/builders-and-slices.mdx b/tvm/builders-and-slices.mdx
index a14b87710..c2888a81c 100644
--- a/tvm/builders-and-slices.mdx
+++ b/tvm/builders-and-slices.mdx
@@ -28,7 +28,7 @@ Then, put a number on the stack:
1 INT // stack: x{} 1
```
-And call [`STU`](/tvm/instructions#cb-stu) ("STore Unsigned integer") to store integer into builder (swapping builder and value to meet `STU` input order):
+And call [`STU`](/tvm/instructions#cbcc-stu) ("STore Unsigned integer") to store integer into builder (swapping builder and value to meet `STU` input order):
```fift Fift
SWAP // stack: 1 x{}
@@ -60,7 +60,7 @@ Slice allows reading data back from a cell, field by field. For example, deseria
CTOS // x{0001001011111111}
```
-Then, call [`LDU`](/tvm/instructions#d3-ldu) ("LoaD Unsigned integer") to read first value (`uint4`).
+Then, call [`LDU`](/tvm/instructions#d3cc-ldu) ("LoaD Unsigned integer") to read first value (`uint4`).
```fift Fift
4 LDU // 1 x{001011111111}
diff --git a/tvm/exit-codes.mdx b/tvm/exit-codes.mdx
index b9a9a0960..e34e09f18 100644
--- a/tvm/exit-codes.mdx
+++ b/tvm/exit-codes.mdx
@@ -6,51 +6,51 @@ import { Aside } from '/snippets/aside.jsx';
An exit code is a 32-bit signed integer that indicates whether the compute or action phase of the transaction was successful. If not, it holds the code of the exception that occurred.
-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 the resulting state of the transaction.
+Each transaction on TON Blockchain consists of multiple phases. An _exit code_ is a 32-bit signed integer that indicates whether the [compute](#compute-phase) or [action](#action-phase) 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 the 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.
+Exit codes 0 and 1 indicate normal (successful) execution of the [compute phase](#compute-phase). Exit (or [result](#action-phase)) code 0 indicates normal (successful) execution of the [action phase](#action-phase). 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.
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-normal-termination) | [Compute][c] and [action][a] phases | Standard successful execution exit code. |
+| [1](#1-alternative-termination) | [Compute phase][c] | Alternative successful execution exit code. Reserved, but does not occur. |
+| [2](#2-stack-underflow) | [Compute phase][c] | Stack underflow. |
+| [3](#3-stack-overflow) | [Compute phase][c] | Stack overflow. |
+| [4](#4-integer-overflow) | [Compute phase][c] | Integer overflow. |
+| [5](#5-integer-out-of-expected-range) | [Compute phase][c] | Range check error — an integer is out of its expected range. |
+| [6](#6-invalid-opcode) | [Compute phase][c] | Invalid [TVM][tvm] opcode. |
+| [7](#7-type-check-error) | [Compute phase][c] | Type check error. |
+| [8](#8-cell-overflow) | [Compute phase][c] | Cell overflow. |
+| [9](#9-cell-underflow) | [Compute phase][c] | Cell underflow. |
+| [10](#10-dictionary-error) | [Compute phase][c] | Dictionary error. |
+| [11](#11-%22unknown%22-error) | [Compute phase][c] | Described in [TVM][tvm] docs as "Unknown error, may be thrown by user programs." |
+| [12](#12-fatal-error) | [Compute phase][c] | Fatal error. Thrown by [TVM][tvm] in situations deemed impossible. |
+| [13](#13-out-of-gas-error) | [Compute phase][c] | Out of gas error. |
+| [-14](#14-out-of-gas-error) | [Compute phase][c] | Same as 13. Negative, so that it [cannot be faked](#13-out-of-gas-error). |
+| [14](#14-virtualization-error) | [Compute phase][c] | VM virtualization error. Reserved, but never thrown. |
+| [32](#32-action-list-is-invalid) | [Action phase][a] | Action list is invalid. |
+| [33](#33-action-list-is-too-long) | [Action phase][a] | Action list is too long. |
+| [34](#34-invalid-or-unsupported-action) | [Action phase][a] | Action is invalid or not supported. |
+| [35](#35-invalid-source-address-in-outbound-message) | [Action phase][a] | Invalid source address in outbound message. |
+| [36](#36-invalid-destination-address-in-outbound-message) | [Action phase][a] | Invalid destination address in outbound message. |
+| [37](#37-not-enough-toncoin) | [Action phase][a] | Not enough Toncoin. |
+| [38](#38-not-enough-extra-currencies) | [Action phase][a] | Not enough extra currencies. |
+| [39](#39-outbound-message-does-not-fit-into-cell) | [Action phase][a] | Outbound message does not fit into a cell after rewriting. |
+| [40](#40-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-library-reference-is-null) | [Action phase][a] | Library reference is null during library change action. |
+| [42](#42-library-change-action-error) | [Action phase][a] | Library change action error. |
+| [43](#43-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-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:
@@ -59,7 +59,7 @@ The following table lists exit codes with their origin (where they can occur) an
*/}
[c]: /tvm/overview#compute-phase
@@ -67,17 +67,13 @@ The following table lists exit codes with their origin (where they can occur) an
## Exit codes in Blueprint projects
-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`.
+In [Blueprint][bp] tests, exit codes from the [compute phase](#compute-phase) are specified in the `exitCode` field of the object argument for the `toHaveTransaction()` method of the `expect()` matcher. The field for the [result](#action-phase) codes (exit codes from the [action phase](#action-phase)) 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)).
+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-phase) (or [action phase](#action-phase)).
Note that to do so, you'll have to perform a couple of type checks first:
@@ -105,17 +101,17 @@ it('tests something, you name it', async () => {
### 0: Normal termination
-This exit (or [result](#action)) code indicates the successful completion of the [compute phase](#compute) (or [action phase](#action)) of the transaction.
+This exit (or [result](#action-phase)) code indicates the successful completion of the [compute phase](#compute-phase) (or [action phase](#action-phase)) of the transaction.
## Compute phase
[TVM][tvm] initialization and all computations occur in the [compute phase][c].
-If the compute phase fails (the resulting exit code is neither [0](#0%3A-normal-termination) nor [1](#1%3A-alternative-termination)), the transaction skips the [action phase](#action) and proceeds to the bounce phase. In this phase, a bounce message is formed for transactions initiated by the inbound message.
+If the compute phase fails (the resulting exit code is neither [0](#0-normal-termination) nor [1](#1-alternative-termination)), the transaction skips the [action phase](#action-phase) and proceeds to the bounce phase. In this phase, a bounce message is formed for transactions initiated by the inbound message.
### 1: Alternative termination
-This is an alternative exit code for the successful execution of the [compute phase](#compute). It is reserved but never occurs.
+This is an alternative exit code for the successful execution of the [compute phase](#compute-phase). It is reserved but never occurs.
### 2: Stack underflow
@@ -301,7 +297,7 @@ fun onInternalMessage() {
### 7: Type check error
-If an argument to a primitive is of an incorrect value type or there is any other mismatch in types during the [compute phase](#compute), an error with exit code 7 is thrown: `Type check error`.
+If an argument to a primitive is of an incorrect value type or there is any other mismatch in types during the [compute phase](#compute-phase), an error with exit code 7 is thrown: `Type check error`.
```tolk title="Tolk"
fun touch(y: T): void asm "NOP" // so that the compiler doesn't remove instructions
@@ -448,7 +444,7 @@ Fatal error. Thrown by TVM in situations deemed impossible.
### 13: Out of gas error
-If there isn't enough gas to complete computations in the [compute phase](#compute), an error with exit code 13 is thrown: `Out of gas error`.
+If there isn't enough gas to complete computations in the [compute phase](#compute-phase), an error with exit code 13 is thrown: `Out of gas error`.
However, this code isn't immediately shown as is — instead, the bitwise NOT operation is applied, changing the value from 13 to -14. Only then is the code displayed.
@@ -464,7 +460,7 @@ fun onInternalMessage() {
### -14: Out of gas error
-See [exit code 13](#13%3A-out-of-gas-error).
+See [exit code 13](#13-out-of-gas-error).
### 14: Virtualization error
@@ -472,21 +468,21 @@ Virtualization error related to pruned branch cells. Reserved but never thrown.
## Action phase
-The [action phase][a] is processed after the successful execution of the [compute phase](#compute). It attempts to perform the actions stored in the action list by [TVM][tvm] during the compute phase.
+The [action phase][a] is processed after the successful execution of the [compute phase](#compute-phase). It attempts to perform the actions stored in the action list by [TVM][tvm] during the compute phase.
-Some actions may fail during processing, in which case those actions may be skipped or the whole transaction may revert, depending on the mode of actions. The code indicating the resulting state of the [action phase][a] is called a _result code_. Since it is also a 32-bit signed integer that essentially serves the same purpose as the _exit code_ of the [compute phase](#compute), it is common to call the result code an exit code as well.
+Some actions may fail during processing, in which case those actions may be skipped or the whole transaction may revert, depending on the mode of actions. The code indicating the resulting state of the [action phase][a] is called a _result code_. Since it is also a 32-bit signed integer that essentially serves the same purpose as the _exit code_ of the [compute phase](#compute-phase), it is common to call the result code an exit code as well.
### 32: Action list is invalid
If the list of actions contains exotic cells, an action entry cell does not have references, or some action entry cell cannot be parsed, an error with exit code 32 is thrown: `Action list is invalid`.
### 33: Action list is too long
-If there are more than 255 actions queued for execution, the [action phase](#action) will throw an error with an exit code 33: `Action list is too long`.
+If there are more than 255 actions queued for execution, the [action phase](#action-phase) will throw an error with an exit code 33: `Action list is too long`.
```tolk title="Tolk"
import "@stdlib/gas-payments";
@@ -568,7 +564,7 @@ If the maximum number of cells in the library is exceeded or the maximum depth o
### 50: Account state size exceeded limits
-If the account state (contract storage, essentially) exceeds any of the limits specified in [config param 43 of TON Blockchain](/foundations/config#param-43-account-and-message-limits) by the end of the [action phase](#action), an error with exit code 50 is thrown: `Account state size exceeded limits`.
+If the account state (contract storage, essentially) exceeds any of the limits specified in [config param 43 of TON Blockchain](/foundations/config#param-43-account-and-message-limits) by the end of the [action phase](#action-phase), an error with exit code 50 is thrown: `Account state size exceeded limits`.
If the configuration is absent, the default values are:
@@ -583,12 +579,14 @@ If the configuration is absent, the default values are:
- `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 Tolk introduces any custom exit codes.
+## Tolk compiler
- ## Tolk compiler
+Tolk utilizes exit codes below 128. 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-phase), 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.
- */}
+- **0:** When the `onBouncedMessage()` handler is not defined, all bounced messages are rejected with an [exit code 0](#0-normal-termination), which is considered a normal termination.
+- **5:** If there is an exhaustive enum `match` fallthrough or an enum deserialization range or membership check, an [exit code 5: integer out of expected range](#5-integer-out-of-expected-range) is thrown.
+- **9:** If there is a slice or array deserialization invalidation, an [exit code 9: cell underflow](#9-cell-underflow) is thrown.
+- **63:** If there is an opcode (or prefix) mismatch when unpacking a struct, a Tolk-specific exit code 63 is thrown. Additionally, it is the default exit code for `throwIfOpcodeDoesNotMatch()` function, which can be overridden.
[tlb]: /languages/tl-b/overview
[tvm]: /tvm/overview
diff --git a/tvm/gas.mdx b/tvm/gas.mdx
index c3a591598..179bf7289 100644
--- a/tvm/gas.mdx
+++ b/tvm/gas.mdx
@@ -10,12 +10,12 @@ Each instruction consumes a fixed amount of `10` gas and `1` gas for each bit of
Examples:
-| Instruction | TL-B | Gas | Notes |
-| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
-| [`NEWC`](/tvm/instructions#c8-newc) | `#C8` | `18` | 8-bit prefix without operands |
-| [`STU`](/tvm/instructions#cb-stu) | `#CB` `cc:uint8` | `26` | 8-bit prefix, 8-bit operand |
-| [`PUSHINT_LONG`](/tvm/instructions#82-pushint_long) | `#82` `l:(## 5)` `xxx:(int (8 * l + 19))` | `23` | 8-bit prefix, 5-bit operand, length of `xxx` depends on `l`, so it is not included |
-| [`STSLICE_CONST`](/tvm/instructions#cfc0_-stsliceconst) | `#CFC0_` `x:(## 2)` `y:(## 3)` `c:(x * ^Cell)` `sss:((8 * y + 2) * Bit)` | `24` | 9-bit prefix (`CF` is 8 bits, `C0_` is `C_`, which is just bit `1`), 2-bit and 3-bit operands, refs `c` and variable-length `sss` are not included |
+| Instruction | TL-B | Gas | Notes |
+| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [`NEWC`](/tvm/instructions#c8-newc) | `#C8` | `18` | 8-bit prefix without operands |
+| [`STU`](/tvm/instructions#cbcc-stu) | `#CB` `cc:uint8` | `26` | 8-bit prefix, 8-bit operand |
+| [`PUSHINT_LONG`](/tvm/instructions#82lxxx-pushint_long) | `#82` `l:(## 5)` `xxx:(int (8 * l + 19))` | `23` | 8-bit prefix, 5-bit operand, length of `xxx` depends on `l`, so it is not included |
+| [`STSLICE_CONST`](/tvm/instructions#cfc_xysss-stsliceconst) | `#CFC0_` `x:(## 2)` `y:(## 3)` `c:(x * ^Cell)` `sss:((8 * y + 2) * Bit)` | `24` | 9-bit prefix (`CF` is 8 bits, `C0_` is `C_`, which is just bit `1`), 2-bit and 3-bit operands, refs `c` and variable-length `sss` are not included |
## Cell operations
@@ -28,7 +28,7 @@ This applies to all instructions that internally operate with cells (including d
## Exceptions
-TVM consumes `50` gas when any exception is thrown, both explicitly by [`THROW`](/tvm/instructions#f2c4_-throw)-like instructions or implicitly during execution of other instructions. This happens before the jump to the exception handler `c2`.
+TVM consumes `50` gas when any exception is thrown, both explicitly by [`THROW`](/tvm/instructions#f2c4_n-throw)-like instructions or implicitly during execution of other instructions. This happens before the jump to the exception handler `c2`.
## Implicit jumps and returns
@@ -40,11 +40,11 @@ Calling more than `8` extraordinary continuations in a chain consumes `1` gas fo
## Tuple operations
-[`TUPLE`](/tvm/instructions#6f0-tuple), [`TUPLEVAR`](/tvm/instructions#6f80-tuplevar), [`UNTUPLE`](/tvm/instructions#6f2-untuple), [`UNTUPLEVAR`](/tvm/instructions#6f82-untuplevar), [`UNPACKFIRST`](/tvm/instructions#6f3-unpackfirst), [`UNPACKFIRSTVAR`](/tvm/instructions#6f83-unpackfirstvar), [`EXPLODE`](/tvm/instructions#6f4-explode), [`EXPLODEVAR`](/tvm/instructions#6f84-explodevar) consumes `1` gas for each entry been pushed or popped into a tuple. [`TPUSH`](/tvm/instructions#6f8c-tpush), [`TPOP`](/tvm/instructions#6f8d-tpop), [`SETINDEX`](/tvm/instructions#6f5-setindex), [`SETINDEXVAR`](/tvm/instructions#6f85-setindexvar), [`SETINDEXQ`](/tvm/instructions#6f7-setindexq)/[`SETINDEXVARQ`](/tvm/instructions#6f87-setindexvarq) consumes `len(tuple)` gas for the resulting tuple size after push/pop/set. Same applies to instructions operating with `c7`: [`SETGLOB`](/tvm/instructions#f87_-setglob)/[`SETGLOBVAR`](/tvm/instructions#f860-setglobvar), [`RANDU256`](/tvm/instructions#f810-randu256)/[`RAND`](/tvm/instructions#f811-rand), [`SETRAND`](/tvm/instructions#f814-setrand), [`ADDRAND`](/tvm/instructions#f815-addrand).
+[`TUPLE`](/tvm/instructions#6f0n-tuple), [`TUPLEVAR`](/tvm/instructions#6f80-tuplevar), [`UNTUPLE`](/tvm/instructions#6f2n-untuple), [`UNTUPLEVAR`](/tvm/instructions#6f82-untuplevar), [`UNPACKFIRST`](/tvm/instructions#6f3k-unpackfirst), [`UNPACKFIRSTVAR`](/tvm/instructions#6f83-unpackfirstvar), [`EXPLODE`](/tvm/instructions#6f4n-explode), [`EXPLODEVAR`](/tvm/instructions#6f84-explodevar) consumes `1` gas for each entry been pushed or popped into a tuple. [`TPUSH`](/tvm/instructions#6f8c-tpush), [`TPOP`](/tvm/instructions#6f8d-tpop), [`SETINDEX`](/tvm/instructions#6f5k-setindex), [`SETINDEXVAR`](/tvm/instructions#6f85-setindexvar), [`SETINDEXQ`](/tvm/instructions#6f7k-setindexq)/[`SETINDEXVARQ`](/tvm/instructions#6f87-setindexvarq) consumes `len(tuple)` gas for the resulting tuple size after push/pop/set. Same applies to instructions operating with `c7`: [`SETGLOB`](/tvm/instructions#f87_k-setglob)/[`SETGLOBVAR`](/tvm/instructions#f860-setglobvar), [`RANDU256`](/tvm/instructions#f810-randu256)/[`RAND`](/tvm/instructions#f811-rand), [`SETRAND`](/tvm/instructions#f814-setrand), [`ADDRAND`](/tvm/instructions#f815-addrand).
## Stack operations
-TVM consumes 1 gas for each stack element deeper than 32 elements inside the resulting new stack each time stack gets copied: when calling or jumping to a continuation with a non-empty argument number, an initial stack, or both, when extending a continuation stack using [`SETCONTARGS`](/tvm/instructions#ec-setcontargs_n) and similar instructions, when using [`RUNVM`](/tvm/instructions#db4-runvm) (both for initial and resulting stacks of the vm).
+TVM consumes 1 gas for each stack element deeper than 32 elements inside the resulting new stack each time stack gets copied: when calling or jumping to a continuation with a non-empty argument number, an initial stack, or both, when extending a continuation stack using [`SETCONTARGS`](/tvm/instructions#ecrn-setcontargs_n) and similar instructions, when using [`RUNVM`](/tvm/instructions#db4fff-runvm) (both for initial and resulting stacks of the vm).
## Extra currency
@@ -52,7 +52,7 @@ The first `5` executions of `GETEXTRABALANCE` consume at most `26 + 200` gas eac
## RUNVM
-[`RUNVM`](/tvm/instructions#db4-runvm) and [`RUNVMX`](/tvm/instructions#db50-runvmx) consume `40` extra gas before starting a VM.
+[`RUNVM`](/tvm/instructions#db4fff-runvm) and [`RUNVMX`](/tvm/instructions#db50-runvmx) consume `40` extra gas before starting a VM.
## Cryptography
diff --git a/tvm/overview.mdx b/tvm/overview.mdx
index e2f668e50..975926969 100644
--- a/tvm/overview.mdx
+++ b/tvm/overview.mdx
@@ -32,7 +32,7 @@ The total state of TVM consists of the following components:
- [**Control registers**](/tvm/registers). A small fixed set of special registers, denoted as `c0`, `c1`, ..., `c5`, and `c7` (`c6` does not exist).
- [**Gas counter**](/tvm/gas). Tracks remaining computation budget. Each instruction decrements gas. When counter hits zero/negative value, an exception is raised, and the run aborts.
- **Current continuation (`cc`)**. A special register that stores a list of the next instructions to execute. Similar to the instruction pointer in traditional architectures.
-- **Current codepage (`cp`)**. Determines how to decode the next instruction in `cc`. Different codepages may implement different instruction sets, allowing for adding new features to TVM without affecting old smart contracts. Currently, only codepage `0` (`cp0`) is implemented. Smart contract runs [`SETCP0`](/tvm/instructions#ff-setcp) instruction to explicitly use codepage `0`.
+- **Current codepage (`cp`)**. Determines how to decode the next instruction in `cc`. Different codepages may implement different instruction sets, allowing for adding new features to TVM without affecting old smart contracts. Currently, only codepage `0` (`cp0`) is implemented. Smart contract runs [`SETCP0`](/tvm/instructions#ffnn-setcp) instruction to explicitly use codepage `0`.
## TVM data types
diff --git a/tvm/registers.mdx b/tvm/registers.mdx
index fa94b21f3..edeee52f4 100644
--- a/tvm/registers.mdx
+++ b/tvm/registers.mdx
@@ -29,7 +29,7 @@ Same as `c0`, but invoked only in special control flow instructions, such as [`R
**Initial value**: `ExcQuit` — extraordinary continuation which terminates TVM with an exception. In this case, the exit code is an exception number.
-Invoked implicitly on any exception that occurs during TVM execution. Can be invoked explicitly by [`THROW`](/tvm/instructions#f2c4_-throw)-like instructions. To set a custom exception handler, use [TRY](/tvm/instructions#f2ff-try).
+Invoked implicitly on any exception that occurs during TVM execution. Can be invoked explicitly by [`THROW`](/tvm/instructions#f2c4_n-throw)-like instructions. To set a custom exception handler, use [TRY](/tvm/instructions#f2ff-try).
## `c3` — function selector
@@ -37,7 +37,7 @@ Invoked implicitly on any exception that occurs during TVM execution. Can be inv
**Initial value**: Root cell of code currently executing in TVM.
-Invoked by [`CALLDICT`](/tvm/instructions#f0-calldict) instruction with a function ID (integer) passed on the stack. The function selector should jump to a function with that ID.
+Invoked by [`CALLDICT`](/tvm/instructions#f0nn-calldict) instruction with a function ID (integer) passed on the stack. The function selector should jump to a function with that ID.
Fift-ASM assembler constructs following function selector ([`Asm.fif`:1624](https://github.com/ton-blockchain/ton/blob/4ebd7412c52248360464c2df5f434c8aaa3edfe1/crypto/fift/lib/Asm.fif#L1624)):
@@ -89,7 +89,7 @@ The previous action is always the first reference of the next one. If action its
**Initial value**: `Tuple[Tuple[0x076ef1ea, 0, 0, ...]]`.
-The zero element of the `c7` tuple is an environment information (which itself is also a tuple). The remaining 255 slots are used for global variables. [`[i] SETGLOB`](/tvm/instructions#f87_-setglob) modifies `c7`, inserting an element with index `i`, [`[i] GETGLOB`](/tvm/instructions#f85_-getglob) reads `i`-th element from `c7`.
+The zero element of the `c7` tuple is an environment information (which itself is also a tuple). The remaining 255 slots are used for global variables. [`[i] SETGLOB`](/tvm/instructions#f87_k-setglob) modifies `c7`, inserting an element with index `i`, [`[i] GETGLOB`](/tvm/instructions#f85_k-getglob) reads `i`-th element from `c7`.
### Structure of environment information tuple