RUNVM 规格
目前,TVM 中的代码无法调用 "沙盒 "中的外部不信任代码。换句话说,外部代码始终可以不可逆地更新代码、合约数据或设置操作(如发送所有资金)。
RUNVM
指令允许生成一个独立的虚拟机实例,运行所需的代码并获取所需的数据(堆栈、寄存器、耗气量等),而没有污染调用者状态的风险。以安全的方式运行任意代码可能对 v4 风格插件、Tact 的init
风格子合约计算等有用。
xxxxxxxxxxxxx Fift 语法 | xxxxxxxxxxxxxxxxx 堆栈 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 说明 |
---|---|---|
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] | 以代码 code 和堆栈 x_1...x_n 运行子虚拟机。返回生成的堆栈 x'_1...x'_m 和 exitcode。其他参数和返回值由标志启用,见下文。 |
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] | 相同,但会从堆栈中弹出标志。 |
标志类似于 fift 中的 runvmx
:
+1
:设置 c3 为代码+2
:运行代码前推送一个隐式 0- +4": 从堆栈中取出
c4
(持久数据),返回其最终值 +8
:从堆栈中取gas限制g_l
,返回消耗的gasg_c
+16
:从堆栈中取出c7
(智能合约上下文)+32
:返回c5
的最终值(操作)+64
:从堆栈中弹出硬gas限制(由ACCEPT启用)g_m
+128
:"孤立的 gas 消耗"。子虚拟机将有一组单独的访问 cell 和一个单独的 chksgn 计数器。+256
:弹出整数r
,从顶部返回整数r
值:- 如果 RUNVM 调用成功且 r 已设置,则返回 r 个元素。如果 r 未设置,则返回所有元素;
- 如果 RUNVM 成功,但堆栈中没有足够的元素(堆栈深度小于 r),则在子虚拟机中视为异常,exit_code=-3,exit_arg=0(因此 0 将作为唯一的堆栈元素返回);
- 如果 RUNVM 异常失败 - 只返回一个元素 - exit arg(不要误认成 exit_code );
- 如果是 OOG,exit_code = -14,exit_arg 为 gas 量。
gas成本:
- 66 gas
- 每向子虚拟机提供一个堆栈元素,就产生 1 个 gas (前 32 个免费)
- 子虚拟机每返回一个堆栈元素,就产生 1 个 gas (前 32 个免费)