Skip to main content

SVM Development

QoreChain includes a Solana Virtual Machine (SVM) execution environment, allowing developers to deploy and execute SBF/BPF programs using familiar Solana tooling. The SVM module exposes a Solana-compatible JSON-RPC interface on port 8899, which qorechaind start launches automatically (see JSON-RPC Server below).

note

The commands below use the qorechain-vladi mainnet, live since 7 June 2026 running chain version v3.1.85. Substitute --chain-id qorechain-diana for the testnet.


Overview

The x/svm module provides:

  • Native QOR as a first-class SVM asset — the account's unified balance, visible in lamports
  • SBF/BPF program deployment and execution
  • Data account creation and management
  • A Solana-compatible JSON-RPC endpoint
  • Bidirectional address mapping between QoreChain and Solana address formats
  • Compute budget metering and rent-based storage economics

Native QOR on the SVM Interface

As of chain version v3.1.82, the SVM interface is a first-class native-QOR interface, not a separate sandbox balance. The account's one unified balance — the same funds visible as uqor on the Cosmos interface and as 18-decimal wei on the EVM — appears on the SVM side in lamports (9 decimals):

1 uqor = 1,000 lamports · 1 QOR = 1,000,000,000 lamports
  • getBalance / getAccountInfo return the account's native QOR (in lamports).
  • getSignaturesForAddress returns the transaction history touching an address — usable for deposit detection with standard Solana tooling.
  • System Program transfers move native QOR — a Solana-style transfer instruction moves the same funds a Cosmos MsgSend or an EVM transfer would.
  • SVM address form — an account's SVM address is its 20 account bytes right-padded to 32 bytes and base58-encoded. All three address forms (qor1..., 0x..., base58) refer to the same account.

The public endpoints (https://svm.qore.host, https://svm-testnet.qore.host) are read-only — transaction submission is disabled at the edge. Run your own node (port 8899) to submit SVM transactions.


JSON-RPC Server

The Solana-compatible JSON-RPC server is started by qorechaind start and is enabled by default. It is configured through a [svm-rpc] section in app.toml:

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

The defaults are enable = true and address = "127.0.0.1:8899", so a freshly started node already serves the Solana JSON-RPC interface on port 8899 — @solana/web3.js connects at http://127.0.0.1:8899 with no extra setup. getVersion reports 1.18.0-qorechain, and getBalance / getAccountInfo return live on-chain SVM accounts.

PropertyValue
Default URLhttp://127.0.0.1:8899
EnabledYes, by default
Started byqorechaind start
CompatibilitySolana JSON-RPC (subset)
getVersion1.18.0-qorechain

Supported Methods

MethodDescription
getAccountInfoRetrieve account data and lamport balance
getBalanceGet account balance in lamports (native QOR)
getSignaturesForAddressTransaction history for an address
getSlotCurrent slot number
getMinimumBalanceForRentExemptionMinimum balance for a given data size
getVersionSVM runtime version info
getHealthHealth check for the SVM endpoint

Deploying and Interacting with Programs

info

Modern SBF execution. The SVM execution engine has been modernized onto solana-sbpf 0.21.1, so freshly-compiled SBF programs from the current Solana toolchain (platform-tools v1.53 / agave 4.x) both deploy and run on QoreChain — execution is fully supported, not deploy-only. Programs built with either cargo build-sbf --arch v0 or --arch v3 are supported.

  1. Deploy an SBF Program — Compile your Solana program to an SBF shared object with the current platform-tools (v1.53 / agave 4.x), then deploy it to 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

    The transaction response includes the program ID in base58 format.

  2. Execute an Instruction — Call an on-chain BPF program with instruction data:

    # Execute instruction
    qorechaind tx svm execute <program-id-base58> <data-hex> \
    --from mykey \
    --gas auto \
    -y
    ParameterFormatDescription
    program-id-base58Base58 stringThe deployed program's address
    data-hexHex-encoded bytesSerialized instruction data
  3. Create a Data Account — Programs often need accounts to store state. Create one with a specified size and owner:

    # Create data account
    qorechaind tx svm create-account <owner-base58> <space> <lamports> \
    --from mykey \
    --gas auto \
    -y
    ParameterDescription
    owner-base58The program that owns this account (base58)
    spaceSize of the data field in bytes
    lamportsInitial balance (must meet rent exemption minimum)

    Query the minimum rent-exempt balance for a given size:

    # RPC: getMinimumBalanceForRentExemption
    curl -X POST http://localhost:8899 \
    -H "Content-Type: application/json" \
    -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getMinimumBalanceForRentExemption",
    "params": [1024]
    }'
  4. Using @solana/web3.js — The Solana JavaScript SDK works directly with the QoreChain SVM endpoint:

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

Address Mapping

QoreChain maintains a bidirectional address mapping between native Bech32 addresses (qor1...) and Solana-style base58 addresses:

DirectionExample
Native to SVMqor1abc...xyz maps to a deterministic base58 address
SVM to NativeBase58 program addresses map back to qor1... equivalents

The mapping is deterministic and managed by the x/svm module. Both representations refer to the same underlying account.


Rent Model

The SVM module uses a rent-based storage model to prevent state bloat:

ParameterValue
Lamports per byte per year3,480
Rent exemption multiplier2.0
Collection frequencyEach epoch
  • Accounts with a balance above 2 * (data_size * 3480 / seconds_per_year) in lamports are rent-exempt and are never charged.
  • Accounts below the rent-exemption threshold are charged rent each epoch. If the balance reaches zero, the account is purged.
info

Best practice: Always fund data accounts above the rent-exemption minimum to avoid unexpected account deletion.


Compute Budget

Each instruction execution is metered with compute units:

ParameterValue
Max compute units per instruction1,400,000
Max CPI (cross-program invocation) depth4
Max program size10 MB
Max account data size10 MB

Programs that exceed the compute budget are halted and the transaction is reverted.


Parameters Summary

ParameterValue
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 port8899

Cross-VM Interoperability

SVM programs can communicate with EVM and CosmWasm contracts through the asynchronous cross-VM message path:

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

Messages are queued and processed by the EndBlocker. See Cross-VM Interoperability for details on the message lifecycle and timeout behavior.


Next Steps