Skip to main content
The FunC standard library serves as a wrapper around the most commonly used TVM assembly commands that aren’t built-in. For detailed descriptions of these commands, refer to the TVM documentation. Some explanations in this document adapted from there. Some functions in the library are commented out, meaning they have already been optimized and integrated as built-in operations. However, their type signatures and behaviors remain unchanged. Additionally, some less frequently used TVM commands are not yet included in the standard library. These may be added in future updates.

Tuple manipulation primitives

Most function names and types in this section are self-explanatory. For more details on polymorphic functions, refer to the Polymorphism with forall section. Note: Currently, values of atomic type tuple cannot be converted into composite tuple types (e.g.,[int, cell]) and vice versa.

Lisp-style lists

Lists can be represented as nested 2-element tuples. Empty list is conventionally represented as TVM null value (it can be obtained by calling null()). For example, the tuple (1, (2, (3, null))) represents the list [1, 2, 3]. Elements of a list can be of different types. Lists in FunC are represented as nested two-element tuples. An empty list is conventionally represented by the TVM null value, which can be obtained using null(). For example, the tuple (1, (2, (3, null))) corresponds to the list [1, 2, 3]. Lists in FunC can contain elements of different types.

cons

Adds an element to the beginning of a lisp-style list.

uncons

Extracts the head and tail of a lisp-style list.

list_next

Extracts the head and tail of a lisp-style list. It can be used as a (non-)modifying method. Example

car

Returns the head of a lisp-style list.

cdr

Returns the tail of a lisp-style list.

Other tuple primitives

empty_tuple

Creates an empty tuple (0 elements).

tpush

Appends a value to the tuple (x1, ..., xn), forming (x1, ..., xn, x). The resulting tuple must not exceed 255 elements, or a type check exception is thrown.

single

Creates a tuple with a single element — singleton

unsingle

Unpacks a singleton.

pair

Creates a two-element tuple (pair).

unpair

Unpacks a pair into two separate values.

triple

Creates a three-element tuple (triple).

untriple

Unpacks a triple into three separate values.

tuple4

Creates a four-element tuple.

untuple4

Unpacks a four-element tuple into four separate values.

Tuple element access

first

Returns the first element of a tuple.

second

Returns the second element of a tuple.

third

Returns the third element of a tuple.

fourth

Returns the fourth element of a tuple.

Pair and triple element access

pair_first

Returns the first element of a pair.

pair_second

Returns the second element of a pair.

triple_first

Returns the first element of a triple.

triple_second

Returns the second element of a triple.

triple_third

Returns the third element of a triple.

Domain specific primitives

Extracting info from c7

The c7 special register holds useful data about smart contract execution. The following primitives facilitate easy retrieval of this information:

now

Returns the current Unix timestamp as an integer.

my_address

Retrieves the smart contract’s internal address as a Slice containing MsgAddressInt. If needed, it can be further processed using functions like parse_std_addr.

get_balance

Returns the smart contract’s balance as a tuple:
  • int: The remaining balance in nanotoncoins.
  • cell: A dictionary (with 32-bit keys) containing balances of extra currencies.
Since this is retrieved during the compute phase, the balance reflects the incoming message value, with storage_fee and import_fee already subtracted.

cur_lt

Returns the logical time of the current transaction.

block_lt

Returns the logical time at the beginning of the current block.

config_param

Returns the value of the global configuration parameter with integer index i as cell or null value.

my_code

Retrieves the smart contract’s code from c7.

Hashes

cell_hash

Calculates the representation hash of the given cell c and returns it as a 256-bit unsigned integer x. This function is handy for signing and verifying signatures of arbitrary entities structured as a tree of cells.

slice_hash

Computes the hash of the given slice s and returns it as a 256-bit unsigned integer x. The result is equivalent to creating a standard cell containing only the data and references from s and then computing its hash using cell_hash.

string_hash

Calculates the SHA-256 hash of the data bits in the given slice s. A cell underflow exception is thrown if the bit length of s is not a multiple of eight. The hash is returned as a 256-bit unsigned integer x.

Signature checks

check_signature

