Transactions

Anatomy of a Transaction

A transaction is a Nock ISA noun. At the highest level, a raw transaction consists of only a few elements hierarchically arranged:

  • Version number (currently %1).

  • Transaction ID: a cryptographic Tip5 hash of transaction contents.

  • Spends: a map of a note name to a spend.

Notes

A note is an unspent transaction output (UTXO) representing a specific amount of $NOCK owned by someone. It's like a check made out to be spendable only under certain conditions, including ownership. Every note contains five essential pieces of information:

  1. The name uniquely identifies the note. It's derived from two hashes: one committing to the spending conditions (the lock-root), and one committing to where the note came from (the source). This means one can reference a note without knowing how to spend it or where it originated, improving privacy and efficiency.

  2. The lock defines who can spend the note and under what conditions. In v1, this is a Merkle tree of spending conditions. One might require two-of-three signatures, or one signature plus a secret, or just a certain block height. The lock-root (the hash of this tree) is baked into the note's name, so the spending conditions can't be changed after the note is created.

  3. The source is a cryptographic commitment to the note's origin. For regular notes, this is the hash of the seeds that created it—a commitment to all the transfers that spent into this note. For coinbase notes (newly minted $NOCK captured by miners), the source is the hash of the previous block, avoiding circular dependencies in proof generation.

  4. The assets field is simple: how many nicks (the smallest unit of $NOCK) the note contains. One nock equals 65,536 nicks.

  5. The note-data field is arbitrary key-value information associated with the note. This could be metadata, application-specific data, or anything else that needs to travel with the value. It's limited to prevent bloat.

The note name consists of two hashes, the first being the lock root (or hash of the lock script) and the second being the source commitment (where the note came from). This is a note name for a note produced in block 38,220, for instance, as a cell of atoms:

[B4aUQXDmX7CHuM9XycSogGcCoi2CyP66TRbNNeinKXyNXgy7gT62DQp
 8ypyL1AFW45qz97cE3EHP8ye3PCrXjo8Cbpa2qwD5qoBNXzhhN8iSK8]

Notes are created when a transaction creates them as outputs. They persist indefinitely in the UTXO set, the global ledger of all unspent notes. They are cancelled when a transaction spends them, consuming them as inputs and creating new notes as outputs. A note can only be spent once. When one spends a note, one must:

  1. Prove one can satisfy its lock (provide a valid witness).

  2. Specify where the value goes (create seeds for output notes).

  3. Account for every nick (outputs + fees = input assets).

Notes cannot be spent partially. If one has a 1,000-nick note and wants to send 300 nicks to someone, one creates two output notes: one for 300 nicks (to them) and one for 700 nicks (back to the originator, minus fees).

This note-based model produces a clear ownership model. Each note is discrete, identifiable, and explicitly owned. There's no shared pool of “account balance”; one owns specific notes, just like one owns specific paper bills in one's physical wallet.

Spends

To spend a note, one provides a witness which proves that one has satisfied one branch of the lock tree. Seeds specify where value goes, and incurs transaction fees. Thus each spend consists of:

  • Witness: proof that the note can be unlocked.

  • Seeds: individual transfers to output notes.

  • Fees: sum of all fees.

Let's work through these components in detail.

Witness

A witness, the cryptographic proof that a note can be unlocked by the sender, contains various conditions:

  • Lock Merkle proof: a lock is organized as a Merkle tree of spending conditions, and only the branch being utilized is revealed. The Merkle proof demonstrates that one's chosen spend condition is actually part of the note's lock without exposing the other branches. This preserves privacy: alternative spending paths remain hidden.

  • PKH signatures: If the spending path includes a pay-to-pubkey-hash condition (PKH), one provides the required public keys and Schnorr signatures (possibly 1-of-1, possibly m-of-n multisig). These prove that one controls the private keys corresponding to the public key hashes in the lock. Nockchain uses batch verification to check all signatures efficiently.

  • Hashlock preimages: If the spending path includes a hashlock (HAX), one provides the preimage—the secret data that hashes to the value specified in the lock. This enables atomic swaps and hash-time-locked contracts: “one can spend this note if one reveals the secret.”

  • Timelock data: If the spending path includes timelocks (TIM), the system checks these dynamically against the current block height. Absolute timelocks specify a minimum block height (e.g., “spendable after block 50,000”), while relative timelocks specify a waiting period from the note's creation (“spendable 100 blocks after this note was created”). Unlike signatures and preimages, timelocks don't require witness data, but are only verified by comparing block heights.

