KIP-17 explained in one sentence: Toccata gives Kaspa scripts native covenant tools to inspect a spending transaction and enforce how a UTXO may evolve. The active specification adds transaction introspection, byte operations, stack signature checks, hashing, arithmetic, and larger bounded script limits while preserving Kaspa’s deterministic UTXO validation model.
Key takeaways
- KIP-17 lets a locking script examine defined fields of the transaction that is trying to spend its UTXO.
- Introspection plus byte operations can enforce state transitions, such as recreating a controlled output with an incremented counter.
- The specification includes new signature, hash, arithmetic, conversion, concatenation, and substring operations.
- New behavior is gated by the Toccata activation DAA score; older scripts and addresses remain valid.
- Covenants are programmable spending constraints, not an unrestricted virtual machine or an automatic guarantee that an application is secure.
What did KIP-17 add to Kaspa?
The active KIP-17 specification describes covenants and improved scripting capabilities at Kaspa’s consensus and script-engine layers. The document was updated on May 31, 2026, and KIP pull request #32 merged it into the maintained KIP repository on June 2.
Its central change is transaction introspection. A script can ask narrowly defined questions about the spending transaction: its version, lock time, subnetwork ID, gas field, payload, input outpoints, sequences, input UTXO metadata, and output scripts. Existing KIP-10 operations already exposed counts, amounts, full scripts, and the currently evaluated input index; KIP-17 expands that surface and documents the combined model.
That distinction matters. A Kaspa covenant does not run continuously and does not own an account. It is a rule attached to a UTXO. When someone attempts to spend that output, every validating node executes the script against the same transaction data and accepts only a transition that satisfies the rule.
How do native covenants enforce a UTXO state transition?
A conventional locking script usually answers, “Is this spend authorized?” A covenant can also answer, “Does this spend create the permitted successor state?” It can compare the next output’s script, amount, payload, timing, or other exposed fields with constraints encoded in the current output.
KIP-17 gives a counter as its compact example. The spender supplies the previous transaction and payload as witness data. The script checks that the supplied transaction hashes to the referenced outpoint, requires the new payload to increment the prior counter, requires a successor output to use the expected script public key, and restricts the output shape. In pseudocode, the transition resembles delta(previous_payload, transaction) = new_payload.
This is native covenant behavior because validation occurs under Kaspa’s consensus rules. It is still application code: the author must specify every invariant that matters. Forgetting fee handling, a continuation output, an authorization branch, or an edge case can produce a flawed design even when the opcode implementation works correctly.
Which KIP-17 opcodes matter most?
The opcode list is broad, but it is easier to understand in functional groups.
Transaction and UTXO introspection
Operations expose transaction-level values and indexed input or output data. Examples include OpTxVersion, OpTxLockTime, OpOutpointTxId, OpTxInputSeq, OpTxInputDaaScore, and bounded script or payload substring access. Index and range arguments must be non-negative; substring positions are zero-based, with an inclusive start and exclusive end.
Byte strings, hashing, and signatures
OpCat and OpSubstr let scripts construct or select byte sequences. Bitwise operations support fixed-shape transformations. KIP-17 also specifies BLAKE2b and BLAKE3 variants, plus Schnorr and ECDSA checks over a 32-byte message hash supplied on the stack. These stack-signature checks verify a stated message; they do not silently recreate Kaspa’s normal transaction signature digest.
Arithmetic and conversions
Multiplication, division, modulo, OpNum2Bin, and OpBin2Num help scripts encode and validate bounded numeric state. Defined failures include division by zero, signed overflow, an insufficient target byte size, or values outside the eight-byte script-number range. Deterministic failure behavior is a consensus requirement, not a user-interface detail.
The specification deliberately leaves several opcode slots disabled, including left/right slicing and bit shifts. A reserved number in the opcode table is not evidence that an operation is available.
How are resource limits kept explicit?
KIP-17 changes script-engine ceilings after Toccata: the maximum script element, total scripts size, and operations-per-script ceilings rise to 1,000,000, compared with pre-activation limits of 520 bytes, 10,000 bytes, and 201 operations respectively. The specification immediately adds an important qualification: transaction transient-mass rules are expected to constrain practical execution before those ceilings are reached.
Large ceilings therefore do not mean free or unmetered computation. Builders must account for transaction mass, standardness policy, fees, witness size, validation cost, and application-specific denial-of-service risks. A script that is consensus-valid may still be economically impractical or rejected by node relay policy if it does not meet current policy requirements.
KIP-17 also works alongside other Toccata components. The guide to Kaspa ZK hardening and the KIP-21 inactivity shortcut explains why proof verification and sequencing commitments need their own limits and evidence. They are related building blocks, not one interchangeable feature.
What does KIP-17 not prove?
The specification lists possible uses such as tokens, vaults, congestion controls, stateful applications, and bridges combined with KIP-16 proof verification. That list describes what the primitives may support. It does not show that a specific token, vault, bridge, or rollup has been audited, deployed, adopted, or proven safe.
KIP-17 also does not turn Kaspa into an account-based general-purpose virtual machine. Its model remains UTXO-oriented and deliberately constrained. Application state must be represented through transactions and outputs, while scripts validate allowed spends.
Finally, a merged KIP is one evidence layer. Maintained node code, a compatible release, an activation parameter, operator upgrades, and observed network behavior are separate layers. Our review of the Toccata merge into Rusty Kaspa follows that implementation path without treating repository activity as proof of application adoption or a KAS price effect.
What should a Kaspa covenant builder verify?
Start with the maintained KIP and exact Rusty Kaspa release rather than an old opcode table. Pin toolchain and compiler versions, reproduce test vectors, and test only with valueless assets until the full lifecycle is understood. Review genesis, continuation, split, merge, fee, timeout, recovery, and malformed-witness paths.
Treat every transaction boundary as hostile input. Confirm indices before access, bound all variable-length data, validate the precise successor script and covenant binding, and fail closed when an unexpected branch appears. Higher-level languages can reduce mistakes, but generated script still needs inspection, deterministic tests, and independent review appropriate to the value at risk.
Frequently asked questions
Is a Kaspa covenant the same as a smart contract?
It is a form of programmable contract, but the execution model is a bounded UTXO locking script rather than an unrestricted account-based virtual machine. The distinction affects state, composability, tooling, and security review.
Can an old Kaspa address continue to receive and spend KAS?
Yes. KIP-17 says existing scripts and addresses remain valid. New covenant functionality requires compatible transaction and script behavior after activation.
Does OpCheckSigFromStack authorize the whole transaction?
Not automatically. It checks a supplied signature against a supplied 32-byte message hash and public key. The script author defines what that message represents and how the result constrains the spend.
Are the larger script limits a throughput promise?
No. They are script-engine ceilings. Transaction mass, relay policy, fees, workload composition, and real node performance determine what is practical.
Source and verification note
This article is based primarily on the maintained KIP-17 document and merged kaspanet/kips PR #32. Opcode names, argument rules, limits, activation semantics, example logic, and stated use cases were checked against the specification as merged on June 2, 2026. The earlier Rusty Kaspa implementation PR #797 provides implementation history. These sources establish specification and code status; they do not establish the security, deployment, usage, or economic value of any particular covenant application.