Checks whether the given signature is a valid Ed25519 signature of the provided hash using the specified public key. The hash and public key are both 256-bit unsigned integers. The signature must be at least 512 bits long, and only the first 512 bits are used. If the signature is valid, the function returns -1; otherwise, it returns 0. Remember that CHKSIGNU converts the hash into a 256-bit slice and then calls CHKSIGNS. This means that if the hash was initially generated from some data, that data gets hashed twice — the first time when creating the hash and the second time within CHKSIGNS.

check_data_signature

Verifies whether the given signature is a valid Ed25519 signature for the data contained in the slice data, using the specified public key, just like check_signature. A cell underflow exception is thrown if the data bit length is not a multiple of eight. The verification follows the standard Ed25519 process, where SHA-256 is used to derive a 256-bit number from data, which is then signed.

Computation of BoC size

The following functions help calculate storage fees for user-provided data.

compute_data_size?

Returns (x, y, z, -1) or (null, null, null, 0). It recursively calculates the number of unique cells x, data bits y, and cell references z in the directed acyclic graph (DAG) at cell c. This provides the total storage used by the DAG while recognizing identical cells. The computation uses a depth-first traversal with a hash table to track visited cells, preventing redundant visits. If the total amount of visited cells x exceeds max_cells, the process stops before visiting the (max_cells + 1) -th cell, and the function returns 0 to indicate failure. If c is null, the function returns x = y = z = 0.

slice_compute_data_size?

It works similarly to compute_data_size? but takes a slice s instead of a cell. The result x does not include the cell that contains the slice s, but y and z account for the data bits and cell references inside s.

compute_data_size

A strict version of compute_data_size? that throws a cell overflow exception (8) if the computation fails.

slice_compute_data_size

A strict version of slice_compute_data_size? that throws a cell overflow exception (8) if the computation fails.

Persistent storage save and load

get_data

Returns the persistent contract storage cell, which can be later parsed or modified using slice and builder functions.

set_data

Sets cell c as persistent contract data. You can update the persistent contract storage with this primitive.

Continuation primitives

get_c3

The c3 register typically holds a continuation set up by the contract code. It is used for function calls. The primitive returns the current value of c3.

set_c3

Updates the c3 value to modify the contract’s execution code at runtime. The current code and function call stack remain unchanged, but future function calls use the updated code.

bless

Converts a slice s into a basic continuation c, where c.code = s, an empty stack and a savelist.

accept_message

This function sets the current gas limit gl to its maximum possible value gm and resets the gas credit gc to zero. At the same time, it deducts the previous gas credit gc from the remaining gas reserve gr. Simply put, the smart contract agrees to purchase gas to complete the transaction. This function is required when processing external messages that do not carry any value and do not provide gas.

set_gas_limit

This function sets the gas limit gl to the smaller of two values: the provided limit or the maximum allowed gas gm. It also resets the gas credit gc to zero. If the contract already uses more gas than this new limit gl, including the current instruction, an out-of-gas exception is triggered before the new limit is applied. Remember that if the limit is 2^63 − 1 or higher, calling set_gas_limit works the same as calling accept_message.

commit

Saves the current state of persistent storage c4 and action registers c5, ensuring execution succeeds with these stored values, even if an exception occurs later.

buy_gas

This function calculates how much gas can be purchased for the gram nanotoncoins and updates the gas limit gl accordingly, similar to set_gas_limit.

Actions primitives

raw_reserve

The raw_reserve function creates an output action that reserves a specific amount of nanotoncoins from the account’s remaining balance. The behavior depends on the mode parameter:
  • If mode = 0, exactly the amount of nanotoncoins is reserved.
  • If mode = 2, up to the amount of nanotoncoins is reserved.
  • If mode = 1 or mode = 3, all but the amount of nanotoncoins is reserved.
This process is equivalent to generating an outbound message that transfers the amount of nanotoncoins or b − amount nanotoncoins, where b represents the remaining balance, to the sender. This ensures that subsequent output actions cannot exceed the remaining funds. Mode Flags
  • Bit +2 in mode: prevents failure if the specified amount cannot be reserved. Instead, the entire remaining balance is reserved.
  • Bit +8 in mode: negates amount (amount <- -amount) before executing further actions.
  • Bit +4 in mode: increases amount by the original balance of the current account before the compute phase, including all extra currencies, before performing any other checks and actions.
