RUNVM Specification
Currently there is no way for code in TVM to call external untrusted code "in sandbox". In other words, external code always can irreversibly update code, data of contract, or set actions (such as sending all money).
RUNVM
instruction allows to spawn an independent VM instance, run desired code and get needed data (stack, registers, gas consumption etc) without risks of polluting caller's state. Running arbitrary code in a safe way may be useful for v4-style plugins, Tact's init
style subcontract calculation etc.
xxxxxxxxxxxxx Fift syntax | xxxxxxxxxxxxxxxxx Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 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] | Runs child VM with code code and stack x_1...x_n . Returns the resulting stack x'_1...x'_m and exitcode.Other arguments and return values are enabled by flags, see 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] | Same thing, but pops flags from stack. |
Flags are similar to runvmx
in fift:
+1
: set c3 to code+2
: push an implicit 0 before running the code+4
: takec4
from stack (persistent data), return its final value+8
: take gas limitg_l
from stack, return consumed gasg_c
+16
: takec7
from stack (smart-contract context)+32
: return final value ofc5
(actions)+64
: pop hard gas limit (enabled by ACCEPT)g_m
from stack+128
: "isolated gas consumption". Child VM will have a separate set of visited cells and a separate chksgn counter.+256
: pop integerr
, return exactlyr
values from the top:- If RUNVM call successful and r is set, it returns r elements. If r not set - returns all;
- if RUNVM successful but there is not enough elements on stack (stack depth less than r) it is considered as exception in child VM, with exit_code=-3 and exit_arg=0 (so 0 is returned as only stack element);
- if RUNVM fails with exception - only one element is returned - exit arg (not to be mistaken with exit_code);
- in case of OOG, exit_code = -14 and exit_arg is amount of gas.
Gas cost:
- 66 gas
- 1 gas for every stack element given to the child VM (first 32 are free)
- 1 gas for every stack element returned from the child VM (first 32 are free)