FractalVM Specification
FractalVM is a WebAssembly-based virtual machine designed for deterministic, gas-metered smart contract execution with native fractal computation support.
Architecture Overview
Transaction (Deploy/Call)
|
v
+------------------+
| Gas Metering | <-- Checks gas limit, deducts per instruction
+------------------+
|
v
+------------------+ +------------------+
| WASM Runtime | <-> | Host Functions | <-- 12 bridge functions
| (wasmer/wasmtime)| | (Rust impl) |
+------------------+ +------------------+
| |
v v
+------------------+ +------------------+
| Linear Memory | | State DB |
| (max 16 MB) | | (Verkle Tree) |
+------------------+ +------------------+
|
v
+------------------+
| RocksDB |
| (Persistent) |
+------------------+Key Features
WASM-Based
Contracts compile from Rust/C/C++ to WebAssembly. Any language with WASM target support can be used.
Deterministic Execution
All nodes produce identical results for the same input. Floating-point operations are banned; fixed-point only.
Gas Metering
Every instruction and host call has a gas cost. Execution halts when gas is exhausted, preventing infinite loops.
Memory Safety
WASM linear memory model with bounds checking. Contracts cannot access host memory or other contracts' state.
State Isolation
Each contract has its own storage namespace in the Verkle tree. Cross-contract reads require explicit host calls.
Fractal-Native
Host functions like get_fractal_score() let contracts access fractal metrics for scoring and rewards.
Execution Flow
Transaction Received
Node receives a Deploy or Call transaction via JSON-RPC or P2P gossip.
Signature Verification
Dilithium signature is verified. Invalid signatures are rejected immediately.
Gas Check
Sender balance is checked against gas_limit * gas_price. Insufficient funds = reject.
WASM Instantiation
Contract bytecode is loaded into the WASM runtime. Host functions are linked.
Metered Execution
The entry function is called. Each WASM instruction and host call deducts gas.
State Commit
If execution succeeds, storage changes are committed to the Verkle tree. On failure, all changes are reverted.
Gas Refund
Unused gas is refunded to the sender. Consumed gas fees go to the block validator.
Host Functions (ABI)
These 12 functions are the bridge between WASM contract code and the FractalAI runtime. All pointer parameters refer to offsets in the contract's linear memory.
| Function | Gas |
|---|---|
storage_readRead a value from contract storage by key | 200 + 3/byte |
storage_writeWrite a key-value pair to contract storage | 5000 + 10/byte |
get_callerGet the address of the transaction sender | 10 |
get_valueGet the FRAC value attached to this call | 5 |
get_balanceGet the FRAC balance of any address | 100 |
transferTransfer FRAC from contract to an address | 2500 |
get_block_numberGet the current block number | 5 |
get_block_timestampGet the current block timestamp (Unix seconds) | 5 |
get_block_hashGet the hash of a previous block (up to 256 blocks back) | 50 |
emit_eventEmit a log event with topic and data | 375 + 8/byte |
get_fractal_scoreGet the fractal score of the current block's PoFW proof | 50 |
keccak256Compute Keccak-256 hash (for EVM compatibility) | 30 + 6/word |
Minimal Contract Example
#![no_std]
#![no_main]
// Host function imports
extern "C" {
fn storage_read(key_ptr: u32, key_len: u32, val_ptr: u32) -> i32;
fn storage_write(key_ptr: u32, key_len: u32, val_ptr: u32, val_len: u32) -> i32;
fn get_caller(ptr: u32);
}
const COUNTER_KEY: &[u8] = b"counter";
static mut BUFFER: [u8; 64] = [0u8; 64];
#[no_mangle]
pub extern "C" fn increment() {
unsafe {
// Read current value
let bytes_read = storage_read(
COUNTER_KEY.as_ptr() as u32,
COUNTER_KEY.len() as u32,
BUFFER.as_ptr() as u32,
);
let current: u64 = if bytes_read > 0 {
u64::from_le_bytes(BUFFER[..8].try_into().unwrap())
} else {
0
};
// Increment and store
let new_val = current + 1;
let bytes = new_val.to_le_bytes();
storage_write(
COUNTER_KEY.as_ptr() as u32,
COUNTER_KEY.len() as u32,
bytes.as_ptr() as u32,
8,
);
}
}
#[no_mangle]
pub extern "C" fn get_count() -> u64 {
unsafe {
let bytes_read = storage_read(
COUNTER_KEY.as_ptr() as u32,
COUNTER_KEY.len() as u32,
BUFFER.as_ptr() as u32,
);
if bytes_read > 0 {
u64::from_le_bytes(BUFFER[..8].try_into().unwrap())
} else {
0
}
}
}Execution Limits
| Limit | Value |
|---|---|
| Max Gas per Transaction | 10,000,000 |
| Max Gas per Block | 30,000,000 |
| Max Linear Memory | 16 MB (256 pages) |
| Max Stack Depth | 1024 frames |
| Max Contract Size | 512 KB |
| Max Storage Key Size | 256 bytes |
| Max Storage Value Size | 64 KB |
| Max Event Data Size | 16 KB |
| Block Hash Lookback | 256 blocks |
Gas Model
Gas prevents abuse and ensures fair resource allocation. Every operation has a gas cost. If a transaction runs out of gas, all state changes are reverted but the gas fee is still charged.
WASM Instructions
Base cost per instruction type:
- Arithmetic (add, mul): 1 gas
- Memory load/store: 3 gas
- Control flow (br, call): 5 gas
- Memory grow (64KB): 1000 gas
Host Calls
See host functions table above:
- Reads: 5-200 gas
- Writes: 5000+ gas
- Transfer: 2500 gas
- Events: 375+ gas
Transaction Overhead
Fixed costs per transaction:
- Base tx cost: 21,000 gas
- Contract deploy: 32,000 + bytecode
- Per input byte: 16 gas (non-zero)
- Per zero byte: 4 gas
FractalVM vs EVM
| Aspect | FractalVM | EVM |
|---|---|---|
| Bytecode Format | WebAssembly | EVM bytecode |
| Source Languages | Rust, C, C++, AssemblyScript | Solidity, Vyper |
| Memory Model | Linear memory (bounded) | Stack + memory (unbounded) |
| Word Size | 32-bit (WASM i32/i64) | 256-bit (EVM u256) |
| State Storage | Verkle tree (key-value) | Merkle Patricia (key-value) |
| Cryptography | Post-quantum (Dilithium) | ECDSA (secp256k1) |
| AI Integration | Native host functions | None |
| Tooling Maturity | Growing (Rust ecosystem) | Mature (Hardhat, Foundry) |