KIP: 10
Layer: Consensus, Script Engine
Title: New Transaction Opcodes for Enhanced Script Functionality
Authors: Maxim Biryukov (@biryukovmaxim),
Ori Newman <orinewman1@gmail.com>
Status: Active
This KIP introduces transaction introspection opcodes and enhanced arithmetic capabilities to the Kaspa scripting language. The primary additions include opcodes for querying transaction metadata, input/output properties, and support for 8-byte integer arithmetic operations. These enhancements enable more sophisticated script conditions and use cases, particularly in support of mutual transactions as discussed in KIP-9.
This proposal addresses the need for more flexible and powerful scripting capabilities. The new opcodes allow scripts to access transaction data directly and perform calculations with larger numbers, enabling the implementation of various advanced transaction types. The introduction of these features will:
- Enable more sophisticated smart contracts and conditional spending scenarios.
- Support the implementation of mutual transactions as discussed in KIP-9.
- Enable precise calculations with larger numeric values through 8-byte integer support.
The following new opcodes are introduced to enhance script functionality:
OpTxInputCount(0xb3): Returns the total number of inputs in the transactionOpTxOutputCount(0xb4): Returns the total number of outputs in the transactionOpTxInputIndex(0xb9): Returns the index of the current input being validated
OpTxInputAmount(0xbe): Returns the amount of the specified inputOpTxInputSpk(0xbf): Returns the script public key of the specified inputOpTxOutputAmount(0xc2): Returns the amount of the specified outputOpTxOutputSpk(0xc3): Returns the script public key of the specified output
The proposal extends arithmetic operations to support 8-byte integers (previously limited to 4 bytes). This enhancement applies to:
- Basic arithmetic operations
- Numeric comparisons
- Stack operations involving numbers
- All opcodes that produce or consume numeric values
- These opcodes expect an index parameter on the stack
- The index must be within valid bounds (0 to n-1, where n is the number of inputs/outputs)
- For amount opcodes, values are returned in sompis
- Script public key values include both version and script bytes
- Return values directly without requiring parameters
- Values are pushed as minimal-encoded numbers
- Always succeed if executed (assuming KIP-10 is active)
- The implementation of these opcodes requires a hard fork, as they introduce new functionality to the scripting language.
- All nodes must upgrade to support these new opcodes for the network to remain in consensus.
- The activation of these opcodes should be scheduled for a specific daa score, allowing sufficient time for the network to upgrade.
The features introduced in this KIP are activated based on DAA score:
- Prior to activation:
- New opcodes are treated as invalid
- Arithmetic operations remain limited to 4 bytes
- After activation:
- All new opcodes become available
- 8-byte arithmetic support is enabled
- Existing scripts continue to function as before
The following opcodes are reserved for future expansion:
- OpTxVersion (0xb2)
- OpTxLockTime (0xb5)
- OpTxSubnetId (0xb6)
- OpTxGas (0xb7)
- OpTxPayload (0xb8)
- OpOutpointTxId (0xba)
- OpOutpointIndex (0xbb)
- OpTxInputScriptSig (0xbc)
- OpTxInputSeq (0xbd)
- OpTxInputBlockDaaScore (0xc0)
- OpTxInputIsCoinbase (0xc1)
The enhanced opcodes and arithmetic capabilities address several key requirements:
- Transaction Introspection: Scripts can now examine and validate transaction properties directly, enabling complex conditional logic
- Larger Number Support: 8-byte integers allow for precise calculations with large values, essential for financial operations
- Future Extensibility: Reserved opcodes provide a clear path for future enhancements
- Backward Compatibility: The activation mechanism ensures a smooth network upgrade
These opcodes are designed to work within the existing P2SH framework, maintaining compatibility with current address types while significantly expanding the possibilities for script design.
This proposal requires a hard fork, as it introduces new opcodes to the scripting language. Older software will require an update to support these new features. Existing scripts and addresses remain valid, but cannot use the new functionality without being updated.
A reference implementation of the new opcodes and example usage can be found in the following pull request to the rusty-kaspa repository:
KIP-9 introduced the 'storage_mass' formula to mitigate UTXO bloat. This formula, storage_mass(tx) = C * (|O| / H(O) - |I| / A(I))^+, penalizes transactions that create many small-value outputs, where '|O|' is the number of outputs, '|I|' is the number of inputs, H(O) is the harmonic mean of the output values, A(I) is the arithmetic mean of the input values, and 'C' is a constant.
This formula reflects the principle that a transaction should be charged for the storage its outputs require, with the harmonic mean making the formula highly sensitive to small output values. Standard micropayment approaches that involve numerous tiny UTXOs become impractical due to the increased 'storage_mass'.
Relaxing 'storage_mass' is possible by adding inputs to transactions, which increases the arithmetic mean of the inputs A(I), thus reducing the overall storage mass. However, this traditionally requires coordination and signatures from multiple parties.
KIP-10 introduces new opcodes that allow simulating account-based model without needing new signatures when value is sent to an address. By providing introspection capabilities, scripts can enforce rules that govern how UTXOs are spent based on their value, destination address, and other transaction properties
To illustrate the practical application of the new opcodes, we present three scenarios: a threshold scenario, a shared secret scenario, and a mining pool payment scenario.
OP_IF
<owner_pubkey> OP_CHECKSIG
OP_ELSE
OP_TXINPUTINDEX OP_TXINPUTSPK OP_TXINPUTINDEX OP_TXOUTPUTSPK OP_EQUALVERIFY
OP_TXINPUTINDEX OP_TXOUTPUTAMOUNT
<threshold_value> OP_SUB
OP_TXINPUTINDEX OP_TXINPUTAMOUNT
OP_GREATERTHANOREQUAL
OP_ENDIF
This scenario demonstrates a script that allows for two types of spending conditions:
- Owner spending: The owner can spend the UTXO by providing a valid signature.
- Borrower spending: Anyone can spend the UTXO if they create an output with a value greater than the input by a specified threshold amount, sent to the same script. How it Works and Benefits:
This creates an "additive-only spending" pattern where UTXOs can only be spent by "increasing their value" (that is, sending to an output with the same address as the UTXO with increased value), effectively preventing value extraction without owner authorization.
- Uses
OpTxInputAmountandOpTxOutputAmountto verify the threshold condition - Aligns with KIP-9's goal of controlling UTXO growth through value-based constraints
- Enables automated services that can "borrow" funds by adding value
- Provides spam protection through the threshold requirement while incentivizing UTXO value growth
A practical application of the threshold scenario is in mining pool operations. Currently, pools must accumulate coinbase UTXOs and make less frequent payouts to mitigate KIP-9 mass penalties when outputs exceed inputs. With KIP-10 threshold scripts, pools can:
- Have participants use threshold-based P2SH addresses
- Make payouts even with a single coinbase input by "borrowing" participants' UTXOs
- Create efficient M:N transactions combining multiple inputs for multiple participant payouts
- Maintain frequent payouts without mass penalties
- Allow participants to retain full control of their funds while enabling pool operations
Concept:
- Pool Operation: The pool manages a KIP-10 compatible P2SH address for each participant, ensuring each address always has at least one UTXO.
- Payout Process: When a block is mined, the pool can efficiently distribute rewards using a single transaction with multiple inputs and outputs.
While this KIP focuses on transaction introspection opcodes, it's worth noting a related but separate feature being discussed for Kaspa: additive addresses. Additive addresses would allow for auto-compounding behavior where UTXOs can be spent by adding to their value, subject to certain constraints.
The key distinction is that additive addresses can be implemented without consensus changes, using only the existing P2SH mechanism:
- A public key and threshold value can be combined into a standard script that enforces additive-only spending rules
- This script can be hashed to create a P2SH script public key
- The reverse operation (extracting the public key and threshold from the P2SH hash) is impossible by design, as P2SH only stores the hash of the script
While additive addresses complement the functionality provided by KIP-10's introspection opcodes, they serve different purposes and will be proposed separately. The introspection opcodes in this KIP provide general-purpose transaction inspection capabilities, while additive addresses offer a specific optimization for auto-compounding use cases.
OP_IF
<owner_pubkey> OP_CHECKSIG
OP_ELSE
OP_DUP <shared_secret_pubkey> OP_EQUALVERIFY
OP_CHECKSIGVERIFY
OP_TXINPUTINDEX OP_TXINPUTSPK OP_TXINPUTINDEX OP_TXOUTPUTSPK OP_EQUALVERIFY
OP_TXINPUTINDEX OP_TXOUTPUTAMOUNT OP_TXINPUTINDEX OP_TXINPUTAMOUNT OP_GREATERTHANOREQUAL
OP_ENDIF
This scenario demonstrates a more complex script that allows for two types of spending:
- Owner spending: The owner can spend the UTXO by providing a valid signature.
- Authorized Borrower Spending: Someone can spend the UTXO only if they:
- Know a pre-defined secret (implemented as a keypair and verified with a signature)
- Create outputs matching or exceeding input values
- Send funds back to the same script address
- Uses
OpTxInputSpkandOpTxOutputSpkto enforce script and value conditions - Adds authentication layer through shared secret verification
- Limits access to specific authorized parties while maintaining automation benefits
Implementations of these scenarios and additional examples can be found in the rusty-kaspa repository
- Increased complexity in transaction validation, requiring careful implementation and testing.
- Potential for resource consumption attacks if scripts using these opcodes are not properly limited.
- Implications for transaction caching and optimizations, as scripts may now depend on broader transaction context.
- Potential privacy implications of allowing scripts to access more transaction data.
Implementers should be aware of these considerations and implement appropriate safeguards, such as script size and complexity limits, to mitigate potential risks.
-
KIP-9: Extended mass formula for mitigating state bloat https://github.com/kaspanet/kips/blob/master/kip-0009.md
-
Auto-Compounding Additive Addresses Discussion https://research.kas.pa/t/auto-compounding-additive-addresses-kip10-draft/168
-
Micropayments Discussion (KIP-9 Follow-up) https://research.kas.pa/t/micropayments/20
-
Bitcoin Cash CHIP-2021-02: Native Introspection Opcodes https://gitlab.com/GeneralProtocols/research/chips/-/blob/master/CHIP-2021-02-Add-Native-Introspection-Opcodes.md
This proposal draws significant inspiration from BCH's implementation of transaction introspection opcodes. The BCH implementation demonstrated the viability and benefits of native introspection over covenant workarounds. While Kaspa's implementation differs in some details due to its unique architecture and requirements, the core principles and many design decisions were informed by BCH's successful deployment of these features. We appreciate the extensive research and documentation provided by the BCH community in CHIP-2021-02.
-
BCH Implementation Reference
- Bitcoin Cash Node implementation: BCHN MR 1208
- Test cases: BCHN Native Introspection Tests