The lock root is the Merkle root of a tree with each leaf being a spend condition. Spenders only reveal the branch they use, leaving other spending conditions private. For example, for a lock with four spending conditions, the lock looks like this:

        Root
       /    \
      /      \
   Hash1    Hash2
   /  \      /  \
  C1  C2    C3  C4

To spend via condition C3, one provides the spend condition C3, a Merkle proof of [Hash1, Hash of C4], and witness data satisfying C3. This enhances privacy since unused spending paths remain hidden to observers.

For example, a lock [HAX(H) OR (PKH(my-key) AND TIM(min=100))] is spendable by either:

  1. Any buyer with preimage S, where H=hash(S) (i.e. a buyer claims by revealing a secret).

  2. Or I can reclaim after 100 block timeout.

The witness is segregated from the core transaction data (seeds, fees, note references), similar to Bitcoin's SegWit. This separation means the transaction ID is computed from the transaction data alone, without including witness information. This prevents transaction malleability (in which signature changes could alter transaction IDs) and enables future witness format upgrades without changing the transaction structure.

(A v0 witness, supported until block 39,000, simply consisted of a signature without the segregated witness.)

Nockchain's transaction engine supports flexible lock scripts. To summarize, the following lock types exist on notes:

  • pkh, verify m-of-n multisigs using batch verification (including 1-of-1).

  • tim, check timelock as block height constraint (relative or absolute).

  • hax, check hashlock, i.e. verify the preimage hashes to the claimed value.

  • brn, burn (always fails, provably unspendable).

and unions of these (of which only one need be satisfied). This note-based model is similar to Bitcoin, but supports richer lock conditions enabled by zero-knowledge proofs and a timelock system supporting both absolute and relative constraints.

Seeds

Seeds are the individual transfers that direct one's note's value to new output notes. Each seed specifies:

  1. Lock-root: the hash of the recipient's lock script. This determines who can spend the output note and under what conditions. One doesn't need to know the full lock tree, just its hash. The recipient provides the full lock when they eventually spend.

  2. Note-data: an optional key-value data to attach to the output note. This is limited to 2,048 words (leaves in the data tree) to prevent blockchain bloat. Applications can use this for metadata, state information, or protocol-specific data that needs to travel with the value.

  3. Gift: the amount of nicks being transferred. This is the actual value moving to the output note.

  4. Parent-hash: a hash of the note one is spending. This creates an immutable link between inputs and outputs, preventing hash loops in proof generation. Every seed commits to its source, creating a traceable lineage back through the transaction graph.

One can create multiple seeds from a single input, splitting the value across multiple recipients. Conversely, multiple inputs can create seeds pointing to the same lock-root, which then get aggregated into a single output note.

Fees

The fee is the sum of all fees for transactions involved in the note, denominated in nicks (1⁄65536 of a nock, or the integer unit of $NOCK). There is a base rate of 256 nicks for any transaction, which serves as a floor to establish basic spam control.

Fees compensate miners for including a transaction in a block. Fees are calculated based on “word count”, the number of data elements in the witness and note-data fields:

The minimum fee is 256 nicks. Beyond that, one pays 32,768 nicks (0.5 nocks) per word of data. Words include:

  • Signature data in the witness

  • Preimages in the hashlock witness

  • Merkle proof elements

  • Key-value pairs in output note-data

