Chialisp Guide Pt 13: CLVM Tooling & Debugging

13 min read

Terminal window displaying Chialisp CLVM tooling development including run compiler and brun interpreter with syntax-highlighted code

Key Takeaways

  • CLVM tooling includes both Python-based and Rust-based tools, with the Rust implementation offering better performance and closer tracking to consensus behavior
  • The core command-line tools (run, brun, opc, opd, and cdv) form the foundation of Chialisp development workflows
  • Symbol tables and verbose output help developers track down bugs by showing exact code locations where errors occur
  • Modern debugging tools like cldb provide stepwise execution to identify where programs fail
  • Proper validation and testing prevent critical security issues, as demonstrated by the CAT1 vulnerability discovery

Article Summary

CLVM tooling combines command-line utilities like run, brun, and cdv with modern debugging features such as symbol tables and stepwise execution. The Chia Network ecosystem has transitioned to Rust-based implementations for better performance while maintaining backward compatibility with Python tools, giving developers multiple pathways to compile, test, and debug their Chialisp smart coins.

Understanding CLVM Development Tools

Throughout the previous twelve lessons, we’ve built Chialisp programs covering coins, puzzles, conditions, CURRY functions, singletons, CATs, offers, vaults, multisig patterns, DIDs, and advanced features. Now we need to understand the tools that make all of this development possible.

The Chialisp Virtual Machine (CLVM) tooling ecosystem provides developers with everything needed to write, compile, test, and debug smart coins on the Chia blockchain. Think of these tools as your workshop – just as a carpenter needs both basic hand tools and power tools, Chialisp developers rely on a combination of simple command-line utilities and sophisticated debugging instruments.

The tooling landscape has evolved significantly since Chia’s launch. Originally built in Python, the core tools have been reimplemented in Rust for improved performance and better alignment with the Rust-based CLVM runtime that powers the Chia full node. This transition means developers now have choices in their workflow, with both Python and Rust implementations available.

Core Command-Line Tools

Let’s start with the fundamental tools you’ll use every day as a Chialisp developer. These command-line utilities handle the basic tasks of compiling code, running programs, and converting between different formats.

The run Compiler

The run tool takes your human-readable Chialisp code and transforms it into CLVM bytecode that the blockchain can execute. When you write code in files ending with .clsp or .clvm, the run compiler processes these files and outputs the compiled result. For example, running a simple program might look like this: run '(mod ARGUMENT (+ ARGUMENT 3))' and output the compiled form (+ 1 (q . 3)). This compilation step is essential because the CLVM only understands the lower-level compiled format, not the higher-level Chialisp syntax you write.

The brun Interpreter

While run compiles your code, brun actually executes it. The brun tool serves as the CLVM interpreter, allowing you to test your compiled programs by passing in arguments called solutions. This is where you can verify that your puzzle behaves correctly before deploying it to the blockchain. You can pipe compiled output directly to brun to see results immediately, making it perfect for rapid testing cycles.

Operation Code Utilities: opc and opd

The opc and opd tools handle conversions between different representations of CLVM code. The opc utility compiles S-expressions into hex bytecode format, which is how programs are ultimately stored and transmitted on the blockchain. Meanwhile, opd performs the reverse operation, deserializing hex bytecode back into readable S-expressions. These tools are particularly valuable when you need to inspect bytecode from the blockchain or prepare programs for on-chain deployment.

The cdv Development Utility

The cdv (Chia Dev) utility bundles together a comprehensive suite of development commands. Beyond just compilation, cdv offers specialized subcommands for testing coin lifecycles, calculating tree hashes, currying puzzles, managing RPC connections to full nodes, and running test suites. This makes cdv your central command center for most development tasks. The cdv clsp family of commands specifically focuses on Chialisp operations, providing shortcuts for common tasks like building puzzles, retrieving standard library code, and calculating puzzle hashes.

Python vs Rust Toolchains

Understanding the relationship between Python and Rust tooling helps you choose the right tools for your workflow and understand what’s happening under the hood.

Python-Based chia-dev-tools

