#account #index #stack #addresses #on-chain #solana #instructions

已撤回 stack-program

在账户地址上创建链上栈

0.0.1 2022年1月26日

#65#on-chain

ISC 许可证

35KB
913

列表程序

列表程序 创建用于在链上索引 Solana 账户地址的查找表。开发者可以使用这些表来查找和验证与其程序指令和状态相关的账户数据。

开始使用

# Cargo.toml

[dependencies]
index-program = { version = "0.1.0" }

指令

create_index

  • 初始化一个新的 Index 账户。
  • 如果
    • 给定所有者和命名空间已存在索引。

create_pointer

  • 初始化一个新的 Pointer 账户。
  • 初始化一个新的 Proof 账户。
  • 将账户添加到索引的数据结构中。
  • 如果
    • 索引中已存在该名称。
    • 指针值已存在于索引中。

delete_index

  • 关闭一个 Index 账户。
  • 将租金返还给所有者。
  • 如果
    • 该账户不存在。

delete_pointer

  • 关闭一个 Pointer 账户。
  • 关闭一个 Proof 账户。
  • 从索引的数据结构中删除账户。
  • 将租金返还给所有者。
  • 如果
    • 账户不存在。

状态

索引

  • 管理指针集合的元数据。
  • PDA 是所有者地址和自定义命名空间地址的哈希。

指针

  • 命名公钥地址值。
  • PDA 是索引地址和指针名称的哈希。

证明

  • 一个用于在索引中查找公钥名称的“反向记录”。
  • PDA 是索引地址和指针存储地址值的哈希。

Frame 40159

示例

以下示例是为需要创建和管理自己的链上索引的 Solana 程序。这些示例显示了一个使用 Anchor 构建的程序,它有一个单例“授权账户”用于代表程序签署指令。

创建索引

以下是一个示例指令 create_my_index,用于创建由程序拥有的索引。

// create_my_index.rs

use {
    crate::state::*,
    anchor_lang::{prelude::*, solana_program::system_program},
    std::mem::size_of,
};

#[derive(Accounts)]
#[instruction(index_bump: u8)]
pub struct CreateMyIndex<'info> {
    #[account(mut, seeds = [SEED_AUTHORITY], bump = authority.bump, owner = crate::ID)]
    pub authority: Account<'info, Authority>,

    #[account(mut)]
    pub index: AccountInfo<'info>,

    #[account(address = index_program::ID)]
    pub index_program: Program<'info, index_program::program::IndexProgram>,

    #[account(init, payer = signer, space = 8 + size_of<Namespace>())]
    pub namespace: Account<'info, Namespace>

    #[account(mut)]
    pub signer: Signer<'info>,

    #[account(address = system_program::ID)]
    pub system_program: Program<'info, System>,
}

pub fn handler(ctx: Context<CreateMyIndex>, index_bump: u8) -> ProgramResult {
    // Get accounts.
    let authority = &ctx.accounts.authority;
    let index = &ctx.accounts.index;
    let index_program = &ctx.accounts.index_program;
    let namespace = &ctx.accounts.namespace;
    let signer = &ctx.accounts.signer;
    let system_program = &ctx.accounts.system_program;

    // Create an index owned by the program authority.
    index_program::cpi::create_index(
        CpiContext::new_with_signer(
            index_program.to_account_info(),
            index_program::cpi::accounts::CreateIndex {
                index: index.to_account_info(),
                namespace: namespace.to_account_info(),
                owner: authority.to_account_info(),
                payer: signer.to_account_info(),
                system_program: system_program.to_account_info(),
            },
            &[&[SEED_AUTHORITY, &[authority.bump]]],
        ),
        index_bump,
    )
}

创建指针

以下是一个示例指令 create_my_pointer,该指令为程序拥有的索引添加一个指针。

// create_my_pointer.rs

use {
    crate::state::*,
    anchor_lang::{prelude::*, solana_program::system_program},
    std::mem::size_of,
};

#[derive(Accounts)]
#[instruction(reference: Pubkey, pointer_bump: u8, proof_bump: u8)]
pub struct CreateMyPointer<'info> {
    #[account(mut, seeds = [SEED_AUTHORITY], bump = authority.bump, owner = crate::ID)]
    pub authority: Account<'info, Authority>,

    #[account(
      mut,
      constraint = index.owner == authority.key(),
      constraint = index.namespace == namespace.key(),
      owner = index_program.key()
    )]
    pub index: AccountInfo<'info>,

    #[account(address = index_program::ID)]
    pub index_program: Program<'info, index_program::program::IndexProgram>,

    #[account()]
    pub namespace: Account<'info, Namespace>

    #[account()]
    pub pointer: AccountInfo<'info>,

    #[account()]
    pub proof: AccountInfo<'info>,

    #[account(mut)]
    pub signer: Signer<'info>,

    #[account(address = system_program::ID)]
    pub system_program: Program<'info, System>,
}

pub fn handler(
  ctx: Context<CreateMyPointer>,
  reference: Pubkey,
  pointer_bump: u8,
  proof_bump: u8
) -> ProgramResult {
    // Get accounts.
    let authority = &ctx.accounts.authority;
    let index = &ctx.accounts.index;
    let index_program = &ctx.accounts.index_program;
    let pointer = &ctx.accounts.pointer;
    let proof = &ctx.accounts.proof;
    let signer = &ctx.accounts.signer;
    let system_program = &ctx.accounts.system_program;

    // Create an index owned by the program authority.
    index_program::cpi::create_pointer(
        CpiContext::new_with_signer(
            index_program.to_account_info(),
            index_program::cpi::accounts::CreatePointer {
                index: index.to_account_info(),
                pointer: pointer.to_account_info(),
                proof: proof.to_account_info(),
                owner: authority.to_account_info(),
                payer: signer.to_account_info(),
                system_program: system_program.to_account_info(),
            },
            &[&[SEED_AUTHORITY, &[authority.bump]]],
        ),
        index.count.to_string(),
        reference,
        pointer_bump,
        proof_bump,
    )
}

依赖关系

~17-26MB
~438K SLoC