Tolk v1.2 is here, aligned with TVM 12 — bringing new assembler instructions that make contracts cheaper and cleaner.
This update introduces one breaking change, several powerful new capabilities, and a few quality-of-life improvements across the compiler.
✅ Notable changes in Tolk v1.2:
1. Breaking change:
address is now "internal only"2. Rich bounces: not 256 bits, but the full body on bounce
3. Cheap builder-to-slice, StateInit, and address composition
4. Improved compilation errors
5. Anonymous functions (lambdas)
6. Borrow checker to catch undefined behavior
PR on GitHub with detailed info.
✔ `address` is now "internal only"
Before:
*
address meant internal/external/noneNow:
*
address — internal only*
address? (nullable) — internal/none, exactly like "maybe address" in @ton/core*
any_address — internal/external/noneIn 99% of contracts only internal addresses are used. External ones are rare, and "none" can be expressed as nullable.
struct Storage {
// internal, checked automatically
owner: address
}
With new TVM 12 instructions, addresses are validated automatically during (de)serialization without extra gas — no more manual
isInternal() checks.So yes, it's technically a breaking change, but it removes a ton of noise.
A short migration guide, as well as technical details, available here.
✔ Rich bounced messages
Historically, a bounced message only returned the first 256 bits of the original body.
Now TVM 12 supports rich bounces — which lets you obtain the entire body instead.
createMessage({
bounce: BounceMode.RichBounce,
...
})
In
onBouncedMessage, you get access to the original body, exit code, gas used, and more.Old true/false bounce flags still work for backward compatibility.
Rich bounces simplify complex message flows and inter-contract communication — one of the most painful aspects of TON until now.
✔ Cheap builder-to-slice and address composition
Previously, converting a builder to a slice (endCell + beginParse) consumed a lot of gas because cells are expensive. Now there's a new instruction —
BTOS (builder-to-slice) — without intermediate cell creation.-
b.endCell().beginParse() is now cheap: auto-optimized to BTOS- "builder-to-address" is the same
BTOS; hacks around "return a builder with a valid address" can be removed- cheaper
StateInit hashing and address calculationsJust update to Tolk v1.2 + TVM 12, and you'll immediately save gas.
✔ Anonymous functions (lambdas)
Can be used in general-purpose frameworks, perfectly integrated with the type system:
fun customRead(reader: (slice) -> int) { ... }
customRead(fun(s) {
return s.loadUint(32)
})
✔ Low-level compiler enhancements
Also included: better diagnostics with precise ranges, new peephole optimizations, tuple ↔ object conversions, and multiple small fixes. A lightweight borrow checker prevents undefined behavior on concurrent mutations.
As always, all additions are carefully described in a PR.
🌳 We've also started improving TVM itself — new assembler instructions are designed specifically to fit the Tolk type system and optimizer. I have always said: the language is just the beginning. Perfect developer experience requires improving every layer of TON's stack. The road may be sharp and curvy — but we're definitely heading in the right direction.