Skip to main content

Documentation Index

Fetch the complete documentation index at: https://companyname-a7d5b98e-3-gasless.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Tolk provides flexible constructs for controlling contract flow. Use if, assert, and loops to express conditional logic. The match expression is a powerful “pattern-matching” feature.

if statement

Similar to common languages, optionally followed by else if or else.
if (condition) {
    // ...
} else {
    // ...
}
A condition must be a boolean or an integer (will be true if not equals 0):
if (someInt) {     // means "someInt != 0"
    // ...
}
The body of if and else must be enclosed in { ... }:
// invalid
if (condition)
    someFn();

// valid
if (condition) {
    someFn();
}

assert statement

assert throws an exception if a condition is false.
assert (condition) throw ERR_CODE;
It is equivalent to the following form:
if (!condition) {
    throw ERR_CODE;
}
See exceptions.

match expression

match is used to perform different actions for different values of a variable. One common use case is routing values of a union type:
fun demo(v: A | B | C) {
    match (v) {
        A => {
            // use `v.aField` etc.
        }
        B => { /* ... */ }
        C => { /* ... */ }
    }
}
The match is equivalent to a series of if-else checks:
fun demo(v: A | B | C) {
    if (v is A) {
        // use `v.aField` etc.
    }
    else if (v is B) { /* ... */ }
    else { /* ... */ }
}
The match can also be used for expressions (switch-like behavior):
fun invertNumber(curValue: int) {
    return match (curValue) {
        1 => 0,
        0 => 1,
        else => throw ERR_UNEXPECTED,
    };
}
See union types and pattern matching.

Ternary operator

A ternary condition ? when_true : when_false is also available:
fun myAbs(v: int) {
    return v < 0 ? -v : v
}
Note that if types of when_true and when_false are different, a resulting type is a union. However, this is typically not the intended result, so the compiler reports an error.
fun demo(a: int32, b: int64) {
    // instead of inferring result1 as `int32 | int64`,
    // an error "probably it's not what you expected"
    val result1 = a > b ? a : b;

    // correct: specify the type manually
    val result2: int = a > b ? a : b;

    // also correct, types are compatible
    val result3 = a > b ? a as int64 : b;
}

while loops

while and do-while loops repeatedly execute their bodies while the condition remains true. while checks the condition first and may not execute the body at all, whereas do-while runs the body first.
fun demoWhile(i: int) {
    while (i > 0) {
        debug.print(i);
        i -= 1;
    }
}

fun demoDoWhile() {
    var rand: int;
    do {
        rand = random.uint256();
    } while (rand % 2 == 0);
    return rand;  // an odd number
}
For instance, while is used to iterate over maps:
fun iterateOverMap(m: map<int32, Point>) {
    var r = m.findFirst();
    while (r.isFound) {
        // ...
        r = m.iterateNext(r);
    }
}

repeat loop

The repeat (N) statement executes a block N times:
repeat (5) {
    // executed 5 times
}
N does not have to be a constant; it may also be a variable.

Break and continue in loops

The keywords break and continue are not implemented yet, and a for loop may be added in future versions.