在本节中,通过添加跨程序调用 (CPI) 来更新上一个 PDA 部分中的 CRUD 程序,该功能使 Solana 程序能够相互调用。
本教程还介绍了程序在进行跨程序调用时如何“签名”程序派生地址 (PDA)。
更新和删除指令需要修改,以通过调用系统程序处理账户之间的SOL转账。
本节的目的包括演练实现过程 使用 Anchor 框架的 Solana 程序中的 CPI,基于 PDA 构建 上一节中探讨的概念。有关更多详细信息,请参阅 跨程序调用页面。
作为参考,此链接包括 完成 PDA 和 CPI 部分后的最终代码。
本节的起始代码仅包括 completed 的 PDA 部分。
1.更新 Update 指令
首先,该程序需要一个简单的 “付费更新”(pay-to-update) 机制,通过修改 update
struct 和 update
函数。
首先更新 lib.rs
文件,以将 system_program
模块。
use anchor_lang::system_program::{transfer, Transfer};
接下来,更新 Update
结构以包含名为 vault_account
。此帐户由程序控制,在用户更新其消息帐户时接收用户的 SOL。
#[account(
mut,
seeds = [b"vault", user.key().as_ref()],
bump,
)]
pub vault_account: SystemAccount<'info>,
接下来,在更新
指令中添加 CPI 逻辑,将 0.001 SOL 从用户账户转移到保险库账户。
let transfer_accounts = Transfer {
from: ctx.accounts.user.to_account_info(),
to: ctx.accounts.vault_account.to_account_info(),
};
let cpi_context = CpiContext::new(
ctx.accounts.system_program.to_account_info(),
transfer_accounts,
);
transfer(cpi_context, 1_000_000)?;
重新生成程序。
build
2.更新 Delete 指令
现在,通过更改 Delete
结构体和 delete
函数。
首先,更新 Delete
结构以包含 vault_account
。这允许在用户关闭其消息账户时将保险库中的任何 SOL 转移回用户。
#[account(
mut,
seeds = [b"vault", user.key().as_ref()],
bump,
)]
pub vault_account: SystemAccount<'info>,
此外,添加 system_program
,因为传输的 CPI 需要调用系统程序。
pub system_program: Program<'info, System>,
接下来,在 delete
指令中添加 CPI 逻辑,以将 SOL 从保险库账户转回用户账户。
let user_key = ctx.accounts.user.key();
let signer_seeds: &[&[&[u8]]] =
&[&[b"vault", user_key.as_ref(), &[ctx.bumps.vault_account]]];
let transfer_accounts = Transfer {
from: ctx.accounts.vault_account.to_account_info(),
to: ctx.accounts.user.to_account_info(),
};
let cpi_context = CpiContext::new(
ctx.accounts.system_program.to_account_info(),
transfer_accounts,
).with_signer(signer_seeds);
transfer(cpi_context, ctx.accounts.vault_account.lamports())?;
请注意,_ctx:Context<Delete>
更改为 ctx: Context<Delete>
,以在函数正文中使用上下文。
重新生成程序。
build
3.重新部署程序
(这个还没写完,一直在草稿箱里,先发出来吧。但最近方向侧重点在量化上,我本人喜欢变来变去不可持续)