> 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/ja/gaido/call-solana-from-evm.md).

# EVMからSolanaを呼ぶ

RomeのCPIとヘルパーprecompileを使って、SolidityからSolanaプログラムを呼び出します。

Rome のプリコンパイルにより、Solidity コントラクトは Solana プログラムを直接呼び出せます。このガイドではその仕組みを説明します。

## 前提条件

* 公開リポジトリの Rome Solidity インターフェース [`rome-solidity`](https://github.com/rome-protocol/rome-solidity) repo（GitHub からインストール、npm ではありません — 参照 [Solidityをデプロイ](/ja/gaido/deploy-solidity.md#using-the-rome-solidity-sdk)）— プリコンパイルのインターフェースは次にあります [`contracts/interface.sol`](https://github.com/rome-protocol/rome-solidity/blob/master/contracts/interface.sol)
* デプロイ済みの Rome コントラクト（参照 [Solidityをデプロイ](/ja/gaido/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 が署名し、さらに `salts` の各エントリごとに 1 つ
// ソルト付きサブPDA（Rome は ["EXTERNAL_AUTHORITY", contract, salt] を導出します）
CpiProgram.invoke_signed(programId, accounts, data, salts);
```

## lamport を転送する

シンプルな lamport および SPL の転送には、HelperProgram のプリコンパイルを使ってください。手動で CPI を組み立てる必要はありません。これを呼び出すコントラクトは **自身**として動作します: 以下の転送は、コントラクト自身の lamport とトークン（外部権限 PDA が署名します）を移動するものであり、ユーザーのものではありません。コントラクトがユーザーの SPL トークンを自分が管理するトークンアカウントへ取り込み、その所有者を把握したい場合、ユーザーは SPL のデリゲーションを付与します。コントラクトへの ERC-20 `transfer` または `transferFrom` はラッパーのエスクロー台帳にクレジットされるだけで、コントラクトには引き出し元のトークンアカウントが与えられません — 参照 [Solana プログラムを統合する](/ja/gaido/integrate-solana-program.md).

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

    // このコントラクトの PDA から EVM アドレスの PDA へ lamport を転送
    function transferSol(address to, uint64 lamports) external {
        Helper.transfer_lamports(to, lamports);
    }

    // このコントラクトの PDA 所有トークンアカウントから SPL トークンを転送
    function transferSpl(address to, uint64 tokens, bytes32 mint) external {
        Helper.transfer_spl(to, tokens, mint);
    }

    // ミント用に呼び出し元の ATA を作成
    function createAta(bytes32 mint) external {
        Helper.create_ata(msg.sender, mint);
    }
}
```

`transfer_spl` には複数のオーバーロードがあります（ `transferFrom` のフロー向けの delegate 版を含む）。正確なシグネチャは `interface.sol`. キャッシュ済みのトラックでは、代わりに `ISplCached` (`0xff…05`) / `IAssociatedSplCached` (`0xff…06`) を使用します — コントラクトは 1 つのトラックを一貫して使い、レガシートラックだけが `invoke` カスタムプログラム（参照 [Solana プログラムを統合する](/ja/gaido/integrate-solana-program.md)).

## アカウントデータの読み取り

CpiProgram の読み取りショートカットを使って、任意の Solana アカウントのデータを読み取れます：

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

## PDA の導出

System プリコンパイルを使って Solidity から Program Derived Address を見つけます：

```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 → あなたの対象 → 対象の呼び出し → さらに 1 つ。呼び出しの深さを計画してください。
3. **Solana の pubkey は `bytes32`,** 20 バイトの Ethereum アドレスではありません。
4. **命令データは生のバイト列です** ターゲットのプログラムが期待する形式（通常は Borsh、リトルエンディアン）で。

## 次は

* **実際のアプリで見てみる** — [cardo](https://github.com/rome-protocol/cardo) は、アダプターコントラクトなしで、ユーザーのウォレットから直接プリコンパイルに CPI 呼び出しを送ります； [rome-dex](https://github.com/rome-protocol/rome-dex) （デュアルレーン AMM）も同様に動作し、さらにカストディ不要のルーターコントラクトも備えています； [aerarium](https://github.com/rome-protocol/aerarium) は、Solidity から Solana プログラムを呼び出さないレンディングアプリです。
* [Solana プログラムを統合する](/ja/gaido/integrate-solana-program.md) — ユーザーの Solana アイデンティティ、それを使った署名、ワントラックルール、そして向こう側の実プログラムのためのアカウント提供
* [プリコンパイル参照](/ja/rifarensu/precompiles.md) — すべてのプリコンパイル上のすべてのセレクタ
* [SolanaからEVMを呼ぶ](/ja/gaido/call-evm-from-solana.md) — 逆方向: Solana ウォレットから EVM コントラクトを駆動する
* [Token Interop](/ja/ji-ben-gai-nian/token-interop.md) — ERC-20 と SPL トークンがどのように連携するか
* [制約](/ja/ji-ben-gai-nian/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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.rome.builders/ja/gaido/call-solana-from-evm.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
