Solana 学习开发之旅

2025年04月03日更新 33 人订阅
原价: ¥ 20 限时优惠
专栏简介 【Solana】使用 CLI 创建 SPL 标准的 Token 以及基础使用 【Solana】完善 SPL Token 名称和 Logo 【Solana】创建 SPL 标准的 NFT 以及完善 metadata 【Solana】一些基本的js脚本 【Solana】Anchor 框架使用笔记 【Solana】Anchor 示例:通过 CPI 实现 Sol 转账与手续费收取 Solana Hello World: 安装与开发指南 Solana 与 Rust 算术入门—从 Solidity 到 Anchor Solana Anchor 程序接口定义语言(IDL) Solana Anchor 框架下的 Require 与自定义错误 Solana 程序:支持升级与无构造函数实现 Solidity 开发者必知的 Rust 语法基础 Rust 的独特语法解析 Rust 类函数宏解析 Rust 结构体、属性宏与自定义派生宏 Rust 与 Solana 中的可见性及模块化复用 Solana 中的时钟与其他区块变量 Solana 系统变量详解 Solana 日志、事件日志与历史交易查询 Solana 中的Tx.origin、msg.sender 和 onlyOwner Solana 计算单元与交易费用概述 Solana 与 Anchor 中的账户初始化 Solana 计数器教程:账户数据的读写 使用 Solana Web3.js 和 Anchor 读取账户数据 在 Solana 中实现映射表与嵌套映射表 Solana 存储成本、最大容量与账户调整 在 Anchor 中读取账户余额:Solana 的 address(account).balance Solana 中的函数修饰符与 Fallback 函数:为何不存在 Solana 中的 SOL 转移与分割:取代 msg.value 的设计 使用不同签名者修改账户:Solana 中的权限控制 PDA 与密钥对账户:Solana 中的地址与权限模型 Anchor 中的 init_if_needed 与重新初始化攻击防范 Solana 中的 Multicall:批处理交易和交易大小的限制 Solana 中的 Owner 和 Authority 删除和关闭 Solana 中的账户和程序 在 Anchor 中的 #[derive(Accounts)] 不同类型的账户 在链上读取另一个 Anchor 程序的账户数据 Anchor 中的跨程序调用

Anchor 中的跨程序调用

  • 0xE
  • 发布于 2025-04-03 10:59
  • 阅读 1535

本文将详细讲解如何在 Anchor 框架中实现 CPI,重点展示调用另一个 Anchor 程序的过程,并以 Alice 调用 Bob 的示例说明。

跨程序调用(CPI)是指在 Solana 中一个程序调用另一个程序的公共函数。本文将详细讲解如何在 Anchor 框架中实现 CPI,重点展示调用另一个 Anchor 程序的过程,并以 Alice 调用 Bob 的示例说明。注意,本教程适用于 Anchor 程序,不适用于纯 Rust 开发的程序。


CPI 基础回顾

CPI 的典型示例是向系统程序转账 SOL:

pub fn send_sol(ctx: Context<SendSol>, amount: u64) -> Result<()> {
    let cpi_context = CpiContext::new(
        ctx.accounts.system_program.to_account_info(),
        system_program::Transfer {
            from: ctx.accounts.signer.to_account_info(),
            to: ctx.accounts.recipient.to_account_info(),
        }
    );

    let res = system_program::transfer(cpi_context, amount);

    if res.is_ok() {
        return Ok(());
    } else {
        return err!(Errors::TransferFailed);
    }
}

CpiContext 表示跨程序调用,调用其他程序的逻辑与之类似。


Bob 程序

首先创建 Bob 程序:

anchor init bob

将以下代码写入 bob/lib.rs:

use anchor_lang::prelude::*;
use std::mem::size_of;

declare_id!("BN2aLyQ8UJozgebuDVdwhY47VZA2RbS3HDRDz5zyYQqw");

#[program]
pub mod bob {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        msg!("Data Account Initialized: {}", ctx.accounts.bob_data_account.key());
        Ok(())
    }

    pub fn add_and_store(ctx: Context<BobAddOp>, a: u64, b: u64) -> Result<()> {
        let result = a + b;
        ctx.accounts.bob_data_account.result = result;
        Ok(())
    }
}

#[account]
pub struct BobData {
    pub result: u64,
}

#[derive(Accounts)]
pub struct BobAddOp<'info> {
    #[account(mut)]
    pub bob_data_account: Account<'info, BobData>,
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(init, payer = signer, space = size_of::<BobData>() + 8)]
    pub bob_data_account: Account<'info, BobData>,
    #[account(mut)]
    pub signer: Signer<'info>,
    pub system_program: Program<'info, System>,
}

Bob 提供两个函数:initialize 初始化存储账户,add_and_store 将两个 u64 相加并存储。


Alice 程序

在 bob 项目中创建 Alice 程序:

anchor new alice

编辑 programs/alice/Cargo.toml,添加依赖:

[dependencies]
bob = { path = "../bob", features = ["cpi"] }

此依赖使 Alice 能访问 Bob 的函数和结构体,类似 Solidity 中的接口导入。

Alice 的完整代码如下:


use anchor_lang::prelude::*;
use bob::cpi::accounts::BobAddOp;
use bob::program::Bob;
use bob::BobData;

declare_id!("GaKz6s9cpFBNMTM56TE3uQLMJ3YefZp4VFiUnCkQT8fU");

#[program]
pub mod alice {
    use super::*;

    pub fn ask_bob_to_add(ctx: Context<AliceOp>, a: u64, b: u64) -> Result<()> {
        let cpi_ctx = CpiContext::new(
            ctx.accounts.bob_program.to_account_info(),
            BobAddOp {
                bob_data_account: ctx.accounts.bob_data_account.to_account_info(),
            }
        );

        let res = bob::cpi::add_and_store(cpi_ctx, a, b);

        if res.is_ok() {
            return Ok(());
        } else {
            return err!(Errors::CPIToBobFailed);
        }
    }
}

#[error_code]
pub enum Errors {
    #[msg("cpi to bob failed")]
    CPIToBobFail...

剩余50%的内容订阅专栏后可查看

点赞 1
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论