The Debugger shows the contract's state while stepping through a transaction.
It can be used on transactions created on Remix or by providing a transaction's address. The latter assumes that you have the contract's source code or that you have input the address of a verified contract.
To start a debugging session either:
-
Click the debug button in the Terminal when a successful or failed transaction appears there. The Debugger will be activated and will gain the focus in the Side Panel.
-
Activate the Debugger in the Plugin Manager and then click the bug in the icon panel. To start the debugging session, input the address of a deployed transaction - while having the source code in the editor and then click the Start debugging button.
The debugger will highlight the relevant code in the Editor. If you want to go back to editing the code without the Debugger's highlights, then click the Stop Debugging button.
To learn more about how to use this tool go to the Debugging Transactions page.
This page will go over the Debugger's Use generated sources option, its navigation and its panels.
This option is available for contracts using Solidity 0.7.2 or greater. See the solidity blog for more details about generated sourcess.
Using generated sources will make it easier to audit your contracts. When the option is checked, you can step into those compiler outputs — while debugging.
These compiler outputs will appear in a separate .yul file in the Remix editor.
Moving the slider will highlight the relevant code in the Editor. On the most granular level, it scrolls through a transaction's opcodes (see the opcode section below). At each opcode, the transaction's state changes and these changes are reflected in the Debugger's panels.
This button goes to the previous opcode. If the previous step involves a function call, function will not be entered.
This button steps back to the previous opcode.
This button advances to the next opcode. If the next line contains a function call, Step into will go into the function.
This button advances to the next opcode. If the next step involves a function call, function will not be entered.
Breakpoints can be placed in the gutter of the Editor. If the current step in the call has passed a breakpoint, this button will move the slider to the most recently passed breakpoint.
When you are in a call and click on this button, the slider will be moved to the end of the call.
If a breakpoint is ahead in the code, this button will advance to that point.
The Function stack lists the functions that the transaction is interacting with.
The Solidity Locals are the local variables inside a function.
These are the state variables of the contract.
This panel shows the step number and the opcode that the debugger is currently on.
As you drag the slider (which is above the navigation buttons), the focussed step number & opcode changes.
Step details shows more info about the opcode step.
This panel shows the EVM Stack.
For more info about the stack.
Memory is cleared for each new message call. Memory is linear and can be addressed at byte level. Reads are limited to a width of 256 bits while writes can be either 8 bits or 256 bits wide.
The Memory panel consists of 3 columns. You might need to make Remix's side panel a bit wider to get the formatting to be correct. (Drag the border between the main panel and the side panel to the right).
The 1st column is the location in memory. The 2nd column is the hex encoded value. The 3rd column is the decoded value. If there is nothing, then the question marks (?) will show - like this:
0x10: 00000000000000000000000000000000 ????????????????
Here is a full example of the Memory panel,
Some address slots have hex encoded values and those values are then decoded. For example, check position 0xa0 and 0x140.
This is the persistant storage.
All computations are performed on a data array called the call stack. It has a maximum size of 1024 elements and contains words of 256 bits.
The call data contains the functions parameters.
The refers to the value that the function will return.
This shows the persistant storage at the end of the function.
Breakpoints can be placed in the gutter of the Editor to pause the debugger.
The debugger's granular information gives users detailed information about what is happening in a transaction - so not only is the debugger good for debugging, it is also an excellent teaching tool.
To learn about using the debugger, go to Debugging Transactions.