メインコンテンツまでスキップ

SVM開発

QoreChainにはSolana Virtual Machine (SVM)実行環境が組み込まれており、開発者は使い慣れたSolanaツールを使ってSBF/BPFプログラムをデプロイ・実行できます。SVMモジュールはポート8899でSolana互換のJSON-RPCインターフェースを公開しており、これはqorechaind startによって自動的に起動されます(以下のJSON-RPCサーバーを参照)。

注記

以下のコマンドは、2026年6月7日から稼働しているチェインバージョンv3.1.97を実行中の**qorechain-vladi**メインネットを使用しています。テストネットの場合は--chain-id qorechain-dianaに置き換えてください。


SVMトランザクション送信は現在無効化されています

チェインバージョンv3.1.89(8月22日)以降、インシデントを受けて、SVM実行レーンはトランザクション送信についてネットワーク全体で無効化されています——x/svm宛に送信されるトランザクション(プログラムデプロイ、命令実行、アカウント作成、送金)はすべてcode 11, "SVM module is disabled"を返します。これは自分自身のノードにもパブリックエンドポイントにも当てはまります。読み取り系のRPCメソッドは引き続き応答する場合がありますが、このレーンが再開されるまでは、実運用のSVM統合を構築したりリハーサルしたりしないでください。これはランタイムパラメータではなくコンパイル時の無効化であるため、ガバナンス投票によって再度有効化することはできません。外部監査によって問題なしと確認されるまで、無効のままとなる見込みです。

概要​

x/svmモジュールは以下を提供します:

  • ネイティブQORをファーストクラスのSVMアセットとして — アカウントの統合残高がlamports単位で参照できます
  • SBF/BPFプログラムのデプロイと実行
  • データアカウントの作成と管理
  • Solana互換のJSON-RPCエンドポイント
  • QoreChainとSolanaのアドレス形式間の双方向アドレスマッピング
  • コンピュートバジェットの計測とレントベースのストレージ経済性

SVMインターフェース上のネイティブQOR​

チェインバージョンv3.1.82以降、SVMインターフェースは独立したサンドボックス残高ではなく、ファーストクラスのネイティブQORインターフェースです。アカウントが持つ単一の統合残高——Cosmosインターフェースではuqorとして、EVMでは18桁小数のweiとして参照できるのと同じ資金——が、SVM側ではlamports(9桁小数)として表示されます:

1 uqor = 1,000 lamports · 1 QOR = 1,000,000,000 lamports
  • getBalance / getAccountInfo はアカウントのネイティブQOR残高(lamports単位)を返します。
  • getSignaturesForAddress は、あるアドレスに関わるトランザクション履歴を返します——標準的なSolanaツールによる入金検知に利用できます。
  • System Programによる送金はネイティブQORを移動します — Solanaスタイルの送金命令は、CosmosのMsgSendやEVMの送金と同じ資金を移動させます。
  • SVMアドレス形式 — アカウントのSVMアドレスは、20バイトのアカウントバイト列を32バイトになるよう右側にパディングし、base58エンコードしたものです。3つのアドレス形式(qor1...、0x...、base58)はすべて同じアカウントを指します。

