10分钟Solana-性能web3-1.2 Solana账户模型

1 阅读4分钟

欢迎订阅专栏10分钟Solana-性能web3

Solana 的账户模型是其架构的基石。与以太坊将代码和数据捆绑在合约账户中的设计不同,Solana 采用了 “一切皆为账户” 的统一模型,并强制将代码(程序)与状态(数据)完全分离

📖 账户的核心结构

每个 Solana 账户都是一个容器,包含以下关键字段:

  • lamports:账户的 SOL 余额,以 lamports 为单位(1 SOL = 10亿 lamports)。账户需维持一定余额以支付链上存储的“租金”。
  • owner:一个程序 ID(公钥),标识唯一有权修改此账户数据或扣减 lamports 的程序
  • executable:布尔值,标记账户是否包含可执行程序代码(即是否为程序账户)。
  • data:存储账户状态的原始字节数组。对于程序账户,存储的是编译后的字节码;对于数据账户,存储的是序列化的应用状态。
  • rent_epoch:记录账户下次需支付租金的 epoch(在“租金豁免”机制下,此字段主要为历史遗留)。

⚖️ “代码与状态分离”的核心设计

Solana 账户模型最核心的设计是 “代码与状态分离”

  • 程序(Programs)是无状态的:程序账户(executable = true)只包含不可变的字节码。它们不存储任何用户数据。
  • 状态存储在独立的数据账户中:所有可变的状态数据都存储在由程序拥有并管理的、独立的数据账户中。

这一设计带来以下优势:

  • 可升级性:升级程序代码时,所有数据账户不受影响,无需迁移状态。
  • 并行执行:交易必须预先声明它将读取或写入哪些账户。这使得 Solana 运行时可以识别互不重叠的交易,并让它们并行执行,极大提升了吞吐量。
  • 安全与透明:程序无法随意修改全局状态,必须获得对特定账户的显式权限,使数据依赖关系清晰可审计。

🗂️ Solana 账户的四种类型

基于上述结构,Solana 账户主要分为以下四种类型:

账户类型executableowner用途
钱包账户 (Wallet/System Account)false系统程序 (System Program)普通用户账户,持有 SOL。数据通常为空。
程序账户 (Program Account)trueBPF 加载器 (BPF Loader)存储智能合约的不可变字节码(即“程序”)。
数据账户 (Data Account)false创建它的程序存储程序的状态数据,如代币余额、NFT 信息等。
PDA (Program Derived Address)false创建它的程序由程序 ID 和种子确定性派生的地址。程序可为其“签名”,实现无密钥控制。

🔑 核心概念:程序派生地址 (PDA)

PDA 是 Solana 账户模型中极具特色的设计。由于程序无法持有私钥,PDA 解决了程序如何“拥有”并控制账户的问题。

  • 确定性派生:PDA 由程序 ID 和一组种子(如用户名、ID)通过哈希函数确定性地生成。
  • 无对应私钥:PDA 不在 ed25519 椭圆曲线上,因此没有对应的私钥,无法像普通钱包一样签名。
  • 程序“代签”:当程序需要以 PDA 的身份进行操作(如转移资产)时,可在交易中提供 PDA 的派生种子。Solana 运行时验证后,便允许该程序为该 PDA“签名”。

PDA 常用于创建程序可控的“保险库”或用户专属的数据账户。

💰 租金机制 (Rent)

为防止状态无限膨胀,Solana 引入了“租金”机制。

  • 存储成本:账户需维持最低 SOL 余额以支付存储费用。租金与账户数据大小成正比。
  • 租金豁免 (Rent-Exempt):若账户存入至少 2 年租金的 SOL,则被视为“租金豁免”,其数据将永久保存。这是当前的标准做法。
  • 账户关闭:关闭账户可退还剩余的租金。

🆚 与以太坊账户模型的对比

特性Solana以太坊 (EVM)
核心原则一切皆为账户区分外部账户 (EOA) 和合约账户
代码与状态完全分离耦合,合约代码和状态存储在同一账户
状态存储方式状态存储在独立的数据账户中状态存储在合约账户内部的键值存储中
存储成本持续性租金(租金豁免后可免除)一次性 Gas 费(永久存储)
并行处理支持,通过预声明账户实现并行执行不支持,交易顺序执行
账户控制owner 程序控制由私钥 (EOA) 或代码 (合约) 控制
开发复杂性较高,需管理账户、权限和租金相对较低,Solidity 更易上手

理解这个账户模型是开发 Solana 程序的第一步。如果你想继续了解如何在实际开发中创建和管理这些账户,或者对 PDA 的具体应用更感兴趣,可以随时告诉我。