Skip to content

Upload and call a module

The Hub stores the artifact, recomputes its content address and rejects any mismatch. Uploading needs a session token or an API key with modules:write; it does not need developer enrollment.

Develop → Create → Work → Upload .hbc (max 16 MiB). The module then appears in your module list and in the Explorer search.

The response is the module record:

{
"manifest_address": "0xa99c85c5c7c08f302256cad48b51d7c363a6fcea09d5d48e570c711eed8e6d90",
"name": "hashchain_worker",
"language": "rust",
"functions": ["work"],
"hbc_size": 79150,
"stateless": true,
"uploader": "0x78248efc7f73d98b5eba157d2c719a5aa9e9c1ff",
"exec_count": 1,
"deployed_at": 1791464337,
"manifest": { "compiler": "hivec-rs/0.2.0", "functions": ["work"], "language": "rust", "name": "hashchain_worker", "runtime": "hive-wasm-v1", "manifest_address": "0xa99c…6d90" }
}

409 already_exists means a module with this exact address is already deployed: it is ready to use. stateless: true means it can be a committee worker. Read any module with GET /v1/modules/{address}, list them with GET /v1/modules?developer=0x…, and download the artifact with GET /v1/modules/{address}/hbc (verify the address yourself).

POST /v1/execute
{"module": "0x…", "function": "name", "input": <string or JSON>, "gas_limit": 1000000}
  • No authentication needed (60 requests per minute per IP); with an API key (tasks:submit) the key’s budget applies.
  • input: a string is passed byte for byte; any other JSON value is passed as canonical JSON (no floats).
  • gas_limit: default 1,000,000, maximum 50,000,000.
Terminal window
curl -s -X POST https://testnet-rpc.necter.network/v1/execute -H 'content-type: application/json' \
-d '{"module":"0x5b89b7c4f37ab4cf68f30999424ee32775d5c137d35c066e8ce9ce75563887bb","function":"multiply","input":{"a":7,"b":6}}'
{
"success": true,
"output": "{\"result\":42}",
"error": null,
"events": [],
"gas_used": 100472,
"receipt_hash": "0x05bda0ee3c3791dabc033c3e5686059e9895ad07df86cdaf1d11896a1bd577b4",
"round_id": "exec:0xd28e56c2a1a7ea740e68e9f07f3706a65dc7528f87d97594ee9dd84846a9ba21",
"round": { "issued_at": 1791472859, "nonce": "604d35257779249f4d01d558442e07bd" },
"agreeing": 3,
"quorum": 3,
"consensus": {
"state": "finalized",
"validators": 4,
"quorum": 3,
"agreeing_nodes": ["ndsr-11c5d098b068068d", "ndsr-246d0603c8cf3d65", "ndsr-b5afa746863644ff"],
"tally": { "0x05bda0ee…77b4": 3 },
"nodes": { "ndsr-64e1cb9f4fef3c60": "still running (quorum already reached)", "…": "voted 0x05bda0ee…" },
"ordering": { "scope": "pure", "fence": null }
}
}

A call whose module fails (abort, trap, out of gas) still returns 200 with "success": false and the error message: it was executed and agreed on. Errors of the request itself:

Status error Meaning
400 invalid_field, bad_request Missing input, bad address, gas_limit out of range, function not exported
404 not_found Unknown module
413 too_large Body over 256 KiB
429 rate_limited Wait Retry-After seconds
502 no_consensus Validators disagreed (a non-deterministic module) or votes were invalid
503 unavailable Module busy (another round holds it) or validators syncing
504 timeout No quorum of answers in time

hivejs wraps /api/execute, which the RPC host serves with the same behaviour as /v1/execute. It runs in Node 18+ (any runtime with fetch):

call.mjs
import { Hive, HiveExecutionError } from 'hivejs'
const math = new Hive('0x5b89b7c4f37ab4cf68f30999424ee32775d5c137d35c066e8ce9ce75563887bb', {
gatewayUrl: 'https://testnet-rpc.necter.network',
})
const res = await math.call('multiply', { a: 7, b: 6 })
console.log(res.data, res.gasUsed, res.receiptHash)
try {
await math.call('divide', { a: 1, b: 0 })
} catch (e) {
if (e instanceof HiveExecutionError) console.log('failed on-chain:', e.message, e.gasUsed)
else throw e
}
{ result: 42 } 100472 0x05bda0ee3c3791dabc033c3e5686059e9895ad07df86cdaf1d11896a1bd577b4
failed on-chain: HiveJS: execution failed: guest abort: division by zero 72890

res.data is the output parsed as JSON, res.output the raw string, plus res.events, res.receipt, res.nodeId, res.timestamp. Errors: HiveExecutionError (the module ran and failed; .receipt, .gasUsed), HiveRequestError (4xx; .status, .body), HiveNetworkError (5xx, network, timeout). call is never retried automatically. Options: gasLimit, timeout (30 s), retries (GETs only), headers, fetch.

Neither /v1/execute nor hivejs sends a caller identity, so a module cannot know who called it. If a function must be restricted, have the user sign a message (EIP-191) and verify the signature inside the module (see Data validation & attestation) or in your backend before calling.