From 4814902ce759fd9d8b9761d7f288660c00c8be38 Mon Sep 17 00:00:00 2001 From: tolk-vm Date: Fri, 19 Jun 2026 13:40:56 +0300 Subject: [PATCH 1/3] Changes for Tolk v1.4.2: rename TON to GRAM --- .../techniques/contract-sharding.mdx | 2 +- content/contract-dev/techniques/gas.mdx | 8 +-- .../techniques/using-on-chain-libraries.mdx | 2 +- content/standard/tokens/nft/deploy.mdx | 6 +- content/tolk/basic-syntax.mdx | 4 +- content/tolk/examples.mdx | 58 +++++++++---------- content/tolk/features/message-sending.mdx | 12 ++-- content/tolk/features/standard-library.mdx | 24 ++++---- content/tolk/from-func/stdlib-comparison.mdx | 2 +- content/tolk/from-func/tolk-vs-func.mdx | 14 ++--- content/tolk/idioms-conventions.mdx | 2 +- content/tolk/syntax/structures-fields.mdx | 2 +- content/tolk/syntax/variables.mdx | 2 +- content/tolk/types/numbers.mdx | 34 ++++++----- content/tolk/types/tensors.mdx | 1 + content/tvm/exit-codes.mdx | 8 +-- 16 files changed, 94 insertions(+), 87 deletions(-) diff --git a/content/contract-dev/techniques/contract-sharding.mdx b/content/contract-dev/techniques/contract-sharding.mdx index ecde84c9b..822fd58e5 100644 --- a/content/contract-dev/techniques/contract-sharding.mdx +++ b/content/contract-dev/techniques/contract-sharding.mdx @@ -64,7 +64,7 @@ contract TodoParent with Deployable { let init: StateInit = initOf TodoChild(self.numChildren); send(SendParameters{ to: contractAddress(init), - value: ton("0.1"), // pay for message, the deployment, and give some TON for storage + value: grams("0.1"), // pay for message, the deployment, and give some TON for storage mode: SendIgnoreErrors, code: init.code, // attaching the `StateInit` will cause the message to deploy data: init.data, diff --git a/content/contract-dev/techniques/gas.mdx b/content/contract-dev/techniques/gas.mdx index 6d4277cb0..6fe9bd828 100644 --- a/content/contract-dev/techniques/gas.mdx +++ b/content/contract-dev/techniques/gas.mdx @@ -251,7 +251,7 @@ fun onInternalMessage(in: InMessage) { maxCells, ); val oldBalance = contract.getOriginalBalance() - in.valueCoins; - reserveToncoinsOnBalance( + reserveGramsOnBalance( max(oldBalance, minTonsForStorage), RESERVE_MODE_AT_MOST, ); @@ -311,7 +311,7 @@ import "@stdlib/gas-payments"; fun onInternalMessage(in: InMessage) { // Reserve the original balance plus any storage debt - reserveToncoinsOnBalance( + reserveGramsOnBalance( contract.getStorageDuePayment(), RESERVE_MODE_INCREASE_BY_ORIGINAL_BALANCE | RESERVE_MODE_EXACT_AMOUNT, ); @@ -334,7 +334,7 @@ If the remaining trace involves `n` unique contracts, no more than `n` freeze li ```tolk title="Tolk" -const FreezeDueLimit: coins = ton("0.1"); // Current mainnet freeze_due_limit. +const FreezeDueLimit: coins = grams("0.1"); // Current mainnet freeze_due_limit. fun onInternalMessage(in: InMessage) { // The trace is still receiver -> A -> B @@ -369,7 +369,7 @@ The final code in the receiver contract could look like this: ```tolk title="Tolk" import "@stdlib/gas-payments"; -const FreezeDueLimit: coins = ton("0.1"); // Current mainnet freeze_due_limit. +const FreezeDueLimit: coins = grams("0.1"); // Current mainnet freeze_due_limit. fun onInternalMessage(in: InMessage) { val workchain = contract.getAddress().getWorkchain(); diff --git a/content/contract-dev/techniques/using-on-chain-libraries.mdx b/content/contract-dev/techniques/using-on-chain-libraries.mdx index 15f4fb9b6..080b33068 100644 --- a/content/contract-dev/techniques/using-on-chain-libraries.mdx +++ b/content/contract-dev/techniques/using-on-chain-libraries.mdx @@ -92,7 +92,7 @@ fun onInternalMessage(in: InMessage) { calculateGasFeeWithoutFlatPrice(-1, sizeCountingGas) + calculateStorageFee(-1, DEFAULT_DURATION, orderBits, orderCells); - reserveToncoinsOnBalance(toReserve, RESERVE_MODE_BOUNCE_ON_ACTION_FAIL); + reserveGramsOnBalance(toReserve, RESERVE_MODE_BOUNCE_ON_ACTION_FAIL); val reply = createMessage({ bounce: BounceMode.NoBounce, diff --git a/content/standard/tokens/nft/deploy.mdx b/content/standard/tokens/nft/deploy.mdx index 12af49c6d..412e3f5ba 100644 --- a/content/standard/tokens/nft/deploy.mdx +++ b/content/standard/tokens/nft/deploy.mdx @@ -193,7 +193,7 @@ struct NftItemInitAtDeployment { struct (0x00000001) DeployNft { queryId: uint64 itemIndex: uint64 - attachTonAmount: coins + attachGrams: coins initParams: Cell } @@ -206,7 +206,7 @@ fun onInternalMessage(in: InMessage) { queryId: 0, itemIndex: , // will be sent to the item contract on deployment - attachTonAmount: ton("0.005"), + attachGrams: grams("0.005"), initParams: NftItemInitAtDeployment { recipientAddress: address(""), content: ("" as SnakeString).toCell() @@ -216,7 +216,7 @@ fun onInternalMessage(in: InMessage) { val msg = createMessage({ bounce: true, dest: address(""), - value: ton("0.01"), + value: grams("0.01"), body: deploy }); diff --git a/content/tolk/basic-syntax.mdx b/content/tolk/basic-syntax.mdx index 6d23f7ead..1d053008d 100644 --- a/content/tolk/basic-syntax.mdx +++ b/content/tolk/basic-syntax.mdx @@ -132,7 +132,7 @@ Constants can be declared only at the top level, not inside functions: ```tolk const ONE = 1 -const MAX_AMOUNT = ton("0.05") +const MAX_AMOUNT = grams("0.05") const ADMIN_ADDRESS = address("EQ...") ``` @@ -292,7 +292,7 @@ To [construct and send a message](/languages/tolk/features/message-sending), a m ```tolk val reply = createMessage({ bounce: BounceMode.NoBounce, - value: ton("0.05"), + value: grams("0.05"), dest: someAddress, body: RequestedInfo { ... } }); diff --git a/content/tolk/examples.mdx b/content/tolk/examples.mdx index 2f400dec4..45aa0ba36 100644 --- a/content/tolk/examples.mdx +++ b/content/tolk/examples.mdx @@ -47,9 +47,9 @@ Some files in the source directory are not runnable on their own and depend on o > ```tolk // 6905(computational_gas_price) * 1000(cur_gas_price) = 6905000 ~= 0.01 TON - const MINIMAL_MESSAGE_VALUE_BOUND = ton("0.01") - const MIN_TONS_FOR_STORAGE = ton("0.01") - const JETTON_WALLET_GAS_CONSUMPTION = ton("0.015") + const MINIMAL_MESSAGE_VALUE_BOUND = grams("0.01") + const MIN_GRAMS_FOR_STORAGE = grams("0.01") + const JETTON_WALLET_GAS_CONSUMPTION = grams("0.015") ``` @@ -102,7 +102,7 @@ Some files in the source directory are not runnable on their own and depend on o transferRecipient: address sendExcessesTo: address? customPayload: cell? - forwardTonAmount: coins + forwardGrams: coins forwardPayload: ForwardPayloadRemainder } @@ -119,7 +119,7 @@ Some files in the source directory are not runnable on their own and depend on o // is null when minting (not initiated by another wallet) transferInitiator: address? sendExcessesTo: address? - forwardTonAmount: coins + forwardGrams: coins forwardPayload: ForwardPayloadRemainder } @@ -156,7 +156,7 @@ Some files in the source directory are not runnable on their own and depend on o struct (0x00000015) MintNewJettons { queryId: uint64 mintRecipient: address - tonAmount: coins + gramAmount: coins internalTransferMsg: Cell } @@ -312,7 +312,7 @@ Some files in the source directory are not runnable on their own and depend on o contract.getAddress(), storage.jettonWalletCode, ), - value: msg.tonAmount, + value: msg.gramAmount, // a newly-deployed wallet contract will immediately handle it body: msg.internalTransferMsg, }); @@ -426,20 +426,20 @@ Some files in the source directory are not runnable on their own and depend on o var msgValue = in.valueCoins; var tonBalanceBeforeMsg = contract.getOriginalBalance() - msgValue; - var storageFee = MIN_TONS_FOR_STORAGE - min( + var storageFee = MIN_GRAMS_FOR_STORAGE - min( tonBalanceBeforeMsg, - MIN_TONS_FOR_STORAGE, + MIN_GRAMS_FOR_STORAGE, ); msgValue -= (storageFee + JETTON_WALLET_GAS_CONSUMPTION); - if (msg.forwardTonAmount) { - msgValue -= (msg.forwardTonAmount + in.originalForwardFee); + if (msg.forwardGrams) { + msgValue -= (msg.forwardGrams + in.originalForwardFee); val notifyOwnerMsg = createMessage({ // cause receiver can have uninitialized contract bounce: BounceMode.NoBounce, dest: storage.ownerAddress, - value: msg.forwardTonAmount, + value: msg.forwardGrams, body: TransferNotificationForRecipient { queryId: msg.queryId, jettonAmount: msg.jettonAmount, @@ -477,13 +477,13 @@ Some files in the source directory are not runnable on their own and depend on o storage.jettonBalance -= msg.jettonAmount; storage.save(); - var forwardedMessagesCount = msg.forwardTonAmount ? 2 : 1; + var forwardedMessagesCount = msg.forwardGrams ? 2 : 1; assert (in.valueCoins > - msg.forwardTonAmount + + msg.forwardGrams + // 3 messages: wal1->wal2, wal2->owner, wal2->response // but last one is optional (it is ok if it fails) forwardedMessagesCount * in.originalForwardFee + - (2 * JETTON_WALLET_GAS_CONSUMPTION + MIN_TONS_FOR_STORAGE) + (2 * JETTON_WALLET_GAS_CONSUMPTION + MIN_GRAMS_FOR_STORAGE) ) throw ERR_NOT_ENOUGH_TON; val deployMsg = createMessage({ @@ -499,7 +499,7 @@ Some files in the source directory are not runnable on their own and depend on o jettonAmount: msg.jettonAmount, transferInitiator: storage.ownerAddress, sendExcessesTo: msg.sendExcessesTo, - forwardTonAmount: msg.forwardTonAmount, + forwardGrams: msg.forwardGrams, forwardPayload: msg.forwardPayload, } }); @@ -594,7 +594,7 @@ Some files in the source directory are not runnable on their own and depend on o title="fees-management.tolk" > ```tolk - const MIN_TONS_FOR_STORAGE = ton("0.05") + const MIN_GRAMS_FOR_STORAGE = grams("0.05") ``` @@ -738,7 +738,7 @@ Some files in the source directory are not runnable on their own and depend on o struct (0x00000001) DeployNft { queryId: uint64 itemIndex: uint64 - attachTonAmount: coins + attachGrams: coins initParams: Cell } @@ -748,7 +748,7 @@ Some files in the source directory are not runnable on their own and depend on o } struct BatchDeployDictItem { - attachTonAmount: coins + attachGrams: coins initParams: Cell } @@ -782,7 +782,7 @@ Some files in the source directory are not runnable on their own and depend on o newOwnerAddress: address sendExcessesTo: address? customPayload: dict - forwardTonAmount: coins + forwardGrams: coins forwardPayload: RemainingBitsAndRefs } ``` @@ -799,7 +799,7 @@ Some files in the source directory are not runnable on their own and depend on o fun deployNftItem( itemIndex: int, nftItemCode: cell, - attachTonAmount: coins, + attachGrams: coins, initParams: Cell, ) { val deployMsg = createMessage({ @@ -809,7 +809,7 @@ Some files in the source directory are not runnable on their own and depend on o contract.getAddress(), nftItemCode, ), - value: attachTonAmount, + value: attachGrams, body: initParams, }); deployMsg.send(SEND_MODE_PAY_FEES_SEPARATELY); @@ -836,7 +836,7 @@ Some files in the source directory are not runnable on their own and depend on o deployNftItem( msg.itemIndex, storage.nftItemCode, - msg.attachTonAmount, + msg.attachGrams, msg.initParams, ); if (isLast) { @@ -879,7 +879,7 @@ Some files in the source directory are not runnable on their own and depend on o deployNftItem( itemIndex, storage.nftItemCode, - dictItem.attachTonAmount, + dictItem.attachGrams, dictItem.initParams, ); if (itemIndex == storage.nextItemIndex) { @@ -1013,9 +1013,9 @@ Some files in the source directory are not runnable on their own and depend on o throw ERROR_INVALID_WORKCHAIN; val fwdFee = in.originalForwardFee; - var restAmount = contract.getOriginalBalance() - MIN_TONS_FOR_STORAGE; - if (msg.forwardTonAmount) { - restAmount -= (msg.forwardTonAmount + fwdFee); + var restAmount = contract.getOriginalBalance() - MIN_GRAMS_FOR_STORAGE; + if (msg.forwardGrams) { + restAmount -= (msg.forwardGrams + fwdFee); } if (msg.sendExcessesTo != null) { assert (msg.sendExcessesTo.getWorkchain() == BASECHAIN) @@ -1026,11 +1026,11 @@ Some files in the source directory are not runnable on their own and depend on o // base nft spends fixed amount of gas, will not check for response assert (restAmount >= 0) throw ERROR_TOO_SMALL_REST_AMOUNT; - if (msg.forwardTonAmount) { + if (msg.forwardGrams) { val ownershipMsg = createMessage({ bounce: BounceMode.NoBounce, dest: msg.newOwnerAddress, - value: msg.forwardTonAmount, + value: msg.forwardGrams, body: NotificationForNewOwner { queryId: msg.queryId, oldOwnerAddress: storage.ownerAddress, diff --git a/content/tolk/features/message-sending.mdx b/content/tolk/features/message-sending.mdx index 41ada57c7..dcbbfdc5e 100644 --- a/content/tolk/features/message-sending.mdx +++ b/content/tolk/features/message-sending.mdx @@ -7,7 +7,7 @@ Tolk provides a high-level function `createMessage`, which is followed by `send` ```tolk val reply = createMessage({ bounce: BounceMode.NoBounce, - value: ton("0.05"), + value: grams("0.05"), dest: senderAddress, body: RequestedInfo { ... } }); @@ -20,16 +20,16 @@ When handling a message, some values can be represented in multiple valid forms. ### Message value -The message value consists of a Toncoin amount: +The message value consists of a GRAM amount: ```tolk -value: someTonAmount +value: someGramAmount ``` -When extra currencies are required, the message value includes both Toncoin and a dictionary: +When extra currencies are required, the message value includes both GRAM and a dictionary: ```tolk -value: (someTonAmount, extraDict) +value: (someGramAmount, extraDict) ``` This is possible because the `value` field is defined as a union: @@ -250,7 +250,7 @@ While a field `stateInit: ContractState | cell` is named as `stateInit`, emphasi ## `createExternalLogMessage` -`createExternalLogMessage` follows the same general model as `createMessage`. [External outgoing messages](/foundations/messages/external-out) do not support bounce behavior, attached Toncoin, or related options, so the set of available fields is different. External messages are used only for emitting logs intended for indexers. +`createExternalLogMessage` follows the same general model as `createMessage`. [External outgoing messages](/foundations/messages/external-out) do not support bounce behavior, attached GRAM, or related options, so the set of available fields is different. External messages are used only for emitting logs intended for indexers. Example: diff --git a/content/tolk/features/standard-library.mdx b/content/tolk/features/standard-library.mdx index 68f36bd7b..922886a0b 100644 --- a/content/tolk/features/standard-library.mdx +++ b/content/tolk/features/standard-library.mdx @@ -48,19 +48,21 @@ const hexSlice = "1020".hexToSlice() const rawSlice = "abcd".literalSlice() ``` -### `ton()` +### `grams()` -Calculates nanotoncoins at compile time. +Calculates nanograms at compile time. ```tolk -const ONE_TON = ton("1"); // `coins`, value: 1000000000 +const ONE_GRAM = grams("1"); // `coins`, value: 1000000000 fun calcCost() { - val cost = ton("0.05"); // `coins`, value: 50000000 - return ONE_TON + cost; + val cost = grams("0.05"); // `coins`, value: 50000000 + return ONE_GRAM + cost; } ``` +The old `ton()` function is still available for backward compatibility, but `grams()` is preferred. + ## Common functions All functions in this section are available everywhere. They are defined in `@stdlib/common.tolk`, which is auto-imported. @@ -171,7 +173,7 @@ Returns `address` — the internal address of the current smart contract. It can #### `contract.getOriginalBalance` -Returns `coins` — the balance of the smart contract in nanotoncoins at the start of the [compute phase](/tvm/exit-codes#compute-phase). +Returns `coins` — the balance of the smart contract in nanograms at the start of the [compute phase](/tvm/exit-codes#compute-phase). #### `contract.getOriginalBalanceWithExtraCurrencies` @@ -394,17 +396,19 @@ Checks which specific blockchain address is contained in `any_address`. Casts `any_address` to `address`, with a runtime check that the value is internal. To skip the check, use an [unsafe cast](/languages/tolk/types/type-checks-and-casts): `addr = myAny as address`. -### Reserving Toncoin on the contract balance +### Reserving GRAM on the contract balance The standard library provides several `RESERVE_MODE_XXX` constants for [reserve modes](/foundations/actions/reserve), as well as the following functions. -#### `reserveToncoinsOnBalance` +#### `reserveGramsOnBalance` + +Creates an output action that reserves GRAM on the contract balance. -Creates an output action that reserves Toncoin on the contract balance. +`reserveToncoinsOnBalance` is a deprecated alias for `reserveGramsOnBalance`. #### `reserveExtraCurrenciesOnBalance` -Similar to `reserveToncoinsOnBalance`, but also accepts a dictionary `extraAmount`. +Similar to `reserveGramsOnBalance`, but also accepts a dictionary `extraAmount`. ### Creating and sending messages diff --git a/content/tolk/from-func/stdlib-comparison.mdx b/content/tolk/from-func/stdlib-comparison.mdx index e0c5640b0..a4de56611 100644 --- a/content/tolk/from-func/stdlib-comparison.mdx +++ b/content/tolk/from-func/stdlib-comparison.mdx @@ -106,7 +106,7 @@ Other functions: | `parse_std_addr` | use `address` type | | `parse_var_addr` | _(deleted)_ | | `config_param` | `blockchain.configParam` | -| `raw_reserve` | `reserveToncoinsOnBalance` | +| `raw_reserve` | `reserveGramsOnBalance` | | `raw_reserve_extra` | `reserveExtraCurrenciesOnBalance` | | `send_raw_message` | use `createMessage` | | `set_code` | `contract.setCodePostponed` | diff --git a/content/tolk/from-func/tolk-vs-func.mdx b/content/tolk/from-func/tolk-vs-func.mdx index 583af1688..ff4f33c0e 100644 --- a/content/tolk/from-func/tolk-vs-func.mdx +++ b/content/tolk/from-func/tolk-vs-func.mdx @@ -271,7 +271,7 @@ fun onInternalMessage(in: InMessage) { ```tolk val reply = createMessage({ bounce: BounceMode.NoBounce, - value: ton("0.05"), + value: grams("0.05"), dest: senderAddress, body: RequestedInfo { ... } }); @@ -358,12 +358,12 @@ b{011000} STSLICECONST There are [differences between standard libraries](/languages/tolk/from-func/stdlib-fc). For example, functions from `stdlib.fc` started having descriptive names: -| FunC | Tolk | -| :------------------: | :-------------------------------: | -| `cur_lt()` | `blockchain.logicalTime()` | -| `car(l)` | `list.getHead()` | -| `raw_reserve(coins)` | `reserveToncoinsOnBalance(coins)` | -| `~dump(x)` | `debug.print(x)` | +| FunC | Tolk | +| :------------------: | :----------------------------: | +| `cur_lt()` | `blockchain.logicalTime()` | +| `car(l)` | `list.getHead()` | +| `raw_reserve(coins)` | `reserveGramsOnBalance(coins)` | +| `~dump(x)` | `debug.print(x)` | Many global-scope functions became methods for primitives: diff --git a/content/tolk/idioms-conventions.mdx b/content/tolk/idioms-conventions.mdx index f773cd6f2..e272ce93a 100644 --- a/content/tolk/idioms-conventions.mdx +++ b/content/tolk/idioms-conventions.mdx @@ -235,7 +235,7 @@ struct (0x98765432) RequestedInfo { fun respond(/* ... */) { val reply = createMessage({ bounce: BounceMode.NoBounce, - value: ton("0.05"), + value: grams("0.05"), dest: addressOfB, body: RequestedInfo { // ... initialize fields diff --git a/content/tolk/syntax/structures-fields.mdx b/content/tolk/syntax/structures-fields.mdx index 3c6c78c45..252f9dc75 100644 --- a/content/tolk/syntax/structures-fields.mdx +++ b/content/tolk/syntax/structures-fields.mdx @@ -76,7 +76,7 @@ Fields with default values may be missed out of a literal: struct DefDemo { f1: int = 0 f2: int? = null - f3: (int, coins) = (0, ton("0.05")) + f3: (int, coins) = (0, grams("0.05")) } fun demo() { diff --git a/content/tolk/syntax/variables.mdx b/content/tolk/syntax/variables.mdx index 08fd20abe..afede42d4 100644 --- a/content/tolk/syntax/variables.mdx +++ b/content/tolk/syntax/variables.mdx @@ -149,7 +149,7 @@ Constants are not limited to integers: const ADMIN_ADDR = address("UQ...") // type `coins` -const MINIMAL_COST = ton("0.05") +const MINIMAL_COST = grams("0.05") // even objects with constant fields const ZERO_POINT: Point = { x: 0, y: 0 } diff --git a/content/tolk/types/numbers.mdx b/content/tolk/types/numbers.mdx index af2ff9d31..c76acc357 100644 --- a/content/tolk/types/numbers.mdx +++ b/content/tolk/types/numbers.mdx @@ -15,13 +15,13 @@ Tolk provides additional integer types to accommodate (de)serialization: There are also types of variable bit-width: -| Name | Inclusive range | Space taken | Notes | -| -------------------- | ------------------------------------- | ---------------------- | ----------------------------------------------------------------------------- | -| Unsigned `coins` | 0 to 2120-1 | Between 4 and 124 bits | They represent nanoToncoin, where 109 nanoToncoin equals 1 Toncoin | -| Unsigned `varuint16` | Same as `coins` | Same as `coins` | Rarely used | -| Unsigned `varuint32` | 0 to 2248-1 | Between 5 and 253 bits | Rarely used | -| Signed `varint16` | -2119 to 2119-1 | Same as `coins` | Rarely used | -| Signed `varint32` | -2247 to 2247-1 | Between 5 and 253 bits | Rarely used | +| Name | Inclusive range | Space taken | Notes | +| -------------------- | ------------------------------------- | ---------------------- | ---------------------------------------------------------------------- | +| Unsigned `coins` | 0 to 2120-1 | Between 4 and 124 bits | They represent nanograms, where 109 nanograms equals 1 GRAM | +| Unsigned `varuint16` | Same as `coins` | Same as `coins` | Rarely used | +| Unsigned `varuint32` | 0 to 2248-1 | Between 5 and 253 bits | Rarely used | +| Signed `varint16` | -2119 to 2119-1 | Same as `coins` | Rarely used | +| Signed `varint32` | -2247 to 2247-1 | Between 5 and 253 bits | Rarely used | All these types are **257-bit integers at runtime**. [Overflows can occur at runtime](/tvm/exit-codes#4%3A-integer-overflow), but they are more likely during serialization. @@ -77,11 +77,11 @@ fun demo(d: Demo) { The virtual machine supports only signed 257-bit integers. Floating-point numbers do not exist. -Represent monetary, Toncoin values with `coins`: +Represent monetary GRAM values with `coins`: ```tolk -// 1.23 Toncoin or 1,230,000,000 nanoToncoin -const MIN_BALANCE = ton("1.23") +// 1.23 GRAM or 1,230,000,000 nanograms +const MIN_BALANCE = grams("1.23") ``` ## Serialization @@ -194,9 +194,9 @@ fun f(op: int32, qid: uint64) { } ``` -### Type `coins` and function `ton("0.05")` +### Type `coins` and function `grams("0.05")` -Similar to `int32`, Tolk has a dedicated `coins` type representing nanoToncoin values. +Similar to `int32`, Tolk has a dedicated `coins` type representing nanogram values. The `coins` type has special serialization rules. It's serialized as variadic integer: small values consume fewer, large values consume more. @@ -204,13 +204,15 @@ Arithmetic with `coins` degrades to `int`, similar to `intN`, except for additio Values of type `int` can be cast back to `coins`, following the same rules as `intN`. -There is a `ton` built-in function, which calculates nanoToncoin values at compile-time. It accepts only constants and literals, e.g., `ton(some_variable)` is invalid. +There is a `grams` built-in function, which calculates nanogram values at compile-time. It accepts only constants and literals, e.g., `grams(some_variable)` is invalid. ```tolk -const ONE_TON = ton("1"); // `coins`, value: 1000000000 +const ONE_GRAM = grams("1"); // `coins`, value: 1000000000 fun calcCost() { - val cost = ton("0.05"); // `coins`, value: 50000000 - return ONE_TON + cost; + val cost = grams("0.05"); // `coins`, value: 50000000 + return ONE_GRAM + cost; } ``` + +The old `ton("0.05")` function is still available for backward compatibility, but `grams` is preferred. diff --git a/content/tolk/types/tensors.mdx b/content/tolk/types/tensors.mdx index 5f76eeabe..e57dd08ca 100644 --- a/content/tolk/types/tensors.mdx +++ b/content/tolk/types/tensors.mdx @@ -76,6 +76,7 @@ The following syntax is valid: ```tolk var (i, j) = (10, 20) +var (a, [b, c]) = (1, [2, 3]) ``` This is a 2-component tensor `(10, 20)` assigned to two variables: diff --git a/content/tvm/exit-codes.mdx b/content/tvm/exit-codes.mdx index 69c02688d..c7da3d4ee 100644 --- a/content/tvm/exit-codes.mdx +++ b/content/tvm/exit-codes.mdx @@ -41,7 +41,7 @@ The following table lists exit codes with their origin (where they can occur) an | [34](#34-invalid-or-unsupported-action) | [Action phase][a] | Action is invalid or not supported. | | [35](#35-invalid-source-address-in-outbound-message) | [Action phase][a] | Invalid source address in outbound message. | | [36](#36-invalid-destination-address-in-outbound-message) | [Action phase][a] | Invalid destination address in outbound message. | -| [37](#37-not-enough-toncoin) | [Action phase][a] | Not enough Toncoin. | +| [37](#37-not-enough-grams) | [Action phase][a] | Not enough GRAMs. | | [38](#38-not-enough-extra-currencies) | [Action phase][a] | Not enough extra currencies. | | [39](#39-outbound-message-does-not-fit-into-cell) | [Action phase][a] | Outbound message does not fit into a cell after rewriting. | | [40](#40-cannot-process-message) | [Action phase][a] | Cannot process a message — not enough funds, the message is too large, or its Merkle depth is too big. | @@ -486,17 +486,17 @@ If there are more than 255 actions queued for execution, the [action phase](#act import "@stdlib/gas-payments"; fun onInternalMessage() { - // For example, let's attempt to queue the reservation of a specific amount of nanoToncoins + // For example, let's attempt to queue the reservation of a specific amount of nanograms // This won't fail in the compute phase, but will result in exit code 33 in the action phase repeat (256) { - reserveToncoinsOnBalance(1000000, RESERVE_MODE_AT_MOST); + reserveGramsOnBalance(1000000, RESERVE_MODE_AT_MOST); } } ``` ### 34: Invalid or unsupported action -There are only four supported actions at the moment: changing the contract code, sending a message, reserving a specific amount of nanoToncoin, and changing the library cell. If there is any issue with the specified action (invalid message, unsupported action, etc.), an error with exit code 34 is thrown: `Invalid or unsupported action`. +There are only four supported actions at the moment: changing the contract code, sending a message, reserving a specific amount of nanograms, and changing the library cell. If there is any issue with the specified action (invalid message, unsupported action, etc.), an error with exit code 34 is thrown: `Invalid or unsupported action`. ```tolk title="Tolk" fun onInternalMessage() { From 95e1ec45af619d4920cdf6d1da242a8ba905a171 Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Fri, 19 Jun 2026 16:25:59 +0200 Subject: [PATCH 2/3] Revert one change to prevent conflicts: page got changed to use Tolk and grams() in another PR --- content/contract-dev/techniques/contract-sharding.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/contract-dev/techniques/contract-sharding.mdx b/content/contract-dev/techniques/contract-sharding.mdx index 822fd58e5..ecde84c9b 100644 --- a/content/contract-dev/techniques/contract-sharding.mdx +++ b/content/contract-dev/techniques/contract-sharding.mdx @@ -64,7 +64,7 @@ contract TodoParent with Deployable { let init: StateInit = initOf TodoChild(self.numChildren); send(SendParameters{ to: contractAddress(init), - value: grams("0.1"), // pay for message, the deployment, and give some TON for storage + value: ton("0.1"), // pay for message, the deployment, and give some TON for storage mode: SendIgnoreErrors, code: init.code, // attaching the `StateInit` will cause the message to deploy data: init.data, From a125384806804ebdd9397639f70d8b02ef377f7d Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Fri, 19 Jun 2026 16:30:43 +0200 Subject: [PATCH 3/3] Resolve a consistency issue uncovered by Coderabbit --- content/tvm/exit-codes.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/tvm/exit-codes.mdx b/content/tvm/exit-codes.mdx index c7da3d4ee..88903396f 100644 --- a/content/tvm/exit-codes.mdx +++ b/content/tvm/exit-codes.mdx @@ -518,9 +518,9 @@ If the destination address in the outbound message is invalid, e.g., it does not If the optional `mode` flag +2 is set, this error won't be thrown, and the given message won't be sent. -### 37: Not enough Toncoin +### 37: Not enough GRAMs -If all funds of the inbound message with base `mode` 64 set have already been consumed and there are not enough funds to pay for the failed action, or the [TL-B][tlb] layout of the provided value (`CurrencyCollection`) is invalid, or there are not enough funds to pay forward fees or not enough funds after deducting fees, an error with exit code 37 is thrown: `Not enough Toncoin`. +If all funds of the inbound message with base `mode` 64 set have already been consumed and there are not enough funds to pay for the failed action, or the [TL-B][tlb] layout of the provided value (`CurrencyCollection`) is invalid, or there are not enough funds to pay forward fees or not enough funds after deducting fees, an error with exit code 37 is thrown: `Not enough GRAMs`. If the optional `mode` flag +2 is set, this error won't be thrown, and the given message won't be sent. @@ -528,7 +528,7 @@ If all funds of the inbound message with base `mode` 64 set have already been co ### 38: Not enough extra currencies -Besides the native currency, Toncoin, TON Blockchain supports up to $2^{32}$ extra currencies. They differ from creating new Jettons because extra currencies are natively supported — one can potentially just specify an additional `HashmapE` of extra currency amounts in addition to the Toncoin amount in the internal message to another contract. Unlike Jettons, extra currencies can only be stored and transferred and do not have any other functionality. +Besides the native currency, GRAM, TON Blockchain supports up to $2^{32}$ extra currencies. They differ from creating new Jettons because extra currencies are natively supported — one can potentially just specify an additional `HashmapE` of extra currency amounts in addition to the GRAM amount in the internal message to another contract. Unlike Jettons, extra currencies can only be stored and transferred and do not have any other functionality. When there is not enough extra currency to send the specified amount, an exit code 38 is thrown: `Not enough extra currencies`.