Skip to content

Contract Registry

The contract registry is the network allowlist for smart-contract packages. It records the exact package versions, hashes, runtime, review metadata, and status that the network has approved for use.

The registry is different from Package Provenance:

  • provenance proves who signed a package descriptor and whether it still matches the WASM, manifest, and runtime being instantiated;
  • registry approval proves the network has accepted that signed package for new contract instances or release workflows.

Production networks usually use both. Provenance establishes package identity and integrity. The registry decides whether that package is allowed.

Where It Fits

Registry validation happens during transaction INSTANTIATE_CONTRACT after provenance validation:

  1. The instantiate payload is checked against the deployed code and manifest.
  2. Package provenance is validated when present or required.
  3. Accepted provenance produces package name, package version, descriptor hash, and accepted signer metadata.
  4. Registry validation looks for a matching registry entry.
  5. If the entry exists and its status is allowed, a registry reference is stored in the contract metadata.

This ordering matters. The registry lookup uses accepted provenance. Without accepted provenance, required registry mode cannot know which package descriptor to match and fails with CONTRACT_REGISTRY_APPROVAL_REQUIRED.

What Gets Registered

A registry entry identifies one approved package by exact hashes:

json
{
  "id": "pkg-report-store-0.1.0",
  "packageName": "report-store",
  "packageVersion": "0.1.0",
  "codeHash": "<sha256-of-wasm>",
  "manifestHash": "<canonical-manifest-sha256>",
  "descriptorHash": "<sha256-of-package-descriptor>",
  "runtime": "wasm-assemblyscript-v1",
  "status": "approved",
  "auditMetadata": {
    "reviewId": "SEC-1234"
  },
  "approvalMetadata": {
    "approvedFor": "production"
  }
}
FieldMeaningReview guidance
idRegistry entry id.Use a stable id that includes package name, version, and environment when useful.
packageNamePackage identity from the descriptor.Must match the signed package descriptor.
packageVersionPackage version from the descriptor.Must match the signed package descriptor and release record.
codeHashSHA-256 hash of the approved WASM bytes.Must match the descriptor and deployed code hash.
manifestHashCanonical hash of the approved manifest.Must match the descriptor and instantiate manifest hash.
descriptorHashSHA-256 hash of the canonical package descriptor.Must match accepted package provenance.
runtimeRuntime accepted for the package.Current registry payloads accept wasm-assemblyscript-v1.
statusApproval status for new use.approved, suspended, or retired.
auditMetadataSecurity/review evidence.Use for audit ids, reviewer notes, risk classification, or review timestamps.
approvalMetadataGovernance/release evidence.Use for change ids, approval scope, environment, or launch tickets.

The registry row also records the approving actor, transaction hash, creation height, and update height. Those fields are written by consensus execution, not by the package author.

Matching Rules

During registry validation, NOOSChain searches contract_package_registry by:

  • package name;
  • package version;
  • code hash;
  • manifest hash;
  • descriptor hash.

All five must match. This prevents a package name and version from being reused with different bytecode, a different manifest, or a different signed descriptor.

The lookup comes from accepted provenance:

text
accepted provenance
  packageName
  packageVersion
  descriptorHash
      +
instantiate payload
  codeHash
  manifestHash
      =
registry lookup key

If a package has the same name and version but a different hash, it is a different package for registry purposes and needs its own review and registry entry.

Statuses

StatusMeaningTypical use
approvedThe package is allowed for new instantiations when registry policy permits approved entries.Normal production use after review.
suspendedThe package is temporarily blocked from new use.Incident investigation, audit expiry, key concern, or pending review.
retiredThe package is intentionally withdrawn from new use.Replaced package, deprecated behavior, or end-of-life version.

Status changes affect new instantiations and release checks. They do not rewrite old blocks, delete deployed contracts, or make historical replay impossible.

Registry Policy

The default registry policy is:

json
{
  "mode": "optional",
  "allowedStatuses": ["approved"]
}

mode controls whether registry approval is mandatory:

ModeBehavior
optionalInstantiation can proceed without accepted provenance or without a matching registry entry. If accepted provenance matches an entry with a disallowed status, instantiation fails.
requiredInstantiation must have accepted provenance, must match a registry entry, and that entry must have an allowed status.

allowedStatuses controls which registry statuses are valid for use. Production policy normally allows only approved.

Unlike package provenance policy, which is now loaded from contract_provenance_policies/default, registry policy is currently supplied by the protocol execution context, with the default above when no explicit policy is provided. Treat it as a protocol/network configuration decision: if the network wants registry approval to be a hard gate, run with required registry policy.

Instantiate Outcomes

When registry validation succeeds, the contract metadata includes a compact registry reference:

json
{
  "contractRegistry": {
    "entryId": "pkg-report-store-0.1.0",
    "packageName": "report-store",
    "packageVersion": "0.1.0",
    "status": "approved"
  }
}

When it fails, common deterministic failure codes are:

Failure codeMeaning
CONTRACT_REGISTRY_APPROVAL_REQUIREDRegistry policy is required, but there is no accepted provenance to identify the package.
CONTRACT_REGISTRY_ENTRY_NOT_FOUNDRegistry policy is required and no entry matched package name, version, code hash, manifest hash, and descriptor hash.
CONTRACT_REGISTRY_ENTRY_NOT_APPROVEDA matching entry exists, but its status is not in allowedStatuses.
CONTRACT_REGISTRY_ENTRY_ALREADY_EXISTSA registration attempted to reuse an existing registry id or the same package/version/code/manifest tuple.

