RUNVM Specification
Currently, TVM does not provide a mechanism for executing external untrusted code within a secure sandbox environment. In other words, any external code invoked has unrestricted access and can permanently modify the contract's code and data or trigger actions such as transferring all funds.
The RUNVM
instruction creates an isolated VM instance, allowing code execution while safely retrieving data such as stack state, registers, and gas consumption. This ensures the caller's state remains unaffected. This allows arbitrary code to run safely, which is helpful for v4-style plugins, Tact's init
-style subcontract calculations, and similar use cases.
Fift syntax | Stack | Description |
---|---|---|
flags RUNVM | x_1 ... x_n n code [r] [c4] [c7] [g_l] [g_m] - x'_1 ... x'_m exitcode [data'] [c4'] [c5] [g_c] | Executes a child VM with the given code and stack values x_1 ... x_n . Returns the modified stack x'_1 ... x'_m along with an exit code. Flags determine other arguments and return values. See details below. |
RUNVMX | x_1 ... x_n n code [r] [c4] [c7] [g_l] [g_m] flags - x'_1 ... x'_m exitcode [data'] [c4'] [c5] [g_c] | It is the same as RUNVM but retrieves flags from the stack. |
Flags operate similarly to RUNVMX
in Fift:
+1
: setsc3
to code.+2
: pushes an implicit0
before executing the code.+4
: takes persistent datac4
from the stack and returns its final value.+8
: takes the gas limitg_l
from the stack and returns the consumed gasg_c
.+16
: takesc7
(smart contract context) from the stack.+32
: returns the final value ofc5
(actions).+64
: pops the hard gas limitg_m
enabled byACCEPT
from the stack.+128
: enables "isolated gas consumption", meaning the child VM maintains a separate set of visited cells and achksgn
counter.+256
: pops an integerr
and ensures exactlyr
values are returned from the top of the stack:- If
RUNVM
call succeeds andr
is set, it returnsr
elements. Ifr
is not set, it returns all available elements. - If
RUNVM
is successful but lacks elements on the stack, meaning the stack depth is less thanr
, it is treated as an exception in the child VM. Theexit_code
is set to-3
, andexit_arg
is set to0
, so0
is returned as the only stack element. - If
RUNVM
fails with an exception, only one element is returned,exit_arg
, which should not be confused withexit_code
. - In the case of running out of gas,
exit_code
is set to-14
, andexit_arg
contains the amount of gas.
- If
Gas cost:
- 66 gas;
- 1 gas for each stack element passed to the child VM (the first 32 elements are free);
- 1 gas for each stack element returned from the child VM (the first 32 elements are free).