从 EVM 调用 Solana
通过 Rome 的 CPI 和辅助预编译,从 Solidity 调用 Solana 程序。
Rome 的预编译使 Solidity 合约能够直接调用 Solana 程序。本指南涵盖其工作机制。
前提条件
来自公开仓库的 Rome Solidity 接口
rome-solidity仓库(npm 发布待定)— 预编译接口位于contracts/interface.sol已部署的 Rome 合约(参见 部署 Solidity)
将每个接口绑定到其预编译地址:
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 程序,请自行构建账户列表和指令数据:
关键限制
所有账户都必须预先声明。 Solana 交易必须包含 CPI 将要触及的每一个账户——CPI 内部无法动态发现账户。
CPI 深度限制:4 层。 Rome EVM → 你的目标 → 目标的调用 → 再多一层。请规划好调用深度。
Solana 公钥是
bytes32, 不是 20 字节的以太坊地址。指令数据是原始字节 其格式应符合目标程序的预期(通常为 Borsh、little-endian)。
下一步
从 Solana 调用 EVM — 反向流程:通过 Solana 钱包驱动 EVM 合约
代币互操作 — ERC-20 和 SPL 代币如何协同工作
限制 — CPI 深度及其他限制
最后更新于
这有帮助吗?