使用Anchor编写测试程序

安装依赖

sudo apt-get update
sudo apt-get install -y \
    build-essential \
    pkg-config \
    libudev-dev llvm libclang-dev \
    protobuf-compiler libssl-dev

安装Rust

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
. "$HOME/.cargo/env"
rustc --version

安装Solana CLI

sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"

添加环境变量

export PATH="$HOME/.local/share/solana/install/active_release/bin:$PATH"
sudo vi /etc/profile
export PATH=$PATH:/usr/local/go/bin
source /etc/profile

版本更新

agave-install update

安装 Anchor CLI

cargo install --git https://github.com/coral-xyz/anchor avm --force
avm --version

版本更新

avm install latest
avm use latest

指定版本

avm install 0.30.1
avm use 0.30.1

确认版本

anchor --version

Solana CLI Basics

solana config set --url devnet

Create Wallet

solana-keygen new
Wrote new keypair to /home/surou/.config/solana/id.json
pubkey: BAGNJGtBngKZKdcZRNjebnS6mwPg5prDgj6JyR74D4ad

查看当前地址

solana address

获取测试币

solana config set -ud
solana airdrop 5

注:当前devnet最大每次5 SOL

查看余额

solana balance

Anchor CLI Basics

初始化项目名

anchor init anchor init my-project
cd my-project
anchor build
anchor deploy
anchor test

测试交易

anchor init 自动创建的测试程序

use anchor_lang::prelude::*;

declare_id!("9X2BqKSgKDrEhRsemfmkrAjpYVB78HpoWRBKTMPBPup9");

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

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        msg!("Greetings from: {:?}", ctx.program_id);
        Ok(())
    }
}

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

交易发起地址:https://explorer.solana.com/address/BAGNJGtBngKZKdcZRNjebnS6mwPg5prDgj6JyR74D4ad?cluster=devnet

部署交易

https://explorer.solana.com/tx/47xSqiSDduatTW2xXgQeDNvkN12aboAaThzFqXVHQTqsZGXhrbQRTkRiREkLk3skLfCRxJVmbHi2da5t6BkGxL9d?cluster=devnet

  • 程序账户(新建):9X2BqKSgKDrEhRsemfmkrAjpYVB78HpoWRBKTMPBPup9
  • 缓冲区账户:HHYvtbHvaUQgX6zG2BvPui8PwQ23zS5Bneqm1eELj8V6 {缓冲区账户是 Solana 生态系统中一种用于存储和管理程序数据的特殊账户类型,它为开发人员提供了灵活的数据管理和更新机制}
  • 程序存储账户:https://explorer.solana.com/address/9ZHpouNY6xrEVWjzgtFp4zsJGrViVGkS7JS4xEn9qo5f?cluster=devnet
    • Upgradeable:Yes
    • Upgrade Authority: BAGNJGtBngKZKdcZRNjebnS6mwPg5prDgj6JyR74D4ad

查看交易地址,发现很多笔与BPFLoaderUpgradeab1e11111111111111111111111的交易被打包
例如:https://explorer.solana.com/tx/2FB1tRfGn2NSXF7hHFwTeE9WAAa4eHTwmh82Ly1M4EUBcRZfTiCo2RRyjWPK6w4vD9vNNSH6RjWRudhHmtmBpWWn?cluster=devnet

Solana 上每笔交易能够携带的数据量存在限制。要是程序的字节码过大,就需要把字节码分割成多个部分,然后通过多笔交易依次上传。这就会产生很多笔与 BPFLoaderUpgradeable 相关的交易。

发起交易

执行 anchor test,自动执行程序中的initialize

describe("my-project", () => {
  // Configure the client to use the local cluster.
  anchor.setProvider(anchor.AnchorProvider.env());

  const program = anchor.workspace.MyProject as Program<MyProject>;

  it("Is initialized!", async () => {
    // Add your test here.
    const tx = await program.methods.initialize().rpc();
    console.log("Your transaction signature", tx);
  });
});

对应交易为:https://explorer.solana.com/tx/3vzfjypR6AJVYvGgr8tiqpqTXrbYGsyMXwaidhv35haxCGFJJfDUT5oLra5dAoZpLx7tQsmTT7goZxTCuLNUz5qS?cluster=devnet

程序升级

anchor upgrade --program-id 9X2BqKSgKDrEhRsemfmkrAjpYVB78HpoWRBKTMPBPup9 ./target/deploy/my_project.so 

对应交易:https://explorer.solana.com/tx/5B8ZdZrZ3oKxMr5iF1PXdbPRPD1LZ75vEFVTmnQUUNrAhqm18kt8ydM4S6o4Z9LN3jMN69nvDXW5b4vc8PzzLWDM?cluster=devnet

对比首次部署时的交易:https://explorer.solana.com/tx/47xSqiSDduatTW2xXgQeDNvkN12aboAaThzFqXVHQTqsZGXhrbQRTkRiREkLk3skLfCRxJVmbHi2da5t6BkGxL9d?cluster=devnet

缓冲区账户由 HHYvtbHvaUQgX6zG2BvPui8PwQ23zS5Bneqm1eELj8V6 更新为 AxQ65Tm1VSptQWT22AsZFsdFovbYgo4i7dJHJLNwJjxa
类似于以太坊中的升级代理合约变更了逻辑地址

对比以太坊,Solana的程序升级简化很多

https://www.anchor-lang.com/docs/installation