Filecoin Virtual Machine(FVM)
1. 简介
FVM 是 Filecoin 的虚拟机,不太懂区块链的话可以简单认为和 eth 的 EVM 类似(完全不懂这个就可以不看本文啦),但其实 FVM 更像 dfinity 的 WASM 容器,并且FVM 也是用 WASM 实现的.Filecoin 预计在2022年6月左右引入该功能.这种幅度的变化会影响许多组件:
- 链状态层,用于存储和加载用户提供的代码.
- 执行层, 用于编译/解释用户提供的代码,运行设计此类代码的状态转换,并验证结果.
- gas 模型,用于保护网络并面对用户可编程代码时调节链容量需求/供应动态.
- 预先存在的baseline协议,以促进针对系统功能的可编程性.
Filecoin 虚拟机(FVM)是一个基于IPLD(简单描述:将文件分为固定大小的trunk,然后所有trunk构建一个merkle树,多个版本的文件可以共用相同的trunk,甚至于可以像git一样,新trunk存储旧trunk和对旧trunk的修改就好)的 WASM执行层,能够运行任意用户提供的代码.FVM取代了现有的非可编程执行层 Legacy VM.native actors的逻辑(相当于Filecoin中的智能合约)部署为Wasm 字节码.针对非Filecoin 运行时(例如evm)的foreign actors也通过运行时模拟得到支持.
本文是对FIP-0030的归纳总结,FIP-0030 为FVM 提供了一个参考的架构,并结识了它各种组件:(a) Machine,(b) Call Manager,(c) Invocation Container, (d)Kernel,(e)Syscalls 和 (f)Externs.定义了actor 代码必须遵守的contract、系统调用可用的目录、IPLD状态操作的机制以及进一步的技术细节.
2. FVM 规范
2.1. 参考实现
filecoin-project/ref-fvm是fvm的一个参考实现,和本规范配套.
2.2. 上下文和 VM 接口
在 Filecoin 中 VM 是执行层中负责在状态树上应用transactions的组件.这些transactions被封装在消息中,有两种消息:
- 显示消息 由secp256k1 或 BLS 账户actors 发送到链上,带有签名以证明其真实性
- 隐式消息 由系统生成,不会出现在链上,也没有签名.比如包括cron ticks 和 reward cycles
VM 实例输入参数简单示范
let machine = Machine::new(
epoch, // 链 epoch
base_fee, // 当前有效的基本费用
base_circ_supply, // 基础循环供应
nv, // 网络版本
state_root, // 初始状态树的根 CID
blockstore, // blockstore 在执行期间加载和保存对象
)
然后将消息应用到机器.每个应用程序都会生成一个返回对象,其中至少包含一个消息回执,一个矿工惩罚和一个矿工tip.
let ApplyRet { receipt, penalty, tip } := machine.apply_message(msg1);
let ApplyRet { receipt, penalty, tip } := machine.apply_message(msg2);
let ApplyRet { receipt, penalty, tip } := machine.apply_message(msg3);
消息回执记录在链上.它保存交易的退出代码、使用的gas,并且(可选)仅在成功时返回数据.
惩罚和 tip 是协议的加密经济规则用来计算块生产者的块奖励数量
一旦调用者处理完所有应用消息,就会刷新机器.这个操作将会计算最终状态根.此操作还可能将新写入的块提交到blockstore
let final_state_root = machine.flush();
2.3. 责任
FVM 讲消息应用到状态树,它并不负责推进链本身.具体而言,主要负责:
- 加载链上的Wasm 模块并将他们编译为机器码
- 对提供的消息执行预先检查
- 跨actors 路由呼叫, 通过呼叫管理器抽象
- 处理来自actors的系统调用,并交付结果
- 必要时与外部环境(filecoin 客户端)交互
- 管理IPLD状态读取和写入操作
- 实例化<核心技术设计>中描述的对象堆栈以此应用消息
2.4. 核心技术设计
该图可以作为FVM技术设计的参考
Machine
Machine 是FVM在具体epoch的实例化,在特定的状态根上,准备好接收消息以执行
Call Manager
Call Manager 协议奥处理给定消息所涉及的调用堆栈.这需要配置和销毁Invocation Container,跟踪gas使用情况,并在超过gas限制时停止执行
Invocation Container
Invocation Container(IC)是在单个调用的上下文中运行actor 代码的环境/沙箱.同一actor 的冲入或递归将衍生出另一个IC.
IC 是FVM实现合约的Wasm 引擎的一个实例.合约包括:
- 可用sysCalls作为可导入的主机提供的函数
- 表示跨FVM边界的数据的共享类型
- actore 拥有的内存,用于在Syscalls中交换数据
- 透明的gas 核算和自动执行暂停
- (未来)社区通过一些治理过程"blessed"普及Wasm模块的动态连接,以减少actore 字节码大小(例如FVM SDK、IPLD编解码器等)
Syscalls
Syscall是 Wasm 导入提供给actor的函数,允许它与Externs环境交互,并调用在客户端执行(而不是Wasm)的性能更高的复杂操作(例如加密原语)
Kernel
Kernel 是有Call Manager 创建并注入 Invocation Container的对象,它处理Syscalls,并存储调用范围内的状态
Externs
和SYScalls是FVM 提供给actor的函数蕾西,Externs是node 提供给FVM的函数.根据所使用的编程语言,Externs 层可能只是逻辑(如果客户端和FVM都是用相同的语言编写的),或者是FFI 形式的物理表示.
2.5. actors
actors 相当于其他网络中的只能合约: 他们是存在于链上的逻辑片段,可以通过 message 触发.
2.5.1 actor type
我们区分了3中类型的actor:
- Built-in actors
- Native actors
- Foreign actors
built-in actors
built-in actors 是协议定义的actor 类型.到目前为止,这些actor 与 legacy VM一起发布并与其紧密集成.对于Lotus,这些actor 位于 filecoin-project/specs-actors
通过采用通用的、可以值得执行字节码格式,所有Filecoin客户端都可以依赖编译为Wasm自己吗的单个代码库.这加快了协议开发,缩短了协议升级时间.并减少了协调开销.
该代码库位于 filecoin-project/builtin-actors, FIP-0031 通过状态迁移提出了其在网络中的标准化.
这种方法有一些实际意义
- 规范actors 成为filecoin的公共代码库,核心开发人员围绕它集中开发工作.
- Filecoin 客户端会将规范的Wasm 字节码嵌入到他们的二进制文件中.具体机制取决于实现.
- 网络升级将同意在升级时期迁移到内置参与者的确切CodeCID
下面列出了所有built-in actors 的类型
/// The bundled CAR embedded as a byte slice for easy consumption by Rust programs.
///
/// The root CID of the CAR points to an actor index data structure. It is a
/// CBOR-encoded IPLD Map<String, Cid>, enumerating actor name and their
/// respective CIDs.
///
/// The actor names are values from this enumeration:
///
/// - "account"
/// - "cron"
/// - "init"
/// - "market"
/// - "miner"
/// - "multisig"
/// - "paych"
/// - "power"
/// - "reward"
/// - "system"
/// - "verifreg"
///
/// The Filecoin client must import the contents of CAR into the blockstore, but
/// may opt to exclude the index data structure.
pub const BUNDLE_CAR: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/bundle/bundle.car"));
Native user-defined actors
Native user-defined actors 定义的 actor 是专门为 FVM 运行时编写的 actor.
用户可以使用任何可以编译成 Wasm 字节码的编程语言编写本地用户定义的Wasm.但是一些特定语言的开销(例如运行时,垃圾收集,stdlib等)可能会导致Wasm字节码大小和执行开销过大,从而转化为更高的gas成本.使用Rust 编写Native user-defined actors是合理的选择,它缺乏运行时并可以具有通过no_std省略stdlib的能力和及其成熟的Wasm支持.
Foregin actors
Foregin actors 针对非FVM 运行时的智能合约或程序,通过仿真在可以在Filecoin网络中运行.
运行Foregin actors 的能力对于跨链互操作性很有用, 并将Filecoin的范围和实用性扩展到其他区块链,使他们能够更无缝地访问filecoin 网络的存储能力.
我们目标第一个Foregin actors 通过部署EVM 字节码支持eth 智能合约.这允许将现有经过实战考验的eth 智能合约直接且相对无风险地移植到Filecoin 网络.
每个外部运行时都是一个actor 类型,有CodeCID标识.外部运行时的安装就像任何其他actor 类型一样.Foregin actor 实例是通过 InitAcotr 构建的.
总结
对filecoin 来说是很重要的一步,但在整个公链行业里只能说是平平无奇了,我个人还是推崇definity.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构