🏆 This is the biggest update of Tact since its creation, bigger than all previous milestones combined. There were so many improvements that we've even won over FunC in terms of gas usage on many standard contracts, such as Jettons.
🤔 Don't believe me?
🥳 Let's unpack Tact v1.6.0 together and see these improvements for ourselves!
We'll start with the number one achievement of this release:
⛽️ Gas optimization victory over FunC
Gas has long been a major pain point for Tact. Prior to v1.6.0, Tact's gas usage on many common contracts, such as Jettons, was far from ideal, requiring about 2.5 times gas of the FunC reference implementation.
But with Tact 1.6.0, those old gas-expensive days are long gone.
🤯 For example, a Tact rewrite of the reference FunC Jetton code consumes less gas for transfer, burn and discovery messages!
😎 So, expect to receive easy-to-use idiomatic Tact implementations of common contracts in the near future
Some of the things we did to achieve this:
▪️ Removed "system" cell — for most cases, parent contract code is no longer stored in the system cell with all the child contract codes
▪️ Removed redundant address checks
▪️ Deprecated
Deployable trait in favor of receive(){}▪️ Introduced contract parameters as an alternative to
init() functionAnd optimized compiler internals, many old and new functions in the stdlib:
🧰 Some of the standard library additions and changes
• Added specialized
deploy and message functions for efficient on-chain deployments and non-deployment messages respectively• Many math functions, such as
divc, mulShiftRightCeil, and others• More advanced functions, such as
setGasLimit, setSeed, myCode, and others• Handy
throwIf and throwUnless functions, which deprecated their "native" prefixed counterparts• Optimized
emptyCell and emptySlice functions•
Int.toString function now consumes up to 64% less gas•
Int.toFloatString function now consumes up to 62% less gasAdded many functions for
Cell, Slice and Builder types:• Variable integer serialization types and the corresponding
.load and .store functions of Slice and Builder types• Functions
Slice.hashData and String.hashData for efficient hashes of data only• Functions for working with addresses:
Slice.asAddress, Slice.asAddressUnsafe, contractHash, and a new BasechainAddress type with its helper functions• ...and more!
🧳 More auxiliary things
• Basic
let-destructuring of structs and Messages• Compile-time method ID expressions for getters and Message opcodes
• The
codeOf expression to get the code of child contracts• More map improvements and new methods, like
replace and replaceGet• New augmented assignment operators
&&=, ||=, >>= and <<=• Better error reporting for many cases
• Generation of constants in TypeScript wrappers
• The
-w, --watch CLI flags for watching for changes and automatic recompilations• CLI for the Tact's TVM disassembler —
unboc• Fixes of the compilation report
• Fixes of the compiler's third-party API
• Fixes of the internal infrastructure and code generation
• Lots of other smaller bug fixes and enhancements
• ...and documentation for all of that and beyond!
Besides, check out the updated Awesome Tact list and add your awesome projects, especially those using Tact in production!
⚠️ Breaking changes
There are only two, and they're both pretty minor:
• Tact 1.6.0 replaces
Context.bounced field with Context.bounceable — whether the received message can bounce back or not. Previously, bounced field was useless since any bounced messages would be handled in a separate bounced() receiver.• The
enabledMasterchain option was removed from tact.config.json. Going forward, support of masterchain addresses is always enabled in Tact contracts.♥️ Special thanks goes to all the contributors and community members — without you there would be nothing. Let's keep building the future of smart contracts with ⚡️ Tact!
📜 See full release notes for Tact v1.6.0
📥 And upgrade Tact in your projects
🍲 we're beating the gas allegations with this one 🗣🗣🗣
♨️ @tact_kitchen

