Skip to main content

Tolk vs FunC: standard library

FunC has a rich standard library, known as the "stdlib.fc" file. It's quite low-level and contains many asm functions closely related to TVM instructions.

Tolk also has a standard library based on the FunC one. Three main differences:

  1. It's split into multiple files: common.tolk, tvm-dicts.tolk, and others. Functions from common.tolk are always available. Functions from other files are available after import:
import "@stdlib/tvm-dicts"

beginCell() // available always
createEmptyDict() // available due to import
  1. You don't need to download it from GitHub; it's part of the Tolk distribution.
  2. Tolk has functions and methods (called via the dot operator). Many global FunC functions became methods of builders/slices/etc. and can no longer be called as functions.

Functions vs methods

In FunC, there are no methods, actually. All functions are globally scoped.
You can call any function using the dot operator:

;; FunC
cell config_param(int x) asm "CONFIGOPTPARAM";

config_param(16); ;; ok
16.config_param(); ;; also ok...

So, when you call b.end_cell(), you actually call a global function end_cell. Since all functions are globally scoped, there are no "short methods."

someTuple.tuple_size();
;; why not someTuple.size()? because it's a global function:
;; int tuple_size(tuple t)

Tolk separates functions and methods like it's done in most languages:

  1. functions can NOT be called via dot, only methods can.
  2. methods can have short names, they don't conflict.
// FunC
someCell.cell_hash(); // or cell_hash(someCell)
someSlice.slice_hash();

// Tolk
someCell.hash(); // the only possible
someSlice.hash();

A list of renamed functions

If the Required import column is empty, a function is available without imports.

Note that some functions were deleted because they either can be expressed syntactically, or they were very uncommon in practice.

The table is "sorted" in a way how functions are declared in stdlib.fc:

Note: FunC uses snake_case names (for example, begin_cell), while Tolk methods use camelCase (for example, beginCell).

FunC nameTolk nameRequired import
empty_tuplecreateEmptyTuple
t~tpusht.push(v)
first(t) or dot t.first()t.first()
at(t,i) or dot t.at(i)t.get(i) or just t.0 etc.
touch(v) or dotv.stackMoveToTop()tvm-lowlevel
impure_touch(deleted)
single(deleted)
unsingle(deleted)
pair(deleted)
unpair(deleted)
triple(deleted)
untriple(deleted)
tuple4(deleted)
untuple4(deleted)
second(deleted)
third(deleted)
fourth(deleted)
pair_first(deleted)
pair_second(deleted)
triple_first(deleted)
triple_second(deleted)
triple_third(deleted)
minmaxminMax
nowblockchain.now
my_addresscontract.getAddress
get_balance + pair_firstcontract.getOriginalBalance
cur_ltblockchain.logicalTime
block_ltblockchain.currentBlockLogicalTime
cell_hash(c) or dotc.hash()
slice_hash(s) or dots.hash()
string_hash(s) or dots.bitsHash()
check_signatureisSignatureValid
check_data_signatureisSliceSignatureValid
compute_data_size(c) or dotc.calculateSizeStrict()
slice_compute_data_size(s) or dots.calculateSizeStrict()
c.compute_data_size?() or dotc.calculateSize()
slice_compute_data_size?() or dots.calculateSize()
~dumpdebug.print
~strdumpdebug.printString
dump_stackdebug.dumpStack
get_datacontract.getData
set_datacontract.setData
get_c3getTvmRegisterC3tvm-lowlevel
set_c3setTvmRegisterC3tvm-lowlevel
blesstransformSliceToContinuationtvm-lowlevel
accept_messageacceptExternalMessage
set_gas_limitsetGasLimit
buy_gas(deleted)
commitcommitContractDataAndActions
divmoddivMod
moddivmodDiv
muldivmulDivFloor
muldivrmulDivRound
muldivcmulDivCeil
muldivmodmulDivMod
begin_parsebeginParse
end_parse(s) or dots.assertEnd()
load_refloadRef
preload_refpreloadRef
load_intloadInt
load_uintloadUint
preload_intpreloadInt
preload_uintpreloadUint
load_bitsloadBits
preload_bitspreloadBits
load_gramsloadCoins
load_coinsloadCoins
skip_bitss.skipBits
first_bitsgetFirstBits
skip_last_bitsremoveLastBits
slice_lastgetLastBits
load_dictloadDict
preload_dictpreloadDict
skip_dictskipDict
load_maybe_refloadMaybeRef
preload_maybe_refpreloadMaybeRef
cell_depth(c) or dotc.depth()
slice_refs(s) or dots.remainingRefsCount()
slice_bits(s) or dots.remainingBitsCount()
slice_bits_refs(s) or dots.remainingBitsAndRefsCount()
slice_empty?(s) or dots.isEmpty()
slice_data_empty?(s) or dots.isEndOfBits()
slice_refs_empty?(s) or dots.isEndOfRefs()
slice_depth(s) or dots.depth()
equal_slice_bits(a,b) or dota.bitsEqual(b)
builder_refs(b) or dotb.refsCount()
builder_bits(b) or dotb.bitsCount()
builder_depth(b) or dotb.depth()
begin_cellbeginCell
end_cellendCell
store_refstoreRef
store_uintstoreUint
store_intstoreInt
store_slicestoreSlice
store_gramsstoreCoins
store_coinsstoreCoins
store_dictstoreDict
store_maybe_refstoreMaybeRef
store_builderstoreBuilder
load_msg_addrloadAddress
parse_addr(deleted)
parse_std_addrparseStandardAddress
parse_var_addr(deleted)
config_paramblockchain.configParam
raw_reservereserveToncoinsOnBalance
raw_reserve_extrareserveExtraCurrenciesOnBalance
send_raw_messagesendRawMessage
set_codecontract.setCodePostponed
randomrandom.uint256
randrandom.range
get_seedrandom.getSeed
set_seedrandom.setSeed
randomizerandom.initializeBy
randomize_ltrandom.initialize
dumpdebug.print
strdumpdebug.printString
dump_stkdebug.dumpStack
empty_listcreateEmptyListlisp-lists
conslistPrependlisp-lists
unconslistSplitlisp-lists
list_nextlistNextlisp-lists
carlistGetHeadlisp-lists
cdrlistGetTaillisp-lists
new_dictcreateEmptyMap
dict_empty?(d) or dotm.isEmpty
idict_set_refuse native maps
udict_set_refuse native maps
idict_get_refuse native maps
idict_get_ref?use native maps
udict_get_ref?use native maps
idict_set_get_refuse native maps
udict_set_get_refuse native maps
idict_delete?use native maps
udict_delete?use native maps
idict_get?use native maps
udict_get?use native maps
idict_delete_get?use native maps
udict_delete_get?use native maps
udict_setuse native maps
idict_setuse native maps
dict_setuse native maps
udict_add?use native maps
udict_replace?use native maps
idict_add?use native maps
idict_replace?use native maps
udict_set_builderuse native maps
idict_set_builderuse native maps
dict_set_builderuse native maps
udict_add_builder?use native maps
udict_replace_builder?use native maps
idict_add_builder?use native maps
idict_replace_builder?use native maps
udict_delete_get_minuse native maps
idict_delete_get_minuse native maps
dict_delete_get_minuse native maps
udict_delete_get_maxuse native maps
idict_delete_get_maxuse native maps
dict_delete_get_maxuse native maps
udict_get_min?use native maps
udict_get_max?use native maps
udict_get_min_ref?use native maps
udict_get_max_ref?use native maps
idict_get_min?use native maps
idict_get_max?use native maps
idict_get_min_ref?use native maps
idict_get_max_ref?use native maps
udict_get_next?use native maps
udict_get_nexteq?use native maps
udict_get_prev?use native maps
udict_get_preveq?use native maps
idict_get_next?use native maps
idict_get_nexteq?use native maps
idict_get_prev?use native maps
idict_get_preveq?use native maps
udict::delete_get_minuse native maps
idict::delete_get_minuse native maps
dict::delete_get_minuse native maps
udict::delete_get_maxuse native maps
idict::delete_get_maxuse native maps
dict::delete_get_maxuse native maps
pfxdict_get?prefixDictGettvm-dicts
pfxdict_set?prefixDictSettvm-dicts
pfxdict_delete?prefixDictDeletetvm-dicts

