DocsSmart Contract Guide
WASM Smart Contracts

Smart Contract Guide

Write, compile, and deploy WebAssembly smart contracts on FractalAI's native WASM virtual machine. No Solidity, no EVM — pure Rust compiled to WASM with fractal-native host functions.

Why WASM Instead of EVM?

Write in Rust

Use a real systems language with full type safety, no Solidity quirks or reentrancy footguns

Near-Native Speed

WASM executes 10-100x faster than EVM bytecode for compute-heavy operations

Fractal Host Functions

12 native functions including fractal_score for golden-ratio-aware contracts

Memory Safe

Rust's borrow checker prevents entire classes of bugs at compile time

Verkle State

Contract storage backed by Verkle trees with efficient state proofs

Post-Quantum Signed

All contract calls are signed with Dilithium, quantum-safe from day one

Writing a Contract

FractalAI contracts are written in Rust using the fractal-sdk crate. The SDK provides macros for contract entry points, storage abstractions, and access to all 12 host functions.

Rustfractal_token/src/lib.rs
// fractal_token/src/lib.rs
#![no_std]
use fractal_sdk::prelude::*;

#[fractal_contract]
pub struct FractalToken {
    name: String,
    symbol: String,
    total_supply: u64,
    balances: StorageMap<Address, u64>,
    allowances: StorageMap<(Address, Address), u64>,
}

#[fractal_methods]
impl FractalToken {
    /// Initialize the token with a name, symbol, and supply
    pub fn init(&mut self, name: String, symbol: String, initial_supply: u64) {
        self.name = name;
        self.symbol = symbol;
        self.total_supply = initial_supply;

        let caller = env::caller();
        self.balances.insert(caller, initial_supply);

        env::emit_event("Transfer", &(Address::zero(), caller, initial_supply));
    }

    /// Transfer tokens to another address
    pub fn transfer(&mut self, to: Address, amount: u64) -> bool {
        let from = env::caller();
        let from_balance = self.balances.get(&from).unwrap_or(0);

        require!(from_balance >= amount, "Insufficient balance");

        self.balances.insert(from, from_balance - amount);
        let to_balance = self.balances.get(&to).unwrap_or(0);
        self.balances.insert(to, to_balance + amount);

        env::emit_event("Transfer", &(from, to, amount));
        true
    }

    /// Get the balance of an address
    pub fn balance_of(&self, owner: Address) -> u64 {
        self.balances.get(&owner).unwrap_or(0)
    }

    /// Get the fractal score bonus for this block
    pub fn fractal_bonus(&self) -> u64 {
        let score = env::fractal_score(); // returns fixed-point
        // Golden ratio bonus: score approaching 1.618 gets max bonus
        let phi = 1_618_034; // phi * 1e6
        let diff = if score > phi { score - phi } else { phi - score };
        let max_bonus = 1000;
        if diff < 100_000 {
            max_bonus - (diff * max_bonus / 100_000)
        } else {
            0
        }
    }
}

Fractal-native feature: The fractal_bonus() method reads the current block's fractal score via env::fractal_score(). Contracts can use this to reward actions that happen in blocks with scores approaching the golden ratio (1.618...).

Host Functions Reference

These are the 12 native functions available to every WASM contract running on FractalVM. They provide access to blockchain state, storage, and fractal-specific data.

FunctionDescription
storage_readRead a value from contract persistent storage
storage_writeWrite a value to contract persistent storage
get_callerGet the address of the account that called this contract
get_valueGet the FRAC amount sent with this call
get_balanceGet the FRAC balance of any address
transferTransfer FRAC to another address
get_block_numberGet the current block number
get_block_timestampGet the current block timestamp (seconds)
get_block_hashGet the hash of a previous block
emit_eventEmit a log event from the contract
get_fractal_scoreGet the fractal score of the current block (fixed-point)
keccak256Compute keccak256 hash of data

Compile & Deploy

1. Set up your project

bash
cargo new --lib my_contract
cd my_contract

# Add to Cargo.toml:
# [dependencies]
# fractal-sdk = "0.1"
#
# [lib]
# crate-type = ["cdylib"]

2. Compile & deploy

bash
# Compile the contract to WASM
cargo build --target wasm32-unknown-unknown --release

# The output will be at:
# target/wasm32-unknown-unknown/release/fractal_token.wasm

# Deploy via JSON-RPC
curl -X POST http://localhost:9545 \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_sendRawTransaction",
    "params": ["<signed_deploy_tx_hex>"],
    "id": 1
  }'

3. Interact with the contract

Rust
use fractal_node::rpc::Client;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("http://localhost:9545");

    // Call balance_of on the deployed contract
    let balance = client.call_contract(
        "0x<contract_address>",
        "balance_of",
        &[("owner", "0x<your_address>")]
    ).await?;

    println!("Balance: {} tokens", balance);

    // Send a transfer transaction
    let tx_hash = client.send_contract_tx(
        "0x<contract_address>",
        "transfer",
        &[("to", "0x<recipient>"), ("amount", "1000")],
        &wallet,
    ).await?;

    println!("Transfer tx: {}", tx_hash);
    Ok(())
}

Gas Costs

Every operation in FractalVM has a deterministic gas cost. Transactions specify a gas limit; execution reverts if gas runs out. Unused gas is refunded.

OperationGas Cost
storage_read200
storage_write5,000
get_caller2
get_balance400
transfer9,000
emit_event375 + 8/byte
get_fractal_score2
keccak25630 + 6/word
WASM instruction1
Memory page (64KB)100

Best Practices

Minimize storage writes

Storage is the most expensive operation. Batch writes when possible, use events for data that doesn't need on-chain reads.

Use #![no_std]

Contracts should avoid the Rust standard library to keep WASM binaries small. The fractal-sdk provides all needed abstractions.

Validate all inputs

Never trust caller input. Check bounds, validate addresses, and use require!() macros for preconditions.

Leverage fractal scoring

Use env::fractal_score() for time-weighted rewards, random seed derivation, or dynamic pricing based on network quality.

Keep contracts small

WASM binary size affects deployment cost. Strip debug symbols, use wasm-opt for size optimization.

Test with dev node

Run fractal-node --dev for a local single-validator chain with instant blocks and a funded faucet.