James Bachini

How To Debug Solidity Smart Contracts

Solidity Debug Tools

If you’ve ever received a “gas message” error which makes no sense in Solidity then you’ve probably come across one of it’s greatest flaws. Error reporting and debugging isn’t great for blockchain developers but in this tutorial I’m going to provide some tips, tools and resources to debug Solidity smart contracts.

  1. Debug & Test Solidity Smart Contracts
  2. Solidity Debugging Tools & Resources
  3. Solidity Error Reporting
  4. 8 Strategies For Robust Contracts
  5. Next Level Solidity Debugging Framework
James On YouTube
How To Debug Solidity Smart Contracts 1

Debug & Test Solidity Smart Contracts

Smart contracts are often complex, immutable and difficult to fix. That’s why testing and debugging your Solidity contracts is crucial to ensure that they operate flawlessly.

Testing allows you to verify that your contract functions behave as expected. By writing comprehensive unit tests, you can catch bugs and defects before they are deployed.

Debugging is the process of identifying and fixing errors in your code and generally happens either at the compile stage or when we get a failed transaction. It involves using tools and techniques to inspect the state of your contract, trace the execution of your code, and find the root cause of any issues.

Solidity Debugging Tools & Resources

I generally work in a multi-stage process where I’ll write proof-of-concept code and then refactor this and start testing to make it somewhat fit to be deployed, at least on Goerli.

Most typos, missing variables and silly bugs are found at the proof of concept stage. These will be picked up when compiling. I like to do this as much as possible in remix but larger projects may be more well suited to a framework such as hardhat.

The error reporting in remix at the compile level is actually pretty good. It highlights the lines where it thinks there’s an issue and gives informative details about what you’ve messed up.

debug solidity
10 lines of code and I still managed to break it

Once the thing compiles I like to do unit tests and system tests to try and find more bugs. I have switched between hardhat and foundry for this but am finding myself coming back to hardhat more and more because of it’s excellent scripting framework and ethers support.

A simple unit test for a function may look something like this:-

it("Should allow 3rd party creation of perps", async () => {
	const newPerp = await perpFactory.createPerp('FOOBAR',100);
	const perpCount = await perpFactory.perpCount();

Full hardhat unit tests for this contract are here: https://github.com/jamesbachini/PerpFactory/blob/main/test/0x1.05-Perp.js

The other tool that I use for debugging a lot is tenderly which allows you to paste in a transaction hash and then debug the flow to try and figure out where it went wrong.

debugging solidity smart contracts

On mainnet there is also @samczsun’s transaction viewer which provides a breakdown of the call trace and then you can click on each call to get more information about the function calls etc. This is really useful for investigating MEV bots in the wild.

Solidity Transaction Debug

These tools are useful at different times throughout the development process but all come under the Solidity debugger umbrella. It’s worth checking them out if you aren’t already familiar, so you know what is available and how to use them when you do come up against a bug.

Solidity Error Reporting

My biggest complaint with Solidity development is error reporting on reverted transactions. The EVM often doesn’t provide much feedback if a transaction fails leaving the developer in the dark as to what went wrong.

My pet hate is the “Error: gas is missing” or “Error: can’t calculate gas” errors which I get sent at least once a week asking for help. These errors often just mean the transaction is going to revert and wont go through. The reason could be anything from a bad token address to some obscure bug that puts the entire protocol at risk.

By adding require, revert, assert statements to the solidity code we can at least get a custom message which will identify where the problem is.

require(_amount > 0, "Stake32 no funds sent");

Notice we put a contract reference at the start of the error which is very useful when there are multiple contracts or you are interacting with 3rd party interfaces.

8 Strategies For Robust Contracts

  1. Use a linter either in vscode or remix to check your code for errors and best practices as you type
  2. Write unit tests for your contract to ensure they function correctly
  3. Write system tests and fuzz parameters to try and break your own code
  4. Use defensive programming techniques, such as checking for null values and input errors
  5. Use openzeppelin libraries where possible as they are battle tested
  6. Use try-catch blocks to handle exceptions and prevent the transaction failing
  7. Use custom revert, assert, require statements to provide better error reporting
  8. Don’t rely on 3rd party interfaces to behave predictably, especially if they run upgradeable contracts

Next Level Solidity Debugging Framework

Nomic Labs are working on something. These are the guys that built hardhat and I saw a presentation at DevCon Bogota where they announced a new debugging framework for Solidity developers.

My somewhat limited understanding is that it will be a new compiler and local EVM that offers more detailed error reporting. This then enables better debugging tools to be created within Hardhat or maybe there will be a new debugging module added.

How To Debug Solidity Smart Contracts 2
slide from the presentation

It’s something that could definitely improve the workflow for Solidity devs in the future so keep an eye on their releases.

Get The Blockchain Sector Newsletter, binge the YouTube channel and connect with me on Twitter

The Blockchain Sector newsletter goes out a few times a month when there is breaking news or interesting developments to discuss. All the content I produce is free, if you’d like to help please share this content on social media.

Thank you.

James Bachini

Disclaimer: Not a financial advisor, not financial advice. The content I create is to document my journey and for educational and entertainment purposes only. It is not under any circumstances investment advice. I am not an investment or trading professional and am learning myself while still making plenty of mistakes along the way. Any code published is experimental and not production ready to be used for financial transactions. Do your own research and do not play with funds you do not want to lose.