# Deploy contracts

> Deploying a WASM contract on NeuroChain — building for wasm32, the deploy transaction, the VMGuardian audit gate every validator runs, constructor and initialize, fees, limits and continuous monitoring after deploy.

Source: https://docs.nro.world/build/deploy

A deploy is an ordinary signed transaction to `neuro:system.deploy`. Every validator audits the bytecode with [VMGuardian](/ai/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](/diagrams/deploy-flow.svg)

## 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](/neurowasm/#a-minimal-contract) 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 <Badge type="tip" text="optional" />

| Endpoint | What 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

| Item | Cost |
|------|------|
| Deploy | 10 000 gas units × `gas_price` (at 1 uNRO: 0.01 NRO) |
| Rejected by the gate | Nothing |
| Template | The 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](/ai/vmguardian).

## Troubleshooting

| Error | Cause |
|-------|-------|
| `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 taken` | Choose another `name`, or leave it empty. |
| Size error | Bytecode over 512 KiB — build with `opt-level = "z"` and LTO. |
