PlutusData
On-chain data structures for Cardano smart contracts
PlutusData
PlutusData is the serialization format for all on-chain data in Cardano smart contracts. Every datum attached to a UTxO, every redeemer that unlocks a script, and every parameter passed to a validator must be encoded as PlutusData.
The Evolution SDK's Data module gives you type-safe PlutusData creation without touching raw CBOR bytes.
The Five Types
PlutusData consists of five primitive types:
| Type | TypeScript | Use For |
|---|---|---|
| Integer | bigint | Amounts, indices, timestamps, quantities |
| ByteArray | Uint8Array | Hashes, addresses, policy IDs, asset names |
| Constructor | { index: bigint, fields: Data[] } | Variants, tagged unions, structured data |
| Map | Map<Data, Data> | Metadata, key-value stores |
| List | ReadonlyArray<Data> | Arrays of values |
Quick Start
Create PlutusData using TypeScript primitives:
import { } from "@evolution-sdk/evolution"
// Integer (bigint)
const : .. = 5000000n
// ByteArray (Uint8Array)
const = ..("HOSKY")
const = ..("a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8")
// Constructor (variant with fields)
const = ..(0n, []) // variant 0, no fields
// Map (key-value pairs)
const = ..([
[..("name"), ..("My NFT")],
[..("image"), ..("ipfs://Qm...")]
])
// List (array)
const : .. = [100n, 200n, 300n]Integers
Use bigint directly—no wrapper needed:
import { } from "@evolution-sdk/evolution"
// Lovelace amounts
const : .. = 170000n
const : .. = 2000000n
// Token quantities
const : .. = 1n
const : .. = 1000000n
// Negative values supported
const : .. = -500n
// Large numbers
const : .. = 45000000000000000nByte Arrays
Raw bytes for hashes, addresses, and binary data:
import { } from "@evolution-sdk/evolution"
// Transaction hash (32 bytes)
const = ..(
"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
)
// Policy ID (28 bytes)
const = ..(
"1234567890abcdef1234567890abcdef1234567890abcdef12345678"
)
// Asset name (readable string)
const = ..("MyToken")
// Empty byte array (ada-only policyId)
const = new ()When to use Bytes.fromHex vs Text.toBytes:
Bytes.fromHex: For hashes, policy IDs, credential hashes (hexadecimal data)Text.toBytes: For asset names, metadata values (human-readable strings)
Constructors
Tagged unions representing variants or structured data:
import { } from "@evolution-sdk/evolution"
// Simple variant (no data)
const = ..(0n, [])
const = ..(1n, [])
// Variant with single field
const = ..(0n, [
..("abc123def456abc123def456abc123def456abc123def456abc123de")
])
const = ..(1n, [
..("def456abc123def456abc123def456abc123def456abc123def456ab")
])
// Multiple fields
const = ..(0n, [
..("a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"), // tx hash
2n // output index
])Constructor index determines which variant you're creating. Your Plutus validator defines what each index means.
Maps
Key-value pairs where both keys and values are PlutusData:
import { } from "@evolution-sdk/evolution"
// NFT metadata
const = ..([
[..("name"), ..("CryptoKitty #1234")],
[..("image"), ..("ipfs://QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco")],
[..("description"), ..("A rare cryptokitty with rainbow fur")]
])
// Nested maps
const = ..([
[..("name"), ..("MyToken")],
[..("ticker"), ..("MTK")],
[..("decimals"), 6n],
[..("properties"), ..([
[..("mintable"), 1n], // boolean as 0/1
[..("burnable"), 1n]
])]
])Lists
Ordered arrays of PlutusData:
import { } from "@evolution-sdk/evolution"
// List of integers
const : .. = [100n, 250n, 500n, 1000n]
// List of byte arrays (hashes)
const : .. = [
..("abc123def456abc123def456abc123def456abc123def456abc123de"),
..("def456abc123def456abc123def456abc123def456abc123def456ab"),
..("123456789abc123456789abc123456789abc123456789abc12345678")
]
// List of constructors
const : .. = [
..(0n, []), // Claim
..(1n, []), // Cancel
..(2n, [5000000n]) // PartialClaim(amount)
]CBOR Encoding
Convert PlutusData to CBOR for blockchain submission:
import { } from "@evolution-sdk/evolution"
const = ..(0n, [
..([
[..("beneficiary"), ..("addr1...")],
[..("deadline"), 1735689600000n]
]),
5000000n, // amount
1n // version
])
// Encode to hex string
const = ..()
// "d8799fa2646265..."
// Encode to bytes
const = ..()
// Uint8Array [216, 121, 159, ...]
// Decode from CBOR
const = ..()
// Returns original PlutusData structureEquality Comparison
Check if two PlutusData structures are equal:
import { } from "@evolution-sdk/evolution"
const = ..([
[..("name"), ..("Alice")],
[..("age"), 30n]
])
const = ..([
[..("name"), ..("Alice")],
[..("age"), 30n]
])
// Deep equality check
const = ..(, )
// trueReal-World Examples
Escrow Datum
import { } from "@evolution-sdk/evolution"
// Escrow locked until deadline
const = ..(0n, [
..("abc123def456abc123def456abc123def456abc123def456abc123de"), // beneficiary
1735689600000n, // deadline (Unix timestamp)
10000000n // locked lovelace amount
])
const = ..()
// Attach to UTxO as inline datumCIP-68 NFT Metadata
import { } from "@evolution-sdk/evolution"
// Reference NFT metadata (label 100)
const = ..([
[..("name"), ..("SpaceAce #4242")],
[..("image"), ..("ipfs://QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco")],
[..("rarity"), ..("legendary")],
[..("attributes"), ..([
[..("class"), ..("explorer")],
[..("power"), 9000n]
])]
])
const = ..(0n, [
,
1n, // version
[] // extra fields
])Redeemer with Multiple Actions
import { } from "@evolution-sdk/evolution"
// Action variants
const = ..(0n, [])
const = ..(1n, [])
const = ..(2n, [
1735776000000n // new deadline
])
// Use in transaction
const = Multi-Sig Validator Redeemer
import { } from "@evolution-sdk/evolution"
const = ..(0n, [
// Required signers (list of key hashes)
[
..("abc123def456abc123def456abc123def456abc123def456abc123de"),
..("def456abc123def456abc123def456abc123def456abc123def456ab")
] as ..,
2n // threshold (2 of N)
])When to Use PlutusData Directly
Use the Data module directly when:
- Quick prototyping or testing
- Working with dynamic data structures
- Debugging CBOR encoding issues
- Building tooling or explorers
For production smart contract integration, use TSchema for type-safe schema definitions with automatic validation.