Solana 账户的五个字段:所有权、可执行标志与押金怎么互相约束 图 1
Solana 账户的五个字段:所有权、可执行标志与押金怎么互相约束 · 图 1

结论先说

Solana 链上的全部状态是一张键值存储:每个键是 32 字节地址,每个值是一个账户对象。官方文档给每个账户定义了固定五个字段——lamports(余额)、data(数据)、owner(所属程序)、executable(可执行标志)、rent_epoch(已弃用的租金纪元)。这套结构与以太坊“账户里挂着代码和数据、代码互相调用”的模型是两种世界:在 Solana 上,代码和数据分开住,数据自己不会动,只有它的所属程序能改它。理解了这条所有权边界,Solana 的一大半设计就顺了。

五个字段各管什么

lamports 是余额,单位是 SOL 的十亿分之一。所属程序可以扣减余额,任何程序理论上都可以向其入金。data 是一段字节数组,上限 10 MiB,内容格式完全由所属程序自己定义——代币账户存余额结构、订单簿账户存挂单,全是一串裸字节,读之前必须先按程序约定反序列化。owner 指向一个程序地址,写明“谁能改这个账户的数据”;只有数据被清零后账户才允许换所属程序。executable 是布尔值:为真表示这是程序账户,data 里放的是可执行字节码;为假则是普通数据账户。设置可执行标志本身还有三条运行时规则:账户必须达到免租余额、只有当前所属程序能设置、且账户必须可写。rent_epoch 字段已被官方标注为弃用,新建免租账户该字段固定为最大值,可以理解为历史遗留。

五个字段构成:余额、数据、所有者、可执行标志与押金状态

押金逻辑:所谓租金是可退还的预存

账户必须维持一个与数据体积成正比的最低 lamports 余额,才允许把数据长期存在链上,这就是常被叫作“租金”的机制。官方文档的口径很明确:它更像一笔可退还的押金而不是持续收费——账户被主动关闭时,余额原路退还。历史上确实存在按纪元扣费的租金收集阶段,账户在零 lamports、租金支付中、免租三种状态间迁移,但租金收集机制已被弃用,当前开发实践是给新账户一次性存入免租最低余额,通过 RPC 的 getMinimumBalanceForRentExemption 可以按数据长度查询这个数额。写程序时要注意:可执行账户若不满足免租条件会被运行时直接拒绝。

所有权边界带来了什么

程序账户(executable 为真)与数据账户的分工,意味着“状态迁移只能由定义它的程序完成”:转账走系统程序账户,代币余额变动走代币程序,任何其它指令都无法直接改写别人地盘上的数据。好处是运行时可以精确判断指令间的读写冲突,放心并行执行互不重叠的指令;代价是复杂业务必须把要碰的账户全部提前声明,交易结构因此显得啰嗦。程序派生地址(PDA)是这套模型的延伸:程序用种子派生出自己名下的“无私钥账户”,用来存放与业务对象一一对应的状态,其规范 bump 的取法见Solana PDA为何需要canonical bump?

和以太坊账户模型的对照

以太坊一侧每个地址对应一个统一账户,EOA 存余额,合约账户同时存代码和数据,合约之间直接互相调用、互相改状态。比特币则完全不同,用 UTXO 表达所有权,可对照比特币 UTXO 是什么?和账户模型区别。三种模型里,Solana 的特点是把“谁有权改这块状态”写进了每个账户的结构字段,权限不靠代码约定而靠运行时强制。Sui 的对象模型与它有神似之处——对象也有明确所有者,机制见Sui 是什么?对象模型与并行执行怎么工作,但两者在对象生命周期与并行策略上仍有实质差异。

用户视角看什么

第一,读任意链上状态的正确姿势是:按地址取账户,再按所属程序的格式反序列化 data,拿到一串看不懂的字节不代表数据丢了。第二,账户有押金成本:创建大体积数据账户要预付与体积成正比的 lamports,关闭账户可退回,所以“链上空间不是免费的”。第三,检查一份数据能信到什么程度,可以先看 owner 是哪个程序——owner 若是众所周知的官方程序地址,与 owner 是一个刚部署的第三方程序,可信度显然不同。

小结

五个字段定义了 Solana 状态世界的物理法则:余额与数据分开记账,owner 划定唯一写权,executable 区分代码与数据,押金约束存储体积,租金字段交给历史。它换来的核心红利是可并行、可预测的状态访问,也让链上调查多了一个抓手——先看账户归谁。本文为机制说明,依据官方文档整理,不构成投资建议。