See also for accept_messageacceptExternalMessage:

  • Effects and nuances: /v3/documentation/smart-contracts/transaction-fees/accept-message-effects.
  • FunC stdlib reference: /v3/documentation/smart-contracts/func/docs/stdlib#accept_message.

A list of added functions

Tolk standard library has some functions missing in FunC but is pretty typical for everyday tasks.

Since Tolk is actively developed, and its standard library changes, it better considers the tolk-stdlib/ folder in sources here. Besides functions, there some constants were added: SEND_MODE_*, RESERVE_MODE_*, etc.

When FunC becomes deprecated, the documentation about Tolk stdlib will be rewritten entirely, anyway.

Remember that all the functions above are wrappers over the TVM assembler. If something is missing, you can quickly wrap any TVM instruction yourself.

Some functions became mutating, not returning a copy

FunCTolk
int flags = cs~load_uint(32);var flags = cs.loadUint(32);
......

Most FunC functions used with ~ tilda in practice now mutate the object. For example, if you used cs~load_uint(…), just use cs.loadUint(…), and everything is fine. But if you used cs.load_uint(…) to obtain a copy, you'll need to express it another way.

Read about mutability.

How does embedded stdlib work under the hood?

As told above, all standard functions are available out of the box. You need import for non-common functions (it's intentional), but still, no external downloads.

It works the following way.

The first thing the Tolk compiler does at the start is locate the stdlib folder by searching predefined paths relative to an executable binary. For example, if you launch the Tolk compiler from a package installed (e.g. /usr/bin/tolk), locate stdlib in /usr/share/ton/smartcont. You may pass the TOLK_STDLIB env variable if you have a non-standard installation. It's standard practice for compilers.

A WASM wrapper tolk-js also contains stdlib. So, when you take tolk-js or blueprint, all stdlib functions are still available out of the box.

JetBrains and VS Code IDE plugins also auto-locate stdlib to provide auto-completion. If you use blueprint, it automatically installs tolk-js; therefore, folder node_modules/@ton/tolk-js/ exists in your project file structure. Inside are common.tolk, tvm-dicts.tolk, and others.

Was this article useful?