common
common.tolk Tolk standard library file
Definitions
int
type int = builtinint is the primitive 257-bit signed integer type.
bool
type bool = builtinbool is a classic boolean type, which can hold only two values: true and false.
At the TVM (TON virtual machine) level, it's an integer -1 or 0.
Note: boolVar as int is possible, but remember, that true is -1, not 1!
cell
type cell = builtincell is a data structure, which can hold of up to 1023 bits (not bytes!)
and up to 4 references (refs) to other cells.
Both contract code and contract state are represented by a tree of cells.
slice
type slice = builtinslice is a "cell opened for reading".
When you call cell.beginParse, you get a slice, from which you can load binary data
or high-level structures with T.fromSlice.
builder
type builder = builtinbuilder is a "cell at the stage of creation".
When you call beginCell, you get a builder, populate it with binary data or structures,
and after builder.endCell, you get a cell.
continuation
type continuation = builtincontinuation is an "executable cell" representing executable TVM bytecode.
They are used to manage execution flow in TVM programs and serve as
the basis for function calls, exception handling, and control flow operations.
address
type address = builtinaddress represents a standard (internal) address: workchain + hash.
Addresses are comparable with == operator, they have methods like address.getWorkchain.
In binary, it's 267 bits: '10' (addr_std) + '0' (no anycast) + workchain (int8) + hash (uint256).
If you wish to describe "a potentially missing address", use address? (nullable).
When set to null, address? will be serialized as '00' ("none address"):
'00' (two zero bits) is a standard representation of a "missing" ("none") address.
At the TVM level, addresses are slices, so it's possible to someAddress as slice.
See docs
any_address
type any_address = builtinany_address represents an internal/external/none address.
You can test it with any_address.isExternal and similar methods.
If you wish to describe "internal or none address", use address? (nullable)
instead of "any". That's why any_address is used in practice extremely rarely.
At the TVM level, addresses are slices, so it's possible to anyAddress as slice.
See docs
never
type never = builtinnever is a special type that represents computations that never complete normally.
A function that always throws an exception returns never, and the compiler knows
that any code after it is unreachable.
intN
type intN = builtinint8, int32, int222, etc. is "a fixed-width signed integer with N bits", N <= 257.
Note: it's still int at runtime, you can assign "100500" to "int8":
overflow will happen at serialization to a cell/builder, NOT at assignment.
uintN
type uintN = builtinuint32, uint64, uint111, etc. is "a fixed-width unsigned integer with N bits", N <= 256.
Note: it's still int at runtime, you can assign "100500" to "uint8":
overflow will happen at serialization to a cell/builder, NOT at assignment.
coins
type coins = builtincoins is a special primitive representing "nanotoncoins". One TON = 10^9 nanotoncoins.
You can create coins with ton() function: ton("0.05") (actually, int 50000000 at runtime).
Arithmetic operations on coins degrade to 257-bit int type.
varint16
type varint16 = builtinvarint16 is int at runtime, but serialized as "variadic signed int", -2^119 <= X < 2^119.
varuint16
type varuint16 = builtinvaruint16 is int at runtime, but serialized as "variadic unsigned int", 0 <= X < 2^120.
varint32
type varint32 = builtinvarint32 is int at runtime, but serialized as "variadic signed int", -2^247 <= X < 2^247.
varuint32
type varuint32 = builtinvaruint32 is int at runtime, but serialized as "variadic unsigned int", 0 <= X < 2^248.
string
type string = builtinstring represents text data stored as a cell in snake format.
Snake format: data bytes, if more data exists — ref to next cell.
Example of "abcd" in a single chunk: cell(data: "abcd") (32 bits inside)
Example of "abcd" in two chunks: cell(data: "ab", ref: cell(data: "cd"))
At the TVM level, string is a TVM CELL (1 stack slot).
bitsN
type bitsN = builtinbits256, bits111, etc. is "a fixed-width slice with N bits and 0 refs", N <= 1023.
Note: use as operator to convert slice to bitsN: someSlice as bits256
(manually writing as enforces you to think that this conversion is correct).
Note: similar to intN, you can assign an invalid slice to bitsN,
an error will be fired at serialization with T.toCell and similar, NOT at assignment.
bytesN
type bytesN = builtinbytes8, bytes99, etc. is a convenient alias for bits(N*8)
map
struct map<K, V> {
private tvmDict: dict
}map<K, V> is "a map from a key K to a value V".
Internally, it's an "optional cell": an empty map is null, a non-empty points to a root cell.
Restrictions for K and V types:
- a key must be fixed-width; valid:
int32,uint64,address,bits256,Point; invalid:int,coins - a value must be serializable; valid:
int32,coins,AnyStruct,Cell<AnyStruct>; invalid:int,builder
array
struct array<T> {
private tvmTuple: tuple
}array<T> is a container that stores from 0 to 255 elements of type T.
Internally, it's a TVM tuple: the i-th element of a TVM tuple is the i-th element of an array.
On a stack, an array occupies one stack slot regardless of its size.
T can be any type (complex types are converted to sub-tuples under the hood).
Work with array using its methods: arr.push(v), arr.get(i), etc.
unknown
type unknown = builtinunknown represents one TVM primitive (one stack slot) with a kind unknown at compile-time.
Any type T can be cast to unknown and back. If T is a TVM primitive, it's a type-only cast.
Otherwise, an object is converted to a tuple, and is still stored as one stack slot.
var u1 = 5 as unknown; // stack: "5"
u1 as int; // stack: "5"
var u2 = (10, 20) as unknown; // stack: "[ 10 20 ]" (a TVM tuple)
u2 as (int, int); // stack: "10 20" (two integers)Be extremely careful using unknown, because the compiler is unable to validate the casts.
An invalid cast from your side leads to stack corruption, resulting in undefined behavior.
tuple
type tuple = array<unknown>tuple represents a TVM tuple. Essentially, it's "an array of unknown elements".
Reading an individual element results in unknown, cast it to perform some actions:
// wrong:
var elem = someTuple.get(0); // unknown
return elem + 123; // error, can not apply `+`
// correct:
var elem = someTuple.get(0) as int;
return elem + 123;lisp_list
struct lisp_list<T> {
private tvmTuple: [T, lisp_list<T>] | null
}lisp_list<T> is a set of nested 2-element TVM tuples:
[1, [2, [3, null]]] represents a list [1, 2, 3].
Unlike array<T>, it can represent a list longer than 255 elements,
but it has access only to the frontmost element (head).
To use lisp-style list, import the @stdlib/lisp-lists and call its methods.
var list: lisp_list<int> = [];
list.prependHead(1);
list.prependHead(2);
// list is now "2 1" (on a stack: [ 2 [ 1 null ] ])
list.getHead(); // 2dict
type dict = cell?Think of it as "a map with unknown keys and unknown values".
Prefer using map<K, V>, not dict.
void
type void = builtinvoid is the unit type representing the absence of a meaningful value.
It's similar to both void and unit in other languages.
Note: a function without return type means "auto infer", NOT "void".
Cell
struct Cell<T> {
private readonly tvmCell: cell
}Cell<T> represents a typed cell reference (as opposed to untyped cell).
struct ExtraData { ... }
struct MyStorage {
...
extra: Cell<ExtraData> // TL-B `^ExtraData`
optional: Cell<ExtraData>? // TL-B `(Maybe ^ExtraData)`
code: cell // TL-B `^Cell`
data: cell? // TL-B `(Maybe ^Cell)`
}Note, that st = MyStorage.fromSlice(s) does NOT deep-load any refs; st.extra is Cell<T>, not T;
you should manually call st.extra.load() to get T (ExtraData in this example).
Typed cells are comparable with == and !=, just like raw cell.
createEmptyTuple
@pure
@deprecated("use `[]` instead of `createEmptyTuple`")
fun createEmptyTuple(): array<unknown>Creates a TVM tuple with zero elements.
Deprecated since Tolk v1.3. Use [] to get an empty array instead:
// old way, deprecated:
var t = createEmptyTuple();
// new way, preferred:
var t = []; // array<unknown>
// create an empty typed array:
var numbers: array<int> = [];array<T>.push
@pure
fun array<T>.push(mutate self, value: T): voidAppends a value to array. If its size exceeds 255, throws a type check exception.
Source codearray<T>.first
@pure
fun array<T>.first(self): TReturns the first element of a non-empty array.
Source codearray<T>.get
@pure
fun array<T>.get(self, index: int): TReturns the i-th element of an array.
array<T>.set
@pure
fun array<T>.set(mutate self, value: T, index: int): voidSets the i-th element of an array to a specified value
(an element with this index must already exist, a new element is not created).
array<T>.size
@pure
fun array<T>.size(self): intReturns the size of an array (elements count in it).
Source codearray<T>.last
@pure
fun array<T>.last(self): TReturns the last element of a non-empty array.
Source codearray<T>.pop
@pure
fun array<T>.pop(mutate self): TPops and returns the last element of a non-empty array.
Source codeT.toTuple
@pure
fun T.toTuple(self): array<unknown>Packs any object from a stack to a tuple.
An object occupies N slots on a stack — the tuple will be of size N.
It works identically as casting an object to unknown.
Example:
struct Point { x: int, y: int }
var p: Point = { x: 1, y: 2 };
var t = p.toTuple(); // [ 1 2 ]
p = Point.fromTuple(t); // back
t.get(0) as int; // 1It can be used for logging or low-level purposes like running a child VM or custom "equals". See T.fromTuple counterpart.
Source codeT.fromTuple
@pure
fun T.fromTuple(packedObject: array<unknown>): TUnpacks a tuple back to an object on a stack.
It works identically as casting unknown to an object.
See T.toTuple for explanation and examples.
ton
@pure
fun ton(floatString: string): coinsConverts a constant floating-point string to nanotoncoins.
Example: ton("0.05") is equal to 50000000.
Note, that ton() requires a constant string; ton(some_var) is an error.
min
@pure
fun min(x: int, y: int): intComputes the minimum of two integers.
Source codemax
@pure
fun max(x: int, y: int): intComputes the maximum of two integers.
Source codeminMax
@pure
fun minMax(x: int, y: int): (int, int)Sorts two integers.
Example: minMax(x, y) with (x=20, y=10) and with (x=10, y=20) returns (10, 20)
abs
@pure
fun abs(x: int): intComputes the absolute value of an integer.
Source codesign
@pure
fun sign(x: int): intReturns the sign of an integer: -1 if x < 0, 0 if x == 0, 1 if x > 0.
divMod
@pure
fun divMod(x: int, y: int): (int, int)Computes the quotient and remainder of x / y. Example: divMod(112,3) = (37,1)
Source codemodDiv
@pure
fun modDiv(x: int, y: int): (int, int)Computes the remainder and quotient of x / y. Example: modDiv(112,3) = (1,37)
Source codemulDivFloor
@pure
fun mulDivFloor(x: int, y: int, z: int): intComputes multiple-then-divide: floor(x * y / z). The intermediate result is stored in a 513-bit integer to prevent precision loss.
Source codemulDivRound
@pure
fun mulDivRound(x: int, y: int, z: int): intSimilar to mulDivFloor, but rounds the result: round(x * y / z).
Source codemulDivCeil
@pure
fun mulDivCeil(x: int, y: int, z: int): intSimilar to mulDivFloor, but ceils the result: ceil(x * y / z).
Source codemulDivMod
@pure
fun mulDivMod(x: int, y: int, z: int): (int, int)Computes the quotient and remainder of (x * y / z). Example: mulDivMod(112,3,10) = (33,6)
Source codecontract
struct contractcontract is a built-in struct, it has only static methods.
Example: contract.getCode() and other methods.
contract.getAddress
@pure
fun contract.getAddress(): addressReturns the internal address of the current smart contract. If necessary, it can be parsed further using address.getWorkchain and others.
Source codecontract.getOriginalBalance
@pure
fun contract.getOriginalBalance(): coinsReturns the balance (in nanotoncoins) of the smart contract at the start of Computation Phase.
Source codecontract.getOriginalBalanceWithExtraCurrencies
@pure
fun contract.getOriginalBalanceWithExtraCurrencies(): [coins, ExtraCurrenciesMap]Same as contract.getOriginalBalance, but also returns the balance in extra currencies.
Source codecontract.getData
@pure
fun contract.getData(): cellReturns the persistent contract storage cell. It can be parsed or modified with slice and builder primitives later.
Source codecontract.setData
fun contract.setData(c: cell): voidSets the persistent contract storage.
Source codecontract.getCode
@pure
fun contract.getCode(): cellRetrieves code of smart-contract from c7.
Source codecontract.setCodePostponed
fun contract.setCodePostponed(newCode: cell): voidCreates an output action that would change this smart contract code after successful termination of the current run.
Source codeMASTERCHAIN
const MASTERCHAIN = -1BASECHAIN
const BASECHAIN = 0blockchain
struct blockchainblockchain is a built-in struct, it has only static methods.
Example: blockchain.configParam(16) and other methods.
blockchain.now
@pure
fun blockchain.now(): intReturns current Unix timestamp (in seconds).
Source codeblockchain.logicalTime
@pure
fun blockchain.logicalTime(): intReturns the logical time of the current transaction.
Source codeblockchain.currentBlockLogicalTime
@pure
fun blockchain.currentBlockLogicalTime(): intReturns the starting logical time of the current block.
Source codeblockchain.configParam
@pure
fun blockchain.configParam(x: int): cell?Returns the value of the global configuration parameter with integer index i as a cell or null value.
commitContractDataAndActions
fun commitContractDataAndActions(): voidCommits current state of registers c4 (persistent data) and c5 (actions)
so that the current execution is considered "successful" with the saved values even if an exception
in Computation Phase is thrown later.
PackOptions
struct PackOptions {
/// when a struct has a field of type `bits128` and similar (it's a slice under the hood),
/// by default, compiler inserts runtime checks (get bits/refs count + compare with 128 + compare with 0);
/// these checks ensure that serialized binary data will be correct, but they cost gas;
/// however, if you guarantee that a slice is valid (for example, it comes from trusted sources),
/// set this option to true to disable runtime checks;
/// note: `int32` and other are always validated for overflow without any extra gas,
/// so this flag controls only rarely used `bitsN` type
skipBitsNValidation: bool = false
}PackOptions allows you to control behavior of obj.toCell() and similar functions.
UnpackOptions
struct UnpackOptions {
/// after finished reading all fields from a cell/slice, call [slice.assertEnd] to ensure no remaining data left;
/// it's the default behavior, it ensures that you've fully described data you're reading with a struct;
/// example: `struct Point { x: int8; y: int8 }`, input "0102" is ok, "0102FF" will throw excno 9;
/// note: setting this to false does not decrease gas (DROP from a stack and ENDS cost the same);
/// note: this option controls [T.fromCell] and [T.fromSlice], but is ignored by [slice.loadAny];
/// note: `lazy` ignores this option, because it reads fields on demand or even skips them
assertEndAfterReading: bool = true
/// this excNo is thrown if a prefix doesn't match, e.g. for `struct (0x01) A` given input "88...";
/// similarly, for a union type, this is thrown when none of the opcodes match;
/// note: `lazy` ignores this option if you have `else` in `match` (you write custom logic there)
throwIfOpcodeDoesNotMatch: int = 63
}UnpackOptions allows you to control behavior of MyStruct.fromCell(c) and similar functions.
T.toCell
@pure
fun T.toCell(self, options: PackOptions = {}): Cell<T>Convert anything to a cell (most likely, you'll call it for structures).
var st: MyStorage = { ... };
contract.setData(st.toCell());Internally, a builder is created, all fields are serialized one by one, and a builder is flushed (beginCell() + serialize fields + endCell()).
Source codeT.fromCell
@pure
fun T.fromCell(packedCell: cell, options: UnpackOptions = {}): TParse anything from a cell (most likely, you'll call it for structures).
var st = MyStorage.fromCell(contract.getData());Internally, a cell is unpacked to a slice, and that slice is parsed (packedCell.beginParse() + read from slice).
Source codeT.fromSlice
@pure
fun T.fromSlice(rawSlice: slice, options: UnpackOptions = {}): TParse anything from a slice (most likely, you'll call it for structures).
var msg = CounterIncrement.fromSlice(cs);All fields are read from a slice immediately unless lazy.
If a slice is corrupted, an exception is thrown (most likely, excode 9 "cell underflow").
Note, that a passed slice is NOT mutated, its internal pointer is NOT shifted.
If you need to mutate it, like cs.loadInt(), consider calling cs.loadAny<CounterIncrement>().
slice.loadAny
@pure
fun slice.loadAny<T>(mutate self, options: UnpackOptions = {}): TParse anything from a slice, shifting its internal pointer.
Similar to slice.loadUint() and others, but allows loading structures.
var st: MyStorage = cs.loadAny(); // or cs.loadAny<MyStorage>()Similar to MyStorage.fromSlice(cs), but called as a slice method and mutates the slice.
Note: options.assertEndAfterReading is ignored by this function, because it's actually intended
to read data from the middle.
slice.skipAny
@pure
fun slice.skipAny<T>(mutate self, options: UnpackOptions = {}): selfSkip anything in a slice, shifting its internal pointer.
Similar to slice.skipBits() and others, but allows skipping structures.
struct TwoInts { a: int32; b: int32; }
cs.skipAny<TwoInts>(); // skips 64 bitsbuilder.storeAny
@pure
fun builder.storeAny<T>(mutate self, v: T, options: PackOptions = {}): selfStore anything to a builder.
Similar to builder.storeUint() and others, but allows storing structures.
var b = beginCell().storeUint(32).storeAny(msgBody).endCell();T.forceLoadLazyObject
@pure
fun T.forceLoadLazyObject(self): sliceForces an object created by lazy to load fully. Returns the remaining slice (having read all fields).
Since options.assertEndAfterReading is ignored by lazy (fields are loaded on demand),
this method can help you overcome this, if you really need to check input consistency.
val msg = lazy CounterMessage.fromSlice(s);
match (msg) { // it's a lazy match, without creating a union on the stack
CounterIncrement => {
...
newCounter = curCounter + msg.incBy; // `incBy` loaded here, on demand
msg.forceLoadLazyObject().assertEnd() // the purpose: get remainder
}
}Note: while slice.assertEnd may seem reasonable, these checks are avoided in practice,
because the purpose of lazy is to auto-detect and load only necessary fields, not up to the end.
Cell<T>.load
@pure
fun Cell<T>.load(self, options: UnpackOptions = {}): TParse data from already loaded cell reference.
struct MyStorage { ... extra: Cell<ExtraData> }
var st = MyStorage.fromCell(contract.getData());
// st.extra is cell; if we need to unpack it, we do
var extra = st.extra.load(); // it's ExtraData, unpacked from loaded refCell<T>.beginParse
@pure
fun Cell<T>.beginParse(self): sliceConverts a typed cell into a slice.
Source codeCell<T>.hash
@pure
fun Cell<T>.hash(self): uint256Returns hash of a typed cell, same as cell.hash.
Source codeRemainingBitsAndRefs
type RemainingBitsAndRefs = sliceRemainingBitsAndRefs is a special built-in type to get "all the rest" slice tail on reading.
struct JettonMessage {
... some fields
forwardPayload: RemainingBitsAndRefs;
}When you deserialize JettonMessage, forwardPayload contains "everything left after reading fields above".
Source codecreateEmptyCell
@pure
fun createEmptyCell(): cellCreates a cell with zero bits and references.
Equivalent to beginCell().endCell().
createEmptySlice
@pure
fun createEmptySlice(): sliceCreates a slice with zero remaining bits and references.
Equivalent to beginCell().endCell().beginParse().
stringCrc32
@pure
@deprecated("""use `"str".crc32()` instead of `stringCrc32("str")`""")
fun stringCrc32(constString: string): intCompile-time function that calculates crc32 of a constant string.
const op = stringCrc32("some_str") // = 4013618352 = 0xEF3AF4B0Note: stringCrc32(slice_var) does NOT work! It accepts a constant string and works at compile-time.
stringCrc16
@pure
@deprecated("""use `"str".crc16()` instead of `stringCrc16("str")`""")
fun stringCrc16(constString: string): intCompile-time function that calculates crc16 (XMODEM) of a constant string.
const op = stringCrc16("some_str") // = 53407 = 0xD09FNote: stringCrc16(slice_var) does NOT work! It accepts a constant string and works at compile-time.
stringSha256
@pure
@deprecated("""use `"str".sha256()` instead of `stringSha256("str")`""")
fun stringSha256(constString: string): intCompile-time function that calculates sha256 of a constant string and returns 256-bit integer.
const hash = stringSha256("some_crypto_key")Note: it's a compile-time function, stringSha256(slice_var) does NOT work!
Use slice.bitsHash or slice.hash (declared below) to hash a slice without/with its refs at runtime.
stringSha256_32
@pure
@deprecated("""use `"str".sha256_32()` instead of `stringSha256_32("str")`""")
fun stringSha256_32(constString: string): intCompile-time function that calculates sha256 of a constant string and takes the first 32 bits.
const minihash = stringSha256_32("some_crypto_key")Note: stringSha256_32(slice_var) does NOT work! It accepts a constant string and works at compile-time.
stringToBase256
@pure
@deprecated("""use `"str".toBase256()` instead of `stringToBase256("str")`""")
fun stringToBase256(constString: string): intCompile-time function that takes N-chars ascii string and interprets it as a number in base 256.
const value = stringToBase256("AB") // = 16706 (65*256 + 66)Note: stringToBase256(slice_var) does NOT work! It accepts a constant string and works at compile-time.
cell.hash
@pure
fun cell.hash(self): uint256Computes the representation hash of a cell and returns it as a 256-bit unsigned integer. Useful for signing and checking signatures of arbitrary entities represented by a tree of cells.
Source codeslice.hash
@pure
fun slice.hash(self): uint256Computes the hash of a slice and returns it as a 256-bit unsigned integer. The result is the same as cell.hash for a cell containing data and references from this slice.
Source codebuilder.hash
@pure
fun builder.hash(self): uint256Computes the hash of a builder and returns it as a 256-bit unsigned integer. The same as "transform builder to cell + calc hash of that cell", but without cell creation.
Source codeslice.bitsHash
@pure
fun slice.bitsHash(self): uint256Computes sha256 of the data bits of a slice (without refs). If the bit length is not divisible by eight, throws a cell underflow exception.
Source codecell.hashEqual
@pure
fun cell.hashEqual(self, another: cell): boolChecks whether two cells are equal by comparing their hashes.
Used internally by the compiler for operators == and != on cells.
isSignatureValid
@pure
fun isSignatureValid(hash: uint256, signature: slice, publicKey: uint256): boolChecks the Ed25519-signature of a hash (uint256, usually computed as the hash of some data)
using publicKey (also represented by a 256-bit unsigned integer).
The signature must contain at least 512 data bits; only the first 512 bits are used.
Note that CHKSIGNU creates a 256-bit slice with the hash and calls CHKSIGNS.
That is, if parameter hash is computed as the hash of some data, these data are hashed twice,
the second hashing occurring inside CHKSIGNS.
isSliceSignatureValid
@pure
fun isSliceSignatureValid(data: slice, signature: slice, publicKey: int): boolChecks whether signature is a valid Ed25519-signature of the data portion of slice data using publicKey,
similarly to isSignatureValid.
If the bit length of data is not divisible by eight, throws a cell underflow exception.
The verification of Ed25519 signatures is the standard one,
with sha256 used to reduce data to the 256-bit number that is actually signed.
random
struct randomrandom is a built-in struct, it has only static methods.
Example: random.uint256() and other methods.
random.uint256
fun random.uint256(): uint256Generates a new pseudo-random unsigned 256-bit integer x. Ensure you've called random.initialize in advance to make it unpredictable!
Source coderandom.range
fun random.range(limit: int): intGenerates a new pseudo-random integer z in the range 0..limit−1 (or limit..−1, if limit < 0). More precisely, an unsigned random value x is generated as in random; then z := x * limit / 2^256 is computed. Ensure you've called random.initialize in advance to make it unpredictable!
Source coderandom.getSeed
@pure
fun random.getSeed(): uint256Returns the current random seed used to generate pseudo-random numbers.
Source coderandom.setSeed
fun random.setSeed(seed: uint256): voidSets the random seed to the provided value.
Source coderandom.initializeBy
fun random.initializeBy(mixSeedWith: uint256): voidInitializes (mixes) random seed with the provided value.
Source coderandom.initialize
fun random.initialize(): voidMixes the random seed with this transaction's logical time (blockchain.logicalTime, asm LTIME).
LTIME is the network ordering value for this transaction (not unixtime).
Typically, call once before random.uint256 / random.range.
cell.calculateSize
@pure
fun cell.calculateSize(self, maxCells: int): (int, int, int, bool)Returns (x, y, z, -1) or (null, null, null, 0).
Recursively computes the count of distinct cells x, data bits y, and cell references z
in a tree of cells, effectively returning the total storage used by this tree taking into account
the identification of equal cells.
The values of x, y, and z are computed by a depth-first traversal of this tree,
with a hash table of visited cell hashes used to prevent visits of already-visited cells.
The total count of visited cells x cannot exceed non-negative maxCells;
otherwise the computation is aborted before visiting the (maxCells + 1)-st cell and
a zero flag is returned to indicate failure.
slice.calculateSize
@pure
fun slice.calculateSize(self, maxCells: int): (int, int, int, bool)Similar to cell.calculateSize, but accepting a slice instead of a cell.
The returned value of x does not take into account the cell that contains the slice itself;
however, its data bits and cell references are accounted for in y and z.
cell.calculateSizeStrict
fun cell.calculateSizeStrict(self, maxCells: int): (int, int, int)A non-quiet version of cell.calculateSize that throws a cell overflow exception (8) on failure.
slice.calculateSizeStrict
fun slice.calculateSizeStrict(self, maxCells: int): (int, int, int)A non-quiet version of slice.calculateSize that throws a cell overflow exception (8) on failure.
cell?.depth
@pure
fun cell?.depth(self): intReturns the depth of a cell: 0 if no references, otherwise 1 + maximum of depths of all references.
When called for null, returns 0.
slice.depth
@pure
fun slice.depth(self): intReturns the depth of a cell: 0 if no references, otherwise 1 + maximum of depths of all references.
Source codebuilder.depth
@pure
fun builder.depth(self): intReturns the depth of a builder: 0 if no references, otherwise 1 + maximum of depths of all references.
Source codedebug
struct debugdebug is a built-in struct, it has only static methods.
Example: debug.print(v) and other methods.
debug.print
fun debug.print<T>(x: T): voidDump a variable to the debug log as a raw TVM stack value.
Source codedebug.printString
fun debug.printString(x: string): voidDump a string to the debug log.
Source codedebug.dumpStack
fun debug.dumpStack(): voidDumps the stack (at most the top 255 values) and shows the total stack depth.
Source codecreateEmptyMap
@pure
@deprecated("use `[]` instead of `createEmptyMap`")
fun createEmptyMap<K, V>(): map<K, V>Returns an empty typed map. It's essentially "PUSHNULL", since TVM NULL represents an empty map.
// old way, deprecated:
var m: map<int8, int32> = createEmptyMap();
// new way, preferred:
var m: map<int8, int32> = [];createMapFromLowLevelDict
@pure
fun createMapFromLowLevelDict<K, V>(d: dict): map<K, V>Converts a low-level TVM dictionary to a typed map.
Actually, does nothing: accepts an "optional cell" and returns the same "optional cell",
so if you specify key/value types incorrectly, it will fail later, at map.get and similar.
map<K, V>.toLowLevelDict
@pure
fun map<K, V>.toLowLevelDict(self): dictConverts a high-level map to a low-level TVM dictionary. Actually, does nothing: returns the same "optional cell".
Source codemap<K, V>.isEmpty
@pure
fun map<K, V>.isEmpty(self): boolChecks whether a map is empty (whether a cell is null).
Note: a check m == null will not work, use m.isEmpty().
map<K, V>.exists
@pure
fun map<K, V>.exists(self, key: K): boolChecks whether a key exists in a map.
Source codemap<K, V>.get
@pure
fun map<K, V>.get(self, key: K): MapLookupResult<V>Gets an element by key. If not found, does NOT throw, just returns isFound = false.
val r = m.get(123);
if (r.isFound) {
r.loadValue()
}map<K, V>.mustGet
@pure
fun map<K, V>.mustGet(self, key: K, throwIfNotFound: int = 9): VGets an element by key and throws if it doesn't exist.
Source codemap<K, V>.set
@pure
fun map<K, V>.set(mutate self, key: K, value: V): selfSets an element by key.
m.set(k, 3);Since it returns self, calls may be chained.
map<K, V>.setAndGetPrevious
@pure
fun map<K, V>.setAndGetPrevious(mutate self, key: K, value: V): MapLookupResult<V>Sets an element and returns the previous element at that key. If no previous, isFound = false.
val prev = m.setAndGetPrevious(k, 3);
if (prev.isFound) {
prev.loadValue()
}map<K, V>.replaceIfExists
@pure
fun map<K, V>.replaceIfExists(mutate self, key: K, value: V): boolSets an element only if the key already exists. Returns whether an element was replaced.
Source codemap<K, V>.replaceAndGetPrevious
@pure
fun map<K, V>.replaceAndGetPrevious(mutate self, key: K, value: V): MapLookupResult<V>Sets an element only if the key already exists and returns the previous element at that key.
Source codemap<K, V>.addIfNotExists
@pure
fun map<K, V>.addIfNotExists(mutate self, key: K, value: V): boolSets an element only if the key does not exist. Returns whether an element was added.
Source codemap<K, V>.addOrGetExisting
@pure
fun map<K, V>.addOrGetExisting(mutate self, key: K, value: V): MapLookupResult<V>Sets an element only if the key does not exist. If exists, returns an old value.
Source codemap<K, V>.delete
@pure
fun map<K, V>.delete(mutate self, key: K): boolDelete an element at the key. Returns whether an element was deleted.
Source codemap<K, V>.deleteAndGetDeleted
@pure
fun map<K, V>.deleteAndGetDeleted(mutate self, key: K): MapLookupResult<V>Delete an element at the key and returns the deleted element. If not exists, isFound = false.
val prev = m.deleteAndGetDeleted(k);
if (prev.isFound) {
prev.loadValue()
}map<K, V>.findFirst
@pure
fun map<K, V>.findFirst(self): MapEntry<K, V>Finds the first (minimal) element in a map. If key are integers, it's the minimal integer. If keys are addresses or complex structures (represented as slices), it's lexicographically smallest. For an empty map, just returns isFound = false. Useful for iterating over a map:
var r = m.findFirst();
while (r.isFound) {
// ... use r.getKey() and r.loadValue()
r = m.iterateNext(r)
}map<K, V>.findLast
@pure
fun map<K, V>.findLast(self): MapEntry<K, V>Finds the last (maximal) element in a map. If key are integers, it's the maximal integer. If keys are addresses or complex structures (represented as slices), it's lexicographically largest. For an empty map, just returns isFound = false. Useful for iterating over a map:
var r = m.findLast();
while (r.isFound) {
// ... use r.getKey() and r.loadValue()
r = m.iteratePrev(r)
}map<K, V>.findKeyGreater
@pure
fun map<K, V>.findKeyGreater(self, pivotKey: K): MapEntry<K, V>Finds an element with key > pivotKey.
Don't forget to check isFound before using getKey() and loadValue() of the result.
map<K, V>.findKeyGreaterOrEqual
@pure
fun map<K, V>.findKeyGreaterOrEqual(self, pivotKey: K): MapEntry<K, V>Finds an element with key >= pivotKey.
Don't forget to check isFound before using getKey() and loadValue() of the result.
map<K, V>.findKeyLess
@pure
fun map<K, V>.findKeyLess(self, pivotKey: K): MapEntry<K, V>Finds an element with key < pivotKey.
Don't forget to check isFound before using getKey() and loadValue() of the result.
map<K, V>.findKeyLessOrEqual
@pure
fun map<K, V>.findKeyLessOrEqual(self, pivotKey: K): MapEntry<K, V>Finds an element with key <= pivotKey.
Don't forget to check isFound before using getKey() and loadValue() of the result.
map<K, V>.iterateNext
@pure
fun map<K, V>.iterateNext(self, current: MapEntry<K, V>): MapEntry<K, V>Iterate over a map in ascending order.
// iterate for all keys >= 10 up to the end
var r = m.findKeyGreaterOrEqual(10);
while (r.isFound) {
// ... use r.getKey() and r.loadValue()
r = m.iterateNext(r)
}map<K, V>.iteratePrev
@pure
fun map<K, V>.iteratePrev(self, current: MapEntry<K, V>): MapEntry<K, V>Iterate over a map in reverse order.
// iterate for all keys < 10 down lo lowest
var r = m.findKeyLess(10);
while (r.isFound) {
// ... use r.getKey() and r.loadValue()
r = m.iteratePrev(r)
}MapLookupResult
struct MapLookupResult<TValue> {
private readonly rawSlice: slice? // holds encoded value, present if isFound
isFound: bool
}MapLookupResult is a return value of map.get, map.setAndGetPrevious, and similar.
Instead of returning a nullable value (that you'd check on null before usage),
this struct is returned (and you check isFound before usage).
val r = m.get(key);
if (r.isFound) {
r.loadValue() // unpacks a returned slice
}MapLookupResult<TValue>.loadValue
@pure
fun MapLookupResult<TValue>.loadValue(self): TValueMapLookupResult<slice>.loadValue
@pure
fun MapLookupResult<slice>.loadValue(self): sliceMapEntry
struct MapEntry<K, V> {
private readonly rawValue: slice? // holds encoded value, present if isFound
private readonly key: K
isFound: bool
}MapEntry is a return value of map.findFirst, map.iterateNext, and similar.
You should check for isFound before calling getKey() and loadValue().
var r = m.findFirst();
while (r.isFound) {
// ... use r.getKey() and r.loadValue()
r = m.iterateNext(r)
}MapEntry<K, V>.getKey
@pure
fun MapEntry<K, V>.getKey(self): KMapEntry<K, V>.loadValue
@pure
fun MapEntry<K, V>.loadValue(self): VMapEntry<K, slice>.loadValue
@pure
fun MapEntry<K, slice>.loadValue(self): slicestring.beginParse
@pure
fun string.beginParse(self): sliceBegins parsing the string content. Use for accessing raw bytes. Remember that a string may be a snake: not just "ab", but "a" + (ref "b").
Source codestring.literalSlice
@pure
fun string.literalSlice(self): sliceCompile-time method that returns raw bytes of a short string literal as a slice. Use this when you need a slice constant, not a string.
const s: slice = "hello".literalSlice()Unlike beginParse(), it works at compile-time and is allowed in constant expressions.
string.crc32
@pure
fun string.crc32(self): intCompile-time method that calculates crc32 of a constant string.
const op = "some_str".crc32() // = 4013618352 = 0xEF3AF4B0Note: this is a compile-time method, it works only with string literals.
Source codestring.crc16
@pure
fun string.crc16(self): intCompile-time method that calculates crc16 (XMODEM) of a constant string.
const op = "some_str".crc16() // = 53407 = 0xD09FNote: this is a compile-time method, it works only with string literals.
Source codestring.sha256
@pure
fun string.sha256(self): intCompile-time method that calculates sha256 of a constant string.
const hash = "some_crypto_key".sha256()Note: this is a compile-time method, it works only with string literals.
Source codestring.sha256_32
@pure
fun string.sha256_32(self): intCompile-time method that calculates sha256 of a constant string and takes the first 32 bits.
const minihash = "some_crypto_key".sha256_32()Note: this is a compile-time method, it works only with string literals.
Source codestring.hexToSlice
@pure
fun string.hexToSlice(self): sliceCompile-time method that converts a constant hex-encoded string to a slice.
const v = "abcdef".hexToSlice() // = slice with 3 bytes: 0xAB,0xCD,0xEFNote: this is a compile-time method, it works only with string literals.
Source codestring.toBase256
@pure
fun string.toBase256(self): intCompile-time method that takes N-chars ascii string and interprets it as a number in base 256.
const value = "AB".toBase256() // = 16706 (65*256 + 66)Note: this is a compile-time method, it works only with string literals.
Source codestringHexToSlice
@pure
@deprecated("""use `"hex".hexToSlice()` instead of `stringHexToSlice("hex")`""")
fun stringHexToSlice(constStringBytesHex: string): sliceCompile-time function that converts a constant hex-encoded string to N/2 bytes.
const v = stringHexToSlice("abcdef") // = slice with 3 bytes: 0xAB,0xCD,0xEFNote: stringHexToSlice(slice_var) does NOT work! It accepts a constant string and works at compile-time.
cell.beginParse
@pure
fun cell.beginParse(self): sliceConverts a cell into a slice.
Source codeslice.assertEnd
fun slice.assertEnd(self): voidChecks if a slice is empty. If not, throws an exception with code 9.
Source codeslice.loadRef
@pure
fun slice.loadRef(mutate self): cellLoads the next reference from a slice.
Source codeslice.preloadRef
@pure
fun slice.preloadRef(self): cellPreloads the next reference from a slice.
Source codeslice.loadInt
@pure
fun slice.loadInt(mutate self, len: int): intLoads a signed len-bit integer from a slice.
Source codeslice.loadUint
@pure
fun slice.loadUint(mutate self, len: int): intLoads an unsigned len-bit integer from a slice.
Source codeslice.loadBits
@pure
fun slice.loadBits(mutate self, len: int): sliceLoads the first 0 ≤ len ≤ 1023 bits from a slice.
slice.preloadInt
@pure
fun slice.preloadInt(self, len: int): intPreloads a signed len-bit integer from a slice.
Source codeslice.preloadUint
@pure
fun slice.preloadUint(self, len: int): intPreloads an unsigned len-bit integer from a slice.
Source codeslice.preloadBits
@pure
fun slice.preloadBits(self, len: int): slicePreloads the first 0 ≤ len ≤ 1023 bits from a slice.
slice.loadCoins
@pure
fun slice.loadCoins(mutate self): coinsLoads the serialized amount of nanotoncoins (any unsigned integer up to 2^120 - 1).
slice.loadBool
@pure
fun slice.loadBool(mutate self): boolLoads a boolean from a slice.
Source codeslice.skipBits
@pure
fun slice.skipBits(mutate self, len: int): selfShifts a slice pointer to len bits forward.
Source codeslice.getFirstBits
@pure
fun slice.getFirstBits(self, len: int): sliceReturns the first 0 ≤ len ≤ 1023 bits of a slice.
slice.removeLastBits
@pure
fun slice.removeLastBits(mutate self, len: int): selfReturns all but the last 0 ≤ len ≤ 1023 bits of a slice.
slice.getLastBits
@pure
fun slice.getLastBits(self, len: int): sliceReturns the last 0 ≤ len ≤ 1023 bits of a slice.
slice.getMiddleBits
@pure
fun slice.getMiddleBits(self, offset: int, len: int): sliceReturns 0 ≤ len ≤ 1023 bits of a slice starting from 0 ≤ offset ≤ 1023.
(in other words, extracts a bit substring [offset, len) out of the slice)
slice.loadDict
@pure
fun slice.loadDict(mutate self): dictLoads a dictionary (TL HashMapE structure, represented as TVM cell) from a slice.
Source codeslice.preloadDict
@pure
fun slice.preloadDict(self): dictPreloads a dictionary (cell) from a slice.
Source codeslice.skipDict
@pure
fun slice.skipDict(mutate self): selfSkip a dictionary from a slice.
Source codeslice.loadMaybeRef
@pure
fun slice.loadMaybeRef(mutate self): cell?Loads (Maybe ^Cell) from a slice.
In other words, loads 1 bit: if it's true, loads the first ref, otherwise returns null.
slice.preloadMaybeRef
@pure
fun slice.preloadMaybeRef(self): cell?Preloads (Maybe ^Cell) from a slice.
Source codeslice.skipMaybeRef
@pure
fun slice.skipMaybeRef(mutate self): selfSkips (Maybe ^Cell) in a slice.
Source codeslice.loadString
@pure
fun slice.loadString(mutate self): stringLoads a string from a slice. A string is a nested ref, so just load a ref.
Source codebeginCell
@pure
fun beginCell(): builderCreates a new empty builder.
Source codebuilder.endCell
@pure
fun builder.endCell(self): cellConverts a builder into an ordinary cell.
Source codebuilder.toSlice
@pure
fun builder.toSlice(self): sliceConverts a builder into a slice.
The same as b.endCell().beginParse()
builder.storeRef
@pure
fun builder.storeRef(mutate self, c: cell): selfStores a reference to a cell into a builder.
Source codebuilder.storeInt
@pure
fun builder.storeInt(mutate self, x: int, len: int): selfStores a signed len-bit integer into a builder (0 ≤ len ≤ 257).
builder.storeUint
@pure
fun builder.storeUint(mutate self, x: int, len: int): selfStores an unsigned len-bit integer into a builder (0 ≤ len ≤ 256).
builder.storeSlice
@pure
fun builder.storeSlice(mutate self, s: slice): selfStores a slice into a builder.
Source codebuilder.storeString
@pure
fun builder.storeString(mutate self, s: string): selfStores a string into a builder (it's a TVM cell, stored as a ref).
Source codebuilder.storeAddress
@pure
fun builder.storeAddress(mutate self, addr: address): selfStores an internal address into a builder.
Source codebuilder.storeAddressOpt
@pure
fun builder.storeAddressOpt(mutate self, addrOrNull: address?): selfStores an internal address or '00' if the parameter is null.
'00' (two zero bits) is a standard representation of a "missing" ("none") address.
builder.storeAddressAny
@pure
fun builder.storeAddressAny(mutate self, addrAny: any_address): selfStores "any address" (internal/external/none) into a builder.
Source codebuilder.storeAddressNone
@pure
fun builder.storeAddressNone(mutate self): selfStores a "none address": '00' (two zero bits) is TL addr_none$00.
Source codebuilder.storeCoins
@pure
fun builder.storeCoins(mutate self, x: coins): selfStores the amount of nanotoncoins into a builder.
Source codebuilder.storeBool
@pure
fun builder.storeBool(mutate self, x: bool): selfStores a boolean into a builder.
Source codebuilder.storeDict
@pure
fun builder.storeDict(mutate self, c: dict): selfStores a low-level TVM dictionary (optional cell) into a builder.
In other words, if c is null, stores 0; if c is not null, stores 1 and a reference to c.
builder.storeMaybeRef
@pure
fun builder.storeMaybeRef(mutate self, c: cell?): selfStores (Maybe ^Cell) into a builder.
In other words, if c is null, stores 0; if c is not null, stores 1 and a reference to c.
builder.storeBuilder
@pure
fun builder.storeBuilder(mutate self, from: builder): selfConcatenates two builders.
Source codeslice.remainingRefsCount
@pure
fun slice.remainingRefsCount(self): intReturns the number of references in a slice.
Source codeslice.remainingBitsCount
@pure
fun slice.remainingBitsCount(self): intReturns the number of data bits in a slice.
Source codeslice.remainingBitsAndRefsCount
@pure
fun slice.remainingBitsAndRefsCount(self): (int, int)Returns both the number of data bits and the number of references in a slice.
Source codeslice.isEmpty
@pure
fun slice.isEmpty(self): boolChecks whether a slice is empty (i.e., contains no bits of data and no cell references).
Source codeslice.isEndOfBits
@pure
fun slice.isEndOfBits(self): boolChecks whether a slice has no bits of data.
Source codeslice.isEndOfRefs
@pure
fun slice.isEndOfRefs(self): boolChecks whether a slice has no references.
Source codeslice.bitsEqual
@pure
fun slice.bitsEqual(self, b: slice): boolChecks whether data parts of two slices coincide.
Source codebuilder.refsCount
@pure
fun builder.refsCount(self): intReturns the number of cell references already stored in a builder.
Source codebuilder.bitsCount
@pure
fun builder.bitsCount(self): intReturns the number of data bits already stored in a builder.
Source codeaddress
@pure
fun address(stdAddress: string): addressCompile-time function that parses a valid contract address.
address("EQCRDM9h4k3UJdOePPuyX40mCgA4vxge5Dc5vjBR8djbEKC5")
address("0:527964d55cfa6eb731f4bfc07e9d025098097ef8505519e853986279bd8400d8")Returns address, which can be stored in a struct, compared with ==, etc.
address.getWorkchainAndHash
@pure
fun address.getWorkchainAndHash(self): (int8, uint256)Extracts workchain and hash from a standard (internal) address.
Source codeaddress.getWorkchain
@pure
fun address.getWorkchain(self): int8Extracts workchain from a standard (internal) address.
Source codecreateAddressNone
@pure
fun createAddressNone(): any_addressCreates a slice representing "none external address" (TL addr_none$00 — two zero bits).
Note! Use this in combination with EXTERNAL addresses (e.g. for createExternalLogMessage).
To represent "internal or none" address (which you most likely need to),
use address? (nullable) and null accordingly.
any_address.isNone
@pure
fun any_address.isNone(self): boolReturns if "any address" is "none". In TL/B, it's addr_none$00.
Source codeany_address.isInternal
@pure
fun any_address.isInternal(self): boolReturns if "any address" is a standard (internal) address: workchain + hash.
Then it can be safely cast to address.
In TL/B, it's addr_std$10.
any_address.isExternal
@pure
fun any_address.isExternal(self): boolReturns if "any address" is an external address, used to communication with the outside world. In TL/B, it's addr_extern$01.
Source codeany_address.getWorkchainAndHash
@pure
fun any_address.getWorkchainAndHash(self): (int8, uint256)Extracts workchain and hash from a standard (internal) address. If the address is not internal, throws a cell deserialization exception.
Source codeany_address.getWorkchain
@pure
fun any_address.getWorkchain(self): int8Extracts workchain from a standard (internal) address. If the address is not internal, throws a cell deserialization exception.
Source codeany_address.castToInternal
@pure
fun any_address.castToInternal(self): addressCasts any_address to address checking that "any" is actually "internal".
E.g., addr = myAny.castToInternal() does the check and returns address.
To skip the runtime check, use unsafe type casting instead: addr = myAny as address.
address.bitsEqual
@pure
@deprecated("use `senderAddress == ownerAddress`, not `senderAddress.bitsEqual(ownerAddress)`")
fun address.bitsEqual(self, b: address): boolChecks whether two addresses are equal. Equivalent to a == b.
Deprecated! Left for smoother transition from FunC, where you used slice everywhere.
Use just a == b and a != b to compare addresses, don't use bitsEqual.
slice.loadAddress
@pure
fun slice.loadAddress(mutate self): addressLoads a standard (internal) address (containing workchain + hash). In TL/B, it's MsgAddressInt.
If an address is incorrect or is not internal, throws a deserialization exception (code 9).
slice.loadAddressOpt
@pure
fun slice.loadAddressOpt(mutate self): address?Loads a standard (internal) address or returns null if the input is "none address".
If an address is incorrect or is not internal/none, throws a deserialization exception (code 9).
'00' (two zero bits) is a standard representation of a "missing" ("none") address.
As a result, you get either address (for internal) or null (for none).
slice.loadAddressAny
@pure
fun slice.loadAddressAny(mutate self): any_addressLoads a valid "any address" (internal/external/none). In TL/B, it's MsgAddress.
RESERVE_MODE_EXACT_AMOUNT
const RESERVE_MODE_EXACT_AMOUNT = 0mode = 0: Reserve exact amount of nanotoncoins
Source codeRESERVE_MODE_ALL_BUT_AMOUNT
const RESERVE_MODE_ALL_BUT_AMOUNT = 1+1: Actually reserves all but amount, meaning currentContractBalance - amount
RESERVE_MODE_AT_MOST
const RESERVE_MODE_AT_MOST = 2+2: Actually set min(amount, currentContractBalance) (without this mode, if amount is greater, the action will fail)
RESERVE_MODE_INCREASE_BY_ORIGINAL_BALANCE
const RESERVE_MODE_INCREASE_BY_ORIGINAL_BALANCE = 4+4: amount is increased by the original balance of the current account (before the compute phase).
RESERVE_MODE_NEGATE_AMOUNT
const RESERVE_MODE_NEGATE_AMOUNT = 8+8: Actually sets amount = -amount before performing any further actions.
RESERVE_MODE_BOUNCE_ON_ACTION_FAIL
const RESERVE_MODE_BOUNCE_ON_ACTION_FAIL = 16+16: If this action fails, the transaction will be bounced.
Source codereserveToncoinsOnBalance
fun reserveToncoinsOnBalance(nanoTonCoins: coins, reserveMode: int): voidCreates an output action which would reserve Toncoins on balance.
For reserveMode consider constants above.
reserveExtraCurrenciesOnBalance
fun reserveExtraCurrenciesOnBalance(nanoTonCoins: coins, extraAmount: dict, reserveMode: int): voidSimilar to reserveToncoinsOnBalance, but also accepts a dictionary extraAmount (represented by a cell or null) with extra currencies. In this way currencies other than Toncoin can be reserved.
Source codeSEND_MODE_REGULAR
const SEND_MODE_REGULAR = 0mode = 0 is used for ordinary messages; the gas fees are deducted from the sending amount; action phases should NOT be ignored.
Source codeSEND_MODE_PAY_FEES_SEPARATELY
const SEND_MODE_PAY_FEES_SEPARATELY = 1+1 means that the sender wants to pay transfer fees separately.
Source codeSEND_MODE_IGNORE_ERRORS
const SEND_MODE_IGNORE_ERRORS = 2+2 means that any errors arising while processing this message during the action phase should be ignored.
Source codeSEND_MODE_BOUNCE_ON_ACTION_FAIL
const SEND_MODE_BOUNCE_ON_ACTION_FAIL = 16in the case of action fail - bounce transaction. No effect if SEND_MODE_IGNORE_ERRORS (+2) is used.
Source codeSEND_MODE_DESTROY
const SEND_MODE_DESTROY = 32mode = 32 means that the current account must be destroyed if its resulting balance is zero.
Source codeSEND_MODE_CARRY_ALL_REMAINING_MESSAGE_VALUE
const SEND_MODE_CARRY_ALL_REMAINING_MESSAGE_VALUE = 64mode = 64 is used for messages that carry all the remaining value of the inbound message in addition to the value initially indicated in the new message.
Source codeSEND_MODE_CARRY_ALL_BALANCE
const SEND_MODE_CARRY_ALL_BALANCE = 128mode = 128 is used for messages that are to carry all the remaining balance of the current smart contract (instead of the value originally indicated in the message).
Source codeSEND_MODE_ESTIMATE_FEE_ONLY
const SEND_MODE_ESTIMATE_FEE_ONLY = 1024do not create an action, only estimate fee.
Source codeExtraCurrenciesMap
type ExtraCurrenciesMap = map<int32, varuint32>ExtraCurrenciesMap represents a dictionary of "extra currencies" other than TON coin.
They can be attached to a message (incoming and outgoing) and stored on contract's balance.
It's a dictionary [currencyID => amount] (amount is like coins, but encoded with a high precision).
ContractState
struct ContractState {
code: cell
data: cell
}ContractState is "code + data" of a contract.
Used in outgoing messages (StateInit) to initialize a destination contract.
AddressShardingOptions
struct AddressShardingOptions {
fixedPrefixLength: uint5 // shard depth, formerly splitDepth
closeTo: address
}AddressShardingOptions provides settings to calculate an address in another shard.
Consider createMessage and address.calculateSameAddressInAnotherShard for usage.
AutoDeployAddress
struct AutoDeployAddress {
workchain: int8 = BASECHAIN
stateInit: ContractState | cell
toShard: AddressShardingOptions? = null
}AutoDeployAddress is a destination that initializes a receiver contract if it does not exist yet.
In order to do this, it contains StateInit — and calculates an address by a hash of StateInit.
createMessage({
dest: {
workchain: 0,
stateInit: {
code: jettonWalletCode,
data: jettonWalletEmptyStorage.toCell()
}
},
...You just provide code+data, and the compiler automatically calculates the destination address, because in TON, the address of a contract, by definition, is a hash of its initial state. You can also use it without sending a message. See AutoDeployAddress.calculateAddress.
Source codeAutoDeployAddress.buildAddress
@pure
@deprecated("use calculateAddress instead")
fun AutoDeployAddress.buildAddress(self): builderDeprecated, use AutoDeployAddress.calculateAddress instead.
Since late 2025 (TVM 12 has a cheap "builder-to-slice" instruction),
there is no need to use this function.
Historically its purpose was to avoid creating a cell and to return builder with a valid address.
AutoDeployAddress.calculateAddress
@pure
fun AutoDeployAddress.calculateAddress(self): addressConstructs an address that a deployed contract will have. For example, from a jetton minter, you want to calculate an address of a jetton wallet:
val jwDeployed = calcDeployedJettonWallet(...);
val jwAddress = jwDeployed.calculateAddress();Just instead of dest for createMessage, you use it is to calculate a jetton/nft address.
AutoDeployAddress.addressMatches
@pure
@deprecated("Use `a == jwDeployed.calculateAddress()` instead of `jwDeployed.addressMatches(a)")
fun AutoDeployAddress.addressMatches(self, addr: address): boolChecks that an address matches a deployed contract. For example, from a jetton minter, you're checking whether a message is from a jetton wallet:
val jwDeployed = calcDeployedJettonWallet(...);
val fromJW = jwDeployed.addressMatches(senderAddress);Just instead of dest for createMessage, you use it is to check whether a sender is a jetton/nft.
Deprecated since late 2025 (TVM 12 with a cheap "builder-to-slice" instruction), to be removed later.
BounceMode
enum BounceMode {
NoBounce // a message will just disappear on error
Only256BitsOfBody // `in.bouncedBody` will be "0xFFFFFFFF" and the first 256 bits of outgoing body (most cheap)
RichBounce // `in.bouncedBody` will be struct RichBounceBody (most expensive, but allows accessing all data sent)
RichBounceOnlyRootCell // `in.bouncedBody` will be struct RichBounceBody without refs in `originalBody`
}BounceMode represents behavior of an outgoing message when a receiver failed to handle it.
If you specify to bounce a message, don't forget about the onBouncedMessage entrypoint.
val outMsg = createMessage({
bounce: BounceMode.Only256BitsOfBody,
...
});
fun onBouncedMessage(in: InMessageBounced) {
// in.bouncedBody is populated depending on BounceMode
// for instance, "Only256BitsOfBody" means
// "bounced prefix 0xFFFFFFFF" and 256 bits of data
in.bouncedBody.skipBouncedPrefix();
val originalOpcode = in.bouncedBody.loadUint(32);
...
}OldBounceMode
@deprecated("use `BounceMode.NoBounce` instead of `false`")
type OldBounceMode = boolBefore TVM-12, bounce was only true or false.
Now, use enum BounceMode instead. "true" behaves like Only256BitsOfBody.
CreateMessageOptions
struct CreateMessageOptions<TBody = void> {
/// whether a message will bounce back on error, and what piece of outgoing `body` it will contain
bounce: BounceMode | OldBounceMode
/// message value: attached tons (or tons + extra currencies)
value: coins | (coins, ExtraCurrenciesMap)
/// destination is either a provided address, or is auto-calculated by stateInit
dest: address // either just send a message to some address
| builder // ... or a manually constructed builder with a valid address
| (int8, uint256) // ... or to workchain + hash (also known as accountID)
| AutoDeployAddress // ... or "send to stateInit" aka deploy (address auto-calculated)
/// body is any serializable object (or just miss this field for empty body)
body: TBody
}Options for creating an outgoing message. Consider createMessage for examples.
Source codecreateMessage
@pure
fun createMessage<TBody>(options: CreateMessageOptions<TBody>): OutMessageCreates a message (OutMessage) — a well-formatted message cell.
Typically, you just send it. In advanced scenarios, you can estimate fees or even postpone sending.
val reply = createMessage({
bounce: BounceMode.NoBounce,
value: ton("0.05"),
dest: senderAddress,
body: RequestedInfo { ... } // note: no toCell! just pass an object
});
reply.send(SEND_MODE_REGULAR);Hint: don't call body.toCell(), pass body directly!
(if body is small, it will be inlined without an expensive cell creation)
(if body is large, the compiler will automatically wrap it into a cell)
If you need an empty body, just miss the field body, fill other 3 fields.
ExtOutLogBucket
struct (0x00) ExtOutLogBucket {
topic: uint248 | bits248
}ExtOutLogBucket is a variant of a custom external address for emitting logs "to the outer world".
It includes some "topic" (arbitrary number), that determines the format of the message body.
For example, you emit "deposit event" (reserving topic "deposit" = 123):
dest: ExtOutLogBucket { topic: 123 },
body: DepositData { ... }and external indexers can index your emitted logs by destination address without parsing body. Serialization details: '01' (addr_extern) + 256 (len) + 0x00 (prefix) + 248 bits = 267 in total
Source codeCreateExternalLogMessageOptions
struct CreateExternalLogMessageOptions<TBody = void> {
/// destination is either an external address or a pattern to calculate it
dest: any_address // either some valid external/none address (not internal!)
| builder // ... or a manually constructed builder with a valid external address
| ExtOutLogBucket // ... or encode topic/eventID in destination
/// body is any serializable object (or just miss this field for empty body)
body: TBody
}Options for creating an external outgoing message. Consider createExternalLogMessage for examples.
Source codecreateExternalLogMessage
@pure
fun createExternalLogMessage<TBody>(options: CreateExternalLogMessageOptions<TBody>): OutMessageCreates an external message (OutMessage) — a well-formatted message cell.
Typically, you just send it. In advanced scenarios, you can estimate fees or even postpone sending.
val emitMsg = createExternalLogMessage({
dest: createAddressNone(),
body: DepositEvent { ... } // note: no `toCell`! just pass an object
});
emitMsg.send(SEND_MODE_REGULAR);Note: createMessage also returns OutMessage, it's okay: a composed message cell is universal.
Hint: don't call body.toCell(), pass body directly!
(if body is small, it will be inlined without an expensive cell creation)
(if body is large, the compiler will automatically wrap it into a cell)
UnsafeBodyNoRef
struct UnsafeBodyNoRef<T> {
forceInline: T
}UnsafeBodyNoRef is used to prevent default behavior: when message body is potentially large,
it's packed into a separate ref. Wrapping body with this struct tells the compiler:
"inline message body in-place, I guarantee it will fit".
struct ProbablyLarge { a: (coins, coins, coins, coins, coins) }
val contents: ProbablyLarge = { ... }; // you are sure: values are small
createMessage({
// body: contents, // by default, will be a ref (max 620 bits)
body: UnsafeBodyNoRef {
forceInline: contents, // but it forces the compiler to inline it
}Another example: your body contains builder or RemainingBitsAndRefs: unpredictable size.
If you guarantee it's small and refs won't clash with code/data, avoid creating a cell.
OutMessage
struct OutMessage {
messageCell: cell
}OutMessage is a result of createMessage. Essentially, it's a composed message cell, ready to be sent.
Source codeOutMessage.send
fun OutMessage.send(self, sendMode: int): voidSends a ready message cell.
For sendMode, see the constants above (SEND_MODE_*).
OutMessage.sendAndEstimateFee
fun OutMessage.sendAndEstimateFee(self, sendMode: int): coinsOutMessage.estimateFeeWithoutSending
@pure
fun OutMessage.estimateFeeWithoutSending(self, sendMode: int): coinsOutMessage.hash
@pure
fun OutMessage.hash(self): uint256StateInit
struct StateInit {
fixedPrefixLength: uint5?
special: (bool, bool)?
code: cell?
data: cell?
library: cell?
}StateInit is a "canonical TL/B representation from block.tlb" of a contract initial state.
But for everyday tasks, it's too complicated. It is not used in practice.
To represent code+data, consider ContractState.
To represent sharding (fixedPrefixLength, formerly splitDepth), consider AutoDeployAddress.
StateInit.calcHashCodeData
@pure
fun StateInit.calcHashCodeData(code: cell, data: cell): uint256Calculates a hash of StateInit if only code+data are set.
val addrHash = StateInit.calcHashCodeData(codeCell, dataCell);
createMessage({
dest: (workchain, addrHash),
...StateInit.calcHashPrefixCodeData
@pure
fun StateInit.calcHashPrefixCodeData(fixedPrefixLength: uint5, code: cell, data: cell): uint256Calculates a hash of StateInit if fixedPrefixLength+code+data are set.
Source codeaddress.buildSameAddressInAnotherShard
@pure
@deprecated("use calculateSameAddressInAnotherShard instead")
fun address.buildSameAddressInAnotherShard(self, options: AddressShardingOptions): builderDeprecated, use address.calculateSameAddressInAnotherShard instead.
Since late 2025 (TVM 12 has a cheap "builder-to-slice" instruction),
there is no need to use this function.
Historically its purpose was to avoid creating a cell and to return builder with a valid address.
address.calculateSameAddressInAnotherShard
@pure
fun address.calculateSameAddressInAnotherShard(self, options: AddressShardingOptions): addressGiven an internal address A="aaaa...a" returns "bbaa...a" (D bits from address B, 256-D from A).
Example for fixedPrefixLength (shard depth) = 8:
self (A) | aaaaaaaaaaa...aaa |
closeTo (B) | 01010101bbb...bbb | shardPrefix = 01010101 (depth 8)
result | 01010101aaa...aaa | address of A in same shard as BMore precisely, self (input) is 267 bits: '100' (std addr no anycast) + workchainA + "aaaa...a". The result is also 267 bits: '100' + workchainB + "bb" (D bits) + "aa...a" (256-D bits).
Source codeaddress.fromValidBuilder
@pure
@deprecated("prefer using `address` everywhere, avoid using `builder` and manual address construction")
fun address.fromValidBuilder(b: builder): addressConverts a builder containing a valid address to address (slice under the hood).
Deprecated! Since late 2025 (TVM 12 has a cheap "builder-to-slice" instruction),
all compiler built-ins return address directly, not builder.
address.fromWorkchainAndHash
fun address.fromWorkchainAndHash(workchain: int8, hash: uint256): addressConstructs an internal address (267 bits) from workchain and hash. Hint: if you just want to send a message, don't call this function, pass workchain+hash directly:
createMessage({
dest: (workchain, hash), // a pair can be passed instead of `address`
... // so, don't call this function in such a casesendRawMessage
fun sendRawMessage(msg: cell, mode: int): voidSends a raw message — a correctly serialized TL object Message X.
In practice, you'll use a high-level wrapper createMessage.
InMessage
struct InMessage {
senderAddress: address // an internal address from which the message arrived
valueCoins: coins // ton amount attached to an incoming message
valueExtra: ExtraCurrenciesMap // extra currencies attached to an incoming message
originalForwardFee: coins // fee that was paid by the sender
createdLt: uint64 // logical time when a message was created
createdAt: uint32 // unixtime when a message was created
body: slice // message body, parse it with `lazy AllowedMsg.fromSlice(in.body)`
}InMessage is an input for onInternalMessage — when your contract accepts a non-bounced message.
Internally, some data exist on the stack, some can be acquired with TVM instructions.
The compiler replaces in.someField and gets a value correctly.
fun onInternalMessage(in: InMessage) {
in.senderAddress // actually calls `INMSG_SRC` asm instruction
in.body // actually gets from a TVM stackInMessageBounced
struct InMessageBounced {
senderAddress: address // an internal address from which the message was bounced
valueCoins: coins // ton amount attached to a message
valueExtra: ExtraCurrenciesMap // extra currencies attached to a message
originalForwardFee: coins // commission that the sender has paid to send this message
createdLt: uint64 // logical time when a message was created (and bounced)
createdAt: uint32 // unixtime when a message was created (and bounced)
bouncedBody: slice // populated depending on `BounceMode` for `createMessage`
}InMessageBounced is an input for onBouncedMessage.
Very similar to a non-bounced input InMessage.
Note that bouncedBody is populated depending on BounceMode specified for createMessage.
fun onBouncedMessage(in: InMessageBounced) {
// in.bouncedBody is populated depending on BounceMode
// for instance, "Only256BitsOfBody" means
// "bounced prefix 0xFFFFFFFF" and 256 bits of data
in.bouncedBody.skipBouncedPrefix();
val originalOpcode = in.bouncedBody.loadUint(32);RichBounceBody
struct (0xfffffffe) RichBounceBody {
originalBody: cell // a cell with original body, but for `RichBounceOnlyRootCell` without refs (cheaper)
originalInfo: Cell<RichBounceOriginalMsgInfo> // some fields of an original (outgoing) message
bouncedByPhase: uint8 // see docs
exitCode: int32 // exception code from `throw` or TVM internals
computePhase: RichBounceComputePhaseInfo? // filled if compute phase executed
}When you use createMessage with "rich bounce mode", and a message is bounced,
then in.bouncedBody inside onBouncedMessage has this format.
fun onBouncedMessage(in: InMessageBounced) {
// suppose you ALWAYS use BounceMode.RichBounce in createMessage
// so you parse ALL bounces as follows
val rich = lazy RichBounceBody.fromSlice(in.bouncedBody);
// handle rich.originalBody, probably with lazy match
// use rich.xxx to get exitCode, gasUsed, and so onRichBounceComputePhaseInfo
struct RichBounceComputePhaseInfo {
gasUsed: uint32
vmSteps: uint32
}Describes compute phase details of a bounced message.
Source codeRichBounceOriginalMsgInfo
struct RichBounceOriginalMsgInfo {
valueCoins: coins
valueExtra: ExtraCurrenciesMap
createdLt: uint64
createdAt: uint32
}Describes original outgoing message fields (besides body) of a bounced message.
createMessage({
bounce: BounceMode.RichBounce,
value: ton("0.05") // it will be `valueCoins` if this message is bouncedslice.skipBouncedPrefix
@pure
fun slice.skipBouncedPrefix(mutate self): selfSkip 0xFFFFFFFF prefix (when a message is bounced).
Used when parsing in.bounceBody for "not rich" BounceMode.Only256BitsOfBody bounces.
slice.loadMessageFlags
@pure
@deprecated("use `onBouncedMessage` handler instead of parsing msgCell flags manually")
fun slice.loadMessageFlags(mutate self): intLoad msgFlags from incoming message body (4 bits).
Source codeslice.loadMessageOp
@pure
fun slice.loadMessageOp(mutate self): intLoads a message opcode (32-bit integer) when parsing message body manually.
Source codebuilder.storeMessageOp
@pure
@deprecated("use `createMessage` instead of composing messages manually")
fun builder.storeMessageOp(mutate self, op: int): selfStores a message opcode (32-bit integer) when composing an output message manually.
Source codeslice.loadMessageQueryId
@pure
@deprecated("use structures and lazy match instead of parsing messages manually")
fun slice.loadMessageQueryId(mutate self): intLoads a message queryId (64-bit integer, immediately following the opcode) when parsing message body manually.
Source codeslice.skipMessageQueryId
@pure
@deprecated("use structures and lazy loading instead of parsing messages manually")
fun slice.skipMessageQueryId(mutate self): selfbuilder.storeMessageQueryId
@pure
@deprecated("use `createMessage` instead of composing messages manually")
fun builder.storeMessageQueryId(mutate self, queryId: int): selfLast updated on