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. Otherwise, does nothing.
This function is similar to throwUnless(), but instead of using the error code directly, it generates it based on the given error message String.
The algorithm for generating the exit code works as follows:
- First, the SHA-256 hash of the
errormessageStringis obtained. - Then, its value is read as a 32-bit big-endian number modulo 63000 plus 1000, in that order.
- Finally, it’s put into the
.mdcompilation report file, which resides with the other compilation artifacts in your project’soutputs/orbuild/directories.
The generated exit code is guaranteed to be outside the common 0–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 thrownrequire(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
500+ gasfun 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:
IntBoolAddressCell,Builder, orSliceStringmap<K, V>- Optionals and
nullvalue void, which is implicitly returned when a function doesn’t have a return value defined
Usage examples:
// Intdump(42); // prints: // File filename.tact:2:1 // dump(42) // 42
// Booldump(true);dump(false);
// Addressdump(myAddress());
// Cell, Builder, or Slicedump(emptyCell()); // Celldump(beginCell()); // Builderdump(emptySlice()); // Slice
// Stringdump("Hello, my name is...");
// Mapslet m: map<Int, Int> = emptyMap();m.set(2 + 2, 4);dump(m);
// Special valuesdump(null);dump(emit("msg".asComment())); // As emit() function doesn't return a value, dump() would print #DEBUG#: void.dumpStack
500+ gasfun dumpStack();Prints the total stack depth and up to 255 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} 0throw
fun throw(code: Int);Unconditionally throws an exception with an error code.
Execution of the current context stops, statements after throw are not executed, and control is passed to the first try...catch block on the call stack. If there is no try or try...catch block among calling functions, TVM terminates the transaction.
Attempts to specify a code outside the range cause an exception with exit code 5: Integer out of expected range.
Usage examples:
fun thisWillTerminateAbruptly() { throw(1042); // throwing with exit code 1042}
fun butThisWont() { try { throw(1042); // throwing with exit code 1042 }
// ... follow-up logic ...}throwIf
Available since Tact 1.6fun throwIf(code: Int, condition: Bool);Similar to throw(), but throws an error code only if condition holds, i.e. is equal to true. Doesn’t throw otherwise.
Attempts to specify a code outside the range cause an exception with exit code 5: Integer out of expected range.
Usage example:
contract Ownership { owner: Address;
init() { self.owner = myAddress(); }
receive() { // Check whether the sender is the owner of the contract, // and throw exit code 1024 if not throwIf(1024, sender() != self.owner); }}throwUnless
Available since Tact 1.6fun throwUnless(code: Int, condition: Bool);Similar to throw(), but throws an error code only if condition does not hold, i.e. if condition is not equal to true. Doesn’t throw otherwise.
This function is also similar to require(), but uses the specified code directly instead of generating one based on a given error message String.
Attempts to specify a code outside the range cause an exception with exit code 5: Integer out of expected range.
Usage example:
contract Ownership { owner: Address;
init() { self.owner = myAddress(); }
receive() { // Check whether the sender is the owner of the contract, // and throw exit code 1024 if not throwUnless(1024, sender() == self.owner); }}nativeThrow
Deprecated since Tact 1.6Use throw() instead.
fun nativeThrow(code: Int);An alias to throw().
nativeThrowIf
Deprecated since Tact 1.6Use throwIf() instead.
fun nativeThrowIf(code: Int, condition: Bool);An alias to throwIf().
nativeThrowUnless
Deprecated since Tact 1.6Use throwUnless() instead.
fun nativeThrowUnless(code: Int, condition: Bool);An alias to throwUnless().