Constraints
  • The amount must be a non-negative integer.
  • mode must be within the range 0..15.

raw_reserve_extra

Similar to raw_reserve, but it also supports an extra_amount dictionary. This dictionary, given as a cell or null, allows reserving currencies other than Toncoin.

send_raw_message

This function sends a raw message stored in msg. This message must contain a properly serialized Message X object, with a few exceptions. The source address can have a dummy value addr_none, which the current smart contract address will automatically replace. The fields ihr_fee, fwd_fee, created_lt, and created_at can hold arbitrary values, as they will be updated with the correct ones during the action phase of the transaction. The integer parameter mode specifies the flags. Currently, there are 3 modes and 4 flags available for messages. A single mode can be combined with multiple flags or none to form the desired mode. The combination is achieved by summing their values. The table below provides descriptions of the available modes and flags.

set_code

Generates an output action to update the smart contract’s code to the one provided in the new_code cell. This change occurs only after the smart contract completes its current execution. See also set_c3.

Random number generator primitives

The pseudo-random number generator relies on a random seed, a 256-bit unsigned integer, and sometimes additional data stored in c7. Before a smart contract executes in the TON Blockchain, its initial random seed is derived from a hash of the smart contract address and the global block random seed. If the same smart contract runs multiple times within a block, each run will use the same random seed. This can be adjusted by calling randomize_ltbefore using the pseudo-random number generator for the first time.

random

Generates a new pseudo-random 256-bit unsigned integer x. The process works as follows:
  • Let r be the previous random seed, a 32-byte array constructed from the big-endian representation of a 256-bit unsigned integer.
  • Compute sha512(r).
  • The first 32 bytes of the hash become the new seed r'.
  • The remaining 32 bytes are returned as the new random value x.

rand

Generates a new pseudo-random integer z in the range 0..range−1 (or range..−1 if range < 0). More precisely, an unsigned random value x is generated as in random; then z := x * range / 2^256 is computed. Produces a pseudo-random integer z within the range 0..range−1 (or range..−1 if range < 0).
  • First, an unsigned random value x is generated using random().
  • Then, z := x * range / 2^256 is calculated.

get_seed

Returns the current random seed as a 256-bit unsigned integer.

set_seed

Sets the random seed to a specified 256-bit unsigned integer seed.

randomize

Mixes an unsigned 256-bit integer x into a random seed r by setting the random seed to sha256 of the concatenation of two 32-byte strings: the first with a big-endian representation of the old seed r, and the second with a big-endian representation of x. Mixes a 256-bit unsigned integer x into the random seed r by updatingr to sha256(r || x), where:
  • r is the previous seed, represented as a 32-byte big-endian array.
  • x is also converted into a 32-byte big-endian array. T- he new seed is the SHA-256 hash of their concatenation.

randomize_lt

Equivalent to calling randomize(cur_lt());.

Address manipulation primitives

The functions below handle the serialization and deserialization of values based on the following TL-B scheme.
  • addr_none is represented by t = (0), i.e., a tuple containing exactly one integer that equals zero
  • addr_extern is represented by t = (1, s), where slice s contains the field external_address. In other words, t is a pair (a tuple consisting of two entries), containing an integer equal to one and slice s
  • addr_std is represented by t = (2, u, x, s), where u is either null (if anycast is absent) or a slice s' containing rewrite_pfx (if anycast is present). Next, integer x is the workchain_id, and slice s contains the address
  • addr_var is represented by t = (3, u, x, s), where u, x, and s have the same meaning as for addr_std
A deserialized MsgAddresscis represented as a tuple t with the following structure:
  • addr_none is represented as t = (0), a single-element tuple where the integer is zero.
  • addr_extern is represented as t = (1, s), where s is a slice containing external_address. In other words, t is a pair with the first element being 1 and the second being s.
  • addr_std is represented as t = (2, u, x, s), where:
    • u is null if anycast is absent or a slice s' containing rewrite_pfx if anycast is present.
    • x is the workchain_id.
    • s is a slice containing the address.
  • addr_var is represented as t = (3, u, x, s), where u, x, and s follow the same structure as addr_std.

