Reference Scripts
Reduce transaction size by referencing on-chain scripts
Reference Scripts
Reference scripts (Plutus V2+) let you store a script on-chain in a UTxO and reference it from other transactions instead of including the full script each time. This reduces transaction size and fees significantly — a script that's 10KB only needs to be included once, then all future transactions reference it.
How It Works
- Deploy: Create a UTxO containing the script as a reference script
- Reference: Future transactions use
readFromto reference the UTxO containing the script - Save: No need to attach the script directly — smaller transactions, lower fees
Step 1: Deploy a Reference Script
Store your validator script on-chain by including it in a UTxO output:
import { , , } from "@evolution-sdk/evolution"
const = ({
: "preprod",
: { : "blockfrost", : "https://cardano-preprod.blockfrost.io/api/v0", : ..! },
: { : "seed", : ..!, : 0 }
})
declare const : any
// Store script in a UTxO (send to your own address or a permanent holder)
const = await .()
const = await
.()
.({
: ,
: .(10_000_000n),
: // Script stored as reference script
})
.()
const = await .()
const = await .()
.("Reference script deployed:", )Step 2: Use the Reference Script
Reference the deployed script UTxO when spending from the validator:
import { , , , type } from "@evolution-sdk/evolution"
const = ({
: "preprod",
: { : "blockfrost", : "https://cardano-preprod.blockfrost.io/api/v0", : ..! },
: { : "seed", : ..!, : 0 }
})
declare const : .[]
declare const : .
// Reference the UTxO containing the script instead of attaching it
const = await
.()
.({
: ,
: .(0n, [])
})
.({ : [] })
.()
const = await .()
await .()The key difference: readFrom makes the UTxO available as a reference input without consuming it. The script is read from the UTxO's reference script field, and the UTxO remains on-chain for future use.
Reference Scripts vs Attached Scripts
| Approach | Transaction Size | First Use | Subsequent Uses |
|---|---|---|---|
Attached (attachScript) | Includes full script | Same size | Same size every time |
Referenced (readFrom) | Only UTxO reference | Deploy tx is larger | Much smaller |
Use reference scripts when: Your script is used in multiple transactions. The deployment cost pays for itself after just a few uses.
Use attached scripts when: One-off transactions or very small scripts where the overhead of a reference UTxO isn't worth it.
Reading Other Data via Reference Inputs
Reference inputs aren't just for scripts — you can also read datums from UTxOs without consuming them:
import { , , type } from "@evolution-sdk/evolution"
const = ({
: "preprod",
: { : "blockfrost", : "https://cardano-preprod.blockfrost.io/api/v0", : ..! },
: { : "seed", : ..!, : 0 }
})
declare const : .[]
declare const : .
declare const : .
// Read oracle data + reference script in same transaction
const = await
.()
.({
: ,
: .(0n, [])
})
.({
: [, ]
})
.()This is commonly used for:
- Oracle feeds — Read price data without consuming the oracle UTxO
- Configuration UTxOs — Read protocol settings stored on-chain
- Shared state — Multiple transactions can read the same UTxO simultaneously
Next Steps
- Locking to Script — Deploy reference scripts when locking funds
- Spending from Script — Use reference scripts when spending
- Datums — Data attached to script UTxOs