Kaspalytics Learn is a work in progress.
Updated: Aug 2, 2026

The Covenant Program Model

How a Kaspa covenant actually works — a script that carries its own state, reconstructs its successor's address, and enforces the transition. Entry point for the KCC covenant conventions.

Kaspa’s Covenants opcodes and Covenant IDs are consensus primitives. They say what a script is allowed to inspect and enforce. They deliberately say nothing about how a covenant should lay out its data.

That last part is a convention problem, and conventions are what the KCC (Kaspa Covenant Conventions) documents standardize. Without them, every covenant is a private binary format that only its own author’s tooling can read.

That line — what the network enforces versus what programs merely agree on — is the most useful one to keep straight, and it is why this series is split into two groups in the sidebar. Break a consensus rule and your transaction is rejected. Break a convention and your covenant still works; it just becomes unreadable to everyone else’s tooling.

This page establishes the mental model. The pages after it fill in the detail, each building on the one before.

The one idea everything rests on

A covenant program is a script that contains its own state as literal bytes, and whose address is the hash of those bytes.

That single sentence has a surprising consequence, and it is the mechanism behind every covenant on this page:

Because the script is the state, and the address is the hash of the script, a covenant can compute the exact address its successor must have — by taking its own bytes, splicing in the new state, and hashing the result.

The script does not need to “remember” anything. It reconstructs its own future from bytes it can already see.

Building up to it

1. P2SH hides the script until you spend

A Pay-To-Script-Hash output commits only to a 32-byte hash. Nobody can read the script from the chain while the output is unspent. To spend it you must reveal the script (the redeem script) and it must hash to the committed value. See P2SH Script Format.

Call that revealed redeem script R. Throughout the KCC documents, R means the entire covenant program.

2. The program carries its state

R is not just logic. It begins with a run of data pushes holding the covenant’s current values, followed by the code that acts on them:

R — a real 58-byte counter covenant 58 bytes
encoded state 08070000000000000002aabb count = 7, tag = 0xaabb
template suffix (the logic) 01085279519358cd7e010252797e7eb976c97601ae937cbc7eaa02000001aa7e01207e7c7e01877e00c388757551 46 bytes of script
Compiled from a SilverScript contract with count = 7. The first 12 bytes are the state; everything after is fixed logic.

Spending the output reveals all of it — so the running script can read its own current state directly out of its own bytes.

3. Splice new state into the same logic

The logic bytes are the template. Keep them, swap the state, and you have the successor program R_next. Here is the same contract compiled with count = 8:

R_next — count incremented 58 bytes
new encoded state 08080000000000000002aabb count = 8 (07 → 08)
template suffix — byte-for-byte identical 01085279519358cd7e010252797e7eb976c97601ae937cbc7eaa02000001aa7e01207e7c7e01877e00c388757551 unchanged
Exactly one byte differs. The logic is untouched, so this is provably the same contract in a new state.

4. The address follows from the bytes

R_next hashes to a different value than R, so it has a different address:

blake2b(R)      = e9c4ef0278b3d9f5d6d234ae89e2e38f30462fb9b9eeb32ed7caa76625552706
blake2b(R_next) = c4497fd43fe47ddf0a83fb58130ad999ce587f0e00a52a5b380c3f51fa6fd511

The script computes that second hash while it is running, wraps it in the standard P2SH script public key, and requires that one of the transaction’s outputs pays to exactly it. If the spender tries to pay anywhere else, the script fails.

That is the whole covenant loop:

Inputs
Covenant instance count = 7
UTXO locked to blake2b(R)
signature_script reveals R
transition
Outputs
Continuation count = 8
UTXO locked to blake2b(R_next)
address enforced by the running script

The consumed instance validates its own successor. Consensus never has to understand the contract — the script does the checking.

One transition of a stateful covenant.

Vocabulary

KCC1 fixes these terms, and the rest of this series uses them precisely.

TermMeaning
CovenantA spending program that inspects transaction context and restricts how this transaction’s outputs may be spent later
Covenant program (R)The complete executable byte string, including every embedded value and its current encoded state. The P2SH redeem script
Covenant instanceA UTXO locked to a covenant program. Identified uniquely by its outpoint
TransitionA transaction consuming one or more covenant instances and creating zero or more continuations
ContinuationAn output the consumed instance accepts as its successor
TemplateWhat is left of R when the state range is removed — an ordered prefix and suffix

