Skip to main content

title: “Hands-on debugging”


Debugging smart contracts

It’s a common situation when you encounter an error in your smart contract. In some cases you will see that unexpected exit code is returned. This can be a sign of a bug in your contract. There are several techniques to debug your contract.

Log to the console

A straightforward and effective technique. The most common values to print are transactions and get‑method results. There are helper functions that let you inspect transactions in a developer‑friendly way.
TypeScript

Dump values from a contract

Three TVM debug instructions exist: Availability depends on the language you use.
  • In Tolk, use functions from the globally available debug object.
  • In FunC, these methods are available globally in stdlib.fc.
  • In Tact, use dumpStack for DUMPSTK and dump function for the other two. Tact also prints the exact line where dump is called, so you can quickly find it in your code.

Explore TVM logs

TypeScript
There are multiple verbosity levels; two are most useful:
  • vm_logs — outputs VM logs for each transaction; includes executed instructions and occurred exceptions.
  • vm_logs_full — outputs full VM logs for each transaction; includes executed instructions with binary offsets, the current stack for each instruction, and gas used by each instruction.
Typical output for vm_logs looks like this:
The contract tries to load a 64‑bit integer (LDU 64) from the slice, but there is not enough data, so exit code 9 occurs. Inspect the same code with the vm_logs_full verbosity level. (Output is heavily truncated from the top)
Stack is printed as [bottom, ..., top], where top is the top of the stack. Here, the stack contains two values:
  • Slice being read
  • Integer (500000000)
However, the slice has only 725 bits and 711 bits were already read, as were both references. The contract tried to read 64 bits, but there was not enough data in the slice. You should locate the load_uint(64) call that causes the issue and ensure enough bits are available or adjust the read width.

Explore the transaction tree

For simple transaction trees, print all transactions and inspect them.
TypeScript
For complex trees, use a GUI tool. Two tools are commonly used:
  • TonDevWallet trace view — requires the TonDevWallet application; does not require a custom @ton/sandbox; requires the @tondevwallet/traces package.
  • TxTracer Sandbox — requires a custom @ton/sandbox package; runs in your browser.
Also these tools allow you to explore each transaction separate logs.