The chia-dev-tools package provides the classic Python implementation of the CLVM toolchain. This package includes run, brun, and the comprehensive cdv utility. For most developers, especially those just starting out, the Python tools remain the recommended entry point. They’re easy to install via pip into a virtual environment, well-documented, and have extensive community support. The Python tools also integrate seamlessly with Python-based testing frameworks, making it natural to write lifecycle tests for your smart coins.

Rust-Based Implementation

The Rust implementation of CLVM tools, available in the chialisp repository (formerly known as clvm_tools_rs), provides performance advantages and closer alignment with the production CLVM runtime. The Rust compiler includes optimizations and improved diagnostics for Modern Chialisp features like let-bindings and strict variable checking. Since the Chia full node itself runs on clvm_rs (the Rust CLVM implementation), using the Rust tools means your development environment matches production behavior more closely.

The transition to Rust wasn’t arbitrary – it addressed real performance bottlenecks and made the codebase easier to verify and maintain. The Rust compiler features a simpler, more transparent structure that makes it easier for developers to understand how Chialisp compiles to CLVM. This architectural improvement reduces the risk of compiler bugs and makes future enhancements more practical.

Choosing Your Toolchain

For most developers, starting with the Python-based chia-dev-tools makes sense. Install it in a virtual environment, learn the basic workflow with run, brun, and cdv, and build your first programs using these stable, well-documented tools. As your projects grow more complex or performance-sensitive, you can explore the Rust implementation to access faster compilation and closer parity with the on-chain runtime. Some developers even use both – Python tools for quick testing and development, Rust tools for final optimization and production testing.

Debugging CLVM Programs

Debugging Chialisp can be challenging because errors often appear far from their actual source. A simple typo in a variable name might cause the variable to evaluate as a string, which gets hashed into something unexpected, making the original mistake nearly impossible to trace. Learning effective debugging techniques saves hours of frustration.

Common Error Patterns

The most frequent error message you’ll encounter is “path into atom,” which occurs when you try to use the first or rest operators on an atom instead of a cons pair. This usually means parameters are misaligned, you’re missing an argument, a parameter has the wrong type, or you forgot to check if something is a list before using list operators. Remember that an empty list is technically an atom, not a cons pair, so always use the list check operator before attempting list operations.

Another common issue involves the sha256 operator, which only works on atoms. If you need to hash complex structures, use the sha256tree function instead. Keep in mind that sha256tree has a higher computational cost and produces different results because it prepends type indicators (1 or 2) based on whether it’s processing an atom or a cons pair.

Symbol Tables for Better Error Messages

When you compile code with run or cdv clsp build, the compiler automatically creates a symbol table file with a .sym extension. This file tracks constant and function names throughout your code, allowing the tools to show you meaningful names in error messages instead of cryptic numbers and memory addresses. To use symbol tables during execution, pass the symbol table file with the –symbol-table or -y flag. While symbol tables can’t identify inline functions or macros (since these get replaced at compile time), they dramatically improve debugging by showing you exactly where in your source code errors occur.

Verbose Output Mode

The verbose output option shows you step-by-step execution of your program, revealing exactly how the CLVM processes each operation. In verbose mode, output begins with (a 2 3) representing the entire program running with its environment. As you follow each “didn’t finish” marker down through nested operations, you can trace execution to the deepest failure point and then work backward to understand what went wrong. This technique is especially valuable for understanding unexpected behavior in complex programs with nested function calls.

The cldb Debugger

The cldb tool provides stepwise debugging with program-readable YAML output. Unlike simply running a program and seeing if it succeeds or fails, cldb lets you step through execution operation by operation, examining the environment, arguments, and operators at each stage. This visibility into the execution process helps you understand not just that something failed, but exactly where and why it failed. The YAML output format makes it easy to parse results programmatically if you’re building automated testing systems.

Using the x Operator for Debugging

The x operator deliberately crashes your program with a specific value, which might sound counterintuitive but proves incredibly useful for debugging. By strategically placing x operators in your code with different values, you can determine which code paths execute and verify that data has the expected structure at different points. Think of it as setting breakpoints in your code – when execution hits an x operator, you know that particular code path ran and can examine the crash output to see what values were present.

Modern Development Environments

Beyond command-line tools, modern Chialisp development benefits from integrated development environments and language-specific tooling that improve the coding experience.

VS Code Extension