Two distinctions worth internalizing early, because they are easy to blur:

  • A program is bytes; an instance is a UTXO. Several UTXOs can hold the identical program. blake2b(R) therefore identifies a contract-in-a-state, not a coin.
  • A template is shared by every state a contract can be in. It is the closest thing to “the contract’s identity” that pure script can express — which is why so much of KCC1 is about hashing and authenticating templates.

Where consensus helps: Covenant IDs

Reconstructing the successor address proves the next output is correct. It does not, on its own, prove that the UTXO you are spending descends from a legitimate origin rather than from a lookalike someone else deployed.

KIP-20 solves that in consensus. A Covenant ID is an optional 32-byte value on a UTXO marking it as a member of a lineage, and a covenant binding on an output names the input authorizing it. Consensus itself enforces that continuations inherit their parent’s Covenant ID, and the OpCov* and OpAuth* opcodes let a script query that structure directly.

So the two halves divide cleanly:

  • The script proves the successor’s contents are correct.
  • Consensus proves the successor’s lineage is correct.

Covenant IDs are covered in depth in Covenant IDs & Bindings.

What the KCC documents standardize

None of the above changes consensus rules. The KCCs are conventions layered on top of primitives that already exist.

DocumentScope
KCC1Byte layouts and ABI: value encodings, entrypoints and dispatch tags, the P2SH envelope, state and templates, lineage roles, virtual elements
KCC2How a program ABI declares who controls a covenant, so observers can answer “whose is this?”
KCC20A fungible-token covenant surface: required state prefix, transfer interface, and a published descriptor

KCC1 is deliberately independent of any source language or compiler. SilverScript is the reference compiler that produces programs in this shape, and every hex example in this series is real output from it.

How to read this series

The pages are ordered so each one only relies on the pages before it, and grouped by whether they describe a network rule or a convention.

Consensus — enforced by the network. True of every covenant, whatever conventions it follows.

#PageWhat it adds
1Covenant OpcodesThe full opcode surface a covenant can call
2Covenant IDs & BindingsKIP-20 lineage — how a covenant gets a forgery-proof identity

Conventions — the KCC documents. Agreements about byte layout that make covenants interoperable.

#PageWhat it adds
3The P2SH Covenant EnvelopeHow R is committed to, revealed, and executed
4The Value ABIHow typed values become bytes — the alphabet everything else is written in
5Entrypoints & DispatchHow one program exposes several callable branches
6State, Templates & ContinuationsHow state is carved out of R and spliced back in
7Template Views & Virtual ElementsPartial state mutation, and committing to data too large to embed
8Leaders & DelegatorsCoordinating a transition across several covenant inputs
9Control PrincipalsKCC2 — declaring who controls a covenant
10KCC20 Fungible TokensThe whole stack applied to a real token standard

If you only read two, read Covenant IDs & Bindings and State, Templates & Continuations — one from each half, and together they cover the concepts that most often trip people up.

Status

KCC1, KCC2, and KCC20 are all Draft. SilverScript is explicitly experimental and its authors recommend testnet-10 only for now. Where the current compiler and the draft specs differ, this series says so on the page where it matters.

The primitives underneath them are not draft — they are active on mainnet as of the Toccata hard fork. On-chain adoption is charted live at covenant transactions, covenant outputs, and covenant UTXO count.

Working examples

Runnable covenant code, useful for seeing the primitives exercised end to end:

Specifications

SpecCovers
KCC1Covenant definition, concepts, byte layouts and ABI
KCC2Control principal references in program ABIs
KCC20Fungible token covenant specification
KIP-10New transaction opcodes for enhanced script functionality
KIP-16New transaction opcodes for verifiable computation (the ZK precompile)
KIP-17Covenants and improved scripting capabilities
KIP-20Covenant IDs

See also the KIPs reference and SilverScript.

Prior art

Covenants are a long-running idea in the UTXO world, and much of the design vocabulary comes from Bitcoin research:

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