Skip to content

Instantly share code, notes, and snippets.

@yanisurbis
Created November 12, 2024 07:54
Show Gist options
  • Select an option

  • Save yanisurbis/c4e87481405c2ed8d3a37f464f6aa035 to your computer and use it in GitHub Desktop.

Select an option

Save yanisurbis/c4e87481405c2ed8d3a37f464f6aa035 to your computer and use it in GitHub Desktop.

Understanding CBOR and Plutus in Cardano: A Deep Dive

What is CBOR?

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 and CBOR

How Plutus Scripts are Serialized

Plutus scripts in Cardano go through multiple stages of transformation:

  1. Source Code → UPLC

    • Plutus scripts start as Haskell code
    • Compiled to Plutus Core (UPLC - Untyped Plutus Core)
    • UPLC is a lambda calculus-based language
  2. 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"

Plutus Script Lifecycle

  1. Development

    -- Write in Haskell
    myValidator :: ValidatorScript
    myValidator = plutusV2Script $ compile $ $$(PlutusTx.compile [|| validationLogic ||])
  2. Compilation

    • Haskell → Plutus IR
    • Plutus IR → UPLC
    • UPLC → CBOR
  3. On-chain Storage

    • Stored as CBOR bytes
    • Referenced by script hash

CBOR in Plutus Transactions

Script Data

// Datum structure in JavaScript
const datum = {
  constructor: 0,
  fields: [
    { bytes: "deadbeef" },
    { int: 42 }
  ]
};

// Converts to CBOR hex
// d8799f4100d8799fd8799f42deadbeef1a0000002affffffff

Redeemer Format

// Redeemer in JavaScript
const redeemer = {
  constructor: 0,
  fields: [
    { int: 1 }  // Action type
  ]
};

// CBOR representation
// d8799f4100d8799f01ffff

Working with Script References

Script Reference Format

// Script reference structure
const scriptRef = {
  type: "PlutusV2",
  script: "4e4d01000033222220051200120011..." // CBOR hex
};

// On-chain reference (hash)
const scriptHash = "a123..."  // Script hash derived from CBOR

Plutus Script Types and CBOR

Spending Validator

-- Haskell/Plutus
type SpendingValidator = Data -> Data -> ScriptContext -> Bool

-- Compiled and serialized to CBOR
-- Complex CBOR structure representing the validator logic

Minting Policy

-- Haskell/Plutus
type MintingPolicy = Data -> ScriptContext -> Bool

-- CBOR representation
-- Simpler CBOR structure due to fewer parameters

Best Practices for Plutus and CBOR

  1. Script Size Optimization

    • Keep scripts minimal
    • Use reference scripts for reuse
    • Monitor CBOR output size
  2. Testing Serialization

    • Test CBOR roundtrips
    • Validate script hashes
    • Check size constraints
  3. 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);

Development Workflow

  1. Write Script

    • Develop in Haskell
    • Use Plutus framework
    • Test logic thoroughly
  2. Compile and Serialize

    • Compile to UPLC
    • Serialize to CBOR
    • Verify correctness
  3. Deploy and Reference

    • Submit to chain
    • Store script hash
    • Use in transactions

Tools and Libraries

  1. Cardano CLI

    # View CBOR content
    cardano-cli script-hash --script-file script.plutus
  2. Development Libraries

    • cardano-serialization-lib
    • lucid-cardano
    • plutus-apps
  3. Testing Tools

    • Plutus Playground
    • Local testnet
    • CBOR debuggers

Common Challenges and Solutions

  1. Size Limitations

    • Break down complex scripts
    • Use reference scripts
    • Optimize UPLC output
  2. Versioning

    • Track script versions
    • Use clear naming
    • Document CBOR changes
  3. Testing

    • Unit test scripts
    • Test serialization
    • Validate on testnet

Conclusion

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment