For the complete documentation index, see llms.txt. This page is also available as Markdown.

从 EVM 调用 Solana

通过 Rome 的 CPI 和辅助预编译,从 Solidity 调用 Solana 程序。

Rome 的预编译使 Solidity 合约能够直接调用 Solana 程序。本指南涵盖其工作机制。

前提条件

将每个接口绑定到其预编译地址:

import {ICrossProgramInvocation, ISystemProgram, IHelperProgram}
    from "@rome-protocol/rome-solidity/contracts/interface.sol";

ICrossProgramInvocation constant CpiProgram    = ICrossProgramInvocation(0xFF00000000000000000000000000000000000008);
ISystemProgram          constant SystemProgram = ISystemProgram(0xFF00000000000000000000000000000000000007);
IHelperProgram          constant Helper        = IHelperProgram(0xFF00000000000000000000000000000000000009);

CpiProgram 预编译

CpiProgram (0xFF…08)会分发 CPI(invoke / invoke_signed)以及跨状态读取快捷方法(account_info, account_data_at, account_u64_at, account_lamports, pdas_batch_derive):

// 调用一个 Solana 程序
CpiProgram.invoke(programId, accounts, instructionData);

// 使用 PDA 签名调用(你的合约作为 PDA 签名)
CpiProgram.invoke_signed(programId, accounts, data, seeds);

转账 lamports

对于来自调用者 PDA 的简单 SOL/lamports 和 SPL 转账,请使用 HelperProgram 预编译——无需手工构建 CPI:

transfer_spl 有多个重载版本(包括用于 transferFrom 流程的委托变体);准确签名请参见 interface.sol。在缓存路径上,改用 ISplCached (0xff…05) / IAssociatedSplCached (0xff…06)——一个合约应始终使用同一路径。

读取账户数据

通过 CpiProgram 读取快捷方法读取任意 Solana 账户的数据:

PDA 派生

通过 System 预编译从 Solidity 查找程序派生地址:

Base58 转换

在以下之间转换 bytes32 和 base58(Solana 的地址格式):

调用自定义 Solana 程序

要调用任何 Solana 程序,请自行构建账户列表和指令数据:

关键限制

  1. 所有账户都必须预先声明。 Solana 交易必须包含 CPI 将要触及的每一个账户——CPI 内部无法动态发现账户。

  2. CPI 深度限制:4 层。 Rome EVM → 你的目标 → 目标的调用 → 再多一层。请规划好调用深度。

  3. Solana 公钥是 bytes32, 不是 20 字节的以太坊地址。

  4. 指令数据是原始字节 其格式应符合目标程序的预期(通常为 Borsh、little-endian)。

下一步

  • 在真实应用中查看rome-dex (双轨 AMM), cardo (CPI 路由至 Meteora / Marinade / Mango / Jupiter),以及 aerarium 在生产环境中从 Solidity 调用 Solana。

  • 从 Solana 调用 EVM — 反向流程:通过 Solana 钱包驱动 EVM 合约

  • 代币互操作 — ERC-20 和 SPL 代币如何协同工作

  • 限制 — CPI 深度及其他限制

最后更新于

这有帮助吗?