Skip to content

Smart Contracts

NOOSChain smart contracts are deterministic WASM programs that run inside the chain execution pipeline. They let teams package reusable business logic, deploy it as contract instances, and grant those contracts controlled access to NOOSChain resources such as buckets, contract storage, and events.

This page explains the model for readers who need the big picture. If you are writing or reviewing contract code, start with Smart Contract Developer Documentation.

What Smart Contracts Are

A smart contract is not a user account and does not sign transactions directly. It is a deployed contract instance with its own chain principal:

text
principalType: "contract"
principalId: contract id

Users submit signed transactions that call contract methods. Consensus orders those calls into blocks. During block execution, NOOSChain loads the contract's registered WASM code, checks the manifest and authorization rules, runs the method through the contract runtime, and applies only the deterministic effects that are allowed by the host layer.

Contracts can:

  • keep contract-scoped key/value state;
  • emit indexed contract events;
  • read bucket and encrypted-record metadata when allowed;
  • add encrypted-record metadata through controlled host functions;
  • participate in bucket access rules as first-class principals.

Contracts cannot bypass consensus, directly mutate database tables, read plaintext from encrypted payloads, or choose their own runtime rules.

Where They Fit In The Chain

Smart contract execution follows the same deterministic rule as the rest of NOOSChain: every validator that executes the same ordered block must reach the same transaction outcome, block hash, and state root.

The high-level flow is:

  1. A contract author builds a WASM module and manifest.
  2. Contract code is deployed by hash.
  3. A contract instance is created from deployed code plus its manifest.
  4. Users submit signed calls to named contract methods.
  5. Consensus orders those calls into blocks.
  6. The contract runtime executes the WASM method with bounded resources.
  7. The host layer stages storage, bucket metadata, and event effects.
  8. If the method succeeds, staged effects are applied through the normal deterministic state pipeline. If it fails, no staged contract effects commit.

The runtime produces candidate effects; the TypeScript host backend decides how those effects become NOOSChain state. That keeps contract code sandboxed and keeps replay, sync, snapshots, and state-root verification deterministic.

Contract Lifecycle

The contract lifecycle has four core stages.

Deploy code: reusable WASM bytecode is registered by hash. The bytecode can then be reused by one or more contract instances.

Instantiate: a contract instance is created with an organization, owner user, deployed code hash, and manifest. The manifest names callable methods, declares resources, and describes invocation policy.

Call: users submit CALL_CONTRACT transactions that name the contract, method, and arguments. The chain checks caller policy and resource permissions before the method's effects can commit.

Deactivate: a chain administrator can permanently deactivate a contract instance. Deactivated contracts cannot be called directly or through nested contract calls.

Package signing, registry approval, releases, and rollout policies add review and governance around this lifecycle. See Package Provenance, Contract Registry, and Publishing.

Identity And Permissions

Every contract call carries two identities:

  • the caller, resolved from the signed transaction;
  • the contract actor, resolved from the deployed contract instance.

The caller proves who asked for the method to run. The contract principal defines what the deployed contract itself is allowed to access.

Bucket access rules may grant permissions to users, organizations, or contracts. For sensitive bucket actions, the default model is deliberately strict: the caller must be allowed to invoke the method, the contract must have the required bucket permission, and the caller must also have the required bucket permission. This prevents a contract from becoming an accidental permission escalator.

For the broader bucket model, see Data Buckets and Permission Model. Contract authors should continue with Smart Contract Authorization for method policy, bucket checks, and nested calls.

Runtime Safety

NOOSChain smart contracts run through a Rust Wasmtime sidecar. Operators can choose where the sidecar binary lives on disk, but they cannot locally choose a different runtime behavior for a block. Runtime requirements are pinned by the chain protocol version so historical blocks replay under the same rules that produced them.

The safety model includes:

  • Wasmtime sandboxing outside the Node.js process;
  • protocol-pinned ABI and runtime capability checks;
  • deterministic fuel and execution limits;
  • bounded memory, host calls, event output, and host IO;
  • manifest-declared method and bucket access rules;
  • staged writes that apply only after a successful method return;
  • deterministic failure outcomes for traps, missing exports, timeout, and limit exhaustion.

There is no user-paid gas model in the current design. Resource limits are consensus safety controls, not fees.

Buckets And Encrypted Data

Contracts interact with buckets through host APIs rather than direct table access. Bucket metadata reads return consensus metadata. Encrypted-record metadata reads return payload hashes, encryption metadata, key references, public indexes, creator fields, and transaction hashes.

Host APIs do not return plaintext or raw encrypted payload bytes to contract code. Encrypted payload availability remains a separate layer controlled by bucket policy, node authorization, and payload backfill.

When a contract adds encrypted-record metadata, the host layer derives caller identity from the transaction and applies the same deterministic bucket, encryption-mode, key-reference, duplicate-record, and state-root logic used by normal encrypted-record transactions.

Packages, Provenance, And Registry

NOOSChain separates two questions:

  • provenance: was this package descriptor signed by an expected signer and does it match the exact code and manifest hashes?
  • registry approval: has the network approved this package/version/hash tuple for use?

Provenance helps prove the package was not substituted or tampered with. Registry approval lets the chain enforce a network-level allowlist for contract packages. Depending on policy, registry entries can be informational or required for instantiation.

For implementation-level detail, see Manifests, Manifest Methods, Package Provenance, and Contract Registry.

Readiness

Contract readiness is local node state. A contract can exist in consensus state while a particular node is not ready to execute it. Readiness can be affected by runtime availability, manifest validity, bucket permissions, and local payload availability.

This distinction matters after restore, node replacement, runtime rollout, or permission changes. The contract is still part of the chain, but a node may need operator attention before it can execute calls locally.

Operator-facing contract runtime and readiness procedures live under the Operators section.

Where To Go Next

Audience-first NOOSChain documentation.