パブリックエンドポイント(https://svm.qore.host、https://svm-testnet.qore.host)は読み取り専用です——トランザクション送信はエッジ側で無効化されています。通常であれば、SVMトランザクションを送信するために自分自身のノード(ポート8899)を運用しますが、上記の注意事項のとおり、x/svmのトランザクションレーン自体が現在、自分自身のノードを含むネットワーク全体で無効化されています。


JSON-RPCサーバー​

Solana互換のJSON-RPCサーバーは**qorechaind startによって起動**され、デフォルトで有効になっています。app.toml内の[svm-rpc]セクションで設定します:

[svm-rpc]
# Enable the Solana-compatible JSON-RPC server
enable = true
# Address the server listens on
address = "127.0.0.1:8899"

デフォルトはenable = true、address = "127.0.0.1:8899"なので、起動したばかりのノードはすでにポート8899でSolana JSON-RPCインターフェースを提供しています——@solana/web3.jsは追加設定なしでhttp://127.0.0.1:8899に接続できます。getVersionは1.18.0-qorechainを返し、getBalance / getAccountInfoはオンチェーンの実際のSVMアカウントを返します。

プロパティ値
デフォルトURLhttp://127.0.0.1:8899
有効化デフォルトで有効
起動元qorechaind start
互換性Solana JSON-RPC(サブセット)
getVersion1.18.0-qorechain

サポートされているメソッド​

メソッド説明
getAccountInfoアカウントデータとlamport残高を取得
getBalanceアカウント残高をlamports単位(ネイティブQOR)で取得
getSignaturesForAddressあるアドレスのトランザクション履歴
getSlot現在のスロット番号
getMinimumBalanceForRentExemption指定したデータサイズに対する最低残高
getVersionSVMランタイムのバージョン情報
getHealthSVMエンドポイントのヘルスチェック

プログラムのデプロイと操作​

備考

最新のSBF実行。 SVM実行エンジンはsolana-sbpf 0.21.1へと刷新されており、現行のSolanaツールチェーン(platform-tools v1.53 / agave 4.x)でコンパイルされたばかりのSBFプログラムは、QoreChain上でデプロイと実行の両方が可能です——実行はデプロイのみでなく完全にサポートされています。cargo build-sbf --arch v0または--arch v3のいずれでビルドしたプログラムもサポートされます。

  1. SBFプログラムをデプロイする — 現行のplatform-tools(v1.53 / agave 4.x)を使ってSolanaプログラムをSBF共有オブジェクトにコンパイルし、QoreChainにデプロイします:

    # Build with the current Solana toolchain (--arch v0 or --arch v3)
    cargo build-sbf --arch v3

    # Deploy the compiled program
    qorechaind tx svm deploy-program ./my_program.so \
    --from mykey \
    --gas auto \
    --gas-adjustment 1.3 \
    -y

    トランザクションのレスポンスには、base58形式のプログラムIDが含まれます。

  2. 命令を実行する — 命令データを指定してオンチェーンのBPFプログラムを呼び出します:

    # Execute instruction
    qorechaind tx svm execute <program-id-base58> <data-hex> \
    --from mykey \
    --gas auto \
    -y
    パラメータ形式説明
    program-id-base58Base58文字列デプロイ済みプログラムのアドレス
    data-hex16進エンコードされたバイト列シリアライズされた命令データ
  3. データアカウントを作成する — プログラムは状態を保存するためにアカウントを必要とすることがよくあります。サイズとオーナーを指定してアカウントを作成します:

    # Create data account
    qorechaind tx svm create-account <owner-base58> <space> <lamports> \
    --from mykey \
    --gas auto \
    -y
    パラメータ説明
    owner-base58このアカウントを所有するプログラム(base58)
    spaceデータフィールドのサイズ(バイト単位)
    lamports初期残高(レント免除の最低額を満たす必要があります)

    指定サイズに対するレント免除の最低残高を照会します:

    # RPC: getMinimumBalanceForRentExemption
    curl -X POST http://localhost:8899 \
    -H "Content-Type: application/json" \
    -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getMinimumBalanceForRentExemption",
    "params": [1024]
    }'
  4. @solana/web3.jsを使う — Solana JavaScript SDKは、QoreChainのSVMエンドポイントに対してそのまま動作します:

    import { Connection, PublicKey } from "@solana/web3.js";

    const connection = new Connection("http://127.0.0.1:8899");

    // Check health
    const health = await connection.getHealth();
    console.log("SVM health:", health);

    // Get slot
    const slot = await connection.getSlot();
    console.log("Current slot:", slot);

    // Get account info
    const pubkey = new PublicKey("YourBase58ProgramId...");
    const accountInfo = await connection.getAccountInfo(pubkey);
    console.log("Account data:", accountInfo);

    // Get balance
    const balance = await connection.getBalance(pubkey);
    console.log("Balance (lamports):", balance);

アドレスマッピング​

QoreChainは、ネイティブBech32アドレス(qor1...)とSolanaスタイルのbase58アドレスとの間で双方向のアドレスマッピングを維持しています:

方向例
ネイティブ → SVMqor1abc...xyzは決定論的なbase58アドレスにマッピングされます
SVM → ネイティブbase58形式のプログラムアドレスは対応するqor1...に逆マッピングされます

このマッピングは決定論的であり、x/svmモジュールによって管理されます。両方の表現は、同一の基盤となるアカウントを指します。


レントモデル​

SVMモジュールは、状態の肥大化を防ぐためにレントベースのストレージモデルを採用しています:

パラメータ値
1バイトあたり年間lamports3,480
レント免除乗数2.0
徴収頻度各エポック
  • 残高が2 * (data_size * 3480 / seconds_per_year)(lamports単位)を上回るアカウントはレント免除となり、決して課金されません。
  • レント免除しきい値を下回るアカウントは、各エポックでレントが課金されます。残高がゼロに達すると、そのアカウントは削除されます。
備考

ベストプラクティス: 予期しないアカウント削除を避けるため、データアカウントには常にレント免除の最低額を上回る資金を入れておいてください。


コンピュートバジェット​

各命令の実行は、コンピュートユニットで計測されます:

パラメータ値
命令あたりの最大コンピュートユニット1,400,000
最大CPI(クロスプログラム呼び出し)深度4
最大プログラムサイズ10 MB
最大アカウントデータサイズ10 MB

コンピュートバジェットを超過したプログラムは停止され、トランザクションはリバートされます。


パラメータまとめ​

パラメータ値
max_program_size10 MB
max_account_data_size10 MB
compute_budget_max1,400,000 CU
max_cpi_depth4
lamports_per_byte_year3,480
rent_exemption_multiplier2.0
JSON-RPCポート8899

クロスVM相互運用性​

SVMプログラムは、非同期のクロスVMメッセージパスを通じてEVMおよびCosmWasmコントラクトと通信できます:

# Cross-VM call example
qorechaind tx crossvm call \
--source-vm svm \
--target-vm evm \
--target-contract 0x1234...abcd \
--payload '...' \
--from mykey \
-y

メッセージはキューに入れられ、EndBlockerによって処理されます。メッセージのライフサイクルとタイムアウトの挙動の詳細については、クロスVM相互運用性を参照してください。


次のステップ​