Kaspalytics Learn is under (heavy) construction. Check back regularly!
Updated: Aug 14, 2026

Transaction Model

The objects a Kaspa transaction is built from - the transaction itself, its inputs and outputs, the outpoint, the locking script, and the coin record a node has to supply from its own state.

The pages before this one described what a transaction does. This page describes what it is made of: a small set of nested objects, each with a fixed list of fields.

Four objects, nested

A transaction is not a flat record. It is one object holding two arrays, and the entries in those arrays hold objects of their own.

Transaction
├─ version, lockTime, subnetworkId, gas, payload
├─ inputs[]
│   └─ Input
│       ├─ previousOutpoint  →  { transactionId, index }
│       ├─ signatureScript
│       ├─ sequence
│       └─ computeCommit
└─ outputs[]
    └─ Output
        ├─ value
        ├─ scriptPublicKey  →  { version, script }
        └─ covenant         →  { authorizingInput, covenantId }   (optional)

This is the whole model. Everything a wallet displays that is not in this tree - the fee, the sender, the amount an input is worth, the balance - is either computed from it or fetched from node state.

The transaction

Seven fields wrap the two arrays.

FieldHoldsWhy it exists
version0 or 1Selects which field set inputs and outputs use. See below.
inputsarray of InputThe coins being spent. A non-coinbase transaction with none is rejected outright.
outputsarray of OutputThe coins being created.
lockTimeu64The earliest point the transaction may be included. Zero means immediately.
subnetworkId20 bytesAll zeros for an ordinary transaction. A reserved value marks the coinbase.
gasu64Zero for an ordinary transaction. Carries the gas commitment on a subnetwork transaction.
payloadbytesArbitrary data, empty by default, opened to ordinary transactions at Crescendo.

A plain payment sets three of them: version zero, the inputs, and the outputs. Lock time stays zero, the subnetwork id stays all zeros, gas stays zero, and the payload stays empty.

Lock time encodes two meanings in one field. Below five hundred billion the value is read as a minimum DAA score; at or above it, as a Unix timestamp in milliseconds. The threshold is far past any block count the network will reach and far before any plausible timestamp, so the two ranges cannot collide.

An input names a coin, it does not contain it

FieldHoldsWhy it exists
previousOutpointoutpointWhich coin is being spent.
signatureScriptbytesThe proof that spending it is allowed - signatures, and for pay-to-script-hash the redeem script too.
sequenceu64Relative lock time, and the finality flag. See below.
computeCommitenumHow much script execution this input is paying for.

The outpoint is two fields and nothing more:

FieldHolds
transactionId32 bytes - the transaction that created the coin
indexu32 - which of that transaction’s outputs it was

The amount is absent. An input identifies a coin; it does not state its value. The value being spent appears nowhere in the transaction, so a transaction cannot be validated on its own - the coin must be looked up.

Sequence carries two meanings in one number. The top bit is a disable flag; when it is set, the input has no relative lock. When it is clear, the low thirty-two bits are a number of blocks that must have passed since the coin’s own DAA score before the input may be spent. Separately, if every input is set to the maximum value - which has that top bit set - the transaction counts as final and its lock time no longer holds it back.

The compute commitment is one of two variants, and the transaction version decides which:

VariantTypeUsed by
sigOpCountu8Version 0
computeBudgetu16Version 1

Both resolve to the same thing - an allowance of script units for that input, on top of a small free budget every input gets. A sigop count states how many signatures the input checks. A compute budget prices arbitrary execution directly, which is what a covenant or a proof verification needs.

An output is an amount and a lock

FieldHoldsWhy it exists
valueu64The amount, in sompi. Integers only; KAS is a display unit.
scriptPublicKeystructThe condition for spending the coin next.
covenantoptionalThe output’s covenant binding. Version 1 only.

The locking script is versioned, though only one version exists so far:

FieldHolds
versionu16 - zero is the only value consensus accepts today
scriptbytes - decoded from the recipient’s address

And a covenant binding, when present, is also two fields:

FieldHolds
authorizingInputu16 - the index of the input that permitted this output
covenantId32 bytes - the lineage the output belongs to

The lock types in circulation are charted at output script classes.

The coin record a node supplies

Because an input is only a pointer, validating a transaction means pairing every input with the coin it names. That coin is its own object, held in the node’s UTXO set rather than in the transaction:

FieldHoldsUsed for
amountu64The value being spent. This is where the fee arithmetic gets its inputs.
scriptPublicKeystructThe lock the signature script has to satisfy.
blockDaaScoreu64When the coin was created - the baseline for relative locks and for maturity.
isCoinbaseboolWhether the longer coinbase maturity rule applies.
covenantIdoptionalThe lineage the coin carries, checked against the covenant rules on spend.

Validation pairs a transaction with node state. The transaction supplies pointers and proofs, the node supplies the coins, and the rules run against the combination.

Two practical consequences follow. A wallet cannot build a transaction without first fetching its own coins - that is what getUtxosByAddresses is for, and why the node serving it needs the UTXO index enabled. And a node that has never seen the parent transaction cannot validate the child, which is the situation the orphan pool exists to hold.

What is computed rather than stored

ValueWhere it comes from
Transaction idA hash over the transaction with signature scripts and payload left out, so the id is settled before anyone signs.
Transaction hashA hash over everything, signatures included.
FeeTotal input value minus total output value. See Fees & Mass.
Compute massDerived from the size and the compute commitments.
Transient massDerived from serialized size.
Storage massDerived from the input and output amounts.

Storage mass is the one exception. The transaction carries a commitment to it, and consensus recalculates the figure and rejects the transaction if the two disagree - so it is stored and computed, and the stored copy is a claim that consensus checks. The SDKs fill it in automatically.

The two versions

VersionEnables
0The original layout. Inputs commit a sigop count; outputs have no covenant field.
1Covenant bindings on outputs, compute budgets on inputs, non-native subnetworks, gas commitments. Arrived with Toccata.

The two cannot be mixed. A version 0 transaction cannot carry a covenant binding, and a version 1 transaction commits compute per input rather than counting signature operations. Version 0 remains valid indefinitely; an ordinary payment does not need version 1.

See Also: UTXO Model, Fees & Mass

Kaspalytics strives to provide accurate data - our highest level of effort is given to data validation and maintenance. However, we cannot guarantee 100% accuracy. Data is subject to inaccuracies and change.

Contact | © 2026 Kaspalytics