Solana/账户模型/租赁与租赁豁免机制

在 solana 上, 每个账户都要消耗存储空间, 而这些空间背后是集群中的节点在为您存数据. 所以, solana 设计了一个租赁机制: 您要为您在链上存的每一字节数据付租金. 但又因为频繁续租太麻烦, 也设计了租赁豁免制度.

租赁

Solana 的账户不是免费的, 它占用存储资源, 而节点们要保存这些数据. 因此, solana 要求每个账户必须有一部分 sol 用作"数据存储租金".

这套机制的核心规则是:

  • 账户存储数据越多, 占用的空间越大, 所需的租金也越多.
  • 租金是预付的, 不是按月扣款, 而是按账户余额和大小一次性"锁定"一笔钱.
  • 如果账户余额不足, 长期空着不用, 系统可以把它回收掉.

这笔"租金"实际上是您存在账户余额里的一部分 sol, solana 运行时会根据当前租金费率计算出租期.

设计租赁机制的根本原因是为了防止账户垃圾, 这些垃圾账户可能被有意或无意的创建:

  • 用户创建大量空账户, 从不清理.
  • 合约部署后遗留无用数据.
  • 程序错误导致堆积大量临时账户.

如果账户没有成本, 链上的状态会无限膨胀, 最终影响性能和稳定性. 通过租赁机制, solana 迫使用户对链上状态负责, 用经济手段做资源管理.

租赁豁免

Solana 也知道频繁续租会很麻烦, 所以它设计了租赁豁免机制: 只要您账户里的 sol 足够多, 超过一个阈值, 系统就默认您"预付了永久租金", 您的账户就不会被回收了.

假设您创建了一个数据账户, 占用了 100 字节. 系统会根据当前的租金费率算出一笔"豁免租金", 比如 0.002 sol. 您只要在账户里放进去这 0.002 SOL, 系统就视作"豁免", 系统永远不会向您再收租, 您的账户也永远不会被删掉.

这套机制设计得非常实用, 带来了几个好处:

  • 开发者不需要给账户设置租期, 续租逻辑.
  • 用户不需要关心账户什么时候过期.
  • 合约运行更加稳定.

Solana 从一开始就采用了租赁和租赁豁免并存的机制, 但是从当前的观察来讲, 即截至到 2025 年 5 月, solana 生态已经几乎完全切换到了租赁豁免这个机制上, 也就是在创建账户后立即存入租赁豁免租金, 以防止账户被意外的回收. 换句话说, 租赁机制已经被事实上弃用了.

租赁周期

从技术上讲, 每个账户都会记录自己的上次租金计费时间和余额. Solana 每个 epoch(大概两天)会进行一次租金结算. 如果某个账户没达到豁免门槛, 长期没有被访问, 且余额又不足以继续支付租金, 那它就可能被标记为"可清除", 节点会对账户数据进行清理, 释放状态空间.

如果您是程序开发者, 一般只要给数据账户设置成"租赁豁免", 后续就不用管它了.

租赁豁免资金计算

账户初始化时就要考虑豁免金额. 您需要提前估算账户空间大小, 并把足够的 sol 存进去. 租赁费率由 solana 网络实时计算, 您可以通过 get_minimum_balance_for_rent_exemption rpc 接口来获取当前存储指定大小的数据时需要的租赁豁免资金数量.

例: 如果小明要在账户中存储 100 字节的数据, 他需要的租赁豁免资金是多少?

答: 当前需要 1586880 lamport. 注意这个值可能会随着时间而发生变动.

import pxsol

print(pxsol.rpc.get_minimum_balance_for_rent_exemption(100, {}))
# 1586880

开发者要注意的细节

Solana 的账户租赁机制是为了控制状态存储成本, 让链上的数据有代价的存储. 同时, 为了开发方便, 又引入了租赁豁免机制, 只要您存够了钱, 就可以让账户永久保留.

对开发者来说, 最重要的是:

  • 明确账户是否需要长期保留. 如果不需要长期保留, 那么没有必要对其进行租赁豁免.
  • 初始化时正确设置余额, 以达成租赁豁免.