Skip to main content
本页内容由 AI 自动翻译,所有内容以英文版本为准。查看英文版 →
租金是可退款的保证金,不是费用。SIMD-0437 通过五个独立的特性门分阶段降低每个账户必须持有的余额。在某个步骤之前创建的账户保持其被资助时的余额,因此每个步骤都会使它们资金过剩。SPL Token 和 Token-2022 程序可以通过 WithdrawExcessLamports 返还这个差额,而无需关闭账户或触及其代币余额。没有过期时间——超额资金会一直留在你自己的账户中,直到你选择移动它。
如果你是 Solana 账户资金模型的新手,请先阅读账户模型。

租金实际上是什么

Solana 上的每个账户都持有一笔 SOL 保证金,其大小由它占用的空间决定。这笔钱不会被花费——当账户关闭时会全额返还。公式是:
ACCOUNT_STORAGE_OVERHEAD 是每个账户都要支付的固定 128 字节,无论其负载如何。lamports_per_byte 是 SIMD-0437 改变的网络范围常数。 因此,标准的 165 字节 SPL 代币账户的成本一直是 (128 + 165) × 6,960 = 2,039,280 lamports——这就是你在钱包打开关联代币账户时看到扣除的约 0.00203928 SOL。

SIMD-0437 改变了什么

SIMD-0437 将 lamports_per_byte 从 6,960 削减到 696——减少 90%——通过五个独立的特性门分阶段推出,以便验证者可以逐步吸收状态增长的影响。 步骤 1 在 2026 年 9 月 3 日在主网激活。步骤 2 在同一天到达测试网,预计在 2026 年 9 月中旬到达主网;步骤 3-5 保留给 Agave 4.4,预计在 2026 年 11 月左右。将时间表视为可能变化——基金会表示如果状态增长表现不佳会暂停推出——并从集群读取实时值而不是硬编码。
SIMD-0437 依赖于 SIMD-0194,后者弃用了租金豁免阈值”以避免在特性激活时设置租金参数时进行不必要的浮点数学”。实际上,Rent sysvar 现在携带 lamports_per_byte_year = 6,333 和 exemption_threshold = 1.0,而不是产生 6,960 的旧 3,480 × 2 分割。不要自己乘以这两个字段——调用 getMinimumBalanceForRentExemption 并让集群回答。

为什么现有账户持有过多资金

降低常数改变了账户需要的东西。它不改变账户拥有的东西。在 6,960 lamports 每字节时资助的账户在步骤 1 激活后保持该余额,因此它的资金过剩为:
对于步骤 1 后的 165 字节 SPL 代币账户,这是 293 × (6,960 − 6,333) = 183,711 lamports,或每个账户约 0.000184 SOL。携带扩展的 Token-2022 账户更大,因此它持有的比例更多——182 字节的账户资金过剩 310 × 627 = 194,370 lamports。 单个来看这是微不足道的。一个多年来与数百个代币交互过的钱包持有的是这个数字的有意义的倍数,到步骤 5 时,每个 165 字节的账户在其最低值之上有 1,835,352 lamports(约 0.00184 SOL)。

哪些账户可以返还它

程序拥有的账户中的超额 lamports 只能由该程序移动。因此,你是否可以在不关闭账户的情况下回收租金完全取决于哪个程序拥有它。

SPL Token 和 Token-2022

两者都公开 WithdrawExcessLamports。账户保持打开,保持其代币余额,并简单地降至当前最低值。

其他所有内容

没有等效指令。租金仅在账户关闭时释放——这是一个具有自己前置条件的破坏性操作,不是租金扫描。
具体来说,对于 Raydium 用户持有的账户类型: 包装 SOL 账户是唯一的代币程序例外:它们的 lamport 余额就是它们的代币余额,所以两个程序都以 TokenError::NativeNotSupported 拒绝它们。两个程序都改为公开 UnwrapLamports(判别式 45)用于该情况——它在 spl-token-interface 中与 WithdrawExcessLamports 一起,所以旧程序也有它,不仅仅是 Token-2022——并且 @solana/spl-token 从 0.4.15 开始为其提供 createUnwrapLamportsInstruction。在普通租金扫描中跳过原生账户并有意处理它们;安全执行此操作的模式是 Raydium 自己的程序使用的模式,下文。

