Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 55 additions & 59 deletions documentation/language/08_cheatsheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
id: cheatsheet
title: Leo Syntax Cheatsheet
sidebar: Cheatsheet
toc_min_heading_level: 2
toc_max_heading_level: 2
---
[general tags]: # (program, import, boolean, integer, field, group, scalar, address, signature, array, tuple, struct, operators, cryptographic_operators, assert, hash, commit, random, address, block, transition, async_transition, function, async_function, inline, mapping, conditionals, loops)

Expand Down Expand Up @@ -109,46 +111,46 @@ Both `address` and `signature` types do not have option variants.


## 4. Records
Defining a `record`
Defining a `record`:
```leo
record Token {
owner: address,
amount: u64,
}
```

Creating a `record`
Creating a `record`:
```leo
let user: User = User {
owner: aleo1ezamst4pjgj9zfxqq0fwfj8a4cjuqndmasgata3hggzqygggnyfq6kmyd4,
balance: 1000u64,
};
```

Accessing `record` fields
Accessing `record` fields:
```leo
let user_address: address = user.owner;
let user_balance: u64 = user.balance;
```

## 5. Structs
Defining a `struct`
Defining a `struct`:
```leo
struct Message {
sender: address,
object: u64,
}
```

Creating an instance of a `struct`
Creating an instance of a `struct`:
```leo
let msg: Message = Message {
sender: aleo1ezamst4pjgj9zfxqq0fwfj8a4cjuqndmasgata3hggzqygggnyfq6kmyd4,
object: 42u64,
};
```

Accessing `struct` fields
Accessing `struct` Fields:
```leo
let sender_address: address = msg.sender;
let object_value: u64 = msg.object;
Expand Down Expand Up @@ -187,24 +189,20 @@ Note that because the `address` and `signature` types do not have option variant


## 6. Arrays
Declaring `arrays`
Declaring `arrays`:
```leo
let arrb: [bool; 2] = [true, false];
let arr: [u8; 4] = [1u8, 2u8, 3u8, 4u8];
let empty: [u8; 0] = [];
```

Accessing elements
Accessing elements:
```leo
let first: u8 = arr[0]; // Get the first element
let second: u8 = arr[1]; // Get the second element
```

Modifying elements

Leo does not support mutable variables, so arrays are immutable after declaration.

Looping Over Arrays
Looping over arrays:
```leo
let numbers: [u32; 3] = [5u32, 10u32, 15u32];

