CBOR (Concise Binary Object Representation) is a binary data format that enables compact and efficient data serialization. Think of it as JSON's more efficient cousin, designed specifically for scenarios where data size and processing speed are crucial. In the Cardano blockchain, CBOR plays a fundamental role in how data is encoded and stored.
Plutus scripts in Cardano go through multiple stages of transformation:
-
Source Code → UPLC
- Plutus scripts start as Haskell code
- Compiled to Plutus Core (UPLC - Untyped Plutus Core)
- UPLC is a lambda calculus-based language
-
UPLC → CBOR
- UPLC is serialized into CBOR format
- This is what actually goes on-chain
- Example of a simple Plutus script in different forms:
-- Original Plutus Script (Haskell)
validateToken :: Data -> Data -> Data -> ()
validateToken _ _ _ = ()
-- After compilation to UPLC (simplified representation)
(program 1.0.0 [[[(lam unit) unit] unit]])
-- Final form: CBOR hex string
4e4d01000033222220051200120011"-
Development
-- Write in Haskell myValidator :: ValidatorScript myValidator = plutusV2Script $ compile $ $$(PlutusTx.compile [|| validationLogic ||])
-
Compilation
- Haskell → Plutus IR
- Plutus IR → UPLC
- UPLC → CBOR
-
On-chain Storage
- Stored as CBOR bytes
- Referenced by script hash
// Datum structure in JavaScript
const datum = {
constructor: 0,
fields: [
{ bytes: "deadbeef" },
{ int: 42 }
]
};
// Converts to CBOR hex
// d8799f4100d8799fd8799f42deadbeef1a0000002affffffff// Redeemer in JavaScript
const redeemer = {
constructor: 0,
fields: [
{ int: 1 } // Action type
]
};
// CBOR representation
// d8799f4100d8799f01ffff// Script reference structure
const scriptRef = {
type: "PlutusV2",
script: "4e4d01000033222220051200120011..." // CBOR hex
};
// On-chain reference (hash)
const scriptHash = "a123..." // Script hash derived from CBOR-- Haskell/Plutus
type SpendingValidator = Data -> Data -> ScriptContext -> Bool
-- Compiled and serialized to CBOR
-- Complex CBOR structure representing the validator logic-- Haskell/Plutus
type MintingPolicy = Data -> ScriptContext -> Bool
-- CBOR representation
-- Simpler CBOR structure due to fewer parameters-
Script Size Optimization
- Keep scripts minimal
- Use reference scripts for reuse
- Monitor CBOR output size
-
Testing Serialization
- Test CBOR roundtrips
- Validate script hashes
- Check size constraints
-
Development Tools
// Example tool usage import { C } from "lucid-cardano"; // Serialize Plutus script const scriptCBOR = C.PlutusScriptV2.new( C.encode_plutus_data_to_bytes(scriptData) ).to_bytes(); // Calculate script hash const scriptHash = C.hash_plutus_data(scriptCBOR);
-
Write Script
- Develop in Haskell
- Use Plutus framework
- Test logic thoroughly
-
Compile and Serialize
- Compile to UPLC
- Serialize to CBOR
- Verify correctness
-
Deploy and Reference
- Submit to chain
- Store script hash
- Use in transactions
-
Cardano CLI
# View CBOR content cardano-cli script-hash --script-file script.plutus -
Development Libraries
cardano-serialization-liblucid-cardanoplutus-apps
-
Testing Tools
- Plutus Playground
- Local testnet
- CBOR debuggers
-
Size Limitations
- Break down complex scripts
- Use reference scripts
- Optimize UPLC output
-
Versioning
- Track script versions
- Use clear naming
- Document CBOR changes
-
Testing
- Unit test scripts
- Test serialization
- Validate on testnet
Understanding how Plutus scripts are serialized to CBOR is crucial for Cardano development. The transformation from high-level Haskell code to on-chain CBOR bytes involves multiple steps and considerations. Proper handling of this process ensures efficient and reliable smart contract deployment and execution on the Cardano blockchain.
Note: Always refer to official Cardano documentation for the most up-to-date information about Plutus script development and CBOR serialization.