This creates a direct relationship between resource consumption and cost. More complex witnesses or data-rich outputs cost proportionally more, but the formula is transparent and predictable, so no per-line-of-code gas optimization is required. Thus Nockchain fees are based on transaction weight, not computational complexity: no gas optimization is required, and fees are predictable.

Of course, output assets must equal input assets minus fees. Every nick in the input notes must be accounted for. If one is spending a 1,000-nick note with a 10-nick fee, one's seeds must specify exactly 990 nicks of outputs. Too little and the transaction is invalid. Too much and it's impossible (no creatio ex nihilo).

In practice, this means if one is sending someone 300 nicks from a 1,000-nick note, one creates two seeds:

  1. Gift of 300 nicks to their lock-root.

  2. Gift of 434 nicks back to the lock-root (change).

to which is added a 256-nick fee to miners (the minimum). The total accounts for 1,000 nicks.

Thus, a complete spend looks like this:

  • Input:

    • 1,000-nick note locked by [2-of-3 multisig OR hashlock]

  • Witness:

    • Lock Merkle proof (proving 2-of-3 path is valid)

    • 2 Schnorr signatures (Alice + Bob)

  • Seeds:

    • 300 nicks → Carol's lock-root

    • 434 nicks → The source's lock-root (change)

  • Fee:

    • 256 nicks

  • Total:

    • 300 + 434 + 256 = 1,000

The witness proves one can unlock the note (Alice and Bob signed). The seeds direct the value (Carol gets 300, the source keeps 434). The fee compensates the miner (256 nicks, the minimum). The transaction is valid because all nicks are accounted for and a witness condition is met.

This spend consumes one input note and creates two output notes, each with their own locks, names, and spending conditions. The cycle continues as those notes are eventually spent, creating new notes, which are spent again. Value flows through the network in discrete, provable steps.

With Nockchain's sophisticated transaction model and zero-knowledge proof-of-work blockchain, users and developers accrue many benefits. Users gain more flexible security (e.g., 2-of-3 multisig OR 1-of-1 with hashlock), better privacy (unused spending paths stay hidden), and predictable costs (fee calculation is transparent and linear). Developers can produce richer sovereign applications, with complex spending conditions (escrows, atomic swaps, time-vaulted assets) and cleaner code (witness separation makes transaction logic clearer). Nockchain furthermore has robust spam protection, efficient validation, and forward scalability with a linear fee structure in line with actual resource costs.

