Datums
Attach data to script-locked UTxOs
Datums
Datums are the data payloads attached to UTxOs at script addresses. When you lock funds to a smart contract, the datum carries the state your validator needs — beneficiary addresses, deadlines, token quantities, or any structured data your contract logic requires.
Datum Options
Evolution SDK supports two ways to attach datums to outputs:
| Type | Description | When to Use |
|---|---|---|
| Inline Datum | Data stored directly in the UTxO | Recommended for most use cases (Plutus V2+) |
| Datum Hash | Only a hash stored on-chain; full datum provided when spending | Legacy Plutus V1 contracts |
Inline Datums
Inline datums embed the full data in the output. The spending transaction can read it directly without needing to provide the datum separately:
import { , , , , } from "@evolution-sdk/evolution"
const = ({
: "preprod",
: { : "blockfrost", : "https://cardano-preprod.blockfrost.io/api/v0", : ..! },
: { : "seed", : ..!, : 0 }
})
// Simple inline datum
const = await
.()
.({
: .("addr_test1wrm9x2dgvdau8vckj4duc89m638t8djmluqw5pdrFollw8qnmqsyu"),
: .(10_000_000n),
: new .({ : .(0n, [5000000n, 1735689600000n]) })
})
.()Datum Hashes
Datum hashes store only a 32-byte hash in the output. The full datum must be provided when spending:
import { Address, Assets, Data, createClient } from "@evolution-sdk/evolution"
const client = createClient({
network: "preprod",
provider: { type: "blockfrost", baseUrl: "https://cardano-preprod.blockfrost.io/api/v0", projectId: process.env.BLOCKFROST_API_KEY! },
wallet: { type: "seed", mnemonic: process.env.WALLET_MNEMONIC!, accountIndex: 0 }
})
// Compute datum hash from PlutusData
const datum = Data.constr(0n, [5000000n])
const datumHash = Data.hashData(datum)
const tx = await client
.newTx()
.payToAddress({
address: Address.fromBech32("addr_test1wrm9x2dgvdau8vckj4duc89m638t8djmluqw5pdrFollw8qnmqsyu"),
assets: Assets.fromLovelace(10_000_000n),
datum: datumHash // DatumHash returned by hashData
})
.build()Type-Safe Datums with TSchema
For production contracts, define your datum structure with TSchema to get compile-time type checking and automatic CBOR encoding:
import { , , } from "@evolution-sdk/evolution"
// Define datum schema matching your validator
const = .({
: .,
: .,
: .
})
type = typeof .
const = .()
// Create type-safe datum
const : = {
: .("abc123def456abc123def456abc123def456abc123def456abc123de"),
: 1735689600000n,
: 10_000_000n
}
// Encode to PlutusData for use in transactions
const = .()Constructing Complex Datums
Variant Datums
For datums with multiple possible shapes:
import { , , } from "@evolution-sdk/evolution"
const = .({
: {
: .,
: .
},
: {
: .,
: .,
: .
},
: {}
})
type = typeof .
const : = {
: { : 1500000n, : 100n }
}
const : = {
: { : 2000000n, : 50n, : 10n }
}Using Raw PlutusData
For quick prototyping without schemas:
import { , , } from "@evolution-sdk/evolution"
// Constructor with fields
const = .(0n, [
.("abc123def456abc123def456abc123def456abc123def456abc123de"),
1735689600000n,
.([
[.("name"), .("My NFT")],
[.("image"), .("ipfs://Qm...")]
])
])Reading Datums from UTxOs
When querying UTxOs, inline datums are available directly on the UTxO object:
import { , , , , } from "@evolution-sdk/evolution"
const = ({
: "preprod",
: { : "blockfrost", : "https://cardano-preprod.blockfrost.io/api/v0", : ..! },
: { : "seed", : ..!, : 0 }
})
// Query UTxOs at a script address
const = .("addr_test1wrm9x2dgvdau8vckj4duc89m638t8djmluqw5pdrFollw8qnmqsyu")
const = await .()
for (const of ) {
if (.) {
// datumOption is InlineDatum or DatumHash
.("UTxO has datum attached")
}
}Best Practices
- Use inline datums for new contracts — they're simpler and don't require datum lookup when spending
- Use TSchema for production — compile-time type checking prevents encoding mistakes
- Match your validator exactly — field names and order in TSchema must match your Plutus type definitions
- Test round-trips — verify that encoding and decoding your datum produces identical results
Next Steps
- Locking to Script — Send funds to a script address with datums
- Spending from Script — Unlock script UTxOs with redeemers
- TSchema — Type-safe schema definitions
- PlutusData — Raw PlutusData construction