CPI

微信扫码分享

CPI (Cross-Program Invocation)

概念简介

CPI(跨程序调用)是 Solana 区块链中一个重要的机制,允许一个程序直接调用另一个程序的指令。这是 Solana 实现程序可组合性的核心特性。

如果把 Solana 指令比作程序向网络公开的 API 端点,那么 CPI 就像是一个端点在内部调用另一个端点。通过 CPI,开发者可以构建复杂的、模块化的应用程序,充分利用现有程序的功能。

工作原理

当程序 A 调用程序 B 的指令时,账户权限会从一个程序扩展到另一个程序。程序 B 可以使用与程序 A 相同的账户及其原始权限,这意味着:

  • 程序 B 可以使用签名者账户进行签名
  • 程序 B 可以写入可写账户

这种权限传递机制确保了跨程序调用的安全性和一致性。

核心特性

账户权限扩展

  • 被调用程序继承调用程序的账户权限
  • 保持原始账户的可写和签名属性
  • 确保权限链的安全传递

PDA 签名

  • 程序可以代表从其程序 ID 派生的 PDA(程序派生地址)进行签名
  • 签名者权限从调用程序扩展到被调用程序
  • 允许程序在没有私钥的情况下控制账户

调用深度限制

  • 堆栈高度从初始交易的 1 开始
  • 每次程序调用另一个指令时,堆栈高度增加 1
  • CPI 调用深度限制为 4 层
  • 防止无限递归和资源耗尽

实现方法

Solana 提供了两种主要的 CPI 实现方式:

invoke 函数

  • 用于不需要 PDA 签名者的 CPI
  • 适用于简单的跨程序调用场景
  • 内部实际调用 invoke_signed 函数,传递空的签名种子数组

invoke_signed 函数

  • 用于需要 PDA 签名者的 CPI
  • 传递 PDA 的种子用于签名验证
  • 允许程序代表其派生的 PDA 进行操作

使用场景

  • DeFi 协议组合:DEX 调用借贷协议,实现闪电贷交易
  • NFT 市场:市场程序调用 Token 程序转移 NFT 所有权
  • 跨链桥:桥接程序调用多个 Token 程序处理资产转移
  • 游戏应用:游戏逻辑程序调用 NFT 铸造程序生成游戏道具
  • DAO 治理:治理程序调用国库程序执行提案

最佳实践

  1. 验证账户:在进行 CPI 之前,始终验证传入的账户
  2. 检查程序 ID:确保调用的是预期的程序
  3. 处理错误:适当处理被调用程序可能返回的错误
  4. 优化调用深度:避免不必要的深层嵌套调用
  5. 安全性考虑:注意重入攻击和权限提升风险

相关链接