Skip to content

Deploy contracts ​

A deploy is an ordinary signed transaction to neuro:system.deploy. Every validator audits the bytecode with VMGuardian in consensus; a contract that fails the audit is never created anywhere.

Deploy flow: build a wasm32 contract, optionally analyze it, send a deploy transaction; each validator runs the VMGuardian gate; a risk score at or above the threshold fails the transaction with no fee, otherwise the contract is created, its init export runs, then initialize with init_args

1. Build ​

Contracts are no_std Rust compiled to wasm32-unknown-unknown as a cdylib, importing host functions from the env module — declare them with #[link(wasm_import_module = "env")] so they link with current Rust. See NeuroWASM for the interface and a complete example.

toml
[lib]
crate-type = ["cdylib"]

[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
bash
cargo build --release --target wasm32-unknown-unknown
od -An -tx1 -v target/wasm32-unknown-unknown/release/my_contract.wasm | tr -d ' \n' > my_contract.hex

The hex must start with 0061736d (the WASM magic). Maximum size: 512 KiB of bytecode (MAX_BYTECODE_SIZE).

Working examples in the repository: neurochain/contracts/nrc20 (fungible token), ncert (security certificates, NRC-721 style), dao and gov_dao.

2. Check before you send optional ​

EndpointWhat you get
POST /api/v1/contracts/analyze { "bytecode_hex": "…" }risk_score, security_score, ml_score, model, violations — the same analysis the gate runs
POST /api/v1/contracts/attest { "bytecode_hex": "…" }The same result signed by the node with ML-DSA-65, verifiable in the browser

The web app's deploy page runs the analysis in the browser first, then asks the node for a signed attestation.

3. Send the deploy ​

With the SDK (recommended):

js
await nc.deployContract({
  wallet,
  bytecodeHex,
  name: 'MyToken',            // unique contract name, optional
  description: '…',
  template: 'nrc20',          // registered template id, optional
  initArgs: { … },            // passed to initialize, optional; decimals as a number
  gasPrice,
})

By hand — POST /api/v1/transactions with to: "neuro:system.deploy", value: 0, and data set to this JSON string:

json
{ "bytecode_hex": "0061736d…", "name": "MyToken", "description": "", "template": "", "init_args": { } }

signed like any transaction (nc-tx-v2|from|neuro:system.deploy|0|nonce).

The node also exposes POST /api/v1/contracts/deploy (owner, bytecode_hex or base64_wasm, plus a signed operation for neuro:system.deploy); it builds the same transaction for you.

4. What every validator does ​

  1. Gate. Decode the bytecode and look up its SHA3-256 hash:
    • whitelisted (official templates such as NRC-20) → security score 100, no analysis;
    • gate switched off by governance (deploy_security_enabled = 0) → neutral score 70;
    • otherwise run VMGuardian analyze_v2. If risk_score ≥ deploy_risk_threshold (default 0.80), the transaction fails with no fee charged, the rejection is logged with its rule violations, and the nc_deploy_rejected_total metric counts it.
  2. Charge 10 000 gas units × gas_price.
  3. Create the contract at neuro:<10 hex>.app — the first 5 bytes of SHA3-256(owner ‖ nonce). A contract name already taken by another contract fails the deploy.
  4. Constructor. If the module exports init, it runs once with the deploy's storage.
  5. Initialize. If init_args is present, the contract is called with {"function": "initialize", …init_args} — the arguments are flattened to the top level of the JSON — with you as the caller.
  6. Template fee. If template names a registered template with a fee, that fee goes from you to the template's author.

The resulting security score is 100 − risk_score × 100 and is stored with the contract.

Fees ​

ItemCost
Deploy10 000 gas units × gas_price (at 1 uNRO: 0.01 NRO)
Rejected by the gateNothing
TemplateThe template's own fee, if any

After deploy: continuous monitoring ​

Each node re-audits deployed contracts every 20 seconds (MONITOR_INTERVAL_SECS). When a contract's score moves by 10 points or more (MONITOR_SCORE_THRESHOLD) — for example after the model is updated — a certificate update transaction is issued through consensus. Certificates are readable at GET /api/v1/certificates/contract/:address. See VMGuardian.

Troubleshooting ​

ErrorCause
Deploy rejected by VMGuardian: risk_score … >= threshold …The audit found risky patterns; analyze lists them.
gas_price … below block base_fee …Raise gasPrice above the current base fee.
Contract name '…' is already takenChoose another name, or leave it empty.
Size errorBytecode over 512 KiB — build with opt-level = "z" and LTO.