Skip to content
119 changes: 119 additions & 0 deletions CIP-0172/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
CIP: 172
Title: Self-Usable Transaction Outputs
Status: Proposed
Category: Ledger
Authors:
- Carlos Tomé Cortiñas <carlos.tome-cortinas@iohk.io>
Implementors:
Discussions:
Created: 2026-01-15
License: CC-BY-4.0
---

## Abstract

We propose to allow transactions to reference scripts and data present on their
own outputs during validation.

## Motivation: Why is this CIP necessary?

Transaction outputs carry scripts (via reference scripts) and/or data (via
inline datum). However, the Cardano Ledger currently enforces a restriction
that prevents a transaction from satisfying its validation requirements using
scripts and data contained within its own outputs.

This restriction creates a specific inefficiency: if a transaction produces an
output containing a script or datum that is also required to validate that same
transaction, the transaction cannot utilize the copy present in the output.
Instead, the transaction must provide a redundant copy of the same script or
data (e.g., in the transaction witnesses). This forced redundancy increases
transaction size, and thus transaction fees, directly inflating the costs
incurred by users.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow the argument of re-using inlined data.

If a transaction wants to spend an output that carries inlined data, that data would already be in the utxo set and thus the creating tx paid for it. For "normal" datum use, there would only be a datumhash on the utxo and the spending transaction provides the preimage in the witness set. This data resolves across any spent inputs that are parameterized by the same data (hash). I don't know how this evolves for nested transactions but I would expect it to allow re-use of hashed data. For other validation purposes, there is no datum in the context.

So, what exactly motivates the sketched change of getDatum in the agda spec?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do agree with this point, since datums are not reusable from reference inputs either. This change alone would lead to strange semantic where datum from outputs created can be reused throughout a transaction, while ones specified in inputs and reference inputs cannot. If we are to make such a change it would require its own CIP. However, I vaguely remember discussing this point long time ago with some folks that actually write DApps and their argument against was that it is very rare that a script requires the same data and it is usually fairly small anyways.
I think it would be worthwhile analyzing the chain and see whether there could actually be some space savings if we were to add such feature of inline datums being shared throughout a transaction.


In combination with the upcoming feature of [nested transactions](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0118/README.md), in the
Dijkstra era, the current restriction imposes a strict constraint in how
scripts and/or data can be shared within a batch. Specifically, without this
proposal, scripts and/or data produced in transaction outputs are only
accessible to subsequent sub-transactions (via reference inputs). This forces
transaction builders to artificially order transactions or to provide redundant
copies of the same script or data (e.g., if two sub-transactions mutually
depend on each other's script and/or data).

The key idea of this CIP is to remove this restriction, allowing transactions
to reference their own outputs for validation purposes.

### Use cases

#### Stateful dApps

Even for simple dApps consisting of a single script, currently deploying these
dApps on Cardano requires multiple transactions. The minimal workflow for such
a stateful dApp requires (1) deploying the dApp's script in the UTxO and (2)
referencing this script (via reference inputs) to mint the relevant state
tokens.

With the proposed changes, such applications could be deployed in a single
transaction, which simultaneously produces the reference script UTxO's and
mints the state token. This eliminates the need for submitting multiple
transactions, thereby reducing costs, while at the same time improving the
developer's experience.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is a reference script at all needed in this use case?

This exact annoyance could guide a dApp developer to not use reference scripts, but just include the script in the witness set of the transaction that mints the tokens. Thus, only incurring a transaction fee and not require the additional deposit for the reference script in the output (which grows the utxo state, that must be paid).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparing to just including the witness set, adding a script to the UTxO will require the user to lock up the funds in the form of minUtxO, so that is the motivating factor against it. Which means the only reason why a user would want to do this instead of just using a script in witnesses is for further reuse.

So, this statement is incorrect: "not require the additional deposit for the reference script" There is still deposit for including a script in the output.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point is that the script that is used to deploy the initial state tokens will of-course be reused. IE. A DEX pool script (minting policy and spending validator multi-validator). Right now you need to deploy reference scripts, and create the pool in two separate txs.

You could just mint the tokens providing pool script as witness and then deploy reference scripts after but that's still two txs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then, it was just not clear to me as a reader that this example is not an isolated usage, but the optimization of combined publishing scripts as reference + the first usage in the same transaction. The example was helpful and I suggest it should be added to the CIP / existing examples be made more concrete.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@carlostome I think adding such an example would help make the proposal more "user friendly" - which has been important for other CIPs to keep people aware of best-practice design patterns.


#### Nested transactions: order-agnostic script sharing across a batch

The nested transactions CIP specifies that scripts are to be shared among all
sub- and top-level transactions within a batch (see [CIP-0118 > Changes to Transaction
Validity](https://github.com/carlostome/CIPs/tree/master/CIP-0118#changes-to-transaction-validity)).

With the current restriction, this requirement can only be partially achieved
by sharing scripts either (1) from transaction witnesses or (2) via reference
inputs that point to outputs of sub-transactions in the same batch which have
already been applied to the UTxO state.

With the proposed change in this CIP, the requirement can be achieved allowing
scripts to be shared directly from transaction outputs, regardless of which
sub- or top-level transaction they appear in. This eliminates the dependency on
processing order and enables more flexible script sharing within the batch.

## Specification

There is an [Agda
specification](https://github.com/IntersectMBO/formal-ledger-specifications/tree/carlos/usable-outputs)
prototype of the proposed changes (for Conway).

### Changes to the Ledger logic

- The function `txscripts` needs to be modified to include scripts from `txouts`.
- The function `getDatum` needs to be modified to include data from `txouts`.

## Rationale: How does this CIP achieve its goals?

The current ledger logic prohibits transactions from accessing their own
outputs during validation. However, this restriction comes at the cost of
redundancy when the same script or datum serves dual purposes: being included
in an output for future use and being required for current validation.

This CIP achieves its goal by relaxing this restriction so that validation may
reference scripts and data committed in the transaction body’s outputs, which
removes the need to carry duplicate copies in witnesses and reduces transaction
size and fees.

### Backward compatibility

The changes proposed in this CIP break backward compatibility of Plutus scripts
whose logic depends on the script being part of the outputs of the transaction
being validated.

## Path to Active

### Acceptance Criteria

- Fully implemented in Cardano node

### Implementation Plan

- TODO
Comment on lines +109 to +115
Copy link
Collaborator

@rphair rphair Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Acceptance Criteria
- Fully implemented in Cardano node
### Implementation Plan
- TODO
### Acceptance Criteria
- [ ] Fully implemented in Cardano node
### Implementation Plan
- [ ] Update the formal Ledger specification with "changes to the Ledger logic" above
- [ ] Implement the outlined changes in the Cardano node
- [ ] Complete a hard fork enabling support for the changes outlined here

I used https://github.com/carlostome/CIPs/tree/master/CIP-0118#implementation-plan as a template:

  1. @Ryun1 @lehins can please double check for consistency with similar Ledger proposals?
  2. @carlostome & others please add anything in developer relations that could be seen as a dependency (a common issue with Ledger changes so perhaps implicit & therefore no need to publicise it?)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p.s. I can also see (somehow missed before) in the original comment the current uncertainty about implementation in Conway vs. Dijkstra... understandably this would still be TODO while that decision is made.


## Copyright

This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode).