Source Expressions

Source expression are the bread-and-butter of Gate. Each source represents a data point, which can be combined and compared to other sources in order to create rules.

Source expressions are the bread-and-butter of Gate. Each source represents a data point, which can be combined and compared to other sources in order to create invariants.

Literals

source number: integer = 6;
source text: string = "Hello, world!";
source wallet: address = 0xcafeface...abcd1234;
source cond: boolean = true;

source numbers: list<integer> = list(1, 2, -3);
source nameToValue: map<string, integer> = map("token_1": 10, "token_2": 4);
source items: tuple<integer, address> = tuple(42, 0x12341234...dadd);
source calldata: bytes = bytes(0x123456);

A few notes:

  1. Floating-point numbers are not supported.

  2. A list must contain items of the same type.

  3. A tuple length and element types must be exact.

  4. A map must contain values of the same type.

  5. Lists and tuples can be nested as much as you like.

Operations

Arithmetic

  • + - Addition

  • -

    • Subtraction (2 - 1)

    • Negation (-3)

  • * - Multiplication

  • ** - Power

  • / - Integer Division ( 7 / 3 == 2)

  • ! - Not operator

Conditions

Conditions can be used as conditions for rules, or even as independent data sources.

  • == - Equals

  • > - Greater than

  • < - Less than

  • >= - Greater or equal

  • <= - Less or equal

Operator precedence behaves as expected.

Logic Combinators

Booleans (e.g conditions) can be combined using and, oroperations:

Parenthesized expressions

Expressions can be parenthesized in order to force the required precedence, or simply to improve clarity.

Source identifiers as expressions

Sources declared using the source statement can be used within source expressions.

Data sources

Hexagate provides external data sources (full reference in Data sources).

Data sources can be constructed and used as valid source expressions. Each parameter to the source can itself be any valid expression (as long as it's type matches the expected type of the data source)

Conditional expressions

Since Gate is not a programming language, if statements do not make sense. However, it may still be desirable to use conditional expressions, similar to ternary operators in other languages.

In this example, b would be 4, because 3 == 3 (if the condition was false, like 3 == 4, then b would be 5

The parentheses around the condition are not mandatory, but might help improve readability

For expressions

For expressions are a powerful tool, which can be used to create complex rules. They are very similar to python's list comprehension.

Example

Let's say I want to sum the balances of some addresses but I don't know the addresses in advance - they are available through a function of a contract.

  1. First, we call the getAddresses() function to get the list of addresses.

  2. Then, we use a for expression to get the balance of each address. We also filter out a certain address.

  3. Finally, we sum up all the balances in order to the get the final balances sum.

The if <condition> part of the for expression if optional.

Map expressions

Map expressions are similar to for expressions, but are used to create a key-value mapping from a sequence (similar to dictionary comprehension in python).

Example

Currently, values of maps are not visible in the execution trace.

Generics

Some data sources are "generic" (or "typed"), and can contain/return varying data types. When using a generic data source, one must customize it with a specified data type to determine the behavior. This is achieved via the regular <type> syntax.

Example

For a more complex and real-world example, see the documentation for the Fetch data source.

Last updated