Skip to content

Commit 749d0db

Browse files
committed
docs: add docs
1 parent 562e648 commit 749d0db

File tree

241 files changed

+4622
-3232
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

241 files changed

+4622
-3232
lines changed
Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
---
2+
title: PlutusData
3+
description: On-chain data structures for Cardano smart contracts
4+
---
5+
6+
import { Card, Cards } from 'fumadocs-ui/components/card'
7+
8+
# PlutusData
9+
10+
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.
11+
12+
The Evolution SDK's Data module gives you type-safe PlutusData creation without touching raw CBOR bytes.
13+
14+
## The Five Types
15+
16+
PlutusData consists of five primitive types:
17+
18+
| Type | TypeScript | Use For |
19+
|------|-----------|---------|
20+
| **Integer** | `bigint` | Amounts, indices, timestamps, quantities |
21+
| **ByteArray** | `Uint8Array` | Hashes, addresses, policy IDs, asset names |
22+
| **Constructor** | `{ index: bigint, fields: Data[] }` | Variants, tagged unions, structured data |
23+
| **Map** | `Map<Data, Data>` | Metadata, key-value stores |
24+
| **List** | `ReadonlyArray<Data>` | Arrays of values |
25+
26+
## Quick Start
27+
28+
Create PlutusData using TypeScript primitives:
29+
30+
```typescript twoslash
31+
import { Core } from "@evolution-sdk/evolution"
32+
33+
// Integer (bigint)
34+
const lovelaceAmount: Core.Data.Data = 5000000n
35+
36+
// ByteArray (Uint8Array)
37+
const tokenName = Core.Text.toBytes("HOSKY")
38+
const policyId = Core.Bytes.fromHex("a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8")
39+
40+
// Constructor (variant with fields)
41+
const unlockAction = Core.Data.constr(0n, []) // variant 0, no fields
42+
43+
// Map (key-value pairs)
44+
const metadata = Core.Data.map([
45+
[Core.Text.toBytes("name"), Core.Text.toBytes("My NFT")],
46+
[Core.Text.toBytes("image"), Core.Text.toBytes("ipfs://Qm...")]
47+
])
48+
49+
// List (array)
50+
const quantities: Core.Data.Data = [100n, 200n, 300n]
51+
```
52+
53+
## Integers
54+
55+
Use `bigint` directly—no wrapper needed:
56+
57+
```typescript twoslash
58+
import { Core } from "@evolution-sdk/evolution"
59+
60+
// Lovelace amounts
61+
const fee: Core.Data.Data = 170000n
62+
const deposit: Core.Data.Data = 2000000n
63+
64+
// Token quantities
65+
const nftQuantity: Core.Data.Data = 1n
66+
const ftQuantity: Core.Data.Data = 1000000n
67+
68+
// Negative values supported
69+
const delta: Core.Data.Data = -500n
70+
71+
// Large numbers
72+
const totalSupply: Core.Data.Data = 45000000000000000n
73+
```
74+
75+
## Byte Arrays
76+
77+
Raw bytes for hashes, addresses, and binary data:
78+
79+
```typescript twoslash
80+
import { Core } from "@evolution-sdk/evolution"
81+
82+
// Transaction hash (32 bytes)
83+
const txHash = Core.Bytes.fromHex(
84+
"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
85+
)
86+
87+
// Policy ID (28 bytes)
88+
const policyId = Core.Bytes.fromHex(
89+
"1234567890abcdef1234567890abcdef1234567890abcdef12345678"
90+
)
91+
92+
// Asset name (readable string)
93+
const assetName = Core.Text.toBytes("MyToken")
94+
95+
// Empty byte array (ada-only policyId)
96+
const adaPolicyId = new Uint8Array()
97+
```
98+
99+
**When to use `Bytes.fromHex` vs `Text.toBytes`:**
100+
101+
- **`Bytes.fromHex`**: For hashes, policy IDs, credential hashes (hexadecimal data)
102+
- **`Text.toBytes`**: For asset names, metadata values (human-readable strings)
103+
104+
## Constructors
105+
106+
Tagged unions representing variants or structured data:
107+
108+
```typescript twoslash
109+
import { Core } from "@evolution-sdk/evolution"
110+
111+
// Simple variant (no data)
112+
const claimAction = Core.Data.constr(0n, [])
113+
const cancelAction = Core.Data.constr(1n, [])
114+
115+
// Variant with single field
116+
const verificationKeyCred = Core.Data.constr(0n, [
117+
Core.Bytes.fromHex("abc123def456abc123def456abc123def456abc123def456abc123de")
118+
])
119+
120+
const scriptCred = Core.Data.constr(1n, [
121+
Core.Bytes.fromHex("def456abc123def456abc123def456abc123def456abc123def456ab")
122+
])
123+
124+
// Multiple fields
125+
const outputRef = Core.Data.constr(0n, [
126+
Core.Bytes.fromHex("a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"), // tx hash
127+
2n // output index
128+
])
129+
```
130+
131+
**Constructor index** determines which variant you're creating. Your Plutus validator defines what each index means.
132+
133+
## Maps
134+
135+
Key-value pairs where both keys and values are PlutusData:
136+
137+
```typescript twoslash
138+
import { Core } from "@evolution-sdk/evolution"
139+
140+
// NFT metadata
141+
const nftMetadata = Core.Data.map([
142+
[Core.Text.toBytes("name"), Core.Text.toBytes("CryptoKitty #1234")],
143+
[Core.Text.toBytes("image"), Core.Text.toBytes("ipfs://QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco")],
144+
[Core.Text.toBytes("description"), Core.Text.toBytes("A rare cryptokitty with rainbow fur")]
145+
])
146+
147+
// Nested maps
148+
const tokenMetadata = Core.Data.map([
149+
[Core.Text.toBytes("name"), Core.Text.toBytes("MyToken")],
150+
[Core.Text.toBytes("ticker"), Core.Text.toBytes("MTK")],
151+
[Core.Text.toBytes("decimals"), 6n],
152+
[Core.Text.toBytes("properties"), Core.Data.map([
153+
[Core.Text.toBytes("mintable"), 1n], // boolean as 0/1
154+
[Core.Text.toBytes("burnable"), 1n]
155+
])]
156+
])
157+
```
158+
159+
## Lists
160+
161+
Ordered arrays of PlutusData:
162+
163+
```typescript twoslash
164+
import { Core } from "@evolution-sdk/evolution"
165+
166+
// List of integers
167+
const prices: Core.Data.Data = [100n, 250n, 500n, 1000n]
168+
169+
// List of byte arrays (hashes)
170+
const approvedSigners: Core.Data.Data = [
171+
Core.Bytes.fromHex("abc123def456abc123def456abc123def456abc123def456abc123de"),
172+
Core.Bytes.fromHex("def456abc123def456abc123def456abc123def456abc123def456ab"),
173+
Core.Bytes.fromHex("123456789abc123456789abc123456789abc123456789abc12345678")
174+
]
175+
176+
// List of constructors
177+
const actions: Core.Data.Data = [
178+
Core.Data.constr(0n, []), // Claim
179+
Core.Data.constr(1n, []), // Cancel
180+
Core.Data.constr(2n, [5000000n]) // PartialClaim(amount)
181+
]
182+
```
183+
184+
## CBOR Encoding
185+
186+
Convert PlutusData to CBOR for blockchain submission:
187+
188+
```typescript twoslash
189+
import { Core } from "@evolution-sdk/evolution"
190+
191+
const datum = Core.Data.constr(0n, [
192+
Core.Data.map([
193+
[Core.Text.toBytes("beneficiary"), Core.Text.toBytes("addr1...")],
194+
[Core.Text.toBytes("deadline"), 1735689600000n]
195+
]),
196+
5000000n, // amount
197+
1n // version
198+
])
199+
200+
// Encode to hex string
201+
const cborHex = Core.Data.toCBORHex(datum)
202+
// "d8799fa2646265..."
203+
204+
// Encode to bytes
205+
const cborBytes = Core.Data.toCBORBytes(datum)
206+
// Uint8Array [216, 121, 159, ...]
207+
208+
// Decode from CBOR
209+
const decoded = Core.Data.fromCBORHex(cborHex)
210+
// Returns original PlutusData structure
211+
```
212+
213+
## Equality Comparison
214+
215+
Check if two PlutusData structures are equal:
216+
217+
```typescript twoslash
218+
import { Core } from "@evolution-sdk/evolution"
219+
220+
const map1 = Core.Data.map([
221+
[Core.Text.toBytes("name"), Core.Text.toBytes("Alice")],
222+
[Core.Text.toBytes("age"), 30n]
223+
])
224+
225+
const map2 = Core.Data.map([
226+
[Core.Text.toBytes("name"), Core.Text.toBytes("Alice")],
227+
[Core.Text.toBytes("age"), 30n]
228+
])
229+
230+
// Deep equality check
231+
const isEqual = Core.Data.equals(map1, map2)
232+
// true
233+
```
234+
235+
## Real-World Examples
236+
237+
### Escrow Datum
238+
239+
```typescript twoslash
240+
import { Core } from "@evolution-sdk/evolution"
241+
242+
// Escrow locked until deadline
243+
const escrowDatum = Core.Data.constr(0n, [
244+
Core.Bytes.fromHex("abc123def456abc123def456abc123def456abc123def456abc123de"), // beneficiary
245+
1735689600000n, // deadline (Unix timestamp)
246+
10000000n // locked lovelace amount
247+
])
248+
249+
const cborHex = Core.Data.toCBORHex(escrowDatum)
250+
// Attach to UTxO as inline datum
251+
```
252+
253+
### CIP-68 NFT Metadata
254+
255+
```typescript twoslash
256+
import { Core } from "@evolution-sdk/evolution"
257+
258+
// Reference NFT metadata (label 100)
259+
const metadata = Core.Data.map([
260+
[Core.Text.toBytes("name"), Core.Text.toBytes("SpaceAce #4242")],
261+
[Core.Text.toBytes("image"), Core.Text.toBytes("ipfs://QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco")],
262+
[Core.Text.toBytes("rarity"), Core.Text.toBytes("legendary")],
263+
[Core.Text.toBytes("attributes"), Core.Data.map([
264+
[Core.Text.toBytes("class"), Core.Text.toBytes("explorer")],
265+
[Core.Text.toBytes("power"), 9000n]
266+
])]
267+
])
268+
269+
const cip68Datum = Core.Data.constr(0n, [
270+
metadata,
271+
1n, // version
272+
[] // extra fields
273+
])
274+
```
275+
276+
### Redeemer with Multiple Actions
277+
278+
```typescript twoslash
279+
import { Core } from "@evolution-sdk/evolution"
280+
281+
// Action variants
282+
const claim = Core.Data.constr(0n, [])
283+
const cancel = Core.Data.constr(1n, [])
284+
const update = Core.Data.constr(2n, [
285+
1735776000000n // new deadline
286+
])
287+
288+
// Use in transaction
289+
const redeemer = claim
290+
```
291+
292+
### Multi-Sig Validator Redeemer
293+
294+
```typescript twoslash
295+
import { Core } from "@evolution-sdk/evolution"
296+
297+
const multiSigRedeemer = Core.Data.constr(0n, [
298+
// Required signers (list of key hashes)
299+
[
300+
Core.Bytes.fromHex("abc123def456abc123def456abc123def456abc123def456abc123de"),
301+
Core.Bytes.fromHex("def456abc123def456abc123def456abc123def456abc123def456ab")
302+
] as Core.Data.Data,
303+
2n // threshold (2 of N)
304+
])
305+
```
306+
307+
## When to Use PlutusData Directly
308+
309+
Use the Data module directly when:
310+
311+
- Quick prototyping or testing
312+
- Working with dynamic data structures
313+
- Debugging CBOR encoding issues
314+
- Building tooling or explorers
315+
316+
For production smart contract integration, use [TSchema](/docs/encoding/tschema) for type-safe schema definitions with automatic validation.
317+
318+
## Next Steps
319+
320+
<Cards>
321+
<Card title="TSchema" href="/docs/encoding/tschema">
322+
Type-safe schema definitions with automatic validation
323+
</Card>
324+
<Card title="Plutus Types" href="/docs/encoding/plutus">
325+
Pre-built types for addresses, credentials, values, and CIP-68
326+
</Card>
327+
<Card title="CBOR" href="/docs/encoding/cbor">
328+
Low-level CBOR encoding and decoding
329+
</Card>
330+
</Cards>

docs/content/docs/encoding/meta.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
"cbor",
66
"bech32",
77
"hex",
8-
"json"
8+
"json",
9+
"data",
10+
"tschema",
11+
"plutus"
912
]
1013
}

0 commit comments

Comments
 (0)