Back to Inazuma

Inazuma docs · Devnet

WASM smart contracts

Inazuma is programmable. Contracts are plain WebAssembly modules executed by a deterministic, fuel-metered runtime inside consensus — they hold INAZ, keep their own key/value state, move funds, emit logs and produce receipts.

Engine

wasmi (WASM)

Metering

Fuel per rai

State

Key/value in consensus

Deploy fee

5 INAZ

1 · The VM

No EVM, no Solidity. Any language that compiles to WebAssembly targets the chain directly.

  • Contracts live at their own base58 address, derived deterministically from creator + nonce + code hash.
  • A contract account holds INAZ exactly like a user account and can send it onward.
  • Storage is a key/value map committed into consensus state, not an off-chain sidecar.
  • Execution is deterministic: no floats, no clocks, no network, no randomness — every node reaches the same result.
  • Calls are metered with fuel bought by the transaction fee; running out reverts the whole call atomically.
  • Every call produces a receipt with return data, logs, fuel used and an error string on revert.
Native tokens (create / mint / transfer / burn) and staking are protocol-level transactions, so simple assets need no contract at all. Use contracts when you need custom logic: AMMs, escrows, game state, mint rules, marketplaces.

2 · Guest ABI

Import these from module "env". Your module must export invoke() -> i32; a non-zero return reverts the call.

ImportMeaning
inz_input_len() -> i32Length of the call arguments.
inz_input(ptr, cap) -> i32Copy call arguments into memory.
inz_return(ptr, len)Set return data (max 8 KB).
inz_log(ptr, len)Emit a log line onto the receipt (max 64).
inz_caller(ptr, cap) -> i32Address that sent the call.
inz_self(ptr, cap) -> i32This contract's address.
inz_value() -> i64INAZ attached to the call, in rai.
inz_height() -> i64Current block height.
inz_balance() -> i64This contract's balance, in rai.
inz_read(kptr, klen, ptr, cap) -> i32Read storage; -1 when the key is unset.
inz_write(kptr, klen, vptr, vlen) -> i32Write storage (max 512 writes per call).
inz_transfer(aptr, alen, amount_rai) -> i32Send INAZ from the contract (max 32 per call).

3 · Deploy

Send a deploycontract transaction whose payload carries hex-encoded WASM. The response predicts the contract address.

# 1. compile to wasm (any language: Rust, C, Zig, AssemblyScript, .wat) rustup target add wasm32-unknown-unknown cargo build --release --target wasm32-unknown-unknown # 2. deploy — payload.code is hex-encoded wasm bytes curl -s https://rpc.inazuma.network -H 'content-type: application/json' -d '{ "jsonrpc":"2.0","id":1,"method":"inaz_sendTransaction", "params":{"tx":{ "kind":"deploycontract", "from":"<your address>", "nonce":7, "fee":"...", "payload":{"code":"0061736d0100..."}, "signature":"<ed25519 sig>" }} }' # → { "hash": "...", "status": "pending", "contract": "<contract address>" }
Deploying burns a flat 5 INAZ into the reward pool on top of the transaction fee. Code must be a valid WASM module, at most 256 KB.

4 · Call & query

callcontract mutates state and costs fuel. inaz_query runs the same code read-only and throws every write away.

# state-changing call — args are hex, value attaches INAZ {"kind":"callcontract","to":"<contract>","payload":{"args":"676574"}, ...} # read-only query, free, no transaction curl -s https://rpc.inazuma.network -H 'content-type: application/json' -d '{ "jsonrpc":"2.0","id":1,"method":"inaz_query", "params":{"address":"<contract>","args":"676574"} }' # → { ok, returnHex, returnText, logs, fuelUsed, writesDiscarded }
MethodReturns
inaz_contractsEvery deployed contract, count and current deploy fee.
inaz_getContractCode hash, size, creator, height, call count, balance, storage preview.
inaz_contractStorageOne storage key's value (hex + text).
inaz_getReceiptok, fuelUsed, return data, logs and error for a call.
inaz_queryRead-only execution — no fee, no state change.

5 · Fuel & fees

Fuel is bought with the transaction fee. There is no separate gas token or gas price to guess.

ParameterValue
Fuel per rai of fee400
Minimum fuel granted1,000,000
Maximum fuel per call2,000,000,000
Read-only query fuel50,000,000
Deploy fee5 INAZ (burned to reward pool)
Out-of-fuel, a trap, or a non-zero return from invoke() reverts every write and transfer from that call. The fee is still consumed.

Limits

LimitValue
Code size256 KB
Call arguments16 KB
Storage key128 bytes
Storage value8 KB
Writes per call512
Transfers per call32
Logs per call64
Return data8 KB

Example contract

A counter written in raw WebAssembly text format, shipped in the core repo.

;; args "" -> increment ;; args "get" -> read without writing ;; args "add:<n>" -> add n (module (import "env" "inz_input_len" (func $input_len (result i32))) (import "env" "inz_read" (func $read (param i32 i32 i32 i32) (result i32))) (import "env" "inz_write" (func $write (param i32 i32 i32 i32) (result i32))) (import "env" "inz_return" (func $ret (param i32 i32))) (memory (export "memory") 1) (data (i32.const 0) "count") (func (export "invoke") (result i32) ... ))

Full source: contracts/counter.wat — runtime: src/contracts.rs. Browse what is live on the explorer.