作弊码是绕过正常交易流程的状态变更操作。它们无需消耗 blockhash 或支付费用即可即时执行,非常适合用于测试环境的初始化设置。
在 Rust 中,作弊码位于 Surfnet::cheatcodes() 下。在 JS 中,它们是 Surfnet
实例上的直接方法。
充值 SOL
fundSol / fund_sol 用于设置任意账户的 lamport 余额,若账户不存在则自动创建。
use surfpool_sdk::{Pubkey, Surfnet};let surfnet = Surfnet::start().await?;let cheats = surfnet.cheatcodes();let wallet = Pubkey::new_unique();cheats.fund_sol(&wallet, 1_000_000_000)?;// Fund several accounts in one call.let bob = Pubkey::new_unique();let carol = Pubkey::new_unique();cheats.fund_sol_many(&[(&bob, 2_000_000_000), (&carol, 3_000_000_000)])?;
充值代币
fundToken / fund_token 通过计算关联的 token
account 向钱包铸造代币,如有需要则自动创建该账户并设置金额。
Token-2022 mints
默认情况下,fundToken 使用经典的 SPL Token program。对于 Token-2022
的铸造,请将 Token-2022 程序 ID
(TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb) 作为最后一个参数传入。
use surfpool_sdk::{Pubkey, Surfnet};let surfnet = Surfnet::start().await?;let cheats = surfnet.cheatcodes();let wallet = Pubkey::new_unique();let mint: Pubkey = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v".parse().unwrap();// Classic SPL Token mint.cheats.fund_token(&wallet, &mint, 5_000_000, None)?;// Token-2022 mint — pass the program id explicitly.let token_2022: Pubkey = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb".parse().unwrap();cheats.fund_token(&wallet, &mint, 5_000_000, Some(&token_2022))?;// Fund many wallets with the same mint.let mob = vec![Pubkey::new_unique(), Pubkey::new_unique()];cheats.fund_token_many(&mob.iter().collect::<Vec<_>>(), &mint, 1_000_000, None)?;
若要在不充值的情况下推导 ATA,请使用 getAta / get_ata:
let ata = cheats.get_ata(&wallet, &mint, None);
设置任意账户状态
setAccount
方法可在一次调用中为任意账户写入 lamport、所有者及原始数据字节。Rust
SDK 还额外提供了 SetAccount 构建器,用于处理 rent_epoch 和 executable
等更高级的字段。
use surfpool_sdk::cheatcodes::builders::SetAccount;use surfpool_sdk::{Pubkey, Surfnet};let surfnet = Surfnet::start().await?;let cheats = surfnet.cheatcodes();let address = Pubkey::new_unique();let owner = Pubkey::new_unique();// Direct method.cheats.set_account(&address, 500_000, &[1, 2, 3], &owner)?;// Builder when you need finer control.cheats.execute(SetAccount::new(address).lamports(500_000).owner(owner).data(vec![1, 2, 3]).rent_epoch(0).executable(false),)?;
修改 Token Account 字段
setTokenAccount 用于更新现有 token
account 的高级字段——委托方、状态、关闭权限及委托金额。当单独使用 fundToken
不足以满足需求时,请使用此方法。
use surfpool_sdk::cheatcodes::builders::SetTokenAccount;use surfpool_sdk::{Pubkey, Surfnet};let cheats = Surfnet::start().await?.cheatcodes();let owner = Pubkey::new_unique();let mint: Pubkey = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v".parse()?;let delegate = Pubkey::new_unique();cheats.execute(SetTokenAccount::new(owner, mint).amount(2_000_000).delegate(delegate).delegated_amount(500_000).state("initialized"),)?;// Later: clear the delegation.cheats.execute(SetTokenAccount::new(owner, mint).clear_delegate())?;
将账户重置为上游状态
resetAccount 会丢弃所有本地修改,并从上游 RPC 重新获取账户数据。传入
includeOwnedAccounts: true
可同时重置目标所拥有的所有账户——在重置程序及其所有 PDA 时非常实用。
需要 `remoteRpcUrl` 才能重新获取
在离线 Surfnet 环境中,resetAccount
会清除本地副本,但由于没有上游数据源,无法重新获取数据。请在启动时配置
remoteRpcUrl,以使重置操作能够恢复上游状态。
use surfpool_sdk::cheatcodes::builders::ResetAccount;use surfpool_sdk::{Pubkey, Surfnet};let cheats = Surfnet::start().await?.cheatcodes();let token_program: Pubkey = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA".parse()?;cheats.execute(ResetAccount::new(token_program).include_owned_accounts(true),)?;
实时账户流
streamAccount
将账户注册为从上游 RPC 进行后台轮询。本地 Surfnet 副本将与主网保持同步,无需测试代码显式轮询。结合
includeOwnedAccounts 可对某个程序所拥有的所有 PDA 进行数据流传输。
需要 `remoteRpcUrl`
streamAccount 仅在以 remoteRpcUrl(或 Rust 中的 remote_rpc_url)启动的
Surfnet 上有效。若没有上游 RPC,则没有可供流式传输的数据源,调用将返回错误。
use surfpool_sdk::cheatcodes::builders::StreamAccount;use surfpool_sdk::{Pubkey, Surfnet};let cheats = Surfnet::builder().remote_rpc_url("https://api.mainnet-beta.solana.com").start().await?.cheatcodes();let oracle: Pubkey = "H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG".parse()?;cheats.execute(StreamAccount::new(oracle).include_owned_accounts(false))?;
Cheatcode 构建器(Rust)
Rust SDK 在 surfpool_sdk::cheatcodes::builders
下提供了类型化构建器,适用于便捷方法无法满足需求的场景。每个构建器均实现了
CheatcodeBuilder trait,并通过 cheats.execute(builder) 执行。
| 构建器 | 构造函数 | 常用设置方法 |
|---|---|---|
SetAccount | new(address: Pubkey) | lamports, data, owner, rent_epoch, executable |
SetTokenAccount | new(owner: Pubkey, mint: Pubkey) | amount, delegate, clear_delegate, state, delegated_amount, close_authority, clear_close_authority, token_program |
ResetAccount | new(address: Pubkey) | include_owned_accounts(bool) |
StreamAccount | new(address: Pubkey) | include_owned_accounts(bool) |
DeployProgram | new(program_id: Pubkey), from_keypair_path(path) | so_path, so_bytes, idl_path |
Is this page helpful?