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

# Solana von EVM aus aufrufen

Rufe Solana-Programme aus Solidity über Roms CPI und Hilfs-Precompiles auf.

Romes Precompiles ermöglichen es Solidity-Verträgen, Solana-Programme direkt aufzurufen. Dieser Leitfaden erklärt die Mechanik.

## Voraussetzungen

* Die Rome-Solidity-Interfaces aus dem öffentlichen [`rome-solidity`](https://github.com/rome-protocol/rome-solidity) Repository (von GitHub installiert, nicht über npm — siehe [Solidity bereitstellen](/de/entwicklerleitfaden/deploy-solidity.md#using-the-rome-solidity-sdk)) — die Precompile-Interfaces befinden sich in [`contracts/interface.sol`](https://github.com/rome-protocol/rome-solidity/blob/master/contracts/interface.sol)
* Ein bereitgestellter Rome-Vertrag (siehe [Solidity bereitstellen](/de/entwicklerleitfaden/deploy-solidity.md))

Binden Sie jedes Interface an seine Precompile-Adresse:

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

## Das CpiProgram-Precompile

`CpiProgram` (`0xFF…08`) leitet CPI weiter (`invoke` / `invoke_signed`) plus Cross-State-Leseabkürzungen (`account_info`, `account_data_at`, `account_u64_at`, `account_lamports`, `pdas_batch_derive`):

```solidity
// Ein Solana-Programm aufrufen
CpiProgram.invoke(programId, accounts, instructionData);

// Mit PDA-Signatur aufrufen: Die PDA mit externer Autorität Ihres Vertrags signiert, plus eine
// gesalzene Sub-PDA pro Eintrag in `salts` (Rome leitet ["EXTERNAL_AUTHORITY", contract, salt] ab)
CpiProgram.invoke_signed(programId, accounts, data, salts);
```

## Lamports übertragen

Für einfache Lamport- und SPL-Übertragungen verwenden Sie das HelperProgram-Precompile — kein manuell erstelltes CPI erforderlich. Ein Vertrag, der es aufruft, verhält sich als **selbst**: Die untenstehenden Übertragungen bewegen die eigenen Lamports und Token des Vertrags (seine PDA mit externer Autorität signiert), nicht die des Benutzers. Damit ein Vertrag die SPL-Token eines Benutzers in ein von ihm kontrolliertes Token-Konto ziehen und wissen kann, wem sie gehören, gewährt der Benutzer eine SPL-Delegierung. Ein ERC-20 `transfer` oder `transferFrom` an einen Vertrag schreibt nur das Escrow-Ledger des Wrappers gut und gibt dem Vertrag kein Token-Konto, von dem aus er ausgeben kann — siehe [Integrieren Sie ein Solana-Programm](/de/entwicklerleitfaden/integrate-solana-program.md).

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

    // Lamports von der PDA dieses Vertrags an die PDA einer EVM-Adresse übertragen
    function transferSol(address to, uint64 lamports) external {
        Helper.transfer_lamports(to, lamports);
    }

    // Ein SPL-Token aus dem von der PDA dieses Vertrags besessenen Token-Konto übertragen
    function transferSpl(address to, uint64 tokens, bytes32 mint) external {
        Helper.transfer_spl(to, tokens, mint);
    }

    // Erstelle den ATA des Aufrufers für einen Mint
    function createAta(bytes32 mint) external {
        Helper.create_ata(msg.sender, mint);
    }
}
```

`transfer_spl` hat mehrere Überladungen (einschließlich einer Delegate-Variante für `transferFrom` Abläufe); siehe `interface.sol`Auf dem Cached-Track verwenden Sie `ISplCached` (`0xff…05`) / `IAssociatedSplCached` (`0xff…06`) stattdessen — ein Vertrag verwendet konsequent einen Track, und nur der Legacy-Track kann `invoke` ein benutzerdefiniertes Programm (siehe [Integrieren Sie ein Solana-Programm](/de/entwicklerleitfaden/integrate-solana-program.md)).

## Kontodaten lesen

Lesen Sie die Daten eines beliebigen Solana-Kontos über die Leseabkürzungen des CpiProgram:

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

## PDA-Ableitung

Programmabgeleitete Adressen aus Solidity über das System-Precompile finden:

```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-Konvertierung

Konvertieren zwischen `bytes32` und Base58 (Solanas Adressformat):

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

## Benutzerdefinierte Solana-Programme aufrufen

Um ein beliebiges Solana-Programm aufzurufen, erstellen Sie die Kontoliste und die Instruktionsdaten selbst:

```solidity
contract CustomCPI {
    ICrossProgramInvocation constant CpiProgram = ICrossProgramInvocation(0xFF00000000000000000000000000000000000008);
    bytes32 constant MY_PROGRAM = 0x0000000000000000000000000000000000000000000000000000000000000000; // Ihre Solana-Programm-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);
    }
}
```

## Wichtige Einschränkungen

1. **Alle Konten müssen im Voraus deklariert werden.** Die Solana-Transaktion muss jedes Konto enthalten, das das CPI berühren wird — eine dynamische Kontoermittlung innerhalb von CPI ist nicht möglich.
2. **CPI-Tiefenlimit: 4 Ebenen.** Rome EVM → Ihr Ziel → der Aufruf des Ziels → noch einer. Planen Sie Ihre Aufruftiefe.
3. **Solana-Pubkeys sind `bytes32`,** keine 20-Byte-Ethereum-Adressen.
4. **Instruktionsdaten sind Rohbytes** im Format, das das Zielprogramm erwartet (typischerweise Borsh, Little-Endian).

## Wie es weitergeht

* **Sehen Sie es in einer echten App** — [cardo](https://github.com/rome-protocol/cardo) sendet CPI-Aufrufe direkt aus der Wallet des Benutzers an das Precompile, ohne Adaptervertrag; [rome-dex](https://github.com/rome-protocol/rome-dex) (Dual-Lane-AMM) macht dasselbe und hat außerdem einen verwahrungsfreien Router-Vertrag; [aerarium](https://github.com/rome-protocol/aerarium) ist eine Lending-App, die keine Solana-Programme aus Solidity aufruft.
* [Integrieren Sie ein Solana-Programm](/de/entwicklerleitfaden/integrate-solana-program.md) — die Solana-Identität des Benutzers, das Signieren in ihrem Namen, die One-Track-Regel und die Kontobereitstellung für ein echtes Programm auf der anderen Seite
* [Precompile-Referenz](/de/referenz/precompiles.md) — jeden Selector auf jedem Precompile
* [EVM aus Solana aufrufen](/de/entwicklerleitfaden/call-evm-from-solana.md) — das Gegenteil: EVM-Verträge aus einer Solana-Wallet steuern
* [Token-Interop](/de/kernkonzepte/token-interop.md) — wie ERC-20- und SPL-Token zusammenarbeiten
* [Beschränkungen](/de/kernkonzepte/constraints.md) — CPI-Tiefe und andere Einschränkungen


---

# 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/de/entwicklerleitfaden/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.