load_msg_addr

Extracts a valid MsgAddress prefix from slice s and returns the extracted prefix s' and the remaining part s''.

parse_addr

Splits slice s, which holds a valid MsgAddress, into tuple t, separating its fields. If s is invalid, a cell deserialization exception is raised.

parse_std_addr

Extracts a valid MsgAddressInt, typically msg_addr_std, from slice s, modifies the address prefix if anycast is present, and returns the workchain and 256-bit address as integers. A cell deserialization exception is triggered if the address isn’t 256-bit or s isn’t a valid MsgAddressInt serialization.

parse_var_addr

A modified version of parse_std_addr that returns the modified address as slice s, even if its length is not exactly 256 bits, as in msg_addr_var.

Debug primitives

Debug primitives help inspect the state of various variables while running tests or executing console scripts.

~dump

Prints the given value. Multiple values can be output as a tuple, e.g.,~dump([v1, v2, v3]).

~strdump

Prints a string. The bit length of the slice parameter must be a multiple of 8.

dump_stack

Prints the current stack up to the top 255 values and displays the total stack depth.

Slice primitives

A primitive loads data when it returns both the extracted data and the remainder of the slice. It can be used as a modifying method. A primitive preloads data when it returns only the extracted data, leaving the original slice unchanged. It can be used as a non-modifying method. Unless specified otherwise, loading and preloading primitives read data from the beginning of the slice.

begin_parse

Converts a cell into a slice. The input c must be either an ordinary or exotic cell. See TVM.pdf, 3.1.2. If c is exotic, it is automatically converted into an ordinary cell c' before being transformed into a slice.

end_parse

Checks if the slice s is empty. It throws an exception if it is not.

load_ref

Loads the first reference from a slice.

preload_ref

Preloads the first reference from a slice.

load_int

Loads a signed len-bit integer from a slice.

load_uint

Loads an unsigned len-bit integer from a slice.

preload_int

Preloads a signed len-bit integer from a slice.

preload_uint

Preloads an unsigned len-bit integer from a slice.

load_bits

Loads the first 0 ≤ len ≤ 1023 bits from slice s into a new slice s''.

preload_bits

Preloads the first 0 ≤ len ≤ 1023 bits from slice s into a new slice s''.

load_coins

Loads serialized amount of Toncoin, which is an unsigned integer up to 2^120 - 1.

skip_bits

Returns all bits of s except for the first len bits, where 0 ≤ len ≤ 1023.

first_bits

Returns the first len bits of s, where 0 ≤ len ≤ 1023.

skip_last_bits

Returns all bits of s except for the last len bits, where 0 ≤ len ≤ 1023.

slice_last

Returns the last len bits of s, where 0 ≤ len ≤ 1023.

load_dict

Loads a dictionary D from slice s. It can be used for dictionaries or to values of arbitrary Maybe ^Y types (returns null if the nothing constructor is used).

preload_dict

Preloads a dictionary D from slice s.

skip_dict

Loads a dictionary as load_dict but returns only the remainder of the slice.

Slice size primitives

slice_refs

Returns the number of references in slice s.

slice_bits

Returns the number of data bits in slice s.

slice_bits_refs

Returns both the number of data bits and the number of references in s.

slice_empty?

Checks whether slice s is empty (i.e., contains no bits of data and no cell references).

slice_data_empty?

Checks whether slice s has no bits of data.

slice_refs_empty?

Checks whether slice s has no references.

slice_depth

Returns the depth of slice s. If s has no references, it returns 0; otherwise, the returned value is one plus the maximum depths of cells referred to from s.

Builder primitives

A primitive stores a value x in a builder b by returning a modified version b' with x added at the end. It can also be used as a non-modifying method. Each of the following primitives first checks for enough space in the builder and then verifies the range of the serialized value.

begin_cell

Creates a new empty builder.

end_cell

Converts a builder into a standard cell.

store_ref

Stores a reference to cell c in builder b.

store_uint

Stores an unsigned len-bit integer x in b, where 0 ≤ len ≤ 256.

store_int

