Skip to main content

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 RUNVMx_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.
RUNVMXx_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: take c4 from stack (persistent data), return its final value
  • +8: take gas limit g_l from stack, return consumed gas g_c
  • +16: take c7 from stack (smart-contract context)
  • +32: return final value of c5 (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 integer r, return exactly r 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)

See Also