Codementor Events

An Intro to Solidity Debugging

Published May 09, 2019
An Intro to Solidity Debugging

Welcome to this quick-start tutorial for debugging Solidity.

The goal of this article is to introduce high-level concepts in debugging Solidity smart contracts primarily using the Remix online IDE and additional resources to learn more.

Remix Online IDE

Get Remix
In this tutorial I will be using the Remix Javascript VM. If you have not yet become familiar with Remix here's a good place to start:

First, it helps to have a high-level understanding of what exactly is happening when you write and deploy a solidity smart contract. Solidity code is compiled into Bytecode and interacts with the Ethereum blockchain using JSON RPC.

solidity-diagram.png

There are two primary functions used to call a smart contract function:

_eth_call = View or pure functions (calls) can use return statements but no events

_eth_sendTransaction = Functions that modify the blockchain and will cost ether (transactions) can use events

Types of Errors

When debugging solidity there are 3 major error types:

Syntax Errors = easy to fix - Caught by compiler.

Runtime Errors = Happen after contract has been deployed and solidity has been compiled to bytecode. These will create reverted transactions are not as easy to debug as syntax errors.

Logic Errors = Occur after the contract is deployed. Not a runtime error in that the EVM (Ethereum Virtual Machine) has no issues but the logic of the code isn’t correct.

Common Tools for Debugging

Compiler and debugging = Remix and truffle (syntax, runtime errors, logic)

Linter = IDE Plugins for Visual Studio Code and other IDEs (syntax, logic)

Popular plugin for VS Code -

Tests = Run tests with Mocha, ect. (runtime errors, logic)

Using Remix for Syntax Errors

Screen Shot 2019-05-08 at 1.44.42 PM.png

Remix is great at catching syntax and runtime errors. The Remix online IDE will point out errors as they occur during code creation.

Common Runtime errors

Out of gas - Not enough gas to complete transaction
Revert - An opcode of vm stops transaction may refund ether
Invalid opcode - An opcode is executed that does not exist. Vm stops transaction
Invalid JUMP - Execute a function that does not exist usually calling a function in another contract that does not exist
Stack overflow - Recursion goes too deep, 1024 x limit for any function to call itself
Stack underflow - Try to read item on stack that does not exist

Debugging an Out of Gas error with Remix

Gas limit = The maximum amount we are willing to pay to execute a function.
The gas limit is relevant mostly for functions that are based on conditional logic and costs can vary depending on options used.

If you are unsure about how Gas works, this may help.

How to tell if you have out of gas error in Remix (You won’t always get an accurate error code for this)

remix-not-enuf-gas.png

Here’s a simple smart contract to test the out of gas error. Note the low Gas Limit that has been set. Try running the set function using only 30000 gas and note the error.

It doesn’t tell you that it’s an out of gas error but when you see execution failed and gas - transaction cost are the same then it’s likely an out of gas error.

Double the gas, re-run the function then check the transaction cost field - rinse and repeat to get the correct min amount of gas necessary.

Here's a list of gas prices for solidity code execution

Understanding the Invalid Opcode / Revert Error

Screen Shot 2019-05-08 at 2.48.36 PM.png

Run each function in Remix to see these errors in action.

Debugging with Remix

In the test contract below we are creating a simple wallet that can only hold up to 1000 Wei. The code has a bug. You can test the contract by first sending 300 Wei, then another 300, then 400 which in theory should work since we are not exceeding the magic number of 1000. As it turns out however we run into a problem.

Screen Shot 2019-05-09 at 12.15.29 PM.png

To start the Remix debugger click the “debug” button to the right of the error message that appears below the code window. On the right panel you will then see this -

solidity-debug-1.png

Note the opcodes (PUSH1, MSTORE, etc.) which is what Solidity gets compiled into for the Ethereum Virtual Machine to execute.

It’s not entirely necessary to know all the opcodes but useful to get familiar with them especially for debugging purposes. You can find them here

The top-down, sequential ordering of the opcodes designates the steps being taken during code execution. The current step is the one which is highlighted 000 PUSH1 80 | vm trace step: 28

The slider below the opcode step window shows you where you are in the steps sequence. As you move the slider the lines of code responsible for the opcode execution are highlighted.

*Note - One line of Solidity code may map to more than one opcode execution

Moving forward, we can advance the slider to line 8 of our code and what we want to know is what amount the balance variable is holding. As we can see here it starts out at 0.

balance-check-1.png

Then if we use the step-through arrow button in this next image while keeping an eye on the balance local variable

balance-check-2.png

we see that at the point we run our require statement which adds the balance and msg.value that we are already at 1000 Wei which means the last deposit of 400 Wei we sent had already been added to the balance before we execute the require check and at that point if we try to add msg.value to balance we are 400 Wei over the limit.

The code will work if we simply remove “+ msg.value” from our require statement.

In Closing...

Remix is a powerful tool for debugging Solidity. I hope you have enjoyed this intro to solidity debugging. Learn more about the Remix debugger at

https://remix.readthedocs.io/en/latest/tutorial_debug.html

Other useful resources for Solidity debugging:

(used for base concepts in this tutorial) Remix debugging tutorials
https://www.youtube.com/channel/UCZM8XQjNOyG2ElPpEUtNasA

New verification tool
https://medium.com/limechain/zeppelin-solidity-release-candidate-new-functional-verification-tool-5b722e8d10b2

Debugging with Truffle
https://www.youtube.com/watch?v=0r24KRMvHG0

Mocha Gas Estimator
https://github.com/cgewecke/eth-gas-reporter

Start writing here...

Discover and read more posts from Charles Voltron
get started