Stores a signed len-bit integer x in b, where 0 ≤ len ≤ 257.

store_slice

Stores slice s in builder b.

store_grams

store_coins

Serializes an integer x in the range 0..2^120 − 1 into builder b. The serialization consists of:
  • A 4-bit unsigned big-endian integer l, the smallest l ≥ 0 such that x < 2^8l.
  • An 8l-bit unsigned big-endian representation of x.
A range check exception is thrown if x is outside the supported range. This is the standard way of storing Toncoin.

store_dict

Stores a dictionary D represented by cell c or null into builder b. Stores a 1-bit and a reference to c if c is not null; otherwise, stores a 0-bit.

store_maybe_ref

The same as store_dict.

Builder size primitives

builder_refs

Returns the number of cell references currently stored in builder b.

builder_bits

Returns the number of data bits currently stored in builder b.

builder_depth

Returns the depth of builder b. If b contains no cell references, it returns 0. Otherwise, it returns 1 plus the maximum depth among the referenced cells.

Cell primitives

cell_depth

Returns the depth of the given cell c. If c has no references, the function returns 0. Otherwise, it returns 1 plus the maximum depth among all cells referenced by c. If c is null instead of a cell, the function returns 0.

cell_null?

Checks whether the given cell c is null. In most cases, a null cell represents an empty dictionary. FunC also includes a polymorphic null? built-in function. See built-in for more details.

Dictionaries primitives

As stated in TVM.pdf:
Dictionaries can be represented in two different ways as TVM stack values:
  1. As a slice s containing the serialized TL-B value of type HashmapE(n, X). In simpler terms, s consists either of a single 0 bit if the dictionary is empty or a 1 bit followed by a reference to a cell containing the binary tree’s root — essentially, a serialized value of type Hashmap(n, X).
  2. As a Maybe cell (c^?), which is either a cell that contains a serialized Hashmap(n, X) same as above or null, indicating an empty dictionary. See null values for details. When using this format, the dictionary is typically referred to as D.
Most dictionary-related operations use the second format because it is easier to manipulate on the stack. However, when dictionaries are serialized within larger TL-B objects, they follow the first representation.
In FunC, dictionaries are also represented as cells with the implicit assumption that they can be null. There are no separate types for dictionaries with different key lengths or value types — after all, this is FunC, not FunC++.

Taxonomy note

A dictionary primitive interprets dictionary keys in one of three ways:
  1. Unsigned l-bit integers (denoted by u);
  2. Signed l-bit integers (denoted by i);
  3. l-bit slices (no prefix).
The naming convention of dictionary primitives reflects these distinctions. For example:
  • udict_set is a set-by-key function for dictionaries with unsigned integer keys.
  • idict_set is the equivalent function for signed integer keys.
  • dict_set applies to dictionaries with slice keys.
In function titles, an empty prefix indicates slice keys. Additionally, some primitives have counterparts prefixed with ~, enabling them to be used as modifying methods.

Dictionary values

Values in a dictionary can be stored in two ways:
  1. As a subslice within an inner dictionary cell.
  2. As a reference to a separate cell.
In the first case, even if a value is small enough to fit within a cell, it may not fit within the dictionary. This is because a segment of the corresponding key may already occupy part of the inner cell’s space. The second method, while ensuring storage, is less efficient regarding gas consumption. Storing a value this way is functionally equivalent to inserting a slice with no data bits and a single reference to the value, as in the first method.

dict_set

This function updates the dictionary dict by setting the value corresponding to the key_len-bit key index to value, a slice, and returns the updated dictionary.

dict_set_ref

This is similar to dict_set, but it sets the value to a reference of cell value.

dict_get?

Searches for the key index in the dict dictionary with key_len-bit keys. It retrieves the associated value as a slice and returns a success flag of -1 if found. If not found, it returns (null, 0).

dict_get_ref?

Similar todict_get?, but it returns the first reference of the found value.

dict_get_ref

This variant of dict_get_ref? returns null if the key index is absent in the dictionary dict.

dict_set_get_ref

This function sets the value associated with the index to value. If the value is null, the key is deleted. It then returns the old value or null if it wasn’t present.

dict_delete?

