Zum Hauptinhalt springen

Cross-VM-Interoperabilität

Die Triple-VM-Architektur von QoreChain (EVM, CosmWasm, SVM) ermöglicht es Smart-Contracts auf jeder virtuellen Maschine, mit Contracts auf jeder anderen VM zu kommunizieren. Das Modul x/crossvm stellt sowohl synchrone als auch asynchrone Messaging-Pfade bereit.

hinweis

Die folgenden Endpunkte verweisen standardmäßig auf einen lokalen Knoten. Verwenden Sie im Mainnet die qorechain-vladi-RPC-Endpunkte (Cosmos RPC 26657, EVM JSON-RPC 8545); das Testnet ist qorechain-diana.


Architekturüberblick

EVM (Solidity) CosmWasm (Rust/Wasm) SVM (BPF)
| | |
|--- sync (precompile) ->| |
| | |
|<-- async (EndBlocker) -|-- async (EndBlocker) ->|
| | |
|<------------ async (EndBlocker) ----------------|
PfadRichtungZeitpunktMechanismus
SynchronEVM zu CosmWasmGleiche TransaktionPrecompile bei 0x0000...0901
AsynchronCosmWasm zu EVMNächster BlockMsgCrossVMCall über EndBlocker
AsynchronSVM zu beliebiger VMNächster BlockMsgCrossVMCall über EndBlocker
AsynchronBeliebig zu SVMNächster BlockMsgCrossVMCall über EndBlocker

Synchroner Pfad (EVM zu CosmWasm)

Der synchrone Pfad verwendet ein EVM-Precompile an der Adresse 0x0000000000000000000000000000000000000901. Dies ermöglicht es Solidity-Contracts, CosmWasm-Contracts aufzurufen und innerhalb derselben Transaktion eine Antwort zu erhalten.

Solidity-Beispiel

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

interface ICrossVM {
function call(bytes calldata payload) external returns (bytes memory);
}

contract CrossVMCaller {
ICrossVM constant CROSSVM = ICrossVM(0x0000000000000000000000000000000000000901);

function callCosmWasmContract(
string memory cosmwasmAddr,
string memory executeMsg,
uint256 funds
) external returns (bytes memory) {
bytes memory payload = abi.encode(cosmwasmAddr, executeMsg, funds);
return CROSSVM.call(payload);
}
}

Das Precompile führt den CosmWasm-Contract sofort aus und gibt das Ergebnis zurück. Gas-Kosten: 50.000 Basis + Ausführungskosten.


Asynchroner Pfad

Alle anderen Cross-VM-Richtungen verwenden die asynchrone Nachrichtenwarteschlange. Nachrichten werden in einem Block eingereicht und vom EndBlocker im nächsten Block verarbeitet.

CLI

# CosmWasm to EVM
qorechaind tx crossvm call \
--source-vm cosmwasm \
--target-vm evm \
--target-contract 0x1234...abcd \
--payload '{"method":"transfer","params":["0xRecipient",100]}' \
--from mykey \
-y

# SVM to CosmWasm
qorechaind tx crossvm call \
--source-vm svm \
--target-vm cosmwasm \
--target-contract qor1contractaddr... \
--payload '{"execute":{"action":{}}}' \
--from mykey \
-y

# EVM to SVM (async)
qorechaind tx crossvm call \
--source-vm evm \
--target-vm svm \
--target-contract <program-id-base58> \
--payload '0a0b0c...' \
--from mykey \
-y

Nachrichten-Lebenszyklus

Jede Cross-VM-Nachricht durchläuft eine definierte Reihe von Zuständen:

Submitted --> Pending --> Executed
|
+--> Failed
|
+--> Timed Out
ZustandBeschreibung
SubmittedNachricht in die Warteschlange aufgenommen
PendingWartet auf die Ausführung im nächsten EndBlocker-Durchlauf
ExecutedZiel-Contract erfolgreich aufgerufen; Antwort aufgezeichnet
FailedAusführung des Ziel-Contracts zurückgesetzt; Fehler aufgezeichnet
Timed OutNachricht hat queue_timeout_blocks ohne Ausführung überschritten

Parameter

ParameterWertBeschreibung
max_message_size65.536 bytesMaximale Payload-Größe pro Nachricht
max_queue_size1.000Maximale Anzahl ausstehender Nachrichten in der Warteschlange
queue_timeout_blocks100Blöcke, bevor eine unverarbeitete Nachricht abläuft

Events

Das Modul x/crossvm emittiert die folgenden Events:

EventAttributeBeschreibung
crossvm_requestmessage_id, source_vm, target_vm, target_contract, senderNeue Cross-VM-Nachricht eingereicht
crossvm_responsemessage_id, status, resultNachricht ausgeführt (Erfolg oder Fehler)
crossvm_timeoutmessage_id, source_vm, target_vmNachricht ohne Ausführung abgelaufen

Abonnieren Sie Events über WebSocket:

wscat -c ws://localhost:26657/websocket
> {"jsonrpc":"2.0","method":"subscribe","params":["tm.event='Tx' AND crossvm_request.message_id EXISTS"],"id":1}

Nachrichten abfragen

CLI

# Query a specific message by ID
qorechaind query crossvm message <message-id>

# List all pending messages
qorechaind query crossvm pending

# List messages by sender
qorechaind query crossvm messages-by-sender <address>

JSON-RPC

curl -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "qor_getCrossVMMessage",
"params": ["<message-id>"],
"id": 1
}'

Antwortformat

{
"message_id": "crossvm-00000042",
"source_vm": "cosmwasm",
"target_vm": "evm",
"target_contract": "0x1234...abcd",
"sender": "qor1sender...",
"payload": "...",
"status": "executed",
"result": "0x...",
"submitted_height": 12345,
"executed_height": 12346
}

Designüberlegungen

Atomarität: Synchrone Aufrufe (EVM zu CosmWasm über Precompile) sind atomar — wenn eine der beiden Seiten zurückgesetzt wird, wird die gesamte Transaktion zurückgesetzt. Asynchrone Aufrufe sind über Blöcke hinweg nicht atomar; gestalten Sie Ihre Contracts so, dass sie die Zustände Failed und Timed Out ordnungsgemäß behandeln.

Reihenfolge: Nachrichten in der Warteschlange werden innerhalb jedes EndBlocker-Durchlaufs nach dem FIFO-Prinzip verarbeitet. Es gibt keine garantierte Reihenfolge über verschiedene Quell-VMs hinweg.

Payload-Kodierung: Das Payload-Format hängt von der Ziel-VM ab:

  • EVM-Ziele: ABI-kodierte Funktionsaufrufe
  • CosmWasm-Ziele: JSON-kodierte Execute-Nachrichten
  • SVM-Ziele: Hex-kodierte BPF-Instruktionsdaten

Nächste Schritte