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 (opens in a new tab) hash of
error
messageString
is obtained. - Then, its value is read as a 32-bit big-endian (opens in a new tab) number modulo plus , in that order.
- Finally, it's put into the
.md
compilation 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 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.
Can be applied to the following list of types and values:
Int
Bool
Address
Cell
,Builder
orSlice
String
orStringBuilder
map<K, V>
- Optionals and
null
value void
, which is implicitly returned when a function doesn't have return value defined
Usage examples:
// Int
dump(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 all the values of persistent state variables to the contract's debug console. Evaluated only if debug
option is set in the configuration file, otherwise does nothing.
Usage example:
contract DumpsterFire {
var1: Int = 0;
var2: Int = 5;
receive() {
dumpStack(); // would print 0 5
}
}
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 (opens in a new tab) will terminate the transaction.
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.
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.
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 ...
}