From dd404aa7fe8a4763b337fd8bc828e6e6e5862171 Mon Sep 17 00:00:00 2001 From: Santiago Date: Sun, 7 Jun 2026 11:21:45 -0300 Subject: [PATCH 1/2] docs(language): document automatic reference inputs for ref-backed policies A policy declared with a `ref` field, when used as an input's `from` or as a mint/burn policy, now automatically contributes its `ref` UTxO to the transaction's reference inputs. Document this in the policies and txs guides, and distinguish it from inline `script` bytes (which still require a `cardano::*_witness` block). Co-Authored-By: Claude Opus 4.8 (1M context) --- language/policies.md | 36 ++++++++++++++++++++++++++++++++++-- language/txs.md | 4 ++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/language/policies.md b/language/policies.md index 2680cd8..881861f 100644 --- a/language/policies.md +++ b/language/policies.md @@ -36,10 +36,12 @@ All three fields are optional, but at least one must be present: | -------- | --------------------------------------------------------- | | `hash` | The policy's script hash. | | `script` | The serialized script bytes, to be attached inline. | -| `ref` | A reference identifying where the script can be read from. | +| `ref` | The UTxO where the script lives as a reference script. | The exact way `script` and `ref` are interpreted is chain-specific — see [Cardano features](./cardano) for the witness and reference-script blocks that consume them. +When a policy carries a `ref`, that UTxO is attached automatically — see [Pairing a policy with a witness](#pairing-a-policy-with-a-witness) below. + ## Using a policy A policy identifier is address-like, just like a party. It can appear anywhere a party can: @@ -86,4 +88,34 @@ tx lock( ## Pairing a policy with a witness -When the policy is a script that must be witnessed by the transaction (for example a Plutus minting policy or a script spend), the policy declaration alone is not enough — you also need to attach the script (or a reference to it) to the transaction. That is done with one of the `cardano::*_witness` blocks; see [Cardano features](./cardano). +When the policy is a script that must run in the transaction (for example a Plutus minting policy or a script spend), the chain needs the script itself, not just its hash. There are two ways to supply it, and which one you use depends on how the policy was declared. + +### Reference scripts (the `ref` field) — automatic + +If the policy declares a `ref`, the script already lives on-chain at that UTxO. Whenever you use such a policy in a position that requires its script — as the `from` of an input, or as the policy of a `mint` / `burn` — Tx3 automatically adds that `ref` UTxO to the transaction's reference inputs. You do **not** need a separate `reference` block for it; the same `ref` used by several inputs or blocks is attached only once. + +```tx3 +policy Vault { + hash: 0x6b9c456aa650cb808a9ab54326e039d5235ed69f069c9664a8fe5b69, + ref: 0xANCHORTXHASH#0, +} + +tx withdraw(quantity: Int) { + input locked { + from: Vault, // Vault's `ref` UTxO is added as a reference input + min_amount: Ada(quantity), + redeemer: (), + } + + output { + to: Vault, + amount: locked - Ada(quantity) - fees, + } +} +``` + +A policy declared by hash only contributes no reference input — there is nothing to point at. + +### Inline scripts — explicit + +If the script is not published on-chain, it must be carried inline. The policy declaration alone is not enough; attach the bytes with one of the `cardano::*_witness` blocks. See [Cardano features](./cardano). diff --git a/language/txs.md b/language/txs.md index 1bd9c1e..5c6beab 100644 --- a/language/txs.md +++ b/language/txs.md @@ -75,7 +75,7 @@ input { Every field is optional individually, but the block must give the resolver *something* to find a UTxO with: at least one of `from` or `ref` must be present. -- `from` is a [party](./parties) or [policy](./policies), or any address-like expression. It constrains *who* controls the UTxO. +- `from` is a [party](./parties) or [policy](./policies), or any address-like expression. It constrains *who* controls the UTxO. If `from` is a policy that carries a `ref`, that reference-script UTxO is added to the transaction's reference inputs automatically. - `ref` pins the input to one specific UTxO. - `datum_is` declares the expected datum type so that property access on the input name (`source.field`) is typed. - `min_amount` is a lower bound — the resolver may find a UTxO with more value than required. @@ -203,7 +203,7 @@ burn { } ``` -`amount` is required; `redeemer` is optional and only meaningful when the minting policy is a script. Both blocks may appear multiple times in the same transaction. +`amount` is required; `redeemer` is optional and only meaningful when the minting policy is a script. Both blocks may appear multiple times in the same transaction. If the minted or burned asset's policy carries a `ref`, that reference-script UTxO is added to the transaction's reference inputs automatically. ```tx3 mint { From aab20a6d4e884f78b205e1a14cefb1c40706e0a4 Mon Sep 17 00:00:00 2001 From: Santiago Date: Sun, 7 Jun 2026 11:25:54 -0300 Subject: [PATCH 2/2] docs(language): note that reference blocks also attach reference scripts Clarify that the `reference` block is the explicit way to attach a reference script (when not using a ref-backed policy), not only a way to read oracle datums, and that reference inputs are deduplicated. Co-Authored-By: Claude Opus 4.8 (1M context) --- language/txs.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/language/txs.md b/language/txs.md index 5c6beab..597a82d 100644 --- a/language/txs.md +++ b/language/txs.md @@ -164,6 +164,8 @@ reference { `ref` is required. If `datum_is` is present, the reference's datum can be read via property access on the name. +A `reference` block is also how you attach a **reference script** explicitly — point `ref` at the UTxO that carries the script when you are not using a [ref-backed policy](./policies) (for example, spending from a plain address whose validator's script lives at a known UTxO). When a ref-backed policy *is* used, its reference input is added for you and a separate block is unnecessary. Reference inputs are deduplicated, so an explicit block that names the same UTxO as a policy ref is harmless. + ```tx3 party Receiver;