Solana 技术训练营 2026

2026年01月09日更新 196 人订阅
课程介绍
C4: Solana 程序开发入门: 简单链上数据存储程序扩展为可交易的代币程序
C6:Anchor 入门: SPL 与 Token 2022

使用 Surfpool 进行测试

Surfpool 101

测试依赖跨程序调用(CPI)的 Solana 程序,传统上需要开发者从主网导出账户和程序,然后将其上传到本地验证器。

这种方法适用于少量账户,但在测试像 Jupiter 这样复杂的程序时完全不可行,因为它可能依赖于 40 多个账户和 8 个以上的程序。

Surfpool 通过以下功能解决了这个问题,使开发者能够使用按需获取的主网账户在本地模拟程序:

  • 自定义系统变量:时间旅行(在任何历史 slot 或时间戳测试您的程序)、暂停时钟或停止区块生产
  • 修改账户数据:设置 SOL 供应量(总量、流通量和非流通量)、在程序之间传输账户数据,或更新账户核心数据和代币账户信息
  • 分析链上数据:分析交易的计算单元、账户变更和执行详情,然后通过签名、UUID 或标签检索详细的分析报告

什么是 Surfpool

Surfpool 是一个全面的 SDK 和工具套件,而 Surfnet 是它创建的本地 Solana 网络。可以将 Surfpool 视为您的开发环境,而 Surfnet 则是运行在其中的区块链网络。

Surfnet 是 solana-test-validator 的直接替代品,专为 Solana 开发者提供最佳开发体验而设计。

由 TxTx 团队开发,Surfpool 无缝将基础设施即代码(Infrastructure as Code)集成到基于 Anchor 的项目中,从而实现可复现、可审计且安全的部署,无论是到私有还是公共的 Solana 网络。

第一步

运行 Surfnet 所需的一切都包含在 Surfpool SDK 中。由于安装因操作系统而异,请根据您的具体设置,参阅官方的安装页面

安装 Surfpool SDK 后,使用以下命令启动 Surfnet:

surfpool start

这将在标准本地验证器端口(http://127.0.0.1:8899)上启动 Surfnet,并显示一个终端用户界面,其中包括:

  • 槽位和纪元:当前执行的槽位每 400 毫秒自动处理一次。使用 Tab 手动前进到下一个槽位,或使用 空格键 暂停/恢复自动区块生产。
  • 交易日志:带有时间戳的活动流,显示所有执行的交易。

如果需要基于浏览器的体验,请通过此链接连接到 Surfpool Studio。

⚠️ Surfpool Studio 包含所有终端用户界面功能,并提供额外的功能,例如时间旅行和为任何铸币账户添加代币。

部署程序

设置 Surfnet 后,部署您的程序并开始构建。

Anchor 程序:使用 anchor deploy,并将您的 Anchor.toml 配置为 [programs.localnet]

Pinocchio 程序:通过 Solana CLI 部署,并将您的配置设置为 localnet:solana program deploy ./target/deploy/your_program.so --program-id ./target/deploy/your_program-keypair.json

⚠️ 在 Anchor Workspace 中运行 surfpool start,可提示您使用基础设施即代码(Infrastructure as Code),以便在 Surfnet 上无缝自动部署您的程序。

测试程序

部署到 localnet 后,通过定位本地验证器连接到 Surfnet:

import { Connection } from "@solana/web3.js";

const connection = new Connection("http://localhost:8899", "confirmed");

高级功能

Surfnet 不仅仅是将主网复制到本地网络,它还允许您通过更改账户、系统变量和区块链状态来增强和修改 Solana 的核心功能。

这些修改通过对 Surfnet 的 RPC 调用实现,既可以通过编程方式(用于自动化测试环境)进行更改,也可以通过终端命令(用于一次性操作)进行更改。

在代码中执行 RPC 调用,请使用:

const surfnetCall = {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "<surfnet-method>",
    "params": [<surfnet-method-params]
}

await fetch(connection.rpcEndpoint, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify(surfnetCall)
});

在终端中执行 RPC 调用,请使用:

curl -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "jsonrpc": "2.0",
        "id": 1,
        "method": "<surfnet-method>",
        "params": [<surfnet-method-params]
    }' \
    http://localhost:8899

自定义系统变量

时间旅行

使用 surfnet_timeTravel 方法跳转到区块链历史中的任意时间点。这对于测试您的程序在不同网络状态下的表现或重现特定时间发生的错误非常有价值。

指定以下之一:absoluteEpochabsoluteSlot 或 absoluteTimestamp,如下所示:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "surfnet_timeTravel",
  "params": [
    {
      "absoluteEpoch": 0
    }
  ]
}

暂停和恢复区块生成

控制区块进程以逐步调试交易或测试时间敏感的逻辑。使用 surfnet_pauseClock 暂停区块生成,使用 surfnet_resumeClock 恢复:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "surfnet_pauseClock", // or "surfnet_resumeClock"
  "params": []
}

修改账户数据

设置 SOL 参数

配置 SOL 供应参数以测试经济场景或边界情况。

surfnet_setSupply 方法接受 circulatingnonCirculatingnonCirculatingAccounts 和 total 参数:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "surfnet_setSupply",
  "params": [
    {
      "circulating": 1000000000,
      "nonCirculating": 1000000000,
      "nonCirculatingAccounts": [],
      "total": 1000000000
    }
  ]
}

在程序之间转移账户

使用 surfnet_cloneProgramAccount 克隆程序账户,从一个程序转移到另一个程序。这对于测试程序升级或在不同程序版本之间迁移状态非常有用。

需要同时提供 destinationProgramId 和 sourceProgramId

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "surfnet_cloneProgramAccount",
  "params": [
    {
      "destinationProgramId": "string",
      "sourceProgramId": "string"
    }
  ]
}

更新账户数据

⚠️ 使用以下方法更新已存在的账户将会覆盖账户状态

使用surfnet_setAccount修改任何账户的属性,包括 lamports、数据、所有者和可执行状态。

该方法需要一个pubkey,并接受以下可选字段:dataexecutablelamportsowner 和 rentEpoch

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "surfnet_setAccount",
  "params": [
    "1111111QLbz7JHiBTspS962RLKV8GndWFwiEaqKM",
    {
      "data": "0x123456",
      "executable": false,
      "lamports": 1000000000,
      "owner": "11111111111111111111111111111111",
      "rentEpoch": 0
    }
  ]
}

此外,对于代币账户的修改,可以使用专门的surfnet_setTokenAccount方法,该方法简化了代币账户数据的更改。

需要ownermint参数,并接受以下可选字段:amountcloseAuthoritydelegatedelegateAmountstate 和 tokenProgram

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "surfnet_setTokenAccount",
  "params": [
    "1111111ogCyDbaRMvkdsHB3qfdyFYaG1WtRUAfdh",
    "11111112D1oxKts8YPdTJRG5FzxTNpMtWmq8hkVx3",
    {
      "amount": 1000000000,
      "closeAuthority": "111111131h1vYVSYuKP6AhS86fbRdMw9XHiZAvAaj",
      "delegate": "11111112cMQwSC9qirWGjZM6gLGwW69X22mqwLLGP",
      "delegatedAmount": 1000000000,
      "state": "initialized"
    },
    "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
  ]
}
点赞 0
收藏 0
分享

0 条评论

请先 登录 后评论