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: docs/src/content/docs/book/bounced.mdx
+33-2Lines changed: 33 additions & 2 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,7 +96,7 @@ 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 handles all bounced messages that are not handled by [specific bounced message receivers](#bounced-message-receiver).
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 all bounced messages that are not handled by [specific bounced message receivers](#bounced-message-receiver).
70
100
71
101
```tact /rawMsg: Slice/
72
102
contract MyContract() {
@@ -89,3 +119,4 @@ On TON, bounced message bodies have a 32 bits prefix, where all bits are set, i.
89
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).
0 commit comments