Manifests: Methods
Method declarations are the core of a NOOSChain contract manifest. They map public contract method names to WASM entrypoints and define who may call them, which buckets they may use, how much fuel they may consume, and what ABI they present to callers.
Method Map
exports.methods is a map from public method name to method manifest:
{
"exports": {
"methods": {
"saveReport": {
"entrypoint": "saveReport",
"invoke": { "allow": [{ "principalType": "anyUser" }] },
"buckets": []
}
}
}
}The key, saveReport, is the method name used in transaction CALL_CONTRACT:
{
"contractId": "contract-report-store",
"method": "saveReport",
"args": { "id": "report-001" }
}The manifest must expose at least one method. Method names and entrypoints must match:
^[A-Za-z_][A-Za-z0-9_]*$exports.init
exports.init is an optional initialization export:
{
"exports": {
"init": "init",
"methods": {
"saveReport": {
"entrypoint": "saveReport",
"invoke": { "allow": [{ "principalType": "anyUser" }] },
"buckets": []
}
}
}
}Use init-style logic for deterministic setup that belongs to the contract instance, such as default contract-scoped state. Avoid anything that depends on wall-clock time, randomness, external systems, local files, network calls, or node-local configuration.
If the manifest declares an init export but the WASM module does not export it, initialization fails when the chain attempts to use it.
Method entrypoint
entrypoint is the WASM export name invoked by the runtime:
{
"entrypoint": "saveReport"
}It can differ from the public method name:
{
"exports": {
"methods": {
"save": {
"entrypoint": "saveReportV1",
"invoke": { "allow": [{ "principalType": "anyUser" }] },
"buckets": []
}
}
}
}The current call ABI supports two shapes. Without arguments:
export function saveReport(): i32With arguments:
export function saveReport(argPtr: i32, argLen: i32): i32For argument calls, the contract must export memory. The host writes canonical JSON arguments into memory and passes pointer plus length. Return code 0 means success. A non-zero return fails the transaction.
If the WASM export is missing, the call fails before contract business logic can run.
Method invoke.allow
invoke.allow says which principals may call a method:
{
"invoke": {
"allow": [
{ "principalType": "organization", "principalId": "org-noos" }
]
}
}Supported entries are:
{ "principalType": "anyUser" }{ "principalType": "anyContract" }{ "principalType": "any" }{ "principalType": "system" }{ "principalType": "user", "principalId": "user-admin" }{ "principalType": "organization", "principalId": "org-noos" }{ "principalType": "contract", "principalId": "contract-report-caller" }Use anyUser for genuinely public user-facing methods. Use anyContract for contract-only extension points. Use user or organization for human/application workflows. Use contract for exact C2C callbacks. Use system only for platform-controlled flows.
any allows both user and contract callers. Tooling warns on any because it is broader than anyUser and can expose a method to C2C callers. Use it only for methods intentionally public to both humans and contracts.
The allow list must contain at least one entry. For policy design and bucket permission interaction, see Authorization.
Method buckets
buckets declares the bucket resources a method may use:
{
"buckets": [
{
"bucketId": "bucket-reports",
"access": ["bucket:read_metadata", "bucket:write"],
"availability": "metadata"
}
]
}Each bucket requirement has three fields.
| Field | Meaning |
|---|---|
bucketId | The bucket the method wants to access. |
access | One or more bucket permissions the method requires. |
availability | Whether consensus metadata is enough or local encrypted payload availability is required. |
Supported permissions are:
| Permission | Meaning in a contract method |
|---|---|
bucket:read_metadata | Method may read bucket metadata. |
bucket:read_encrypted | Method may read encrypted-record metadata. It still does not receive plaintext. |
bucket:write | Method may add encrypted-record metadata through the host layer. |
bucket:admin | Administrative bucket capability. Grant to contracts only when intentionally approved. |
Supported availability modes are:
| Availability | Meaning |
|---|---|
metadata | The method needs only consensus metadata. This is the usual mode. |
encrypted_payload_local | The node must have local encrypted payload availability for the relevant records. |
The manifest declaration is not a permission grant. For a sensitive bucket operation, the method declaration, the contract principal's bucket access rule, and the caller's bucket access rule must all line up.
Readiness also uses this section. A contract can be valid in consensus state but locally not ready if a declared bucket is missing, a contract bucket rule is missing, or local encrypted payload availability is required but absent.
Method maxFuel
maxFuel is an optional method-local fuel ceiling:
{
"maxFuel": 5000000
}NOOSChain has protocol-level execution limits. A method may declare a lower limit for its own safety. The effective limit is the lower of the protocol maximum and the method's maxFuel.
Use maxFuel for methods that are expected to be cheap, public, or exposed to untrusted callers. It is a circuit breaker, not a fee.
Method abi
abi describes the caller-facing API:
{
"abi": {
"description": "Stores report metadata.",
"input": { "type": "object" },
"output": { "type": "object" },
"events": []
}
}The ABI is used by SDKs, the Admin GUI, reviewers, tests, and contract callers. It is not a full arbitrary JSON Schema implementation. It supports:
stringnumberintegerbooleannullobjectarray
Value schemas may include description, enum, properties, required, and items.
Input
{
"input": {
"type": "object",
"properties": {
"id": { "type": "string" },
"status": {
"type": "string",
"enum": ["draft", "submitted", "approved"]
},
"formatVersion": { "type": "integer" }
},
"required": ["id", "status", "formatVersion"]
}
}Use explicit required fields. Include a formatVersion property when inputs will evolve over time.
Output
{
"output": {
"type": "object",
"properties": {
"saved": { "type": "boolean" },
"recordId": { "type": "string" }
},
"required": ["saved", "recordId"]
}
}Return values are part of the transaction's contract-call result. Keep them bounded and deterministic.
Events
{
"events": [
{
"topic": "report.saved",
"description": "Report metadata was accepted.",
"schema": {
"type": "object",
"properties": {
"id": { "type": "string" }
},
"required": ["id"]
}
}
]
}Use stable topic names. Do not emit plaintext, secrets, private keys, decrypted payloads, or large unbounded data.
Method Failure Modes
| Failure | Typical cause |
|---|---|
| Method not found | Transaction CALL_CONTRACT uses a method value that is not in exports.methods. |
| Export not found | Method entrypoint is declared but missing from the WASM module. |
| Unauthorized caller | Caller does not match invoke.allow. |
| Bucket declaration missing | Method used a bucket host API without declaring the required bucket permission. |
| Bucket permission missing | Contract principal or caller lacks the required bucket permission. |
| Limit exceeded | Method exceeded protocol or method-local limits. |
Method Checklist
- [ ] Every public method is listed in
exports.methods. - [ ] Every method
entrypointexists in compiled WASM. - [ ] Every method has the narrowest practical
invoke.allow. - [ ] Every bucket host operation has a matching bucket declaration.
- [ ] Bucket access is minimal and avoids unnecessary
bucket:admin. - [ ]
availabilityismetadataunless local encrypted payload availability is truly required. - [ ] ABI input, output, and event schemas are explicit.
- [ ] Public or expensive methods have suitable
maxFuel.