This function deletes the key_len-bit key index from the dictionary dict. It returns the modified dictionary and a success flag of -1 if successful. If the key is not found, it returns the original dictionary and 0.

dict_delete_get?

Deletes the key_len-bit key index from the dictionary dict. If the key is found, it returns the modified dictionary, the original value associated with the key as a Slice, and the success flag -1. If the key is not found, it returns (dict, null, 0).

dict_add?

This add operation is similar to dict_set but only sets the value if the key index does not already exist in the dictionary dict. It returns the modified dictionary and a success flag of -1 or (dict, 0).

dict_replace?

This replace operation works like dict_set, but it only updates the value for the index if the key is already present in the dictionary dict. It returns the modified dictionary and a success flag of -1 or (dict, 0).

Builder counterparts

The following primitives accept a builder as the new value instead of a slice, making them more convenient when the value needs to be serialized from multiple components computed on the stack. Functionally, this is equivalent to converting the builder into a slice and executing the corresponding primitive listed above.

dict_set_builder

It works similarly to dict_set but takes a builder as input.

dict_add_builder?

Similar to dict_add?, but uses a builder.

dict_replace_builder?

Similar todict_replace?, but uses a builder.

dict_delete_get_min

Finds the smallest key k in the dictionary dict, removes it, and returns (dict', k, x, -1), where dict' is the updated dictionary and x is the value associated with k. If the dictionary is empty, it returns (dict, null, null, 0). Note: The key returned by idict_delete_get_min may differ from that returned by dict_delete_get_min and udict_delete_get_min.

dict_delete_get_max

Finds the largest key k in the dictionary dict, removes it, and returns (dict', k, x, -1), where dict' is the updated dictionary and x is the value associated with k. If the dictionary is empty, it returns (dict, null, null, 0).

dict_get_min?

Finds the smallest key k in the dictionary dict and returns (k, x, -1), where x is the value associated with k. If the dictionary is empty, it returns (null, null, 0).

dict_get_max?

Finds the largest key k in the dictionary dict and returns (k, x, -1), where x is the value associated with k. If the dictionary is empty, it returns (null, null, 0).

dict_get_min_ref?

Same as dict_get_min? but it returns a reference.

dict_get_max_ref?

Same as dict_get_max? but it returns a reference.

dict_get_next?

Finds the smallest key k in dict that is greater than the pivot. Returns k, associated value, and a success flag. If the dictionary is empty, it returns (null, null, 0).

dict_get_nexteq?

Similar to dict_get_next?, but instead finds the smallest key k that is greater than or equal to the pivot.

dict_get_prev?

Similar to dict_get_next?, but instead finds the largest key k that is less than the pivot.

dict_get_preveq?

Similar to dict_get_prev?, but instead finds the largest key k that is less than or equal to the pivot.

new_dict

Creates an empty dictionary, which is represented as a null value — a special case of null().

dict_empty?

Checks whether a dictionary is empty. Equivalent to cell_null?.

Prefix dictionaries primitives

TVM supports dictionaries with non-fixed length keys that follow a prefix code structure, meaning no key is a prefix of another key. Learn more in the TVM instruction section.

pfxdict_get?

Searches for the unique prefix of a slice key in the prefix code dictionary dict. If found, returns (s', x, s'', -1), where:
  • s' is the matching prefix of s,
  • x is the corresponding value (a slice),
  • s'' is the remaining part of s,
  • -1 indicates success.
If no matching prefix is found, returns (null, null, s, 0), where s remains unchanged and 0 indicates failure.

pfxdict_set?

Works like dict_set but fails if the given key is a prefix of an existing key in dict. Returns a flag indicating success.

pfxdict_delete?

Similar to dict_delete?.

Special primitives

null

In TVM, the Null type in FunC represents the absence of a value for any atomic type, meaning null can take on any atomic type.

~impure_touch

Marks a variable as used, ensuring the code generated isn’t removed during optimization, even if it’s not impure. See Impure specifier section.

Other primitives

min

Computes the minimum of two integers x and y.

max

Computes the maximum of two integers x and y.

minmax

Returns (min(x, y), max(x, y)), sorting two integers.

abs

Computes the absolute value of x.