Solana 系统变量详解

  • RareSkills
  • 发布于 2024-07-13 22:13
  • 阅读 193

文章详细介绍了 Solana 中的系统变量(sysvars),包括如何通过 Anchor 框架访问这些变量,以及它们的功能和使用场景。

Solana Sysvars

在 Solana 中,sysvar 是只读系统账户,它们使 Solana 程序能够访问区块链状态和网络信息。它们类似于 Ethereum 的全局变量,这些变量也使智能合约能够访问网络或区块链状态信息,但它们具有类似于 Ethereum 预编译的唯一公共地址。

在 Anchor 程序中,你可以通过两种方式访问 sysvars:要么使用 anchor 的 get 方法包装,或者将其视为你的 #[Derive(Accounts)] 中的账户,使用其公共地址。

并非所有 sysvars 都支持 get 方法,并且其中一些已被弃用(关于弃用的信息将在本指南中指定)。对于没有 get 方法的 sysvars,我们将使用其公共地址进行访问。

  • Clock: 用于与时间相关的操作,例如获取当前时间或 slot 编号。
  • EpochSchedule: 包含关于纪元调度的信息,包括特定 slot 的纪元。
  • Rent: 包含租金比率和信息,例如保持账户免租的最低余额要求。
  • Fees: 包含当前 slot 的费用计算器。费用计算器提供了有关在 Solana 交易中每个签名支付多少 lamports 的信息。
  • EpochRewards: EpochRewards sysvar 保留了 Solana 中的纪元奖励分配记录,包括区块奖励和质押奖励。
  • RecentBlockhashes: 包含活跃的最近区块哈希。
  • SlotHashes: 包含近期 slot 哈希的历史记录。
  • SlotHistory: 保留 Solana 中最近纪元内的可用 slot 数组,并在处理新 slot 时进行更新。
  • StakeHistory: 维护整个网络的质押激活和停用记录,按纪元进行记录,并在每个纪元开始时更新。
  • Instructions: 获取当前交易中序列化指令的访问权限。
  • LastRestartSlot: 包含最后一次重启的 slot 编号(Solana 上一次重启的时间)或为零(如果从未发生过)。如果 Solana 区块链崩溃并重启,则应用程序可以使用此信息来确定它是否应等待事情稳定。

区分 Solana 的 slots 和 blocks。

slot 是一个时间窗口(大约 400 毫秒),在该窗口中,指定的领导者可以生成一个区块。一个 slot 包含一个区块(与 Ethereum 上相同类型的区块,即交易列表)。然而,如果区块领导者未能在该 slot 产生区块,则该 slot 可能不包含区块。其关系如下图所示:

solana slots and blocks

尽管每个区块映射到恰好一个 slot,但区块哈希与 slot 哈希并不相同。当你在浏览器中单击一个 slot 编号时,则会打开带有不同哈希的区块详细信息,这一区别是显而易见的。

让我们看下图中来自 Solana 区块浏览器的一个例子:solana slot hashes

图片中高亮的绿色数字是 slot 编号 237240962 ,而高亮的黄色文本是 slot 哈希 DYFtWxEdLbos9E6SjZQCMq8z242Yv2bVoj6dzwskd5vZ。下面高亮的红色的区块哈希是 FzHwFHDAXJBc55rpjShznGCBnC7DsTCjxf3KKAk6hk9T

(其他区块详细信息已被裁剪):solana blockhash

我们可以通过它们独特的哈希来区分区块和 slot,即使它们具有相同的数字。

作为测试,点击浏览器中的任何 slot 编号 在这里,你会注意到将打开一个区块页面。此区块的哈希将与 slot 哈希不同。

使用 get 方法访问 Solana Sysvars

如前所述,并非所有 sysvars 都可以使用 Anchor 的 get 方法进行访问。诸如 Clock、EpochSchedule 和 Rent 之类的 sysvars 可以通过此方法访问。

虽然 Solana 文档将 Fees 和 EpochRewards 列为可以通过 get 方法访问的 sysvars,但在最新版本的 Anchor 中这些已被弃用。因此,无法通过 get 方法在 Anchor 中调用它们。

我们将使用 get 方法访问并记录所有当前支持的 sysvars 的内容。首先,我们创建一个新的 Anchor 项目:

anchor init sysvars
cd sysvars
anchor build

Clock sysvar

要利用 Clock sysvar,我们可以调用 Clock::get()(我们在之前的教程中做过类似的事情)方法,如下所示。

在我们项目的初始化函数中添加以下代码:

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
    // 获取 Clock sysvar
    let clock = Clock::get()?;

    msg!(
        "clock: {:?}",
        // 获取 Clock sysvar 的所有详细信息
        clock
    );

    Ok(())
}

现在,运行对本地方的 Solana 节点的测试并检查日志:solana epoch

EpochSchedule sysvar

在 Solana 中,纪元是大约两天的时间段。SOL 只能在纪元开始时质押或解除质押。如果你在纪元结束之前质押(或解除质押)SOL,则该 SOL 被标记为“激活”或“停用”,同时等待纪元结束。

Solana 在其关于 委托 SOL 的描述中详细说明了这一点。

我们可以使用 get 方法访问 EpochSchedule sysvar,类似于 Clock sysvar。

更新初始化函数,添加以下代码:

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
    // 获取 EpochSchedule sysvar
    let epoch_schedule = EpochSchedule::get()?;

    msg!(
        "epoch schedule: {:?}",
        // 获取 EpochSchedule sysvar 的所有详细信息
        epoch_schedule
    );

    Ok(())
}

再次运行测试,将生成以下日志:test output log

从日志中,我们可以观察到 EpochSchedule sysvar 包含以下字段:

  • slots_per_epoch 以黄色高亮显示,表示每个纪元的 slot 数量,这里是 432,000 个 slot。
  • leader_schedule_slot_offset 以红色高亮显示,决定了下一个纪元的领导者调度的时间(我们在第 11 天讨论过这个)。它也设置为 432,000。
  • warmup 以紫色高亮显示,是一个布尔值,指示 Solana 是否处于预热阶段。在此阶段,纪元开始较小,并逐渐增加大小。这有助于网络在重置后或早期阶段平稳启动。
  • first_normal_epoch 以橙色高亮显示,标识可以拥有其 slot 数的第一个纪元,first_normal_slot 以蓝色高亮显示,则是开始此纪元的 sl...

剩余50%的内容订阅专栏后可查看

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
RareSkills
RareSkills
https://www.rareskills.io/