Register A Package

The package helper can generate a registry payload during publishing:

powershell
npm run contracts:as-sdk:payloads -- --package "contract-packages/report-store-0.1.0" --contract-id "contract-report-store" --owner-user-id "user-admin" --organization-id "org-noos" --registry-id "pkg-report-store-0.1.0" --approval-metadata-json '{"approvedFor":"tutorial"}'

Submit the generated payload as a chain-admin transaction:

powershell
npm run noos -- tx build-and-submit --type REGISTER_CONTRACT_PACKAGE --payload-file "contract-packages/report-store-0.1.0/payloads/register-contract-package.json" --signer-public-key "<ADMIN_PUBLIC_KEY_PEM>" --signer-private-key-path "<ADMIN_PRIVATE_KEY_PATH>" --yes

This submits transaction REGISTER_CONTRACT_PACKAGE.

Only actors with chain:admin can register registry entries. Registration fails if the id already exists, or if another entry already has the same package name, package version, code hash, and manifest hash tuple.

Manual Payload

If you are not using the package helper, create the payload directly:

json
{
  "id": "pkg-report-store-0.1.0",
  "packageName": "report-store",
  "packageVersion": "0.1.0",
  "codeHash": "<sha256-of-wasm>",
  "manifestHash": "<canonical-manifest-sha256>",
  "descriptorHash": "<sha256-of-package-descriptor>",
  "runtime": "wasm-assemblyscript-v1",
  "status": "approved",
  "auditMetadata": {
    "reviewId": "SEC-1234",
    "reviewedAt": "2026-06-05T00:00:00.000Z"
  },
  "approvalMetadata": {
    "changeControlId": "CHG-1234",
    "environment": "production"
  }
}

Then submit it:

powershell
npm run noos -- tx build-and-submit --type REGISTER_CONTRACT_PACKAGE --payload-file "register-contract-package.json" --signer-public-key "<ADMIN_PUBLIC_KEY_PEM>" --signer-private-key-path "<ADMIN_PRIVATE_KEY_PATH>" --yes

This submits transaction REGISTER_CONTRACT_PACKAGE.

Before submitting a manual payload, recompute all hashes from the package files. Do not copy hash values from an untrusted release note.

Suspend Or Retire A Package

Use transaction UPDATE_CONTRACT_PACKAGE_STATUS when a package should stop being accepted for new production use.

Suspend a package while review is pending:

json
{
  "id": "pkg-report-store-0.1.0",
  "status": "suspended",
  "approvalMetadata": {
    "reason": "audit-expired",
    "ticket": "SEC-2345"
  }
}

Retire a package after replacement:

json
{
  "id": "pkg-report-store-0.1.0",
  "status": "retired",
  "approvalMetadata": {
    "reason": "replaced-by-0.2.0"
  }
}

Restore approval after review:

json
{
  "id": "pkg-report-store-0.1.0",
  "status": "approved",
  "auditMetadata": {
    "reviewId": "SEC-3456",
    "result": "accepted"
  },
  "approvalMetadata": {
    "reason": "review-complete"
  }
}

Submit any of those payloads with:

powershell
npm run noos -- tx build-and-submit --type UPDATE_CONTRACT_PACKAGE_STATUS --payload-file "update-contract-package-status.json" --signer-public-key "<ADMIN_PUBLIC_KEY_PEM>" --signer-private-key-path "<ADMIN_PRIVATE_KEY_PATH>" --yes

This submits transaction UPDATE_CONTRACT_PACKAGE_STATUS.

Status updates preserve the package identity and hashes. They only change status, audit metadata, approval metadata, approver fields, transaction hash, and update height.

Relationship To Releases

Release workflow records tie a registry package to a target contract id, optional source contract id, rollout status, migration, audit metadata, approval metadata, and rollback trail.

Before a production release advances, check:

  • the registry entry exists;
  • the registry status is allowed by policy;
  • package name and version match the release;
  • code hash, manifest hash, and descriptor hash match the signed package;
  • audit and approval metadata satisfy the release gate;
  • the target contract uses the expected code and manifest;
  • suspended or retired packages are not promoted.

The registry is the package approval layer. Release workflow is the deployment control layer.

Review Checklist

Use this checklist with the deeper Package Provenance review checklist.

CheckWhat to verifyWhy it matters
Provenance acceptedThe package can produce accepted provenance under the active provenance policy.Required registry mode needs package identity from provenance.
Registry idThe id is stable and scoped correctly for the network or environment.Prevents confusing production and test approvals.
Package identityName and version match the signed descriptor and release plan.Prevents approving the wrong package line.
Code hashRegistry codeHash matches the packaged WASM and instantiate payload.Prevents bytecode substitution.
Manifest hashRegistry manifestHash matches the canonical reviewed manifest.Prevents authorization, bucket, ABI, or migration drift.
Descriptor hashRegistry descriptorHash matches accepted provenance.Ensures the registered package is the signed package.
RuntimeRuntime is supported and matches descriptor and manifest.Prevents runtime compatibility surprises.
StatusStatus is approved for new production use.Suspended or retired packages should not be instantiated.
Audit metadataReview id, reviewer, date, scope, and result are recorded when required.Incident response needs meaningful evidence.
Approval metadataChange id, environment, release scope, and approver intent are recorded.Operators need to know why this package was approved.
Release alignmentRegistry entry matches the target release and rollback plan.Prevents release records from pointing at stale packages.

Next Steps

Audience-first NOOSChain documentation.