# Solana von EVM aus aufrufen

Romes CPI-Precompile ermöglicht es Solidity-Verträgen, jedes Solana-Programm direkt aufzurufen. Dieser Leitfaden behandelt die Mechanik.

## Voraussetzungen

* Rome Solidity SDK installiert: `npm install @rome-protocol/solidity-sdk`
* Ein bereitgestellter Rome-Vertrag (siehe [Solidity bereitstellen](/de/entwicklerhandbucher/deploy-solidity.md))

## Der CPI-Precompile

Der CPI-Precompile unter `0xFF00000000000000000000000000000000000008` stellt zwei Funktionen bereit:

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

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

// Aufruf mit PDA-Signatur (Ihr Vertrag signiert als PDA)
CpiProgram.invoke_signed(programId, accounts, data, seeds);
```

## Einfaches Beispiel: SOL übertragen

```solidity
// 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 des Absenders abrufen
        bytes32 senderPda = RomeEVMAccount.pda(msg.sender);

        // Transfer-Instruktion des System Program erstellen
        ICrossProgramInvocation.AccountMeta[] memory accounts = new ICrossProgramInvocation.AccountMeta[](2);
        accounts[0] = ICrossProgramInvocation.AccountMeta(senderPda, true, true);   // Absender (Signer, schreibbar)
        accounts[1] = ICrossProgramInvocation.AccountMeta(recipient, false, true);   // Empfänger (schreibbar)

        // Transfer-Instruktion des System Program (Variante 2, little-endian u64-Betrag)
        bytes memory data = abi.encodePacked(uint32(2), lamports);

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

## Kontodaten lesen

Der CPI-Precompile ermöglicht es Ihnen außerdem, die Daten eines beliebigen Solana-Kontos zu lesen:

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

## Arbeiten mit SPL-Token

Verwenden Sie das SPL-Token-Precompile für gängige Token-Operationen:

```solidity
import {SplToken, AssociatedSplToken} from "@rome-protocol/solidity-sdk/contracts/core/Precompiles.sol";

contract TokenOperations {
    // Guthaben eines Token-Kontos lesen
    function getBalance(bytes32 tokenAccount) external view returns (uint64) {
        ISplToken.Account memory acc = SplToken.account_state(tokenAccount);
        return acc.amount;
    }

    // SPL-Token übertragen
    function transferTokens(bytes32 recipientAta, bytes32 mint, uint256 amount) external {
        SplToken.transfer(recipientAta, mint, amount);
    }

    // Ein Associated Token Account erstellen
    function createAta(bytes32 wallet, bytes32 mint) external {
        AssociatedSplToken.create_associated_token_account(wallet, mint);
    }
}
```

## PDA-Ableitung

Program Derived Addresses aus Solidity finden:

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

// Eine PDA ableiten
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 Sie zwischen bytes32 und base58 (dem Adressformat von Solana):

```solidity
// bytes32 → base58-String
bytes memory base58Str = SystemProgram.bytes32_to_base58(pubkey);

// base58-String → bytes32
bytes32 pubkey = SystemProgram.base58_to_bytes32(base58Bytes);
```

## Benutzerdefinierte Solana-Programme aufrufen

Um irgendein beliebiges Solana-Programm aufzurufen:

```solidity
contract CustomCPI {
    bytes32 constant MY_PROGRAM = 0x...; // 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 der CPI berührt. Eine dynamische Kontoermittlung innerhalb von CPI ist nicht möglich.
2. **CPI-Tiefe-Limit: 4 Ebenen.** Rome EVM → Ihr Ziel → Aufruf des Ziels → Noch eine Ebene. Planen Sie Ihre Aufruftiefe sorgfältig.
3. **Solana-Pubkeys sind bytes32.** Alle Adressen sind 32-Byte-Solana-Pubkeys, keine 20-Byte-Ethereum-Adressen.
4. **Instruktionsdaten sind rohe Bytes.** Sie müssen die Instruktionsdaten in dem Format kodieren, das das Zielprogramm erwartet (typischerweise Borsh-kodiert, little-endian).

## Was kommt als Nächstes

* [Token-Verpackung](https://github.com/rome-protocol/docs/blob/main/developer-guides/token-wrapping.md) — ERC-20-Wrappers für SPL-Token bereitstellen
* [Transfer-Hook erstellen](https://github.com/rome-protocol/docs/blob/main/developer-guides/build-transfer-hook.md) — EVM-gestützte Transfer-Hooks erstellen
* [CU-Optimierung](https://github.com/rome-protocol/docs/blob/main/developer-guides/cu-optimization.md) — den Verbrauch von Compute Units für CPI-Aufrufe reduzieren


---

# Agent Instructions: 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:

```
GET https://docs.rome.builders/de/entwicklerhandbucher/call-solana-from-evm.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
