Solana时钟及其他“区块”变量

  • RareSkills
  • 发布于 2024-02-20 12:24
  • 阅读 196

文章详细介绍了 Solidity 中的块变量在 Solana 中的类比实现,包括 block.timestamp、block.number、block.coinbase 等,并提供了具体的代码示例和说明。

solana clock

今天我们将覆盖 Solidity 中所有区块变量的类比。并不是所有的变量都有一一对应的类比。在 Solidity 中,我们有以下常用的区块变量:

  • block.timestamp
  • block.number
  • blockhash()

以及一些较少使用的变量:

  • block.coinbase
  • block.basefee
  • block.chainid
  • block.difficulty / block.prevrandao

我们假设你已经知道它们的作用,但如果你需要复习,可以查看 Solidity 全局变量文档

Solana 中的 block.timestamp

通过利用 Clock sysvar 中的 unix_timestamp 字段,我们可以访问 Solana 的区块时间戳。

首先,我们初始化一个新的 Anchor 项目:

anchor init sysvar

将初始化函数替换为以下内容:

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
    let clock: Clock = Clock::get()?;
    msg!(
        "区块时间戳: {}",
        // 获取 block.timestamp
        clock.unix_timestamp,
    );
    Ok(())
}

Anchor 的预导入模块包含 Clock 结构,默认情况下会自动导入:

use anchor_lang::prelude::*;

有些令人困惑的是,unix_timestamp 返回的类型是 i64,而不是 u64,这意味着它支持负数,尽管时间不能为负数。然而,时间间隔可以是负数。

获取星期几

现在让我们创建一个程序,使用 Clock sysvar 中的 unix_timestamp 告诉我们当前是星期几。

chrono crate 提供了 Rust 中的日期和时间操作功能。

在程序目录 ./sysvar/Cargo.toml 中将 chrono crate 添加为依赖项:

[dependencies]
chrono = "0.4.31"

sysvar 模块中导入 chrono crate:

// ...其他代码

#[program]
pub mod sysvar {
    use super::*;
    use chrono::*;  // 新增这一行

    // ...
}

现在,我们在程序下方添加这个函数:

pub fn get_day_of_the_week(
    _ctx: Context<Initialize>) -> Result<()> {

    let clock = Clock::get()?;
    let time_stamp = clock.unix_timestamp; // 当前时间戳

    let date_time = chrono::NaiveDateTime::from_timestamp_opt(time_stamp, 0).unwrap();
    let day_of_the_week = date_time.weekday();

    msg!("星期几是: {}", day_of_the_week);

    Ok(())
}

我们将从 Clock sysvar 获得的当前 unix 时间戳作为参数传递给 from_timestamp_opt 函数,返回一个包含日期和时间的 NaiveDateTime 结构。然后,我们调用星期几方法以根据传递的时间戳获取当前星期几。

并更新我们的测试:

it("获取星期几", async () => {
    const tx = await program.methods.getDayOfTheWeek().rpc();
    console.log("你的交易签名", tx);
});

再次运行测试并获取以下日志:

在插槽 36 中执行交易:
  签名: 5HVAjmo85Yi3yeQX5t6fNorU1da4H1zvgcJN7BaiPGnRwQhjbKd5YHsVE8bppU9Bg2toF4iVBvhbwkAtMo4NJm7V
  状态: Ok
  日志信息:
    程序 H52ppiSyiZyYVn1Yr9DgeUKeChktUiPwDfuuo932Uqxy 调用 [1]
    程序日志: 指令: GetDayOfTheWeek
    程序日志: 星期几是: Wed
    程序 H52ppiSyiZyYVn1Yr9DgeUKeChktUiPwDfuuo932Uqxy 消耗了 1597 个计算单位(总计 200000 个计算单位)

注意日志中的“星期几是: Wed”。

Solana 中的 block.number

Solana 有一个“插槽编号”的概念,和“区块编号”很类似,但并不相同。关于这二者的区别将在以下教程中讨论,因此我们暂时推迟关于如何获取“区块编号”的完整讨论。

block.coinbase

在以太坊中,“块 coinbase”代表已成功挖掘一个区块的矿工的地址,而 Solana 使用一种基于领导者的共识机制,...

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

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

0 条评论

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