Expand All @@ -216,35 +214,27 @@ for i: u8 in 0u8..3u8 {
```

## 7. Tuples
Declaring tuples
Declaring tuples:
```leo
// NOTE: Tuples cannot be empty!
let t: (u8, bool, field) = (42u8, true, 100field);
```
**Tuples cannot be empty.**

Accessing tuple elements

Use destructuring
Accessing tuple elements:

```leo
// Using de-structuring
let (a, b, c) = t;
```

Index-based access
```leo
//Using index-based accessing
let first: u8 = t.0;
let second: bool = t.1;
let third: field = t.2;

```
## 8. Transitions
```leo
transition mint_public(
public receiver: address,
public amount: u64,
) -> Token { /* Your code here */ }
```

## 9. Functions

## 8. Functions
The rules for functions (in the traditional sense) are as follows:

There are three variants of functions:
Expand Down Expand Up @@ -319,7 +309,11 @@ function subtract(a: u64, b: u64) -> u64 {
❌ Cannot call: another `transition` (unless from another program)

### Async Transition
An `async transition` function **modifies private state** exactly like a regular `transition`, but it also includes an onchain portion that can **modify onchain/public state**. It can call `function` and `inline` functions, but **cannot be called by a function or inline**. An `async transition` **must** return a `Future`.
An `async transition` function **modifies private state** exactly like a regular `transition`, but it also includes an onchain portion that can **modify public (onchain) state**.

It can call `function` and `inline` functions, but **cannot be called by a function or inline**.

An `async transition` **must** return a `Future`.
```leo
mapping balances: address => u64

Expand All @@ -336,7 +330,7 @@ async transition mint(receiver: address, amount: u64) -> Future {

❌ Cannot call: another `transition` (unless from another program)

## 10. Loops
## 9. Loops
```leo
let count: u32 = 0u32;

Expand All @@ -345,7 +339,7 @@ for i: u32 in 0u32..5u32 {
}
```

## 11. Conditionals
## 10. Conditionals
```leo
let a: u8 = 1u8;

Expand All @@ -360,59 +354,50 @@ if a == 1u8 {
a = (a == 1u8) ? a + 1u8 : ((a == 2u8) ? a + 2u8 : a + 3u8); // Ternary format
```

## 12. Onchain Storage
## 11. Onchain Storage
### Mappings
```leo
mapping balances: address => u64;

let contains_bal: bool = Mapping::contains(balances, receiver);
let get_bal: u64 = Mapping::get(balances, receiver);
let get_or_use_bal: u64 = Mapping::get_or_use(balances, receiver, 0u64);
let set_bal: () = Mapping::set(balances, receiver, 100u64);
let remove_bal: () = Mapping::remove(balances, receiver);
// Querying
let contains_bal: bool = balances.contains(receiver);
let get_bal: u64 = balances.get(receiver);
let get_or_use_bal: u64 = balances.get_or_use(receiver, 0u64);

// Modifying
balances.set(receiver, 100u64);
balances.remove(balances, receiver);
```
### Storage Variables
```leo
storage var: u8
storage var: u8;

// Querying
let unwrap_var: u8 = var.unwrap();
let unwrap_or_var: u8 = var.unwrap_or(0u8);

// Modifying
var = 8u8;
var = none;
```
### Storage Vectors
```leo
storage vec: [u8]

// Querying
let len_vec: u32 = vec.len();
let val: u8 = vec.get(idx)

// Modifying
vec.set(idx, value);
vec.push(value);
vec.pop();
vec.swap_remove(idx);
vec.clear();
```
## 13. Commands
```leo
async transition matches(height: u32) -> Future {
return async {
assert_eq(height, block.height); // block.height returns latest block height
};
}
let this: address = self.address; // address of this program
let caller: address = self.caller; // address of the program function caller (may be another program)
let signer: address = self.signer; // address of the transaction signer (end user)

let a: bool = true;
let b: u8 = 1u8;
let c: u8 = 2u8;
assert(a); // assert the value of a is true
assert_eq(b, b); // assert a and b are equal
assert_neq(b, c); // assert a and b are not equal
```


## 14. Operators
## 12. Operators
### Standard
```leo
// Arithmetic Operators
Expand Down Expand Up @@ -453,13 +438,24 @@ let squared: field = 1field.square(); // Square of the field/group element
let root: field = 1field.square_root(); // Square root of the field/group element

// Context-dependent Expressions
let this: address = self.address; // Address of program
let height: u32 = block.height; // Height of current blcok
let now: i64 = block.timestamp; // Timestamp of current block
let this: address = self.address; // Address of program
let caller: address = self.caller; // Address of function caller
let checksum: [u8, 32] = self.checksum; // Checksum of a program
let edition: u16 = self.edition; // Edition of a program
let owner: address = self.program_owner; // Address that deployed a program
let signer: address = self.signer; // Address of tx signer (origin)

// Bit Serialization/Deserialization
let bits: [bool; 58] = Serialize::to_bits(value); // Standard serialization (includes type metadata)
let raw_bits: [bool; 32] = Serialize::to_bits_raw(value); // Raw serialization (no metadata, just raw bits)

// Miscellaneous
assert(a); // assert the value of a is true
assert_eq(a, b); // assert a and b are equal
assert_neq(b, c); // assert b and c are not equal
let ternary = boolean ? a : b; // Ternary expression
```

### Cryptographic
Expand Down
96 changes: 96 additions & 0 deletions documentation/language/operators/standard_operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ toc_max_heading_level: 3
| [rem_wrapped](#rem_wrapped) | Wrapping remainder |
| [self.address](#selfaddress)| Address of the current program |
| [self.caller](#selfcaller) | Address of a transition's calling user/program |
| [self.checksum](#selfcaller) | Checksum of a program |
| [self.edition](#selfedition)| Version number of a program |
| [self.program_owner](#selfprogram_owner) | Address that submitted a program's deployment transaction |
| [self.signer](#selfsigner) | Address of the top-level transition's calling user |
| [Serialize::to_bits](#serializeto_bits) | Serialize data to bits |
| [shl](#shl) | Shift left |
Expand Down Expand Up @@ -1150,6 +1153,99 @@ The `self.caller` operator returns the address of the account/program that invok
[Back to Top](#table-of-contents)
***

### `self.checksum`

```leo
async transition matches(checksum: [u8,32]) -> Future {
return check_program_checksum(checksum);
}

async function check_program_checksum(checksum: [u8,32]) {
assert_eq(self.checksum, checksum);
}
```


The `self.checksum` operator returns a program's checksum, which is a unique identifier for the program's code.

You may also refer to another program's checksum with the following syntax:
```leo
import credits.aleo;
...
let ext_checksum: [u8, 32] = Program::checksum(credits.aleo);
```

:::info
* The `self.checksum` operator can only be used in an async function. Using it outside an async function will result in a compilation error.
* The `self.checksum` operator doesn't take any parameters.
* To reference another program's checksum, you will need to import that program first.
:::

[Back to Top](#table-of-contents)
***


### `self.edition`

```leo
async transition matches(edition: u16) -> Future {
return check_program_edition(edition);
}

async function check_program_edition(edition: u16) {
assert_eq(self.edition, edition);
}
```


The `self.edition` operator returns a program's edition, which is the program's version number. A program's edition starts at zero and is incremented by one for each upgrade. The edition is tracked automatically on the network.

You may also refer to another program's edition with the following syntax:
```leo
import credits.aleo;
...
let ext_edition: u16 = Program::edition(credits.aleo);
```

:::info
* The `self.edition` operator can only be used in an async function. Using it outside an async function will result in a compilation error.
* The `self.edition` operator doesn't take any parameters.
* To reference another program's edition, you will need to import that program first.
:::

[Back to Top](#table-of-contents)
***

### `self.program_owner`

```leo
async transition matches(owner: address) -> Future {
return check_program_owner(owner);
}

async function check_program_owner(owner: address) {
assert_eq(self.program_owner, owner);
}
```


The `self.program_owner` operator returns the address that submitted the deployment transaction for a program.
You may also refer to another program's owner with the following syntax:
```leo
import credits.aleo;
...
let ext_owner: u16 = Program::owner(credits.aleo);
```

:::info
* The `self.program_owner` operator can only be used in an async function. Using it outside an async function will result in a compilation error.
* The `self.program_owner` operator doesn't take any parameters.
* To reference another program's owner, you will need to import that program first.
:::

[Back to Top](#table-of-contents)
***

### `self.signer`

```leo
Expand Down
2 changes: 1 addition & 1 deletion documentation/language/programs_in_practice/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ function foo(
}
```

## Inline
## Inline Function

An inline function is declared as `inline {name}() {}`. Similar to helper functions, they contain expressions and statements that can compute values, and cannot be executed directly from the outside. The key difference is that the Leo compiler inlines the body of the function at each call site.

Expand Down
2 changes: 1 addition & 1 deletion documentation/language/programs_in_practice/limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ snarkVM imposes the following limits on Aleo programs:

Some other protocol-level limits to be aware of are:
- **the maximum transaction size is 128 KB.** If your program exceeds this, perhaps by requiring large inputs or producing large outputs, consider optimizing the data types in your Leo code.
- **the maxmimum number of micro-credits your transaction can consume for on-chain execution is `100_000_000`.**. If your program exceeds this, consider optimizing on-chain components of your Leo code.
- **the maximum number of micro-credits your transaction can consume for on-chain execution is `100_000_000`.**. If your program exceeds this, consider optimizing on-chain components of your Leo code.

As with the above restructions. these limits can only be increased via the governance process.

Expand Down