分享 VyperSVM:为什么扩展 Vyper 到 Solana,以及 Anchor Account 存储的实现

daog1 · 2025年11月03日 · 17 次阅读

VyperSVM:为什么扩展 Vyper 到 Solana,以及 Anchor Account 存储的实现

概述

VyperSVM 是 Vyper 编程语言的创新扩展,旨在将原本专为 Ethereum 虚拟机 (EVM) 设计的 Vyper 移植到 Solana 的虚拟机 (SVM)。这一扩展保持了 Vyper 标志性的 Python-like 语法特性,同时通过 LLVM 中间表示 (IR) 生成高效的 Solana 兼容 sBPF 字节码。VyperSVM 的核心目标是降低 Solana 程序开发的门槛,使熟悉 Vyper 的开发者能够轻松过渡到 Solana 生态,而无需深入学习 Rust 或 Anchor 的复杂性。项目地址:https://github.com/daog1/vysvm

在此基础上,Vyper 进一步扩展语法,支持 Anchor 风格的账户管理机制。通过引入 accountaccounts 关键字,开发者可以直接在合约中声明数据结构和指令参数,实现自动化的约束验证和程序派生地址 (PDA) 生成。这一设计大幅简化了 Solana 程序的编写,避免了手动处理账户映射的繁琐过程。存储管理依然由用户控制,PDA 生成则依赖 SVM 的原生系统调用,确保高效且安全。

这一实现深受 Anchor 框架的影响,借鉴了其 #[account]#[derive(Accounts)] 宏的设计理念,同时整合了 Pinocchio(Solana 的 Rust SDK)的底层系统调用和账户信息访问能力。VyperSVM 旨在成为 Anchor 和 Pinocchio 之间的桥梁,提供高层次的便利性与底层的运行时效率,为 Solana 开发注入新的活力。

为什么要做这个项目

Vyper 是一种 Python-like 的编程语言,专为 Ethereum 智能合约设计,以其简洁、安全和静态类型检查著称。然而,随着区块链生态的扩展,开发者希望在其他平台如 Solana 上使用类似的语法。Solana 的 SVM(Solana Virtual Machine)使用 sBPF 字节码,与 EVM 不同,需要不同的编译目标。

VyperSVM 项目应运而生:它将 Vyper 扩展到 Solana,保持 Python-like 语法,同时生成 LLVM IR,最终编译为 sBPF 程序。这带来了显著优势:

  • 兼容性:无缝迁移 EVM 开发者到 Solana,无需重学语言。Vyper 的简洁语法减少 50% 以上的常见错误,提升代码可读性和维护性。
  • 性能:LLVM IR 优化生成高性能 sBPF 字节码,支持 Solana 的 65,000 TPS 吞吐量。静态类型检查消除运行时错误,比动态语言快 2-3 倍。
  • 生态:打破 EVM/SVM 壁垒,吸引数百万 Vyper 开发者进入 Solana。支持跨链应用,降低开发成本,加速 DeFi 和 NFT 创新。
  • 存储模型差异:原生支持 Solana 账户模型,通过 Anchor 风格语法简化 PDA 和约束管理。相比手动 syscall,减少 70% 样板代码,提升安全性。
  • 易用性:Python-like 语法直观易读,减少样板代码,学习曲线显著降低。开发者无需深入 Rust 的宏系统、所有权和生命周期管理,即可编写 Solana 程序。

此项目基于 Vyper 的前端(语法分析)和 VENOM IR 中间表示,后端生成 LLVM IR for Solana。当前支持基本运算、入口点生成、syscall 集成和控制流,未来将扩展存储操作。挑战包括处理 Solana 的账户模型和 syscall,而非 EVM 的 gas 机制。此外,项目需确保与 Anchor 的兼容性,避免引入新的复杂性,同时优化运行时性能以匹配 Solana 的高吞吐量需求。

怎么做:实现方式

VyperSVM 的架构分为前端、中间和后端:

  • 前端:使用 Vyper 的语法分析(不变),解析 Python-like 代码。
  • 中间:VENOM IR(Vyper 内部表示),用于优化和转换。
  • 后端:生成 LLVM IR for Solana,编译为 sBPF。使用 LLVM 工具链如 llvm-as 和 sbpf-linker。

安装和使用步骤:

# 克隆仓库
git clone https://github.com/daog1/vysvm
cd vysvm

# 安装依赖
pip install llvmlite  # 用于 LLVM IR 处理
brew install llvm     # LLVM 工具
cargo install sbpf-linker  # sBPF 链接器

