> For the complete documentation index, see [llms.txt](https://docs.rome.builders/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rome.builders/ru/rukovodstva-dlya-razrabotchikov/call-solana-from-evm.md).

# Вызов Solana из EVM

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

## Требования

* Интерфейсы Rome Solidity из публичного [`rome-solidity`](https://github.com/rome-protocol/rome-solidity) репозитория (публикация в npm ожидается) — интерфейсы предкомпиляции находятся в [`contracts/interface.sol`](https://github.com/rome-protocol/rome-solidity/blob/master/contracts/interface.sol)
* Развернутый контракт Rome (см. [Развертывание Solidity](/ru/rukovodstva-dlya-razrabotchikov/deploy-solidity.md))

Привяжите каждый интерфейс к его адресу предкомпиляции:

```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`):

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

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

## Перевод lamports

Для простых переводов SOL/lamports и SPL из PDA вызывающей стороны используйте предкомпиляцию HelperProgram — вручную собирать CPI не требуется:

```solidity
contract Transfers {
    IHelperProgram constant Helper = IHelperProgram(0xFF00000000000000000000000000000000000009);

    // Перевести lamports на PDA адреса EVM
    function transferSol(address to, uint64 lamports) external {
        Helper.transfer_lamports(to, lamports);
    }

    // Перевести SPL-токен из PDA вызывающей стороны
    function transferSpl(address to, uint64 tokens, bytes32 mint) external {
        Helper.transfer_spl(to, tokens, mint);
    }

    // Создать ATA вызывающей стороны для mint
    function createAta(bytes32 mint) external {
        Helper.create_ata(msg.sender, mint);
    }
}
```

`transfer_spl` имеет несколько перегрузок (включая вариант delegate для `transferFrom` потоков); см. `interface.sol`. В кэшированном варианте используйте `ISplCached` (`0xff…05`) / `IAssociatedSplCached` (`0xff…06`) вместо этого — контракт должен последовательно использовать один вариант.

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

Читайте данные любого аккаунта Solana с помощью сокращенных способов чтения CpiProgram:

```solidity
(
    uint64 lamports,
    bytes32 owner,
    bool isSigner,
    bool isWritable,
    bool executable,
    bytes memory data
) = CpiProgram.account_info(accountPubkey);
```

## Получение PDA

Находите Program Derived Address из Solidity через предкомпиляцию System:

```solidity
ISystemProgram.Seed[] memory seeds = new ISystemProgram.Seed[](2);
seeds[0] = ISystemProgram.Seed("my-program-seed");
seeds[1] = ISystemProgram.Seed(abi.encodePacked(someValue));

(bytes32 pda, uint8 bump) = SystemProgram.find_program_address(targetProgramId, seeds);
```

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

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

```solidity
bytes memory base58Str = SystemProgram.bytes32_to_base58(pubkey);
bytes32 pubkey = SystemProgram.base58_to_bytes32(base58Bytes);
```

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

Чтобы вызвать любую программу Solana, самостоятельно сформируйте список аккаунтов и данные инструкции:

```solidity
contract CustomCPI {
    ICrossProgramInvocation constant CpiProgram = ICrossProgramInvocation(0xFF00000000000000000000000000000000000008);
    bytes32 constant MY_PROGRAM = 0x0000000000000000000000000000000000000000000000000000000000000000; // your Solana program ID

    function callMyProgram(bytes32 account1, bytes32 account2, bytes calldata ixData) external {
        ICrossProgramInvocation.AccountMeta[] memory accounts = new ICrossProgramInvocation.AccountMeta[](2);
        accounts[0] = ICrossProgramInvocation.AccountMeta(account1, false, true);
        accounts[1] = ICrossProgramInvocation.AccountMeta(account2, false, false);

        CpiProgram.invoke(MY_PROGRAM, accounts, ixData);
    }
}
```

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

1. **Все аккаунты должны быть объявлены заранее.** Транзакция Solana должна включать каждый аккаунт, к которому обратится CPI — динамическое обнаружение аккаунтов внутри CPI невозможно.
2. **Ограничение глубины CPI: 4 уровня.** Rome EVM → ваша цель → вызов цели → еще один уровень. Планируйте глубину вызовов.
3. **Pubkey Solana — это `bytes32`,** не 20-байтные адреса Ethereum.
4. **Данные инструкции — это необработанные байты** в формате, который ожидает целевая программа (обычно Borsh, little-endian).

## Что дальше

* **Посмотрите это в реальном приложении** — [rome-dex](https://github.com/rome-protocol/rome-dex) (двухканальный AMM), [cardo](https://github.com/rome-protocol/cardo) (маршруты CPI в Meteora / Marinade / Mango / Jupiter), и [aerarium](https://github.com/rome-protocol/aerarium) вызывать Solana из Solidity в рабочей среде.
* [Вызов EVM из Solana](/ru/rukovodstva-dlya-razrabotchikov/call-evm-from-solana.md) — обратный сценарий: управлять контрактами EVM из кошелька Solana
* [Совместимость токенов](/ru/osnovnye-ponyatiya/token-interop.md) — как взаимодействуют токены ERC-20 и SPL
* [Ограничения](/ru/osnovnye-ponyatiya/constraints.md) — глубина CPI и другие ограничения


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.rome.builders/ru/rukovodstva-dlya-razrabotchikov/call-solana-from-evm.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
