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.
// 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.
| Function | Description |
|---|---|
| storage_read | Read a value from contract persistent storage |
| storage_write | Write a value to contract persistent storage |
| get_caller | Get the address of the account that called this contract |
| get_value | Get the FRAC amount sent with this call |
| get_balance | Get the FRAC balance of any address |
| transfer | Transfer FRAC to another address |
| get_block_number | Get the current block number |
| get_block_timestamp | Get the current block timestamp (seconds) |
| get_block_hash | Get the hash of a previous block |
| emit_event | Emit a log event from the contract |
| get_fractal_score | Get the fractal score of the current block (fixed-point) |
| keccak256 | Compute keccak256 hash of data |
Compile & Deploy
1. Set up your project
cargo new --lib my_contract
cd my_contract
# Add to Cargo.toml:
# [dependencies]
# fractal-sdk = "0.1"
#
# [lib]
# crate-type = ["cdylib"]2. Compile & deploy
# 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
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.
| Operation | Gas Cost |
|---|---|
| storage_read | 200 |
| storage_write | 5,000 |
| get_caller | 2 |
| get_balance | 400 |
| transfer | 9,000 |
| emit_event | 375 + 8/byte |
| get_fractal_score | 2 |
| keccak256 | 30 + 6/word |
| WASM instruction | 1 |
| 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.