You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solana Anchor调用lamports报错如何划转SOL至卖家账户

报错根因

该错误核心原因是 Anchor 框架中 Account<'info, T> 类型本身没有直接暴露 lamports() 方法和 lamports 字段,这类属性/方法属于底层 AccountInfo 类型。你当前持有的是 Box<Account<'info, ListingConfig>> 类型引用,直接调用 lamports 相关方法自然会匹配不到。
除此之外你的原有逻辑还有3个隐含问题:

  • 手动修改lamports值再调用系统程序转账的写法不符合Solana账户操作规范,容易触发运行时错误
  • 代码中使用了未定义的lamports变量,会触发第二个编译错误
  • listing_config账户缺少mut约束,修改余额时会触发权限校验失败
修复方案

优先使用Anchor原生封装的账户关闭API,不需要手动操作lamports、手动构造转账指令,该API会自动完成:将账户内所有剩余SOL划转至指定接收账户、把账户所有权交还给系统程序、重置账户数据长度为0的全流程,符合Solana账户关闭标准。

第一步:修改账户约束

给listing_config字段添加mut标记,开放账户修改权限:

/// The Listing Config used for listing settings
#[account(
    mut,
    seeds=[
        LISTING_CONFIG.as_bytes(),
        seller.key().as_ref(),
        auction_house.key().as_ref(),
        token_account.key().as_ref(),
        auction_house.treasury_mint.as_ref(),
        token_mint.key().as_ref(),
        &token_size.to_le_bytes()
    ],
    bump=listing_config.bump,
)]
pub listing_config: Box<Account<'info, ListingConfig>>,

第二步:替换错误的关闭逻辑

删除invoke_signed调用后所有手动操作lamports、手动构造转账指令的代码,替换为原生close调用:

invoke_signed(&ix, &cpi_accounts.to_account_infos(), &[&auctioneer_seeds])?;

// 关闭ListingConfig账户,账户内所有留存SOL自动转入卖家账户
listing_config.close(ctx.accounts.seller.to_account_info())?;

Ok(())
特殊场景手动操作Lamports写法(不推荐)

如果因业务特殊需求不能使用原生close方法,需要先将Account类型转换为底层AccountInfo再操作lamports:

let listing_config_acct = listing_config.to_account_info();
let seller_acct = ctx.accounts.seller.to_account_info();

let config_lamports = listing_config_acct.lamports();
**listing_config_acct.lamports.borrow_mut() = 0;
**seller_acct.lamports.borrow_mut() += config_lamports;

注意:手动修改lamports必须严格保证所有账户增减的lamports总和为0,否则会直接触发链上运行时错误,非必要不要手动操作。

内容的提问来源于stack exchange,提问作者Asjad khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 13:06:23