Skip to content

Smart Contract Developer Documentation

Use this section when you are writing, testing, packaging, publishing, upgrading, or reviewing NOOSChain smart contracts. For the general product model, see General: Smart Contracts.

Developer Mental Model

A NOOSChain smart contract is a deterministic WASM program plus consensus metadata that tells the chain how the program may be used. The contract code does not write database tables directly. It runs in the Wasmtime sidecar, calls deterministic host imports, and emits candidate effects such as storage writes, bucket metadata writes, events, and return values.

The TypeScript host backend applies those effects only after the method returns success and all authorization, manifest, runtime, and limit checks pass. Traps, non-zero returns, authorization failures, runtime failures, and execution-limit failures discard staged contract effects.

A deployed contract has four important pieces:

  • WASM code registered by codeHash;
  • a manifest that names methods, ABI, resources, nested calls, migrations, and runtime expectations;
  • a contract instance with organization, owner, status, manifest hash, and code hash;
  • method calls submitted as signed chain transactions.

Typical Developer Flow

  1. Write AssemblyScript contract code.
  2. Define the manifest methods, ABI, bucket requirements, and invoke policy.
  3. Build the WASM module.
  4. Run unit, host API, runtime, and replay-oriented tests.
  5. Package the WASM, manifest, descriptor, examples, and README.
  6. Sign the package descriptor when provenance is required.
  7. Submit or request a package registry entry when the network requires approval.
  8. Deploy code and instantiate the contract.
  9. Grant bucket access to the deployed contract principal.
  10. Call the contract and watch readiness, call results, events, and alerts.

The end-to-end walkthrough is Publishing.

Core Concepts

Manifests define the callable surface of a contract. They include the runtime, exported methods, method entrypoints, ABI metadata, invocation policy, bucket requirements, outbound contract calls, migrations, and method fuel ceilings. The canonical manifest hash is consensus-significant. See Manifests, Methods, Calls, and Migrations.

Authorization is split between the caller and the contract principal. The caller must be allowed to invoke the method, and bucket-sensitive host operations require the deployed contract principal and, by default, the caller to have the relevant bucket permission. Nested contract calls add a second manifest edge and target method policy check. See Authorization.

Package provenance proves that a package descriptor was signed by an expected signer and that it binds the exact package name, version, runtime, WASM hash, and manifest hash. Provenance can be checked locally by the SDK and deterministically during transaction INSTANTIATE_CONTRACT. See Package Provenance.

The contract registry is consensus state for packages approved by the network. It is different from provenance: provenance proves origin and integrity, while the registry proves network approval for a package/version/hash tuple. See Contract Registry.

Readiness is node-local execution availability. A contract can exist in consensus state while a particular node cannot execute it because the runtime is unavailable, the manifest is invalid, bucket permissions are missing, or local payload availability does not satisfy the manifest.

Transaction Types

The protocol registry includes these smart-contract transaction types:

  • Transaction DEPLOY_CONTRACT_CODE: registers WASM bytecode by codeHash.
  • Transaction INSTANTIATE_CONTRACT: creates a contract instance from code plus manifest.
  • Transaction CALL_CONTRACT: invokes a named method with optional arguments.
  • Transaction DEACTIVATE_CONTRACT: permanently changes an active contract instance to deactivated.

Transaction CALL_CONTRACT checks contract existence, active status, manifest method existence, method invocation policy, runtime availability, and resource permissions before contract effects can commit.

Transaction DEACTIVATE_CONTRACT is a consensus-governed safety control. The signer must have chain:admin. The transition is one-way in v1: only active contracts can be deactivated, and calls to a deactivated contract fail before target WASM runs.

Call ABI

The current call ABI is deliberately small.

Without arguments, a method may export:

text
export function entrypoint(): i32

With arguments, the contract must export memory. The host canonicalizes the args value to JSON, UTF-8 encodes it, writes it at memory offset 0, and calls:

text
export function entrypoint(argPtr: i32, argLen: i32): i32

Return code 0 means success. A non-zero numeric return fails the transaction with CONTRACT_METHOD_FAILED.

Host API Surface

The host API backend exposes typed operations beneath the WASM import layer:

  • read contract storage;
  • write contract storage;
  • read bucket metadata;
  • read encrypted-record metadata;
  • add encrypted-record metadata;
  • emit contract events.

The current WASM import surface is:

text
noos.consume_fuel(fuel: i32): void
noos.storage_get(keyPtr: i32, keyLen: i32): i32
noos.storage_set(keyPtr: i32, keyLen: i32, valuePtr: i32, valueLen: i32): i32
noos.bucket_get_metadata(bucketPtr: i32, bucketLen: i32): i32
noos.bucket_get_record_metadata(bucketPtr: i32, bucketLen: i32, recordPtr: i32, recordLen: i32): i32
noos.bucket_add_encrypted_record_metadata(inputPtr: i32, inputLen: i32): i32
noos.emit_event(topicPtr: i32, topicLen: i32, dataPtr: i32, dataLen: i32): i32
noos.last_result_ptr(): i32
noos.last_result_len(): i32

Imports return 0 on success and 1 on failure. Success values and failure objects are written to WASM memory as UTF-8 JSON and exposed through last_result_ptr() plus last_result_len().

Runtime And Determinism

Consensus contract execution uses the Rust Wasmtime sidecar. Runtime behavior is selected by the block protocol version, not by local operator preference. Before accepting the sidecar for contract execution, the node performs a mandatory capability handshake. For protocol v1, the sidecar must report the expected sidecar protocol, ABI version, command set, host imports, fuel support, executor version, and Wasmtime version.

Do not change runtime requirements for an existing protocol version. If a new Wasmtime version, host import, sidecar protocol, ABI, or execution limit is needed, add a new chain protocol version and keep old runtime requirement constants available forever so old blocks replay exactly. For deeper protocol rules, see Nooschain Developers: Protocol Versioning.

Testing Path

Useful contract-focused checks include:

bash
npm run test:contract-wasmtime-sidecar
npm run test:contract-wasmtime-sidecar-lifecycle
npm run test:contract-call-execution
npm run test:contract-readiness
npm run test:contract-deterministic-metering
npm run test:contract-runtime-governance
npm run test:contract-fuzz

For full local confidence, include chain and replay verification:

bash
npm run verify:chain
npm run verify:replay
npm run test:ci

Core Concepts

Authoring

Publishing And Lifecycle

Security And Review

Audience-first NOOSChain documentation.