The Chialisp Language extension for Visual Studio Code (by Rigidity) brings syntax highlighting and code editing support to your development environment. This extension understands Chialisp syntax and can highlight errors as you type, helping you navigate complex codebases. Installing this extension transforms VS Code into a proper Chialisp IDE rather than just a text editor.

Clovyr Code Browser IDE

For developers who prefer not to install software locally or who want to experiment with Chialisp without setting up a full development environment, Clovyr Code (introduced in 2022) offers a browser-based IDE. This tool provides a complete VS Code-like interface running in your web browser, with a preconfigured Chialisp environment, real terminal access, and all the command-line tools pre-installed on a private server accessible only to you. You can start writing and testing Chialisp code within seconds, with no installation or registration required. Note: Developers should verify current service availability at clovyr.app.

Web-Based Tools: clvm-lib

The clvm-lib TypeScript library enables Chialisp development in browser-based or Node.js applications. This JavaScript/TypeScript implementation of CLVM tools allows you to compile and execute Chialisp code directly in web applications, making it possible to build browser-based wallets, development playgrounds, or educational tools that work with Chialisp programs. Frontend developers can integrate Chialisp functionality into their applications without requiring users to install command-line tools.

Testing Frameworks and Workflows

Writing code is only half the battle – thorough testing ensures your smart coins behave correctly under all conditions and protects against security vulnerabilities.

The cdv test Command

The cdv test command initializes and runs local test suites, providing a Python-based testing framework specifically designed for Chialisp smart coin lifecycle tests. This framework excels at testing the complete lifecycle of a coin: creation, spending, condition generation, and interaction with other coins. The cdv.test package includes utilities for simulating blockchain state, creating test coins, and verifying that spends produce the expected results.

Writing Effective Tests

Effective Chialisp tests verify both successful paths (coins that should spend correctly do spend correctly) and failure cases (invalid spends are properly rejected). Test edge cases like empty lists, maximum values, negative numbers, and unexpected input types. For programs that interact with multiple coins (like CATs or offers), test the complete ring of announcements and conditions. Remember that bugs in Chialisp often appear far from their source, so comprehensive testing across all code paths helps catch issues early.

REPL for Interactive Development

The Rust-based tools include a REPL (Read-Eval-Print Loop) that accepts Chialisp forms and expressions and produces results interactively. This interactive environment is perfect for experimenting with language features, testing small code snippets, or understanding how specific operators behave. You can define macros, test assertions, and immediately see results without creating full files or running complete compilation cycles.

Real-World Debugging: The CAT1 Vulnerability Case Study

The discovery and resolution of the CAT1 vulnerability demonstrates how critical proper debugging and validation are in blockchain development. This real-world case study from 2022 shows what happens when subtle bugs slip through initial testing and how comprehensive auditing processes catch critical issues.

The Vulnerability Discovered

In a notable 2022 security incident, auditor Trail of Bits raised concerns on June 14th about a potential class of vulnerabilities in the CAT1 (Chia Asset Token) standard. The Chia development team investigated these concerns and discovered a serious security flaw in how CAT1 coins calculated coin IDs. The problematic code used sha256 to hash together a parent coin ID, puzzle hash, and amount without validating the length of each component. Because sha256 simply concatenates its inputs before hashing, an attacker could shift bytes between the puzzle hash and amount fields while maintaining the same overall hash.

This meant someone could make a coin appear to have a much larger (or even negative) value by manipulating where the puzzle hash ended and the amount began. A holder of any CAT1 token could inflate their balance to arbitrary amounts, effectively creating a money printing machine for any CAT they possessed. The vulnerability affected every CAT1 token on the Chia blockchain regardless of the original issuance rules.

The Fix: Proper Validation

The CAT2 standard fixed this vulnerability by adding a validation function that checks each component before concatenation. The new calculate_coin_id function verifies that both the parent ID and puzzle hash are exactly 32 bytes and that the amount is non-negative before proceeding with the hash calculation. If any validation fails, the program exits with an error rather than computing an invalid coin ID. This simple validation step – checking the size of inputs before processing them – prevented the entire class of boundary-shifting attacks.

Lessons for Developers

