Skip to main content

Data Types

Booleans

Leo supports the traditional true or false boolean values. The explicit bool type for booleans in statements is required.

let b: bool = false;

Integers

Leo supports signed integer types i8, i16, i32, i64, i128 and unsigned integer types u8, u16, u32, u64, u128.

let b: u8 = 1u8;

Underscores _ can be used to separate digits in integer literals.

let n: u64 = 1_000_000u64;
info

Higher bit length integers generate more constraints in the circuit, which can slow down computation time.

A Note on Leo Integers

Leo will not default to an integer type. The definition of an integer must include an explicit type.
Type casting is supported as of Leo v1.8.2

let a: u8 = 2u8; // explicit type
let b: u16 = a as u16; // type casting
let c: u8 = 2; // implicit type -- not supported

Field Elements

Leo supports the field type for elements of the base field of the elliptic curve. These are unsigned integers less than the modulus of the base field. The following are the smallest and largest field elements.

let a: field = 0field;
let b: field = 8444461749428370424248824938781546531375899335154063827935233455917409239040field;

Group Elements

The set of affine points on the elliptic curve forms a group. The curve is a Twisted Edwards curve with a = -1 and d = 3021. Leo supports a subgroup of the group, generated by a generator point, as a primitive data type. A group element is denoted by the x-coordinate of its point; for example, 2group means the point (2, 5553594316923449299484601589326170487897520766531075014687114064346375156608).

let a: group = 0group; // the point with 0 x-coordinate, (0, 1)
let b: group = 1540945439182663264862696551825005342995406165131907382295858612069623286213group; // the generator point

The aforementioned generator point can be obtained via a constant associated to the group type.

let g: group = group::GEN; // the group generator

Scalar Elements

Leo supports the scalar type for elements of the scalar field defined by the elliptic curve subgroup. These are unsigned integers less than the modulus of the scalar field. The following are the smallest and largest scalars.

let a: scalar = 0scalar;
let b: scalar = 2111115437357092606062206234695386632838870926408408195193685246394721360382scalar;

Addresses

Addresses are defined to enable compiler-optimized routines for parsing and operating over addresses. These semantics will be accompanied by a standard library in a future sprint.

let receiver: address = aleo1ezamst4pjgj9zfxqq0fwfj8a4cjuqndmasgata3hggzqygggnyfq6kmyd4;

Signatures

Aleo uses the Schnorr signature scheme to sign messages with an Aleo private key. Signatures are a native type in Leo, and can be declared with the keyword signature. Signatures can be verified in Leo using the signature::verify or s.verify operators.

program test.aleo {

struct foo {
a: u8,
b: scalar
}

transition verify_field(s: signature, a: address, v: field) {
let first: bool = signature::verify(s, a, v);
let second: bool = s.verify(a, v);
assert_eq(first, second);
}

transition verify_foo(s: signature, a: address, v: foo) {
let first: bool = signature::verify(s, a, v);
let second: bool = s.verify(a, v);
assert_eq(first, second);
}
}

Array

Leo supports static arrays. Array types are declared as [type; length] and can be nested. Arrays cannot be empty nor modified.

Arrays only support constant accesses. The accessor expression must be a constant expression.

Arrays can contain primitive data types, structs, or arrays. Structs and records can also contain arrays.

Arrays can be iterated over using a for loop.

// Initalize a boolean array of length 4
let arr: [bool; 4] = [true, false, true, false];

// Nested array
let nested: [[bool; 2]; 2] = [[true, false], [true, false]];

struct bar {
data: u8,
}

// Array of structs
let arr_of_structs: [bar; 2] = [bar { data: 1u8 }, bar { data: 2u8 }];

// Access the field of a struct within an array
transition foo(a: [bar; 8]) -> u8 {
return a[0u8].data;
}

// Struct that contains an array
struct bat {
data: [u8; 8],
}

// Record that contains an array
record floo {
owner: address,
data: [u8; 8],
}

// Declare a mapping that contains array values
mapping data: address => [bool; 8];

// Iterate over an array using a for loop and sum the values within
transition sum_with_loop(a: [u64; 4]) -> u64 {
let sum: u64 = 0u64;
for i: u8 in 0u8..4u8 {
sum += a[i];
}
return sum;
}

Tuple

Leo supports tuples. Tuple types are declared as (type1, type2, ...) and can be nested. Tuples cannot be empty or modified.

Tuples only support constant access with a dot . and a constant integer.

Tuples can contain primitive data types, structs, or arrays. Structs and records can also contain tuples.

program test.aleo {
transition baz(foo: u8, bar: u8) -> u8 {
let a: (u8, u8) = (foo, bar);
let result: u8 = a.0 + a.1;
return result;
}
}