- general
int - signed
int32,int256,int88, etc. (0 < N ≤ 257) - unsigned
uint8,uint64,uint119, etc. (0 < N ≤ 256) coins(representing nanotoncoins, 1 TON = 10^9)- (rarely used)
varintNandvaruintN(N = 16/32)
All these types are 257-bit integers at runtime.
The TVM (virtual machine) has only
INT, and all intN are actually “just integers” while running.
Overflow happens only at serialization.Syntax: decimal, hex, and binary literals
All the constants below are justint:
intN describes serialization, int does not
To automatically parse binary data, the compiler must correctly load and store integers.
When a contract schema is designed, it is described in terms such as “queryID is unsigned 64-bit, counterValue is 32-bit”, and similar.
This is expressed directly in Tolk:
IncMessage can be serialized to a cell and decoded back.
A general-purpose type int is “an integer, but no information how to serialize it”. Consider this struct:
Point variable is pretty fine.
But a call p.toCell() gives an error:
int with a specific integer type. For example:
Overflow happens only at serialization
A natural question is: “What about overflow?”- arithmetic works as usual –
vbecomes 256 - no extra gas cost – no runtime bounds checks
- overflow only happens at serialization
Think of smart contracts as a black box:
- inputs are encoded (int32, uint64, etc.)
- inside the contract, arithmetic uses full 257-bit precision
- outputs are serialized again — overflow happens only at this stage
mulDivFloor(x,y,z), which uses 513-bit precision internally to prevent rounding errors.
Similarly, overflow only occurs at the boundary between the contract and the outside world.
Generic int implicitly cast to and from any intN
- arithmetic operations on
intNdegrade toint - numeric literals (like 0, 100) are just
int - direct assignment between
intNandintMis disallowed (as a probable error)
Type coins and function ton("0.05")
Similar to int32, Tolk has a dedicated coins type representing nanoton values.
The purpose of coins is to have special serialization rules. It’s serialized as “variadic integer”:
small values consume a few bits, large values consume more.
- arithmetic with
coinsdegrades toint, similar tointN(except addition/subtraction) - coins can be cast back from
int, following the same rules asintN
ton("0.05") built-in function calculates “nanotoncoins” at compile-time.
It only accepts constant values (e.g., ton(some_var) is invalid).
All of them are first-class types
At runtime, all integers are 257-bit. But they are different from the type system’s perspective. For example, they can be nullable, combined within a union, and so on:No floating-point numbers
Note that only integer types (257-bit) are supported by the virtual machine. There are no floating-point numbers. For example, monetary values are represented as nanotoncoins:Stack layout and serialization
All numeric types are backed by TVM INT. Serialization happens as follows:int— not serialized, useintNand other typesintN— a fixed N-bit signed integeruintN— a fixed N-bit unsigned integercoins— alias tovaruint16var(u)intN— variadic N 16/32: 4/5 bits for len + (8*len)-bit number