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).
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/getAccountInforeturn the account's native QOR (in lamports).getSignaturesForAddressreturns 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
MsgSendor 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.
| Property | Value |
|---|---|
| Default URL | http://127.0.0.1:8899 |
| Enabled | Yes, by default |
| Started by | qorechaind start |
| Compatibility | Solana JSON-RPC (subset) |
getVersion | 1.18.0-qorechain |
Supported Methods
| Method | Description |
|---|---|
getAccountInfo | Retrieve account data and lamport balance |
getBalance | Get account balance in lamports (native QOR) |
getSignaturesForAddress | Transaction history for an address |
getSlot | Current slot number |
getMinimumBalanceForRentExemption | Minimum balance for a given data size |
getVersion | SVM runtime version info |
getHealth | Health check for the SVM endpoint |
Deploying and Interacting with Programs
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.
-
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 programqorechaind tx svm deploy-program ./my_program.so \--from mykey \--gas auto \--gas-adjustment 1.3 \-yThe transaction response includes the program ID in base58 format.
-
Execute an Instruction — Call an on-chain BPF program with instruction data:
# Execute instructionqorechaind tx svm execute <program-id-base58> <data-hex> \--from mykey \--gas auto \-yParameter Format Description program-id-base58Base58 string The deployed program's address data-hexHex-encoded bytes Serialized instruction data -
Create a Data Account — Programs often need accounts to store state. Create one with a specified size and owner:
# Create data accountqorechaind tx svm create-account <owner-base58> <space> <lamports> \--from mykey \--gas auto \-yParameter Description 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: getMinimumBalanceForRentExemptioncurl -X POST http://localhost:8899 \-H "Content-Type: application/json" \-d '{"jsonrpc": "2.0","id": 1,"method": "getMinimumBalanceForRentExemption","params": [1024]}' -
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 healthconst health = await connection.getHealth();console.log("SVM health:", health);// Get slotconst slot = await connection.getSlot();console.log("Current slot:", slot);// Get account infoconst pubkey = new PublicKey("YourBase58ProgramId...");const accountInfo = await connection.getAccountInfo(pubkey);console.log("Account data:", accountInfo);// Get balanceconst 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:
| Direction | Example |
|---|---|
| Native to SVM | qor1abc...xyz maps to a deterministic base58 address |
| SVM to Native | Base58 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:
| Parameter | Value |
|---|---|
| Lamports per byte per year | 3,480 |
| Rent exemption multiplier | 2.0 |
| Collection frequency | Each 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.
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:
| Parameter | Value |
|---|---|
| Max compute units per instruction | 1,400,000 |
| Max CPI (cross-program invocation) depth | 4 |
| Max program size | 10 MB |
| Max account data size | 10 MB |
Programs that exceed the compute budget are halted and the transaction is reverted.
Parameters Summary
| Parameter | Value |
|---|---|
max_program_size | 10 MB |
max_account_data_size | 10 MB |
compute_budget_max | 1,400,000 CU |
max_cpi_depth | 4 |
lamports_per_byte_year | 3,480 |
rent_exemption_multiplier | 2.0 |
| JSON-RPC port | 8899 |
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
- Cross-VM Interoperability — Communication between SVM, EVM, and CosmWasm
- EVM Development — Solidity smart contracts on QoreChain
- CosmWasm Development — Rust-based WebAssembly contracts