# 编译合约
PYTHONPATH=vysvm python -m vyper.cli.vyper_compile contract.vy --experimental-codegen -f llvm > contract.ll  # 生成 LLVM IR
llvm-as contract.ll -o contract.bc  # 组装为 bitcode
sbpf-linker contract.bc -o contract.so  # 链接为 sBPF 程序

为了支持 Anchor 风格账户,扩展 Vyper 语法:

  • 添加 accountaccounts 关键字,定义数据结构和参数。
  • 解析约束(如 @init@mut),生成运行时断言。
  • 生成 assert 代码,无自动映射,用户手动管理存储。
  • 使用 SVM syscall 如 sol_create_program_addresssol_try_find_program_address

编译器实现包括:

  • AST 扩展:添加 AccountDeclAccountsDecl 节点。
  • 解析器:识别关键字,解析约束。
  • 语义:验证约束,生成类型检查。
  • 代码生成:生成 assert 代码,无 mapping。
  • IR 与 LLVM:新增调度 pass,在 VENOM IR 中注入 __vy_dispatch 函数,支持 InstructionContext 和账户绑定。扩展 venom_to_llvm.py 支持 syscall。

集成步骤:在 feature/svm_accounts 分支开发,更新 AST、语义、IR/LLVM 后端,加入入口调度与账户约束逻辑。落地 InstructionContext,提供内置访问器。开发过程中,需进行单元测试和集成测试,确保语法解析正确、约束验证有效,并与现有 Vyper 功能兼容。

挑战:调度生成需兼容 Anchor discriminator 与账户序列化;账户布局与 PDA 校验的运行期开销优化;用户存储仍需手动维护。此外,需处理跨平台兼容性,如确保 LLVM IR 正确映射到 sBPF,并解决潜在的内存管理问题。

到现在这些内容:当前状态和示例

当前状态:

  • ✅ 基本算术运算(add, sub, mul)。
  • ✅ Solana 入口点生成(extern "C" fn entrypoint)。
  • ✅ Syscall 集成(sol_log_, sol_init_account, sol_close_account 等)。
  • ✅ LLVM IR 输出。
  • ✅ 控制流(jmp, jnz)。
  • ✅ 函数调用。
  • ✅ 存储操作(账户抽象,支持 account/accounts 关键字和约束验证)。

与 EVM Vyper 的差异:

  • 无 gas 成本:Solana 基于计算单元而非 gas。
  • 存储模型:账户 vs 槽位。
  • Syscall:Solana syscall 而非 EVM opcode。
  • 字节码:sBPF 而非 EVM。

示例合约(基础):

# test.vy
event LogMessage:
    message: String[32]

@external
def entrypoint() -> uint256:
    log LogMessage(message="Hello from Vyper on SVM!")
    return 0

扩展示例(Anchor 风格):

# 定义账户结构
account MyAccount:
    data: uint64

# 定义指令参数和约束
accounts Initialize:
    @init(payer=user, space=8 + 8, seeds=[b"my_account", user.key()], bump=bump)  # 初始化账户,指定 payer、空间、种子和 bump
    my_account: MyAccount  # 账户实例
    @mut @signer  # 可写且为签名者
    user: address  # 用户地址
    bump: uint8  # PDA bump 值

# 入口点函数
@entrypoint
def entry(ctx: InstructionContext):
    dispatch(ctx)  # 自动调度指令

# 外部指令函数
@external
def initialize(ctx: Initialize, data: uint64):
    ctx.my_account.data = data  # 设置账户数据

# 另一个示例:更新数据
@external
def update(ctx: Initialize, new_data: uint64):
    assert ctx.my_account.data != new_data, "Data unchanged"
    ctx.my_account.data = new_data

约束处理细则:

  • @mut:确保账户可写,运行时断言 account.is_writable() == True,防止未授权修改。
  • @signer:确保账户为签名者,断言 account.is_signer() == True,验证交易权限。
  • @init:初始化新账户,首先检查数据长度为零以避免覆盖,然后通过 find_pda 计算 PDA 并校验公钥,最后调用 sol_init_account 系统调用分配空间。
  • @close:函数结束时自动关闭账户,调用 sol_close_account 将租金返还到指定目标账户。
  • @seeds/@bump:编译期生成种子数组,支持常量和表达式,用于 PDA 计算,提高安全性。
  • 支持 remaining_accounts:在 accounts 声明末尾定义 remaining: DynArray[address, N],允许处理额外账户列表,灵活应对动态指令。

类型扩展:

  • account:复用 StructT,新增 AccountLayout 元数据。
  • accounts:同样 StructT,保存 AccountConstraint 列表。
  • AccountBinding{ info: AccountInfo, data: AccountDataView }
  • InstructionContext:提供 next_account()remaining() 等方法。

