区块链中文技术社区

使用Solana主网账户和程序

通常,本地测试依赖于本地验证器上默认不可用的程序和帐户。
Solana CLI 允许以下操作:

  • 下载程序和账户
  • 将程序和帐户加载到本地验证器

如何从主网加载账户

可以将JUP代币铸币账户下载到文件中:

# solana account -u <source cluster> --output <output format> --output-file <destination file name/path> <address of account to fetch>
solana account -u m --output json-compact --output-file jup.json JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN

然后通过在启动验证器时传递帐户的文件和目标地址(在本地集群上)将其加载到您的本地网络:

# solana-test-validator --account <address to load the account to> <path to account file> --reset
solana-test-validator --account JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN jup.json --reset

同样,也可以下载 Openbook 程序:

# solana program dump -u <source cluster> <address of account to fetch> <destination file name/path>
solana program dump -u m srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX openbook.so

然后通过在启动验证器时传递程序的文件和目标地址(在本地集群上)将其加载到您的本地网络:

# solana-test-validator --bpf-program <address to load the program to> <path to program file> --reset
solana-test-validator --bpf-program srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX openbook.so --reset

https://solana.com/zh/developers/cookbook/development/using-mainnet-accounts-programs

SysvarRent111111111111111111111111111111111 账户用途

在 Solana 区块链中, SysvarRent111111111111111111111111111111111 是一个系统变量(Sysvar)账户。系统变量账户是 Solana 网络中预定义的特殊账户,用于存储与网络运行相关的全局信息,这些信息可以被智能合约和客户端程序访问。

该账户的具体作用

SysvarRent111111111111111111111111111111111 账户专门用于存储租金(Rent)相关的信息。在 Solana 中,租金是为了确保链上存储的有效性和经济性而设计的一种机制。具体来说,该账户存储了以下重要信息:

  1. 租金费率(Rent Exemption) :

    • 这个账户记录了使账户免受租金影响所需的最低余额。如果一个账户的余额低于这个阈值,那么该账户需要定期支付租金,否则可能会被系统清除。
    • 智能合约和客户端程序可以通过读取这个系统变量来确定需要存入多少资金才能使账户免受租金的影响。
  2. 租金计算参数 :

    • 它还包含了用于计算租金的参数,例如每字节的租金费率和租金收取的周期。
    • 这些参数对于开发者和用户来说非常重要,因为它们决定了在 Solana 链上存储数据的成本。

代码示例

在 Solana 的 Rust 编程中,可以通过以下方式访问这个系统变量账户:

use anchor_lang::prelude::*;
use solana_program::sysvar::rent::Rent;

#[program]
pub mod my_solana_program {
    use super::*;

    pub fn read_rent_info(ctx: Context<ReadRentInfo>) -> Result<()> {
        let rent = &ctx.accounts.rent;
        // 读取租金豁免金额
        let rent_exemption = rent.minimum_balance(1024); // 假设账户大小为 1024 字节
        msg!("Rent exemption for 1024 bytes: {}", rent_exemption);
        Ok(())
    }
}

#[derive(Accounts)]
pub struct ReadRentInfo<'info> {
    #[account(address = solana_program::sysvar::rent::ID)]
    pub rent: Account<'info, Rent>,
}

代码解释

在这个示例中,我们定义了一个名为 read_rent_info 的程序指令,用于读取租金信息。通过 Account 结构体,我们指定了 rent 账户的地址为 solana_program::sysvar::rent::ID ,即 SysvarRent111111111111111111111111111111111 。然后,我们可以通过 rent.minimum_balance 方法计算出指定大小的账户所需的租金豁免金额。

通过这种方式,开发者可以在智能合约中动态地获取租金信息,从而更好地管理账户的存储成本。

SysvarC1ock11111111111111111111111111111111 账户用途

在 Solana 区块链中, SysvarC1ock11111111111111111111111111111111 是一个系统变量账户(Sysvar),它代表着 Solana 网络中的时钟信息。下面详细介绍它的作用、使用场景以及相关代码示例。

作用

SysvarC1ock11111111111111111111111111111111 账户存储了 Solana 网络的全局时钟状态,包含了以下关键信息:

  • Unix 时间戳 :表示当前的 Unix 时间,精确到秒。这对于需要依赖时间的智能合约非常重要,比如设定特定时间的任务、活动的开始和结束时间等。
  • Slot 编号 :Slot 是 Solana 中用于衡量时间的基本单位,每个 Slot 代表一个短暂的时间间隔。通过 Slot 编号,可以了解当前区块链的进度和交易的顺序。
  • Epoch 编号 :Epoch 是一组连续的 Slot,通常用于表示区块链的一个周期。Epoch 编号有助于管理和更新网络的状态,例如验证者的轮换等。