WithdrawExcessLamports 指令

两个代币程序指令枚举中的判别式 38。来自 spl-token-interface:
三个属性使其可以安全地对钱包中的每个账户执行:
  • 它不需要金额。 程序自己计算 source.lamports − rent.minimum_balance(source.data_len()),所以它永远不能将账户降至当前最低值以下,并且当后续步骤激活时保持正确。
  • 它不关闭任何东西。 账户保持其数据、所有者和代币余额。
  • 它是幂等的。 对已在最低值的账户运行它会移动零 lamports 并成功。
冻结的代币账户仍然符合条件:冻结限制代币移动,而不是 lamports。

构建指令

@solana/spl-token 不导出它的构建器。从 0.4.15 开始,枚举条目仍然被注释掉 —— 并且注意上游把标识符拼作 WithdrawalExcessLamports,多了一个 “al”,所以请按那个拼写去 grep:
直接编码它。负载是单个判别式字节:
为每个账户传递其自己的 programId。SPL Token 和 Token-2022 指令可以共享一个交易,但每个都必须寻址到拥有其源账户的程序。 在主网上测量,该指令在 SPL Token 程序上花费 270 个计算单位,在 Token-2022 上花费 1,414 个——两种方式都可以忽略不计。真正的限制是交易大小,而不是计算。

查找可回收账户

不要从硬编码的速率推导超额。询问集群每个账户现在需要什么,这样相同的代码在所有五个步骤中都能继续工作:
getMinimumBalanceForRentExemption(0) 是一个有用的旁路:它返回恰好 128 × lamports_per_byte,所以除以 128 可以告诉你集群处于哪个推出步骤,而无需解析 Rent sysvar。

批处理:一个交易中能放多少

每个 WithdrawExcessLamports 指令贡献一个唯一的可写账户密钥——编译消息中的 32 字节——加上约 7 字节的指令编码。目标、权限和费用支付者都是同一个钱包,所以它们之间花费一个密钥。 针对 1,232 字节的交易限制,计算预算指令和区块哈希后,大约 25 条指令能放入。每个交易 20 条是安全的工作数字,也是 Raydium 自己的实现使用的。因此,拥有 116 个可回收账户的钱包在六个交易中扫描,每个交易一个 5,000 lamport 的基础费用。 注意经济学:费用按交易收取,而不是按账户。回收更少的账户不会花费更少,这就是为什么部分扫描很少值得额外的往返。

通过 Raydium 回收

raydium.io/reclaim-rent 页面扫描连接钱包的 SPL Token 和 Token-2022 账户,显示按程序分割的总计,并在批处理交易中扫描所有内容。扫描是只读的——在你按下回收所有租金之前没有签名。 该页面故意仅涵盖代币账户。只能通过关闭来释放租金的账户类型被排除而不是列为不可用,因为关闭账户是一个不同的、破坏性的操作。

从 SDK 演示回收

版本横幅。 这些演示针对 @raydium-io/raydium-sdk-v2@0.2.64-alpha 对 Solana mainnet-beta,验证于 2026 年 9 月;raydium-sdk-V2-demo 仓库本身目前安装 0.2.62-alpha,两者在这里可以互换。WithdrawExcessLamports 是手工编码的,独立于 SDK 版本——SDK 仅用于交易构建和批处理。
raydium-sdk-V2-demo/src/rent 中的两个脚本:
reclaimRent.ts 以每个交易 20 个账户的速率批处理,并在一次通过中签署所有批次:
在发送前模拟。带有 accounts.addresses 的 simulateTransaction 返回执行后的 lamport 余额,这是确认算术与集群实际执行内容匹配的最便宜方式。

