Better Solidity debugging: stack traces are finally here

Debugging Solidity is no longer a blind exercise

Patricio Palladino
Oct 2, 2019 · 3 min read

We’ve all been there. Write some Solidity, run your tests and Transaction reverted. Head scratching ensues, followed by frustration and filling everything up with console.log, commenting out lines of Solidity code and pulling your hair until something starts to make sense.

“state of the art” 🧐

There have been some attempts at stack traces or better error messages out there for a while, but they all have significant drawbacks like being tightly tied to a specific toolchain, only covering a minimal portion of what an insightful error message should be, or simply being unreliable.

This is why we’re super stoked to finally release Buidler EVM: a Ganache alternative that includes a fully featured Solidity-aware stack traces implementation.

Buidler EVM is a development network that is built into Buidler and plays nicely with your current tools. It extracts execution information when running your smart contract tests to help you debug more effectively. Some highlights are:

  • It’s built on top of an unmodified ethereumjs-vm, which is the same EVM implementation as Ganache and Remix IDE. No new consensus bugs.
  • Combined JavaScript and Solidity stack traces that start in JavaScript/TypeScript up to your call to the contract, and continue with the full Solidity call stack.
  • 8000+ lines of testing code making up 500+ tests just for Buidler EVM.
Solidity debugging before Buidler EVM

Buidler EVM has first-class Solidity support. It always knows which smart contracts are being run, what they do exactly and why they fail. When a transaction fails without a reason, Buidler EVM will identify and create a clear error message for the following cases:

  • Calling a non-payable function with ETH
  • Sending ETH to a contract without a payable fallback function
  • Calling a non-existent function when there’s no fallback function
  • Calling a function with incorrect parameters
  • Calling an external function that doesn’t return the right amount of data
  • Calling an external function on a non-contract account
  • Failing to execute an external call because of its parameters (e.g. trying to send more ETH than what’s available)
  • Calling a library without DELEGATECALL
  • Incorrectly calling a precompiled contract
Running Aragon Court’s Truffle tests on Visual Studio Code with Buidler

Buidler EVM’s stack traces are native JavaScript exceptions with a populated call stack, making them manageable with try/catch and composable with existing tooling that provides UIs for native errors, like Visual Studio Code above.

Consistent with our vision for Buidler, making this functionality accessible to as many Ethereum smart contract developers building out of the JavaScript ecosystem is a priority for Buidler EVM, so regardless of what tools you’re using you should be able to incorporate them into a Buidler setup: Solidity 4 and 5, Truffle 4 and 5 tests, Waffle tests, Ethers.js, web3.js, JavaScript, TypeScript, ganache, solidity-coverage, solhint, Vyper and more — all play along with Buidler and there’s no need to leave them behind to use Buidler EVM.

If you’re using or building a tool that isn’t mentioned here, don’t worry. Buidler is designed around an open ecosystem of plugins and integrating new tools and libraries is easy.

Take Buidler EVM out for a spin! Clone this fork of OpenZeppelin with a failing test that will trigger a stack trace:

# https://github.com/nomiclabs/buidler-evm-demo
git clone https://github.com/nomiclabs/buidler-evm-demo.git
cd buidler-evm-demo/
npm install
npx buidler test

Check Buidler out and forget your Solidity debugging frustrations today! 👷‍♀️👷‍♂️

Nomic Labs

We build open source software to unlock developer productivity in the Ethereum ecosystem.