The CAT1 vulnerability teaches several important lessons about Chialisp development. First, always validate input lengths and types before performing operations, especially when concatenating values for hashing. Second, security audits by external experts catch issues that internal teams might miss, even experienced blockchain developers. Third, comprehensive testing must include edge cases and attempts to manipulate boundaries between fields. The Chia team’s rapid response – building monitoring tools within 24 hours, creating the patched CAT2 standard, and coordinating a smooth ecosystem migration – demonstrates professional incident handling, but prevention through careful validation is always better than emergency fixes.

Advanced Tooling Techniques

As you become comfortable with basic tooling, these advanced techniques help you work more efficiently and debug more complex issues.

Converting and Inspecting Bytecode

When you encounter CLVM bytecode in hex format (perhaps from inspecting an on-chain puzzle or examining a spend bundle), use opd to convert it back to readable CLVM format. This reverse-engineering capability helps you understand how existing on-chain coins work and verify that your compiled code matches what you expect. You can also use opc to convert S-expressions to hex when you need to measure the serialized size of your program for cost analysis.

Working with Include Paths

The run compiler supports an –include or -i flag that specifies directories to search for included files. This feature enables you to organize code into reusable libraries, import standard functions, and maintain clean project structures. Set up your include paths to point to commonly used utility functions, condition codes, and library files so you can easily import them into multiple projects without code duplication.

Currying and Uncurrying Puzzles

The cdv clsp curry and uncurry commands help you work with curried puzzles, which we covered in Lesson 3. Currying bakes specific values into a puzzle template, creating a specialized version for a particular use case. The curry command applies these values, while uncurry extracts them back out, which is useful when you need to inspect or modify curried puzzles. These tools handle the complex CLVM manipulations required for proper currying, saving you from manual tree construction.

Calculating Tree Hashes

The cdv clsp treehash command computes the tree hash (puzzle hash) of compiled CLVM code. Since puzzle hashes determine coin addresses and are used extensively in conditions and announcements, being able to quickly calculate them from source code streamlines development. This tool accepts either compiled hex or CLVM expressions and returns the puzzle hash, making it easy to verify that your puzzle matches expected addresses or to generate new coin addresses for testing.

Performance Optimization and Cost Analysis

CLVM programs consume computational resources measured in cost units, which directly affects transaction fees and blockchain capacity. Understanding how to analyze and optimize your code’s cost profile improves both user experience and scalability.

Understanding CLVM Cost

Every CLVM operation has an associated cost, with simple operations like arithmetic having low costs and complex operations like hashing or creating coins having higher costs. The total cost of executing your puzzle determines the transaction fee users pay and affects how many transactions can fit in each block. Programs that perform unnecessary work or use inefficient algorithms directly impact the Chia network’s throughput.

Measuring Program Cost

Use brun with verbose output to see not just that your program runs but how much it costs to run. The execution trace shows cost accumulation through each step, helping you identify expensive operations. For complex programs, this analysis reveals optimization opportunities – perhaps you’re hashing the same value multiple times instead of storing the result, or using recursive functions where iteration would be more efficient.

Optimization Strategies

Common optimization techniques include minimizing redundant calculations by storing intermediate results, using the most efficient operators for each task (for example, the coinid operator is cheaper than manually hashing with sha256 for coin ID calculation), and structuring data to reduce traversal operations. Sometimes the clearest code isn’t the most efficient, so after you have working programs, profile them to find hotspots and consider targeted optimizations for performance-critical sections.

Integration with Full Node and RPC

Chialisp development eventually requires interaction with actual Chia blockchain nodes to test in realistic environments and deploy your smart coins.

RPC Commands in cdv

The cdv rpc family of commands provides a command-line interface to Chia full node RPC endpoints. You can query blockchain state, examine coin records by ID, submit spend bundles for mempool inclusion, and monitor block production. These commands use the same node discovery mechanism as the official Chia commands, making integration seamless. Before using RPC commands, ensure you have a local full node running and synced, as these tools connect to your node to interact with the blockchain.

Testing Against Real Network State

While local testing with cdv test works well for isolated smart coin logic, testing against actual blockchain state reveals issues with timing, network conditions, and interaction with other on-chain puzzles. The testnet provides a safe environment to deploy experimental code without risking real value. Use testnet to verify that your coins behave correctly when interacting with real wallets, DEXs, and other on-chain systems before considering mainnet deployment.