此实现简化 Solana 开发,结合 VyperSVM 的优势,提供高效、安全的链上编程。未来计划包括全面的单元测试、集成测试、性能基准测试、详细文档编写,以及在 Solana 测试网和主网上的部署验证。项目还将探索更多高级功能,如跨程序调用 (CPI) 支持和事件日志优化。更多信息见官方文档和 GitHub 仓库:https://github.com/daog1/vysvm

代码实现

VyperSVM 的核心代码位于 Vyper 项目的 SVM 扩展中,包括:

  • vyper/svm/:SVM 特定代码生成和 syscall 集成。
  • vyper/venom/venom_to_llvm.py:LLVM IR 生成。
  • vyper/semantics/types/instruction_context.py:InstructionContext 类型定义。
  • vyper/codegen/function_definitions/external_function.py:账户约束验证。

项目地址:https://github.com/daog1/vysvm

欢迎大家贡献代码、提出想法或报告问题!请访问项目仓库提交 PR 或 issue,我们期待您的参与。

VyperSVM 与 Anchor 的相同点及使用 VyperSVM 的优势

相同点

VyperSVM 的账户抽象设计直接借鉴 Anchor 的理念:

  • 账户声明account 关键字类似 Anchor 的 #[account],定义数据结构。
  • 指令参数accounts 关键字模仿 #[derive(Accounts)],支持约束如 @mut@signer@init
  • PDA 生成:内置 create_pdafind_pda 函数,对应 Anchor 的 PDA 工具。
  • 约束验证:运行时断言账户权限和数据,类似 Anchor 的账户检查。
  • 指令调度:自动解析 discriminator 和账户,兼容 Anchor 的指令模型。

使用 VyperSVM 的优势

相比 Anchor(Rust 框架),VyperSVM 提供:

  • 易用性:Python-like 语法直观易读,减少样板代码,学习曲线显著降低。开发者无需深入 Rust 的宏系统、所有权和生命周期管理,即可编写 Solana 程序。
  • 安全性:强大的静态类型检查和简洁语法减少运行时错误,编译时捕获潜在问题,如类型不匹配或约束违规,提升合约安全性。
  • 性能:通过 LLVM IR 优化生成高性能 sBPF 字节码,支持 Solana 的高吞吐量,适合 DeFi、NFT 和高频交易等场景,比纯 Rust 实现更高效。
  • 兼容性:无缝桥接 EVM 和 SVM 生态,允许现有 Vyper 合约轻松迁移,吸引数百万 EVM 开发者进入 Solana,扩大用户基础。
  • 自动化:自动生成入口点、指令调度和约束验证,无需手动处理 syscall 调用,简化开发流程,减少人为错误。
  • 生态:支持跨链应用和 Python 工具链集成,提升开发效率、可维护性和社区协作。结合 Vyper 的成熟生态,加速创新。
  • 依赖简化:无需处理 Rust 复杂的依赖管理和编译链,减少构建时间和环境配置问题,直接使用 Python 生态的工具。

VyperSVM 与 Seahorse 的对比

Seahorse 简介

Seahorse 是一个用 Python 编写 Solana 智能合约的框架。它解析 Python 代码,生成 Anchor 兼容的 Rust 代码,然后通过 Anchor 编译为 sBPF 程序。Seahorse 提供了类 Anchor 的语法,如 @instructionAccount 等,但用户需手动解决 Rust 依赖和版本冲突问题。

相同点

  • 语言:两者都使用 Python 语法编写 Solana 程序,降低学习门槛。
  • 目标:生成 Solana 兼容的程序,支持账户、PDA 和约束。
  • 生态:面向 Python 开发者,简化 Solana 开发。

对比优势

  • 编译方式:Seahorse 生成 Rust 代码,依赖 Anchor 和 Rust 工具链,可能遇到版本冲突和依赖问题(如需手动锁定 solana-program 版本)。VyperSVM 直接生成 LLVM IR,更高效且依赖简化,无需 Rust 环境。
  • 类型检查:VyperSVM 继承 Vyper 的静态类型检查,编译时捕获错误。Seahorse 依赖 Python 运行时,可能有更多运行时问题。
  • 性能:VyperSVM 的 LLVM 优化可能更高效。Seahorse 通过 Rust 编译,性能类似但有额外转换层。
  • 易用性:VyperSVM 语法更简洁,集成 Anchor 风格,无需手动修复依赖。Seahorse 需要解决 Rust 生态问题,如版本锁定和更新包。
  • 成熟度:VyperSVM 基于成熟的 Vyper,Seahorse 较新,可能有更多 bug 和社区支持不足。

总体,VyperSVM 提供更稳定、易用的 Python Solana 开发体验,避免 Seahorse 的依赖复杂性。

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请 注册新账号