π«§ Tolk v1.2: rich bounced messages, cheap deployment, and a breaking change that you'll love
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
https://github.com/ton-blockchain/ton/pull/1886 with detailed info.
β `address` is now "internal only"
Before:
* address meant internal/external/none
Now:
* address β internal only
* address? (nullable) β internal/none, exactly like "maybe address" in @ton/core
* any_address β internal/external/none
In 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, https://github.com/ton-blockchain/ton/pull/1886.
β 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 calculations
Just 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 https://github.com/ton-blockchain/ton/pull/1886.
π³ 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.