You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: dev-docs/CHANGELOG-DOCS.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,11 @@ All notable changes to Tact documentation will be documented in this file.
4
4
5
5
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) but does not adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) — the changes made are grouped by their respective milestones. If the change wasn't a part of the milestone but was made in the month associated with it, it will still be included.
6
6
7
+
## Doc: Next
8
+
9
+
- Fixed the description of the fallback bounced message receiver: PR [#3471](https://github.com/tact-lang/tact/pull/3471)
10
+
- Clarified the data layout of bounced messages: PR [#3472](https://github.com/tact-lang/tact/pull/3472)
11
+
7
12
## Doc: 2025-06
8
13
9
14
- Adjusted inline code tag highlighting to support global Starlight themes, and modified the One Light color theme to support proper highlighting of `keyword.operator.new` TextMate scopes: PR [#3346](https://github.com/tact-lang/tact/pull/3346)
Copy file name to clipboardExpand all lines: docs/src/content/docs/book/bounced.mdx
+41-4Lines changed: 41 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,7 +25,11 @@ contract Bounce() {
25
25
message BB {}
26
26
```
27
27
28
-
Only the first message fields that fit into the 224 bits will be available to use in bounced message receivers. Sometimes you need to rearrange the order of the fields in your message so the relevant ones would fit into the limit.
28
+
Since message fields are always laid out sequentially and no automatic rearrangements are made, the partial representation made by the `bounced<M>{:tact}` constructor would only contain the first fields that fit entirely within the 224-bit limit.
29
+
30
+
All subsequent fields that exceed the limit will not be available in bounced message receivers. This also includes fields that fit only partially.
31
+
32
+
If the first field does not wholly conform to the 224-bit limit, none of the bounced message fields would be available. Therefore, to ensure access, prefer arranging the important fields first.
29
33
30
34
```tact
31
35
contract Bounce() {
@@ -42,6 +46,32 @@ message TwoFields {
42
46
}
43
47
```
44
48
49
+
:::caution
50
+
51
+
To prevent potential issues, Tact only allows using the fields that wholly fit the limit. However, the blockchain views that limit as a truncation boundary and keeps the raw bits that fit the [total 256-bit body limit](#caveats) in the original bounced message body cell.
52
+
53
+
You can access that data by removing the concrete receiver and using the [fallback bounced message receiver](#fallback) instead. It will provide you the original, raw body of the received message as a [`Slice{:tact}`][slice].
54
+
55
+
```tact
56
+
contract Bounce() {
57
+
bounced(rawMsg: Slice) {
58
+
let opcode = rawMsg.loadUint(32);
59
+
if (opcode == TooBigToFit.opcode()) {
60
+
// Now, you can obtain the truncated bits that did fit in the remaining
61
+
// 224 bits of the bounced message.
62
+
// Proceed with caution!
63
+
let truncatedData = rawMsg.preloadUint(224);
64
+
}
65
+
}
66
+
}
67
+
68
+
message TooBigToFit {
69
+
data: Int as uint225; // 1 bit is truncated, so the field could not be accessed directly
70
+
}
71
+
```
72
+
73
+
:::
74
+
45
75
For gas optimization reasons, unrecognized bounced messages are ignored by Tact contracts and do not cause erroneous, non-zero [exit codes](/book/exit-codes). That is, if there is no relevant [`bounced(){:tact}` message receiver](#bounced-message-receiver) or no [fallback bounced receiver](#fallback), messages sent from the contract, rejected by their intended recipient and bounced back to the original contract will not be processed, apart from collecting their value and paying any related fees.
46
76
47
77
This behavior is unlike the non-bounced messages such as regular internal or external messages, where if the contract does not handle the message, an error with [exit code 130](/book/exit-codes#130) is thrown: `Invalid incoming message`. Not throwing such errors for bounced messages is a common pattern on TON Blockchain, to which Tact adheres.
@@ -66,13 +96,19 @@ contract MyContract {
66
96
67
97
## Fallback bounced message receiver {#fallback}
68
98
69
-
To process bounced messages manually, you can use a fallback catch-all definition that handles a raw [`Slice{:tact}`](/book/cells#slices) directly. Note that such a receiver will get **all** the bounced messages produced by your contract:
99
+
To process bounced messages manually, you can use a fallback catch-all definition that handles a raw [`Slice{:tact}`][slice] directly. Note that such a receiver handles allbounced messages that are not handled by [specific bounced message receivers](#bounced-message-receiver).
70
100
71
101
```tact /rawMsg: Slice/
72
-
contract MyContract {
73
-
bounced(rawMsg: Slice) {
102
+
contract MyContract() {
103
+
// Specific bounced message receiver
104
+
bounced(msg: bounced<MyMessage>) {
74
105
// ...
75
106
}
107
+
108
+
// Fallback catch-all bounced message receiver
109
+
bounced(rawMsg: Slice) {
110
+
// Here, rawMsg can be anything, except for the bounced<MyMessage>
111
+
}
76
112
}
77
113
```
78
114
@@ -83,3 +119,4 @@ On TON, bounced message bodies have a 32 bits prefix, where all bits are set, i.
83
119
Bounced message receivers handle contract storage just as [internal message receivers](/book/receive#contract-storage-handling) do. In addition, the empty [`return{:tact}` statement](/book/statements#return) and the [`throw(0){:tact}`](/ref/core-debug#throw) patterns [work the same](/book/receive#contract-storage-handling).
Copy file name to clipboardExpand all lines: docs/src/content/docs/book/compile.mdx
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -82,7 +82,9 @@ If you want to pin down a specific version of the compiler, run the following co
82
82
83
83
:::caution
84
84
85
-
Do not mix different Node.js package managers in your projects. If you created the [Blueprint][bp] project with `npm`, stick to using `npm` for the rest of the commands — this will ensure that you don't get "File not found" errors or lock-file conflicts between different package managers.
85
+
Do not mix different Node.js package managers in your projects. Always stick to one — using multiple will break things.
86
+
87
+
If you created the [Blueprint][bp] project with `npm`, stick to using `npm` for the rest of the commands — this will ensure that you don't get "File not found" errors or lock-file conflicts between different package managers.
86
88
87
89
For example, using the `npm` package manager to install dependencies and then switching to `yarn` to build the contracts can lead to the following error message:
Here, `6dfea180` and `12345678`, specified after the `#` in the [constructor definitions](https://docs.ton.org/v3/documentation/data-formats/tlb/tl-b-language#constructors), are opcodes written in hexadecimal notation representing 32-bit unsigned integers. Thus, the automatically generated `6dfea180` opcode of the `GeneratedOpcode{:tact}`[Message][message] represents the decimal value 1845404032, and the manually provided `12345678` opcode of the `ManuallySpecifiedOpcode{:tact}`[Message][message] represents the decimal value 305419896, and**not** 12345678 as it might appear.
164
+
Here, `6dfea180` and `12345678`, specified after the `#` in the [constructor definitions](https://docs.ton.org/v3/documentation/data-formats/tlb/tl-b-language#constructors), are opcodes written in hexadecimal notation representing 32-bit unsigned integers. Thus, the automatically generated `6dfea180` opcode of the `GeneratedOpcode{:tact}`[Message][message] represents the decimal value 1845404032, and the manually provided `12345678` opcode of the `ManuallySpecifiedOpcode{:tact}`[Message][message] represents the decimal value 305419896 —**not** 12345678, even though it looks like a decimal.
Copy file name to clipboardExpand all lines: docs/src/content/docs/book/index.mdx
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,7 +17,7 @@ Here are its main contents:
17
17
18
18
1.#### Quick start
19
19
20
-
The Book begins with a few scenic tours and cheat sheets to get you started immediately. First, it briefly discusses TON Blockchain and how smart contracts work there, then gives an overview of many syntax and semantical aspects of the Tact language.
20
+
The Book begins with a few scenic tours and cheat sheets to get you started immediately. First, it briefly introduces the TON Blockchain and how Tact smart contracts work there, then it gives an overview of many syntax and semantical aspects of the Tact language.
21
21
22
22
<CardGrid>
23
23
<LinkCard
@@ -67,7 +67,7 @@ Here are its main contents:
67
67
68
68
The subsection [Going places](/book/compile) explains how to compile, debug, and test Tact contracts locally. From there, it moves on to provide descriptions of deploying contracts to the TON Blockchain.
69
69
70
-
Lastly, it shows how to further tweak the compiler with its configuration options, interface with existing FunC code, and discusses best practices for securing your smart contracts.
70
+
Lastly, it shows how to further tweak the compiler with its configuration options, interface with existing FunC code, and apply best practices to secure your smart contracts.
0 commit comments