Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

账户模型

官方链接

#![allow(unused)]
fn main() {
pub struct Account{
    pub lamports:u64,
    pub data:Vec<u8>,
    pub owner:Pubkey,
    pub executable:bool,
    pub rent_epoch:Epoch,
}
}

结构分析:

字段 类型 作用
lamports u64 表示账户的 SOL 余额,以 Lamports 为单位。1 SOL = 1,000,000,000 Lamports(10^9)。用于支付交易费用和账户租金。
data Vec<u8> 存储账户的实际数据内容。对于数据账户,存储由 owner program 定义和解析的状态数据;对于程序账户,可能存储可执行字节码或指向程序数据账户的地址。
owner Pubkey 表示拥有该账户写权限的程序 ID。owner program 可以修改账户数据或扣减账户 lamports,任意程序可以向可写账户增加 lamports。
executable bool 标识该账户是否为可执行账户。当为 `true` 时,表示账户存储的是可执行的智能合约;否则,为普通账户。
rent_epoch Epoch 历史遗留字段。早期用于记录账户租金周期;当前重点是账户需要满足 rent-exempt minimum,租金周期字段已不再作为定期扣费依据。

关键字说明

• lamports (u64): • 类型:无符号 64 位整数 (u64)。 • 作用:账户的 SOL 余额,以 Lamports 为单位。用于支付交易费用和账户租金,确保账户持有足够的余额以维持其在区块链上的存在。

• data (Vec<u8>): • 类型:动态字节向量 (Vec<u8>)。 • 作用:存储账户的实际数据。对于数据账户,可以存储代币余额、NFT 元数据等由程序定义的状态;对于程序账户,可能存储可执行字节码或指向程序数据账户的地址。账户数据的格式由 owner program 定义,普通钱包账户通常不用于存储应用状态。

• owner (Pubkey): • 类型:公钥 (Pubkey) –solana自定义类型,非rust原生。 • 作用:标识拥有该账户写权限的程序 ID。只有 owner program 可以修改账户的 data 字段或扣减账户中的 lamports;任意程序可以向可写账户增加 lamports。这里的 owner 不是“用户所有者”,而是 Solana runtime 用来判断账户修改权限的程序地址。

• executable (bool): • 类型:布尔值 (bool)。 • 作用:标识账户是否为可执行账户。当设置为 true 时,表示该账户存储的是可执行的智能合约;否则,为普通账户,用于存储数据和资产。

• rent_epoch (Epoch): • 类型:Epoch 类型,表示区块链的一个时间周期–solana自定义类型,非rust原生。 • 作用:历史上用于管理账户的存储租金周期。当前租金定期扣除机制已废弃,新账户通常需要满足 rent-exempt minimum,即根据账户数据大小存入最低 lamports 余额以保持账户留存在链上。

rent_epoch :这是从 Solana 有定期从账户扣除 lamports 的机制时遗留下来的一个旧字段。虽然这个字段在 Account 类型中仍然存在,但由于租金收集已被弃用,它不再被使用。

示例

Solana 账户的 Account 结构体实例:

#![allow(unused)]
fn main() {
let account = Account {
    lamports: 1_000_000_000, // 1 SOL
    data: vec![0, 1, 2, 3],  // 存储的数据
    owner: Pubkey::new_unique(), // owner program 的地址,此处仅作示例
    executable: false,       // 普通账户
    rent_epoch: u64::MAX,    // 历史遗留字段,rent-exempt 账户通常为 u64::MAX
};
}

原生程序(Native Programs)

以下大部分为对solana官方文档的翻译,如有谬误请联系指正!

系统程序:

1.创建链上所有的新账户

2.为账户分配数据空间

3.转移账户所有权到自定义程序中

BPF加载器

全称 Berkeley Packet Filter Loader(伯克利包过滤器加载器)。在 Solana 中,程序会被编译为 sBPF 字节码,并由 loader program 负责部署、升级和执行。 1.已部署程序账户的 owner 通常是某个 loader program

2.处理程序部署和升级

  • 系统程序(System Program)

    所有在 Solana 上的“钱包”账户都只是由系统程序拥有的账户。这些账户中存储的 lamport 余额代表钱包拥有的 SOL 数量。只有由系统程序拥有的账户才能用作交易费用支付者。
  • BPF Loader

    BPF Loader 是 Solana 用来管理链上程序的加载器,不包括其他原生程序。它负责部署、升级和执行自定义程序;当前常见的可升级程序通常由 BPF Loader Upgradeable(loader-v3)管理。

系统变量账户(Sysvar Accounts)

Sysvar 账户是位于预定义地址的特殊账户,提供对集群状态数据的访问。这些账户会动态更新关于网络集群的数据。账户类型见 Sysvars。

自定义程序(Custom Programs)

在 Solana 上,“智能合约”被称为程序。程序是包含可执行代码的账户。程序账户的 executable 标志为 true。 程序被部署到网络中,可以被用户和其他程序调用以执行它们的指令。

程序账户(Program Account)

Loader-v3 的可升级程序涉及以下账户;部署阶段的临时缓冲账户与持续存在的程序账户不同:

  • Program:程序入口账户,记录 ProgramData 地址。
  • ProgramData:保存程序代码、升级权限等信息。
  • 缓冲账户:在程序部署或升级期间创建的临时账户,用于存储程序的执行代码。成功部署后,代码将被移动到程序执行数据账户,缓冲账户将被关闭。

例如,以下是 Token Extensions Program Account 及其对应的 Program Executable Data Account 在 Solana Explorer 中的链接。 指令使用程序账户地址作为 Program ID。Loader-v3 的 Program 账户指向 ProgramData,后者保存程序代码与升级权限;账户关系依赖所使用的加载器版本。

数据账户(Data Account)

Solana 上的程序是“无状态的”,这意味着程序账户仅存储可执行代码,不存储用于读取的数据。 为了维护状态,程序定义指令以创建由程序拥有的单独账户。每个账户都有自己的唯一地址,可以存储程序定义的任何任意数据。 注意,只有系统程序可以创建新的账户。一旦系统程序创建了账户,它就可以将新账户的所有权转让给另一个程序。 换句话说,为自定义程序创建数据账户需要两个步骤:

1.调用系统程序创建账户,然后将其所有权转让给自定义程序

2.调用现在拥有账户的自定义程序,然后初始化程序指令定义的账户数据

这个账户创建过程通常被抽象为单一步骤。