区块链中文技术社区

Solana核心概念-跨程序调用 (CPI)

跨程序调用(CPI)是指一个程序调用另一个程序的指令(instruction)。这种机制允许 Solana 程序的可组合性。 这种机制允许 Solana 程序的可组合性。

你可以将指令视为程序向网络公开的 API 端点,而 CPI 则是一个 API 内部调用另一个 API。

当一个程序发起对另一个程序的跨程序调用(CPI)时:

Solana 程序运行时定义了一个名为 max_invoke_stack_height 的常量,其值设定为 5。 这表示程序指令调用堆栈的最大高度。 堆栈高度从交易指令的 1 开始,每次程序调用另 一个指令时增加 1。 此设置有效地将 CPI 的调用深度限制为 4。

关键点

如何编写 CPI

编写 CPI 指令遵循与构建添加到交易中的 instruction 相同的模式。在底层,每个 CPI 指令必须指定以下信息:

根据你要调用的程序,可能有一些 crate 提供了用于构建指令的辅助函数。 然后,程序使 用solana_program crate 中的以下函数之一执行 CPI:

基础 CPI

invoke函数用于进行不需要 PDA 签名者的 CPI。 在进行 CPI 时,提供给调用程序的签名者自动扩 展到被调用程序。

pub fn invoke(
    instruction: &Instruction,
    account_infos: &[AccountInfo<'_>]
) -> Result<(), ProgramError>

这是一个在 Solana Playground 上的示例程序,该程序使用invoke函数调用系统程序上的转账指令。你也可以参 考基础 CPI 指南了解更多细节。 你也可 以参考基础 CPI 指南了解更多细节。

带 PDA 签名者的 CPI

invoke_signed函 数用于进行需要 PDA 签名者的 CPI。 用于派生签名者 PDA 的种子作为signer_seeds传 递给invoke_signed函数。

你可以参考程序派生地址页面了解 PDA 的派生方式。

pub fn invoke_signed(
    instruction: &Instruction,
    account_infos: &[AccountInfo<'_>],
    signers_seeds: &[&[&[u8]]]
) -> Result<(), ProgramError>

运行时使用授予调用程序的权限来确定可以扩展到被调用程序的权限。 在此上下文中,权 限指的是签名者和可写账户。 例如,如果调用程序正在处理的指令包含签名者或可写账 户,那么调用程序可以调用另一个也包含了该签名者和/或可写账户的指令。

虽然 PDAs 没有私钥 ,但它们仍然可以通过 CPI 在指令中充当签名者。为了验证 PDA 是从调用程序派生的,生成 PDA 所用的种子必须作 为signers_seeds包含在内。 为了验证 PDA 是从调用程序派生的,生成 PDA 所用的种子 必须作为signers_seeds包含在内。

当 CPI 被处理时,Solana 运行时使用signers_seeds和调用程序的program_id 进 行内部调用create_program_address。 如果找到有效的 PDA,该地址 将被添加为有效签名者 。

这是一个在 Solana Playground 上的示例程序,该程序使用invoke_signed函数调用系统程序上的转账指令,并带有 PDA 签名者。 你可以参 考带 PDA 签名者的 CPI 指南了 解更多细节。

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »