Skip to content

Debug

List of functions commonly used for debugging smart contracts in Tact.

Read more about debugging on the dedicated page: Debugging.

require

fun require(condition: Bool, error: String);

Checks the condition and throws an error with an exit code generated from the error message if the condition is false. Does nothing otherwise.

The algorithm for generating the exit code works as follows:

  • First, the SHA-256 hash of error message String is obtained.
  • Then, its value is read as a 32-bit big-endian number modulo 6300063000 plus 10001000, in that order.
  • Finally, it’s put into the .md compilation report file, which resides with the other compilation artifacts in your project’s outputs/ or build/ directories.

The generated exit code is guaranteed to be outside the common 02550 - 255 range reserved for TVM and Tact contract errors, which makes it possible to distinguish exit codes from require() and any other standard exit codes.

Usage examples:

// now() has to return a value greater than 1000, otherwise an error message will be thrown
require(now() > 1000, "We're in the first 1000 seconds of 1 January 1970!");
try {
// The following will never be true, so this require would always throw
require(now() < -1, "Time is an illusion. Lunchtime doubly so.");
} catch (e) {
// e will be outside of range 0-255
dump(e);
}

dump

fun dump(arg);

Prints the argument arg to the contract’s debug console. Evaluated only if the debug option in the configuration file is set to true, otherwise does nothing.

This function is computationally expensive and consumes a lot of gas because it prints the location from which it was called, i.e. the filename, line and column numbers, and the original expression that was the arg argument.

Can be applied to the following list of types and values:

Usage examples:

// Int
dump(42); // prints:
// File filename.tact:2:1
// dump(42)
// 42
// Bool
dump(true);
dump(false);
// Address
dump(myAddress());
// Cell, Builder or Slice
dump(emptyCell()); // Cell
dump(beginCell()); // Builder
dump(emptySlice()); // Slice
// String or StringBuilder
dump("Hello, my name is..."); // String
dump(beginTailString()); // StringBuilder
// Maps
let m: map<Int, Int> = emptyMap();
m.set(2 + 2, 4);
dump(m);
// Special values
dump(null);
dump(emit("msg".asComment())); // As emit() function doesn't return a value, dump() would print #DEBUG#: void.

dumpStack

fun dumpStack();

Prints the total stack depth and up to 255255 of its values from the top to the contract’s debug console. The values are positioned bottom-up: from the deepest value on the left to the topmost value on the right. Evaluated only if the debug option in the configuration file is set to true, otherwise does nothing.

Usage example:

dumpStack(); // prints:
// File filename.tact:1:1
// dumpStack()
// stack(3 values) : 100000000 C{96...C7} 0

throw

fun throw(code: Int);

An alias to nativeThrow().

nativeThrow

fun nativeThrow(code: Int);

Throws an exception with an error code equal to code. Execution of the current context stops (the statements after nativeThrow won’t be executed) and control will be passed to the first try...catch block in the call stack. If no try or try...catch block exists among caller functions, TVM will terminate the transaction.

Attempts to specify the code outside of 0655350 - 65535 range cause an exception with exit code 5: Integer out of expected range.

Usage examples:

fun thisWillTerminate() {
nativeThrow(42); // throwing with exit code 42
}
fun butThisDoesNot() {
try {
nativeThrow(42); // throwing with exit code 42
}
// ... follow-up logic ...
}

nativeThrowIf

fun nativeThrowIf(code: Int, condition: Bool);

Similar to nativeThrow(), but throws an exception conditionally, when condition is equal to true. Doesn’t throw otherwise.

Attempts to specify the code outside of 0655350 - 65535 range cause an exception with exit code 5: Integer out of expected range.

Usage examples:

fun thisWillTerminate() {
nativeThrowIf(42, true); // throwing with exit code 42
}
fun butThisDoesNot() {
try {
nativeThrowIf(42, true); // throwing with exit code 42
}
// ... follow-up logic ...
}

nativeThrowUnless

fun nativeThrowUnless(code: Int, condition: Bool);

Similar to nativeThrow(), but throws an exception conditionally, when condition is equal to false. Doesn’t throw otherwise.

Attempts to specify the code outside of 0655350 - 65535 range cause an exception with exit code 5: Integer out of expected range.

Usage examples:

fun thisWillTerminate() {
nativeThrowUnless(42, false); // throwing with exit code 42
}
fun butThisDoesNot() {
try {
nativeThrowUnless(42, false); // throwing with exit code 42
}
// ... follow-up logic ...
}