3 个版本
0.0.3 | 2022年1月27日 |
---|---|
0.0.2 | 2022年1月26日 |
0.0.1 | 2022年1月26日 |
#38 in #on-chain
34KB
905 行
列表程序
列表程序创建Solana账户地址列表。开发者可以使用这些列表来索引与其程序相关的账户数据,而无需依赖于链下索引解决方案。
开始使用
# Cargo.toml
[dependencies]
index-program = { version = "0.0.2" }
主网: HPVqgVHeD9NPrJFSCd2UnpBudMYvorXYkzAqmy5naHTr
开发网: HPVqgVHeD9NPrJFSCd2UnpBudMYvorXYkzAqmy5naHTr
说明
create_list
- 初始化一个新的
List
账户。 - 如果
- 给定的所有者和命名空间已经存在列表。
delete_list
- 关闭一个
List
账户。 - 将租金返还给所有者。
push_element
- 初始化一个新的
Element
账户。 - 将元素追加到索引的数据结构中。
- 如果
- 列表已经达到最大容量。
pop_element
- 关闭一个
Element
账户。 - 从索引的数据结构中删除元素。
- 将租金返还给所有者。
状态
列表
- 管理地址列表的元数据。
- PDA是所有者地址和自定义命名空间地址的哈希。
元素
- 具有列表中位置的地址值。
- PDA是列表地址和指针位置的哈希。
示例
以下示例适用于需要创建和管理自己的链上列表的Solana程序。以下示例显示了具有用于代表程序签署指令的单一实例“授权账户”的Anchor程序。
创建列表
以下是一个示例指令create_my_list
,用于创建由程序拥有的列表。
// create_my_list.rs
use {
crate::state::*,
anchor_lang::{prelude::*, solana_program::system_program},
std::mem::size_of,
};
#[derive(Accounts)]
#[instruction(bump: u8)]
pub struct CreateMyList<'info> {
#[account(
mut,
seeds = [SEED_AUTHORITY],
bump = authority.bump,
owner = crate::ID
)]
pub authority: Account<'info, Authority>,
#[account(mut)]
pub list: AccountInfo<'info>,
#[account(address = list_program::ID)]
pub list_program: Program<'info, list_program::program::ListProgram>,
#[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>, bump: u8) -> ProgramResult {
// Get accounts.
let authority = &ctx.accounts.authority;
let list = &ctx.accounts.list;
let list_program = &ctx.accounts.list_program;
let namespace = &ctx.accounts.namespace;
let signer = &ctx.accounts.signer;
let system_program = &ctx.accounts.system_program;
// Create a list owned by the program authority.
list_program::cpi::create_index(
CpiContext::new_with_signer(
list_program.to_account_info(),
list_program::cpi::accounts::CreateList {
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]]],
),
bump,
)
}
推送元素
以下是一个示例指令push_my_element
,用于将元素添加到由程序拥有的列表中。
// create_my_pointer.rs
use {
crate::state::*,
anchor_lang::{prelude::*, solana_program::system_program},
std::mem::size_of,
};
#[derive(Accounts)]
#[instruction(reference: Pubkey, bump: u8)]
pub struct CreateMyPointer<'info> {
#[account(
mut,
seeds = [SEED_AUTHORITY],
bump = authority.bump,
owner = crate::ID
)]
pub authority: Account<'info, Authority>,
#[account()]
pub element: AccountInfo<'info>,
#[account(
mut,
constraint = list.owner == authority.key(),
constraint = list.namespace == namespace.key(),
owner = list_program.key()
)]
pub list: AccountInfo<'info>,
#[account(address = list_program::ID)]
pub list_program: Program<'info, list_program::program::IndexProgram>,
#[account()]
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<CreateMyPointer>,
reference: Pubkey,
bump: u8,
) -> ProgramResult {
// Get accounts.
let authority = &ctx.accounts.authority;
let element = &ctx.accounts.element;
let list = &ctx.accounts.list;
let list_program = &ctx.accounts.list_program;
let signer = &ctx.accounts.signer;
let system_program = &ctx.accounts.system_program;
// Add the reference address into the list.
list_program::cpi::push_element(
CpiContext::new_with_signer(
list_program.to_account_info(),
list_program::cpi::accounts::PushElement {
element: element.to_account_info(),
list: list.to_account_info(),
owner: authority.to_account_info(),
payer: signer.to_account_info(),
system_program: system_program.to_account_info(),
},
&[&[SEED_AUTHORITY, &[authority.bump]]],
),
reference,
bump,
)
}
依赖项
~18–27MB
~461K SLoC