States and templates (KCC-1)
KCC-1 (“Covenant Concepts, Byte Layouts, and ABI”) is the shared language of Kaspa covenants. It fixes how a covenant program is wrapped, where its state lives, and how others recognise it. KCC-1 does not change consensus.
| Term | Meaning |
|---|---|
Covenant program R |
The complete script, including its current state. KCC-1 uses it as the P2SH redeem script |
| Covenant instance | A UTXO locked to a covenant program, identified by its outpoint |
| Transition | A transaction that consumes covenant instances and creates continuations |
| Continuation | An output that a consumed instance accepts as its successor |
| Entrypoint | A named way to spend the covenant, with typed arguments (for example mint or transfer) |
The P2SH envelope
Section titled “The P2SH envelope”A covenant UTXO does not show its program. Its locking script is a pay-to-script-hash (P2SH) commitment:
OP_BLAKE2B OP_DATA_32 <BLAKE2b-256(R)> OP_EQUALTo spend it, the input’s signature script pushes the entrypoint arguments, a 4-byte dispatch tag that
selects the entrypoint, and finally R itself. The node checks that R hashes to the committed value, then
runs R.
dispatch_tag = BLAKE3("name(type,type,...)")[0:4]State lives inside the script
Section titled “State lives inside the script”A covenant’s state is a byte range inside R. The rest of R is its template: a prefix and a suffix.
R = template.prefix ‖ encoded_state ‖ template.suffixWhen state changes, the program changes, so its P2SH hash changes too. A covenant forces its successor by rebuilding the expected next program and comparing hashes:
R_next = template.prefix ‖ encode(next_state) ‖ template.suffixexpected = OP_BLAKE2B OP_DATA_32 <BLAKE2b-256(R_next)> OP_EQUALAn unspent UTXO shows only the hash. Its state becomes visible when it is spent, because R appears in the
spending input. Indexers and wallets track state from those spends and from the transactions that created the
UTXOs.
Template hashes
Section titled “Template hashes”KCC-1 names a template by its hash:
TemplateHash(prefix, suffix) = BLAKE3( LE64(len(prefix)) ‖ prefix ‖ LE64(len(suffix)) ‖ suffix )Two UTXOs with the same template run the same code, whatever their state. That is how a wallet recognises a
KCC-20 token: it checks the template hash. kUSDT’s KCC20 template hash is the standard one, 9703112e…3cf7.
See The KCC20 template.
Leaders and delegators
Section titled “Leaders and delegators”When several inputs of one covenant ID take part in one transition, KCC-1 assigns roles by input order. The first such input is the leader; it validates the whole transition. Every later one is a delegator; it checks only its local conditions, such as its owner’s approval, and relies on the leader. KCC-20 transfers work this way.
Commitments to larger values
Section titled “Commitments to larger values”A virtual element is a value stored only as a 32-byte hash commitment, with the full value supplied when
needed. KCC-20’s extension_commitment field is one: it commits to application-specific extended state. kUSDT
uses no extended state, so its commitment is 32 zero bytes.