使用场景

这个系统变量账户在 Solana 智能合约开发中有广泛的应用,以下是一些常见的使用场景:

  • 时间相关的条件判断 :智能合约可以根据当前的 Unix 时间戳来判断是否满足特定的时间条件,从而执行相应的操作。
  • 交易的时间限制 :在创建或处理交易时,可以使用时钟信息来设置交易的有效时间范围,防止过期交易被处理。
  • 数据的时效性 :对于需要保证数据时效性的应用,如价格预言机,智能合约可以根据时钟信息来判断数据是否过期。

代码示例

在 Rust 编写的 Solana 智能合约中,可以通过以下方式访问 SysvarC1ock11111111111111111111111111111111 账户:

use anchor_lang::prelude::*;
use solana_program::sysvar::clock::Clock;

#[program]
pub mod my_program {
    use super::*;

    pub fn my_function(ctx: Context<MyContext>) -> Result<()> {
        // 获取时钟系统变量
        let clock = Clock::get()?;

        // 打印当前的 Unix 时间戳
        msg!("Current Unix timestamp: {}", clock.unix_timestamp);

        // 打印当前的 Slot 编号
        msg!("Current slot: {}", clock.slot);

        // 打印当前的 Epoch 编号
        msg!("Current epoch: {}", clock.epoch);

        Ok(())
    }
}

#[derive(Accounts)]
pub struct MyContext {}

代码解释

  • use solana_program::sysvar::clock::Clock; :引入 Clock 结构体,用于访问时钟系统变量。
  • let clock = Clock::get()?; :调用 Clock::get() 方法获取当前的时钟信息。
  • msg! 宏用于在 Solana 日志中打印信息,方便调试和监控。
    通过以上代码,智能合约可以轻松地获取和使用 Solana 网络的时钟信息,从而实现各种时间相关的逻辑。

传统 Solana 程序与 Anchor 程序的区别

在 Anchor 框架创建的 Solana 程序里,你看不到 process_instruction 函数,这是因为 Anchor 框架做了抽象和封装,把底层的 Solana 程序处理逻辑简化了。下面详细解释:

1. 传统 Solana 程序与 Anchor 程序的区别

  • 传统 Solana 程序: 在传统的 Solana 程序开发里,你得手动实现 process_instruction 函数。这个函数是程序的入口点,负责接收和处理交易指令。示例如下:
use solana_program::{
    account_info::AccountInfo, entrypoint, 
    entrypoint::ProgramResult, 
    pubkey::Pubkey,
};

entrypoint!(process_instruction);

fn process_instruction(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    instruction_data: &[u8],
) -> ProgramResult {
    // 处理指令逻辑
    Ok(())
}
  • Anchor 程序: Anchor 框架是一个高级的 Solana 程序开发框架,它隐藏了很多底层细节。Anchor 借助宏和自定义语法来定义程序逻辑,而不是直接实现 process_instruction 函数。

2. Anchor 程序的结构

在 Anchor 里,你通常会定义 #[program] 模块,在这个模块中定义指令处理函数。示例如下:

// lib.rs

use anchor_lang::prelude::*;

declare_id!
("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsL
nS");

#[program]
pub mod my_program {
    use super::*;

    pub fn initialize(ctx: 
    Context<Initialize>) -> Result<()> {
        // 初始化逻辑
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    // 账户声明
}

在这个示例中,initialize 函数就是一个指令处理函数,它会在接收到相应的交易指令时被调用。Anchor 会自动处理 process_instruction 函数的实现,把交易指令路由到对应的处理函数。

3. 查看 Anchor 生成的 process_instruction

如果你想查看 Anchor 生成的 process_instruction 函数,可以编译程序,然后查看生成的 Rust 代码。执行以下命令编译程序:

anchor build

编译完成后,在 target/idl 目录下可以找到生成的 IDL(Interface Definition Language)文件,在 target/deploy 目录下可以找到生成的 Rust 代码。这些生成的代码包含了 process_instruction 函数的实现。

总结来说,Anchor 框架通过抽象和封装,让开发者不用直接处理 process_instruction 函数,从而提高了开发效率。

其它

Solana 传统程序: https://solana.com/zh/developers/guides/getstarted/local-rust-hello-world