Debug a contract

Step through and debug your contracts inside the command line.

To debug a contract, let's take the simple counter contract from the Clarinet quickstart as an example.

(define-map Counters principal uint)

(define-read-only (get-count (who principal))
  (default-to u0 (map-get? Counters who))

(define-public (count-up)
  (ok (map-set Counters tx-sender (+ (get-count tx-sender) u1)))

To initiate a debug session for this contract, first run the clarinet console command inside your project.

clarinet console


The ::trace command expects an expression, so make a contract-call? with our count-up function and see what happens.

::trace (contract-call? .counter count-up)

We should see a complete trace of our get-count function call, outputting the arguments that were passed in (tx-sender) and return value (u0).

Here's an example response from the ::trace command:

(contract-call? .counter count-up)  <console>
├── ( get-count tx-sender )  counter:8:38
 (ok true)

If we were to run this command again, we should see the return value go from u0 to u1.


You also might want to set a breakpoint at a specific line to better understand what's happening in your contract.

With ::debug, you can add breakpoints at a specific line of a contract or function to better understand what's happening in your contracts.

To illustrate the power of breakpoints, first add a couple new functions to your contract:

;; Existing contract code...

(define-public (count-twice)

(define-private (double)
    (unwrap-panic (count-up))

Now add a break on the count-up function when calling the new double function.

::debug (contract-call? .counter count-twice)
break count-up
Breakpoint Commands

To step through these breakpoints, you can use one of the following commands:

  • Step-in (step or s): Step into the sub-expressions.
  • Step-out (finish or f): Complete execution of the current expression and return the result to the parent.
  • Step-over (next or n): Continue to completion of the current expression, stepping over sub-expressions.
  • Continue (continue or c): Continue execution until hitting a breakpoint or completing execution.

Using the continue command, the breakpoint you set in the double function will trigger twice due to two count-up calls, which enables you to do variable and map analysis.