Cross Program Invocation

Cross Program Invocation(CPI)是指一个 program 在执行过程中调用另一个程序的 instruction。CPI 实现了可组合性:网络上的任何程序都可以调用其他程序的指令。

Cross-program invocation exampleCross-program invocation example

关键要点

  • 两个函数invoke(无 PDA 签名)和 invoke_signed(带 PDA 签名)。
  • 权限扩展Account 权限(签名者、可写)会从调用方传递到被调用方。被调用方无法提升权限,只能使用调用方传递的权限。
  • 共享计算预算:被调用方消耗的 CU 会减少调用方剩余的预算。
  • 重入性:允许直接自递归(A->A->A),但不允许间接重入(A->B->A 返回 ReentrancyNotAllowed)。

限制

限制项数值来源
最大指令堆栈深度5(SIMD-0268 可达 9)MAX_INSTRUCTION_STACK_DEPTH, MAX_INSTRUCTION_STACK_DEPTH_SIMD_0268
CPI 调用成本1,000 CU(SIMD-0339 为 946)DEFAULT_INVOCATION_COST, INVOKE_UNITS_COST_SIMD_0339
每次 CPI 最多 PDA 签名者16MAX_SIGNERS
CPI 指令数据最大值10 KiB(10,240 字节)MAX_INSTRUCTION_DATA_LEN
返回数据最大值1,024 字节MAX_RETURN_DATA
CPI 账户信息最大数量128(SIMD-0339 可达 255)*MAX_CPI_ACCOUNT_INFOS, MAX_CPI_ACCOUNT_INFOS_SIMD_0339
CPI 序列化成本每 250 字节 1 CUcpi_bytes_per_unit
每次 CPI 账户数据最大重分配10,240 字节(10 KiB)MAX_PERMITTED_DATA_INCREASE

invokeinvoke_signed

Solana 提供了两个用于进行 CPI 的函数:

函数使用场景PDA 签名
invoke所有所需签名者已在原始交易中签名的 CPI
invoke_signed调用程序需要代表其拥有的 PDA 进行签名的 CPI是,通过 signer seeds

在底层,invoke 实际上只是调用了 invoke_signed,并传入一个空的 signer seeds 数组。当你不需要 PDA 签名时,使用 invoke;当程序需要代表 PDA 授权操作时,使用 invoke_signed

这两个函数最终都会触发相同的 syscall(sol_invoke_signed_rust),并经过相同的运行时路径(cpi_common)。唯一的区别在于是否提供了 signer seeds。当提供 seeds 时,运行时会派生 PDA 公钥,并在权限检查前将其加入有效签名者集合。

Is this page helpful?

Table of Contents

Edit Page

管理者

©️ 2026 Solana 基金会版权所有
取得联系