在 Solana 中,系统变量(sysvars)是只读的系统账户,为程序提供区块链状态和网络信息的访问权限。它们类似于以太坊的全局变量,但每个系统变量拥有唯一的公钥地址,类似以太坊的预编译合约。
在 Solana 中,系统变量(sysvars)是只读的系统账户,为程序提供区块链状态和网络信息的访问权限。它们类似于以太坊的全局变量,但每个系统变量拥有唯一的公钥地址,类似以太坊的预编译合约。
在 Anchor 中,访问系统变量有两种方式:
#[derive(Accounts)]
中通过公钥地址将其作为账户引用。并非所有系统变量都支持 get 方法,且部分已被弃用(下文将注明)。对于无 get 方法的系统变量,需通过公钥访问。
以下是常见的 Solana 系统变量:
槽(slot)是约 400 毫秒的时间窗口,领导者在此期间可生成区块。一个槽通常对应一个区块(包含交易列表),但若领导者未生成区块,槽可能为空。通过 Solana 浏览器 查看,槽与区块的哈希始终不同。
支持 get 方法的系统变量包括 Clock、EpochSchedule 和 Rent。Fees 和 EpochRewards 虽在 Solana 文档中列为可访问,但在最新 Anchor 版本中已弃用。
创建新 Anchor 项目:
anchor init sysvars
cd sysvars
anchor build
更新 lib.rs:
use anchor_lang::prelude::*;
declare_id!("DfnoLKzEct937xzk3a3gW2WSwD2tGidFNq9xxuN76QvL");
#[program]
pub mod sysvars {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
let clock = Clock::get()?;
msg!("clock: {:?}",clock);
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize {}
运行 anchor test,日志显示 Clock 的字段(如 unix_timestamp、slot 等)。
Transaction executed in slot 6:
Signature: 2VNMBwFkpvbiL1cdn2K1Xb2gUX4Zt9EnwxFTSabAS3WYxPUFhhuZqygu3bH4NTNfkhm7y6Cgw4dLU5sWaFbjHph1
Status: Ok
Log Messages:
Program DfnoLKzEct937xzk3a3gW2WSwD2tGidFNq9xxuN76QvL invoke [1]
Program log: Instruction: Initialize
Program log: clock: Clock { slot: 6, epoch_start_timestamp: 1741833575, epoch: 0, leader_schedule_epoch: 1, unix_timestamp: 1741833577 }
Program DfnoLKzEct937xzk3a3gW2WSwD2tGidFNq9xxuN76QvL consumed 3853 of 200000 compute units
Program DfnoLKzEct937xzk3a3gW2WSwD2tGidFNq9xxuN76QvL success
纪元(epoch)约为两天,质押或赎回 SOL 需在纪元边界生效(详见 Solana 质押)。
更新 initialize:
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
let epoch_schedule = EpochSchedule::get()?;
msg!("epoch schedule: {:?}",epoch_schedule);
Ok(())
}
日志示例:
Transaction executed in slot 3:
Signature: 5K8Nd27QHGABWSHSHqHLQri4mQYviHcb5PtkBXYzERLXLfcMbrZD7fJZLvJHVVXmVEuB4Ly8htUptMsM2UFwnq4w
Status: Ok
Log Messages:
Program DfnoLKzEct937xzk3a3gW2WSwD2tGidFNq9xxuN76QvL invoke [1]
Program log: Instruction: Initialize
Program log: epoch schedule: EpochSchedule { slots_per_epoch: 432000, leader_schedule_slot_offset: 432000, warmup: false, first_normal_epoch: 0, first_normal_slot: 0 }
Program DfnoLKzEct937xzk3a3gW2WSwD2tGidFNq9xxuN76QvL consumed 3447 of 200000 compute units
Program DfnoLKzEct937xzk3a3gW2WSwD2tGidFNq9xxuN76QvL success
更新 initialize:
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
let rent_var = Rent::get()?;
msg!("Rent {:?}",rent_var);
Ok(())
}
日志示例:
Transaction executed in slot 3:
Signature: 5Fy1zqmj1UaU4ggaFipm4c6CNrGWUADBuebMHzmc9WfwAhoBteMg1g4rP42pbAWYoydyJnMXVgR1ftijcVRXLU4u
Status: Ok
Log Messages:
Program DfnoLKzEct937xzk3a3gW2WSwD2tGidFNq9xxuN76QvL invoke [1]
Program log: Instruction: Initialize
Program log: Rent Rent { lamports_per_byte_year: 3480, exemption_threshold: 2.0, burn_percent: 50 }
Program DfnoLKzEct937xzk3a3gW2WSwD2tGidFNq9xxuN76QvL consumed 3497 of 200000 compute units
Program DfnoLKzEct937xzk3a3gW2WSwD2tGidFNq9xxuN76QvL success
租金详情将在后续文章中展开。
对于无 get 方法的系统变量,需通过公钥在 #[derive(Accounts)] 中引用。
记录网络质...
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!