跨程序调用(CPI)是指一个程序调用另一个程序的指令(instruction)。这种机制允许Solana程序的可组合性。这种机制允许Solana程序的可组合性。你可以将指令视为程序向网络公开的API端点,而CPI则是一个API内部调用另一个API。当一个程序发起对
<!--StartFragment-->
跨程序调用(CPI)是指一个程序调用另一个程序的指令(instruction)。这种机制允许 Solana 程序的可组合性。 这种机制允许 Solana 程序的可组合性。
你可以将指令视为程序向网络公开的 API 端点,而 CPI 则是一个 API 内部调用另一个 API。
<!--EndFragment-->
<!--StartFragment-->
当一个程序发起对另一个程序的跨程序调用(CPI)时:
编写 CPI 指令遵循与构建添加到交易中的 [instruction]相同的模式。在底层,每个 CPI 指令必须指定以下信息:
根据你要调用的程序,可能有一些 crate 提供了用于构建指令的辅助函数。 然后,程序使 用solana_program
crate 中的以下函数之一执行 CPI:
invoke
—— 当没有 PDA 签名者时使用invoke_signed
—— 当调用程序需要使用从其程序 ID 派生的 PDA 进行签名时使用
<!--EndFragment-->
<!--StartFragment-->[invoke
]函 数用于进行不需要 PDA 签名者的 CPI。 在进行 CPI 时,提供给调用程序的签名者自动扩 展到被调用程序。
<!--EndFragment-->
pub fn invoke(
instruction: &Instruction,
account_infos: &[AccountInfo<'_>]
) -> Result<(), ProgramError>
<!--StartFragment-->
这是一个在 [Solana Playground]上的示例程序,该程序使用invoke
函数调用系统程序上的转账指令。你也可以参 考[基础 CPI 指南]了解更多细节。 你也可 以参考[基础 CPI 指南]了解更多细节。
<!--EndFragment-->
<!--StartFragment-->
[invoke_signed
]函 数用于进行需要 PDA 签名者的 CPI。 用于派生签名者 PDA 的种子作为signer_seeds
传 递给invoke_signed
函数。
你可以参考[程序派生地址]页面了解 PDA 的派生方式。 <!--EndFragment-->
pub fn invoke_signed(
instruction: &Instruction,
account_infos: &[AccountInfo<'_>],
signers_seeds: &[&[&[u8]]]
) -> Result<(), ProgramError>
<!--StartFragment-->
运行时使用授予调用程序的权限来确定可以扩展到被调用程序的权限。 在此上下文中,权 限指的是签名者和可写账户。 例如,如果调用程序正在处理的指令包含签名者或可写账 户,那么调用程序可以调用另一个也包含了该签名者和/或可写账户的指令。
虽然 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 指南]了 解更多细节。
<!--EndFragment-->
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!