Control Flow

ZoKrates provides a single thread of execution with a few flow constructs.

Function calls

Function calls help make programs clear and modular.

Arguments are passed by value.

def incr(field a) -> field:
    a = a + 1
    return a

def main():
    field x = 1
    field res = incr(x)
    assert(x == 1) // x has not changed

Generic paramaters, if any, must be compile-time constants. They are inferred by the compiler if that is possible, but can also be provided explicitly.

def foo<N, P>() -> field[P]:
    return [42; P]

def main() -> field[2]:
    // `P` is inferred from the declaration of `res`, while `N` is provided explicitly
    field[2] res = foo::<3, _>()
    return res


An if-expression allows you to branch your code depending on a boolean condition.

def main(field x) -> field:
  field y = if x + 2 == 3 then 1 else 5 fi
  return y

For loops

For loops are available with the following syntax:

def main() -> u32:
    u32 res = 0
    for u32 i in 0..4 do
        for u32 j in i..5 do
            res = res + i
    return res

The bounds have to be constant at compile-time, therefore they cannot depend on execution inputs. They can depend on generic parameters.


Any boolean can be asserted to be true using the assert function.

def main() -> ():
    assert(1f + 1f == 2f)

If any assertion fails, execution stops as no valid proof could be generated from it.