The hard thing about software development in Web3 is that once you publish a smart contract to the blockchain, there’s no way to change it! Your mistake is there for the world (and every hacker) to see, and that buggy code can severely impact the end user.
That’s why at Hiro we want to provide the best tools to make sure your contracts function properly before you publish them. In fact, we’ve recently launched a few new tools to make the debugging process even easier.
Leveraging the Trace Command
First up is the new ::trace command in Clarinet console.
Have you ever wondered to yourself, “how the 🤬 is a 7 getting passed into this contract call?!” Don’t worry, we’ve all been there. That’s why we released a feature to deal with that exact problem.
With the v0.31 release of Clarinet, you can now evaluate any expression using the trace command, and you’ll see a complete trace of all the calls leading up to the problem, complete with arguments, return values, and generated events. With this new command, you can trace your way back to exactly where things went sideways.
To use the trace command, open up the console with clarinet console, then simply run ::trace, passing it the expression that you want to investigate. For example:
Introducing the Clarinet Inline Debugger
If the execution trace is not enough to track down your bug, we’ve got another new trick up our sleeves — step-by-step debugging. Our smart contract debugger allows you to step, line by line, through your contract, probing the state along the way. There are now two supported options for debugging your contracts using Hiro’s tools.
You can debug your code inside VS Code with Hiro’s Clarity extension (new in v0.8 of the Clarity extension):
Or if you prefer the command line, you can now debug inside of clarinet console too:
Both options allow you to run a debug session, where the debugger provides some key features to track down those pesky bugs while it executes your code. To start off, you might want to set a breakpoint at a specific line where you think something fishy might be happening.
If you’re not sure what line of code might be interesting to look at, but you’re interested in following how a specific value changed, you can also set a watchpoint (also known as a data breakpoint), which tells the debugger to stop when a contract variable or map will be modified.
Once your breakpoints are set, start running the debugger, and the tool will stop the execution when it hits one of the breakpoints. At that point, you can evaluate any expression, from the current context, to investigate the current state of your contract. For example, you may want to check the values in your maps and variables.
From there, you can step through each expression and keep an eye on those values. When you hit a function call, you can step over it, and continue to the next expression, or you can step inside and continue investigating inside the called function. This works for calling private functions in the same contract and also for stepping into a contract call across contracts.
With these features, you can work your way through your contracts line by line until you find exactly what section of code is misbehaving.
Start Debugging Today
Using these tools, even the deepest and peskiest bugs will be exposed! For a full walkthrough with all of the details of each debugger, check out the Clarinet Debugger Demo repo, and the corresponding videos on Hiro’s YouTube channel: a demo of the VS Code Debugger and a demo of the Command Line Debugger.
Ready to kickstart your Web3 development journey into Web3? Download our free guide to developing smart contracts.