Raydium 程序在自己这一侧扫描的内容

你的钱包不是唯一释放 lamports 的地方。每个池也持有租金——金库、LP 铸币和程序拥有的状态账户,都在旧速率下资助。该租金属于协议,而不是 LP:它由创建账户的人支付,它不是任何池储备的一部分,它从未进入曲线。 三个程序在 2026 年 9 月 9 日获得了一个管理员指令来返还它: 地址在 reference/program-addresses 中。CLMM 和 Stable AMM 不是该版本的一部分。 这里没有任何东西影响 LP 或交易者。 这些指令移动 lamports,仅此而已。代币余额、账户数据、所有者、池状态、LP 供应、费用计数器和曲线都不受影响,它们都不能关闭账户。池的交换报价在扫描前后是相同的。没有用户端操作、没有选择加入,也没有截止日期。

三个程序各自处理的三种账户形状

所有三个都遵循相同的分派,在源账户的所有者上:
  • 由程序权限 PDA 拥有的代币账户或铸币——程序 CPI 代币程序的 WithdrawExcessLamports(判别式 38),作为该 PDA 签署。
  • 包装 SOL 金库——WithdrawExcessLamports 拒绝原生账户,所以程序首先 SyncNative(这将捐赠的超额折叠到包装的 amount 中),精确测量包装金额增长了多少,为该增量 UnwrapLamports,然后断言包装余额回到其预同步值。如果该检查失败,整个指令以 LamportsCalculateError 回滚。这就是为什么 SOL 端池金库在扫描中保持其完整流动性。
  • 程序拥有的状态账户——AmmInfo、PoolState、AmmConfig、ObservationState、PlatformConfig 等。程序可以直接借记其自己的账户,所以它将余额降至 rent.minimum_balance(data_len),完全没有 CPI。
由任何其他东西拥有的账户被静默跳过,所以传递不相关的账户是无害的而不是致命的。 包装 SOL 序列值得复制,如果你持有自己的原生账户:这是从 wSOL 账户取出超额而不改变账户报告的代币余额的唯一方法。
这些路径依赖于部署的代币程序,而不是 crate 版本。 所有三个程序都手工编码代币指令——WithdrawExcessLamports 的单个 38 字节,UnwrapLamports 的 45 加上 COption<u64>——并将它们发送到拥有源账户的任何代币程序。两条指令都存在于当前主网 SPL Token 和 Token-2022 程序中。运行较旧捆绑 SPL Token 构建的本地验证器或测试工具不实现它们,针对它的扫描在未知判别式上失败,而不是在 Raydium 程序中的任何东西上。针对主网克隆的代币程序测试这些路径。

仍然无法就地回收的内容

CLMM 头寸的租金不受所有这一切的影响——当头寸关闭时它会返还,如上表所说。LaunchLab 基础铸币也是一样:初始化指令在铸造供应的同一调用中撤销 MintTokens,所以没有密钥可以为该铸币签署 WithdrawExcessLamports,其租金被设计困住。

你现在应该回收还是等待?

两者都很好,差异很小:
  • 超额不会去任何地方。 它坐在你自己的账户中。没有过期时间、没有扫描、没有截止日期。
  • 等待会复利。 每个步骤从相同的账户释放更多,步骤 5 后的一次扫描花费的费用与今天的一次扫描相同。
  • 现在回收不会放弃后续步骤。 你今天扫描的账户只是在当前最低值;下一步再次使其资金过剩,你可以再次扫描它。
现在回收的唯一真实成本是基础费用,等待的唯一真实成本是 lamports 保持不动一段时间。

进一步阅读

SIMD-0437

提案本身——五个特性门和分步减少的理由。

降低的租金

Solana 的推出页面:当前步骤、时间表和新账户的变化。

租金减少:数据支持的分析

经济学和分步推出旨在管理的状态增长风险。

账户模型

Solana 账户如何被资助、拥有和关闭——上述所有内容的背景。