Conclusion

Mastering CLVM tooling transforms you from someone who can write Chialisp code into someone who can efficiently develop, debug, and deploy production-ready smart coins. The combination of command-line tools (run, brun, opc, opd, cdv), debugging features (symbol tables, verbose output, cldb), modern IDEs (VS Code extension, Clovyr Code), and testing frameworks (cdv test) provides everything needed for professional Chialisp development. As you’ve progressed through these thirteen lessons, you’ve learned not just the Chialisp language but also the ecosystem that supports it. Real-world case studies like the CAT1 vulnerability remind us that even experienced developers benefit from comprehensive testing, external audits, and proper validation. Now equipped with both language knowledge and tooling expertise, you’re ready to build sophisticated smart coins that are secure, efficient, and reliable. The Chia blockchain ecosystem welcomes your innovations.

Chialisp CLVM Tooling FAQs

What is the difference between run and brun in Chialisp development?

The run tool compiles high-level Chialisp code into CLVM bytecode, while brun executes that compiled bytecode with specific arguments. Run is your compiler that transforms readable code into blockchain-executable format, and brun is your interpreter that actually runs the compiled program to test its behavior.

Should I use Python or Rust CLVM tools for Chialisp development?

Python-based chia-dev-tools are recommended for beginners due to better documentation and community support, while the Rust implementation (chialisp) offers better performance and closer alignment with the production CLVM runtime. Most developers start with Python tools and transition to Rust tools as projects become more complex or performance-sensitive.

How do symbol tables improve debugging in Chialisp?

Symbol tables track constant and function names throughout your code, allowing debugging tools to show meaningful source locations and variable names in error messages instead of cryptic memory addresses. When you compile with run or cdv clsp build, symbol tables are automatically created and can be referenced during execution with the –symbol-table flag to make errors much easier to understand and fix.

What was the CAT1 vulnerability and how was it fixed?

The CAT1 vulnerability allowed attackers to inflate token balances by manipulating byte boundaries between puzzle hash and amount fields during coin ID calculation, because the sha256 function concatenated inputs without validating their lengths. CAT2 fixed this by adding a calculate_coin_id function that validates each component is exactly 32 bytes (for parent ID and puzzle hash) and that amounts are non-negative before performing the hash.

What debugging tools are available for troubleshooting CLVM programs?

Chialisp developers have several debugging tools including symbol tables for readable error messages, verbose output mode for step-by-step execution traces, the cldb debugger for YAML-formatted stepwise debugging, the x operator for deliberate crashes at checkpoints, and opd for converting hex bytecode back to readable format. Using these tools together helps identify bugs that would otherwise be nearly impossible to trace in complex programs.

Chialisp CLVM Tooling Citations

  1. Chia Network – GitHub clvm_tools Repository: Tools for CLVM development – https://github.com/Chia-Network/clvm_tools
  2. Chia Network – GitHub chia-dev-tools Repository: Utility for developing in the Chia ecosystem – https://github.com/Chia-Network/chia-dev-tools
  3. Chia Network – GitHub chialisp Repository: Modern Chialisp compiler implemented in Rust – https://github.com/Chia-Network/chialisp
  4. Chialisp.com – Debugging Documentation: Official debugging guide for Chialisp – https://chialisp.com/debugging/
  5. Chialisp.com – CLVM Documentation: Understanding the Chia Lisp Virtual Machine – https://chialisp.com/clvm/
  6. Chia Network – CAT1 Vulnerability Explained: Technical details of CVE-2022-36447 – https://www.chia.net/2022/07/29/cat1-vulnerability-explained-cve-and-cwe/
  7. Chia Network – GitHub Post-Mortem: CAT1 vulnerability timeline and response – https://github.com/Chia-Network/post-mortem/blob/main/2022-08/2022-08-19-CATbleed.md
  8. Chialisp.com – Common Issues: List of common development pitfalls – https://chialisp.com/common_issues/
  9. Chia Network – GitHub clvm_rs Repository: Rust implementation of CLVM – https://github.com/Chia-Network/clvm_rs
  10. Chia Network – Upgrading the CAT Standard: Blog post announcing CAT2 migration – https://www.chia.net/2022/07/25/upgrading-the-cat-standard/