Вызов Solana из EVM

Предварительная компиляция CPI в Rome позволяет контрактам Solidity напрямую вызывать любой программный модуль Solana. В этом руководстве рассматривается механизм работы.

Требования

  • Установлен Rome Solidity SDK: npm install @rome-protocol/solidity-sdk

  • Развернутый контракт Rome (см. Развернуть Solidity)

Предварительная компиляция CPI

Предварительная компиляция CPI по адресу 0xFF00000000000000000000000000000000000008 предоставляет две функции:

import {CpiProgram} from "@rome-protocol/solidity-sdk/contracts/core/Precompiles.sol";

// Вызов программы Solana
CpiProgram.invoke(programId, accounts, instructionData);

// Вызов с подписью PDA (ваш контракт подписывает как PDA)
CpiProgram.invoke_signed(programId, accounts, data, seeds);

Базовый пример: перевод SOL

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {SystemProgram, CpiProgram} from "@rome-protocol/solidity-sdk/contracts/core/Precompiles.sol";
import {RomeEVMAccount} from "@rome-protocol/solidity-sdk/contracts/core/RomeEVMAccount.sol";

contract SolTransfer {
    function transferSol(bytes32 recipient, uint64 lamports) external {
        // Получить PDA отправителя
        bytes32 senderPda = RomeEVMAccount.pda(msg.sender);

        // Сформировать инструкцию перевода System Program
        ICrossProgramInvocation.AccountMeta[] memory accounts = new ICrossProgramInvocation.AccountMeta[](2);
        accounts[0] = ICrossProgramInvocation.AccountMeta(senderPda, true, true);   // отправитель (подписант, изменяемый)
        accounts[1] = ICrossProgramInvocation.AccountMeta(recipient, false, true);   // получатель (изменяемый)

        // Инструкция перевода System Program (вариант 2, little-endian u64 amount)
        bytes memory data = abi.encodePacked(uint32(2), lamports);

        CpiProgram.invoke(SystemProgram.program_id(), accounts, data);
    }
}

Чтение данных аккаунта

Предварительная компиляция CPI также позволяет читать данные любого аккаунта Solana:

Работа с токенами SPL

Используйте предварительную компиляцию SPL Token для распространенных операций с токенами:

Вычисление PDA

Поиск адресов, производных от программы, из Solidity:

Преобразование Base58

Преобразование между bytes32 и base58 (формат адресов Solana):

Вызов пользовательских программ Solana

Чтобы вызвать любую произвольную программу Solana:

Ключевые ограничения

  1. Все аккаунты должны быть объявлены заранее. Транзакция Solana должна включать каждый аккаунт, к которому обратится CPI. Динамическое обнаружение аккаунтов внутри CPI невозможно.

  2. Ограничение глубины CPI: 4 уровня. Rome EVM → Ваша цель → Вызов цели → Ещё один уровень. Тщательно планируйте глубину вызовов.

  3. Публичные ключи Solana — это bytes32. Все адреса — это 32-байтовые публичные ключи Solana, а не 20-байтовые Ethereum-адреса.

  4. Данные инструкции — это необработанные байты. Вам нужно кодировать данные инструкции в формате, который ожидает целевая программа (обычно Borsh-encoded, little-endian).

Что дальше

Последнее обновление

Это было полезно?