This structure enables:

  • Light clients (just verify Merkle proofs, don't need full lock scripts).

  • Privacy (lock script revealed only when spent).

  • Flexibility (multiple spending paths in a single lock).

Now that we understand the components of a spend, let's examine how transactions move through the network from creation to confirmation.

Transaction Lifecycle

A transaction undergoes a creation step, a signing step, a broadcasting step, a mempool step, inclusion in a block, and finally confirmation. The specific mechanics of creating and signing signatures are described in detail with the wallet documentation.

Creation

A raw transaction is created off-chain. It may be built in a single stage (most common) or produced in several steps. The transaction is built from available notes and target addresses. The transaction ID is calculated from the other data and the raw transaction is produced. The basic components of transaction creation are:

  1. Select input notes and determine which spending path to use for each.

  2. Create seeds specifying output recipients and amounts.

  3. Build witness for each input (signatures, preimages, Merkle proofs).

  4. Calculate fees based on word count.

Input assets should be at least equal to outputs plus fees; if the inputs are more than the outputs plus fees, the leftover value will be returned as a UTXO note to the source address.

Signature

Signing of the raw transaction—the hash of seeds plus fee—takes place with private keys matching the lock conditions of the input notes (for instance, with m-of-n multisigs).

Broadcasting to the Mempool

Raw transactions are broadcast to the Nockchain mempool using libp2p. The mempool is the shared pool of unconfirmed transactions. As transactions arrive to the mempool, a number of validation checks are carried out: signature validity, input existence in UTXO set, transaction formatting, etc. Conflicting transactions (attempting to spend the same notes) are resolved by miners selecting the transaction with higher fees and rejecting conflicting alternatives. The miners share the mempool contents with each other actively.

Validation involves:

  1. Check structure: verify version tag, proper formatting, base field membership.

  2. Validate witnesses: verify Merkle proofs, signature verification, hashlock checking.

  3. Check constraints:

    1. Is the minimum fee met (256 nicks)?

    2. Are word-based fees sufficient?

    3. Are data within limits (2,048 words max)?

    4. Are input assets equal to output assets plus fees?

  4. Verify timelocks: dynamically check against the current block height.

  5. Prevent double-spends: ensure the inputs have not already been spent.

Block Inclusion

Incoming transactions are validated for signatures and field membership. Transactions are prioritized by fees and bundled by miners for inclusion in a candidate block. The miner producing a candidate block includes the raw transaction in a block. The input raw transactions are removed from the UTXO mempool set. This entails conversion of the raw transaction to a full transaction by adding appropriate outputs: the notes now include downstream use authorization in classic UTXO fashion.

Each individual transaction is verified by checking its signature, the input existence and spendability, satisfaction of the lock conditions, and overall well-formedness. Block-level transaction bundles are checked by seeing whether all transactions in the block are valid, that there are no double-spends within the block, and that fee calculations are amenable. Transactions which fail to verify are rejected and tracked separately. There is a separate rebroadcast mechanism for valid transactions from orphaned blocks.

Confirmation

Transactions which have been included in a valid block are cleaned up from the mempool. Input notes are marked as spent in a tracking index and output notes are added to each UTXO set.

While a blockchain is never completely “final”, accumulated proofpower gives high confidence in transaction settlement. Typical practice is to wait three to six blocks for general-purpose confirmation.

Special Transactions

Intents

The transactions we have seen thus far are imperative. In contrast, intents are declarative conditions for note spending. They express an off-chain resolution of conditions which must be met in order for a note to be spendable. They allow Nockchain to provide smart-contract-like flexibility for a UTXO-based model.

Essentially, the user (or user's application) expresses an intent over the chain state. The transactor's off-chain logic processes the intent and generates a proof of valid execution. That proof is then submitted to the chain for verification.

Atomicity

Atomic transactions ensure that multiple dependent operations either all succeed or all fail, enabled through intent batching and cryptographic proof aggregation.

Multiple intents from independent offchain apps are aggregated into batched proofs with explicit dependency chains, ensuring atomicity: either all dependent intents within a combined proof succeed, or none do. Nockchain’s settlement layer verifies aggregated proofs atomically, allowing large batches of notes to be spent or modified simultaneously with minimal on-chain execution.

Coinbase Transactions

Coinbase transactions mint new $NOCK as block rewards according to a fixed emission schedule. Each block includes one coinbase that creates coins rather than spending existing notes. Miners can split rewards across multiple addresses, but all coinbase outputs have mandatory timelocks (100+ blocks) to prevent immediate spending. The source field commits to the parent block hash rather than previous transactions, avoiding hash loops in proof generation.

v0 Notes

Notes created prior to block height 39,000 in October 2025 are v0 notes. These are not invalidated, but they must be spent using the v1 transaction format. Users with v0 notes should:

  1. Continue using existing wallet software (updated for v1 format).

  2. Spend v0 notes normally (wallet handles version differences).

  3. Receive new notes in v1 format automatically.

Developers building on Nockchain should:

  1. Update transaction construction to use v1 format.

  2. Implement lock script generation for flexible spending conditions.

  3. Calculate fees using the new word-based formula.

  4. Test witness construction and validation.

All of these are demonstrated in the CLI wallet application.

Last updated