Skip to content

Commit 2ac0939

Browse files
Merge pull request #552 from ProvableHQ/fix/missing-upgrade-operands
Adding missing operators and adding to cheatsheet
2 parents d5093f5 + 58282d6 commit 2ac0939

File tree

4 files changed

+153
-61
lines changed

4 files changed

+153
-61
lines changed

documentation/language/08_cheatsheet.md

Lines changed: 55 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
id: cheatsheet
33
title: Leo Syntax Cheatsheet
44
sidebar: Cheatsheet
5+
toc_min_heading_level: 2
6+
toc_max_heading_level: 2
57
---
68
[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)
79

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

110112

111113
## 4. Records
112-
Defining a `record`
114+
Defining a `record`:
113115
```leo
114116
record Token {
115117
owner: address,
116118
amount: u64,
117119
}
118120
```
119121

120-
Creating a `record`
122+
Creating a `record`:
121123
```leo
122124
let user: User = User {
123125
owner: aleo1ezamst4pjgj9zfxqq0fwfj8a4cjuqndmasgata3hggzqygggnyfq6kmyd4,
124126
balance: 1000u64,
125127
};
126128
```
127129

128-
Accessing `record` fields
130+
Accessing `record` fields:
129131
```leo
130132
let user_address: address = user.owner;
131133
let user_balance: u64 = user.balance;
132134
```
133135

134136
## 5. Structs
135-
Defining a `struct`
137+
Defining a `struct`:
136138
```leo
137139
struct Message {
138140
sender: address,
139141
object: u64,
140142
}
141143
```
142144

143-
Creating an instance of a `struct`
145+
Creating an instance of a `struct`:
144146
```leo
145147
let msg: Message = Message {
146148
sender: aleo1ezamst4pjgj9zfxqq0fwfj8a4cjuqndmasgata3hggzqygggnyfq6kmyd4,
147149
object: 42u64,
148150
};
149151
```
150152

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

188190

189191
## 6. Arrays
190-
Declaring `arrays`
192+
Declaring `arrays`:
191193
```leo
192194
let arrb: [bool; 2] = [true, false];
193195
let arr: [u8; 4] = [1u8, 2u8, 3u8, 4u8];
194196
let empty: [u8; 0] = [];
195197
```
196198

197-
Accessing elements
199+
Accessing elements:
198200
```leo
199201
let first: u8 = arr[0]; // Get the first element
200202
let second: u8 = arr[1]; // Get the second element
201203
```
202204

203-
Modifying elements
204-
205-
Leo does not support mutable variables, so arrays are immutable after declaration.
206-
207-
Looping Over Arrays
205+
Looping over arrays:
208206
```leo
209207
let numbers: [u32; 3] = [5u32, 10u32, 15u32];
210208
@@ -216,35 +214,27 @@ for i: u8 in 0u8..3u8 {
216214
```
217215

218216
## 7. Tuples
219-
Declaring tuples
217+
Declaring tuples:
220218
```leo
219+
// NOTE: Tuples cannot be empty!
221220
let t: (u8, bool, field) = (42u8, true, 100field);
222221
```
223-
**Tuples cannot be empty.**
224222

225-
Accessing tuple elements
226223

227-
Use destructuring
224+
Accessing tuple elements:
225+
228226
```leo
227+
// Using de-structuring
229228
let (a, b, c) = t;
230-
```
231229
232-
Index-based access
233-
```leo
230+
//Using index-based accessing
234231
let first: u8 = t.0;
235232
let second: bool = t.1;
236233
let third: field = t.2;
237-
238-
```
239-
## 8. Transitions
240-
```leo
241-
transition mint_public(
242-
public receiver: address,
243-
public amount: u64,
244-
) -> Token { /* Your code here */ }
245234
```
246235

247-
## 9. Functions
236+
237+
## 8. Functions
248238
The rules for functions (in the traditional sense) are as follows:
249239

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

321311
### Async Transition
322-
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`.
312+
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**.
313+
314+
It can call `function` and `inline` functions, but **cannot be called by a function or inline**.
315+
316+
An `async transition` **must** return a `Future`.
323317
```leo
324318
mapping balances: address => u64
325319
@@ -336,7 +330,7 @@ async transition mint(receiver: address, amount: u64) -> Future {
336330

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

339-
## 10. Loops
333+
## 9. Loops
340334
```leo
341335
let count: u32 = 0u32;
342336
@@ -345,7 +339,7 @@ for i: u32 in 0u32..5u32 {
345339
}
346340
```
347341

348-
## 11. Conditionals
342+
## 10. Conditionals
349343
```leo
350344
let a: u8 = 1u8;
351345
@@ -360,59 +354,50 @@ if a == 1u8 {
360354
a = (a == 1u8) ? a + 1u8 : ((a == 2u8) ? a + 2u8 : a + 3u8); // Ternary format
361355
```
362356

363-
## 12. Onchain Storage
357+
## 11. Onchain Storage
364358
### Mappings
365359
```leo
366360
mapping balances: address => u64;
367361
368-
let contains_bal: bool = Mapping::contains(balances, receiver);
369-
let get_bal: u64 = Mapping::get(balances, receiver);
370-
let get_or_use_bal: u64 = Mapping::get_or_use(balances, receiver, 0u64);
371-
let set_bal: () = Mapping::set(balances, receiver, 100u64);
372-
let remove_bal: () = Mapping::remove(balances, receiver);
362+
// Querying
363+
let contains_bal: bool = balances.contains(receiver);
364+
let get_bal: u64 = balances.get(receiver);
365+
let get_or_use_bal: u64 = balances.get_or_use(receiver, 0u64);
366+
367+
// Modifying
368+
balances.set(receiver, 100u64);
369+
balances.remove(balances, receiver);
373370
```
374371
### Storage Variables
375372
```leo
376-
storage var: u8
373+
storage var: u8;
377374
375+
// Querying
378376
let unwrap_var: u8 = var.unwrap();
379377
let unwrap_or_var: u8 = var.unwrap_or(0u8);
378+
379+
// Modifying
380380
var = 8u8;
381381
var = none;
382382
```
383383
### Storage Vectors
384384
```leo
385385
storage vec: [u8]
386386
387+
// Querying
387388
let len_vec: u32 = vec.len();
388389
let val: u8 = vec.get(idx)
390+
391+
// Modifying
389392
vec.set(idx, value);
390393
vec.push(value);
391394
vec.pop();
392395
vec.swap_remove(idx);
393396
vec.clear();
394397
```
395-
## 13. Commands
396-
```leo
397-
async transition matches(height: u32) -> Future {
398-
return async {
399-
assert_eq(height, block.height); // block.height returns latest block height
400-
};
401-
}
402-
let this: address = self.address; // address of this program
403-
let caller: address = self.caller; // address of the program function caller (may be another program)
404-
let signer: address = self.signer; // address of the transaction signer (end user)
405-
406-
let a: bool = true;
407-
let b: u8 = 1u8;
408-
let c: u8 = 2u8;
409-
assert(a); // assert the value of a is true
410-
assert_eq(b, b); // assert a and b are equal
411-
assert_neq(b, c); // assert a and b are not equal
412-
```
413398

414399

415-
## 14. Operators
400+
## 12. Operators
416401
### Standard
417402
```leo
418403
// Arithmetic Operators
@@ -453,13 +438,24 @@ let squared: field = 1field.square(); // Square of the field/group element
453438
let root: field = 1field.square_root(); // Square root of the field/group element
454439
455440
// Context-dependent Expressions
456-
let this: address = self.address; // Address of program
441+
let height: u32 = block.height; // Height of current blcok
442+
let now: i64 = block.timestamp; // Timestamp of current block
443+
let this: address = self.address; // Address of program
457444
let caller: address = self.caller; // Address of function caller
445+
let checksum: [u8, 32] = self.checksum; // Checksum of a program
446+
let edition: u16 = self.edition; // Edition of a program
447+
let owner: address = self.program_owner; // Address that deployed a program
458448
let signer: address = self.signer; // Address of tx signer (origin)
459449
460450
// Bit Serialization/Deserialization
461451
let bits: [bool; 58] = Serialize::to_bits(value); // Standard serialization (includes type metadata)
462452
let raw_bits: [bool; 32] = Serialize::to_bits_raw(value); // Raw serialization (no metadata, just raw bits)
453+
454+
// Miscellaneous
455+
assert(a); // assert the value of a is true
456+
assert_eq(a, b); // assert a and b are equal
457+
assert_neq(b, c); // assert b and c are not equal
458+
let ternary = boolean ? a : b; // Ternary expression
463459
```
464460

465461
### Cryptographic

documentation/language/operators/standard_operators.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ toc_max_heading_level: 3
4848
| [rem_wrapped](#rem_wrapped) | Wrapping remainder |
4949
| [self.address](#selfaddress)| Address of the current program |
5050
| [self.caller](#selfcaller) | Address of a transition's calling user/program |
51+
| [self.checksum](#selfcaller) | Checksum of a program |
52+
| [self.edition](#selfedition)| Version number of a program |
53+
| [self.program_owner](#selfprogram_owner) | Address that submitted a program's deployment transaction |
5154
| [self.signer](#selfsigner) | Address of the top-level transition's calling user |
5255
| [Serialize::to_bits](#serializeto_bits) | Serialize data to bits |
5356
| [shl](#shl) | Shift left |
@@ -1150,6 +1153,99 @@ The `self.caller` operator returns the address of the account/program that invok
11501153
[Back to Top](#table-of-contents)
11511154
***
11521155

1156+
### `self.checksum`
1157+
1158+
```leo
1159+
async transition matches(checksum: [u8,32]) -> Future {
1160+
return check_program_checksum(checksum);
1161+
}
1162+
1163+
async function check_program_checksum(checksum: [u8,32]) {
1164+
assert_eq(self.checksum, checksum);
1165+
}
1166+
```
1167+
1168+
1169+
The `self.checksum` operator returns a program's checksum, which is a unique identifier for the program's code.
1170+
1171+
You may also refer to another program's checksum with the following syntax:
1172+
```leo
1173+
import credits.aleo;
1174+
...
1175+
let ext_checksum: [u8, 32] = Program::checksum(credits.aleo);
1176+
```
1177+
1178+
:::info
1179+
* The `self.checksum` operator can only be used in an async function. Using it outside an async function will result in a compilation error.
1180+
* The `self.checksum` operator doesn't take any parameters.
1181+
* To reference another program's checksum, you will need to import that program first.
1182+
:::
1183+
1184+
[Back to Top](#table-of-contents)
1185+
***
1186+
1187+
1188+
### `self.edition`
1189+
1190+
```leo
1191+
async transition matches(edition: u16) -> Future {
1192+
return check_program_edition(edition);
1193+
}
1194+
1195+
async function check_program_edition(edition: u16) {
1196+
assert_eq(self.edition, edition);
1197+
}
1198+
```
1199+
1200+
1201+
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.
1202+
1203+
You may also refer to another program's edition with the following syntax:
1204+
```leo
1205+
import credits.aleo;
1206+
...
1207+
let ext_edition: u16 = Program::edition(credits.aleo);
1208+
```
1209+
1210+
:::info
1211+
* The `self.edition` operator can only be used in an async function. Using it outside an async function will result in a compilation error.
1212+
* The `self.edition` operator doesn't take any parameters.
1213+
* To reference another program's edition, you will need to import that program first.
1214+
:::
1215+
1216+
[Back to Top](#table-of-contents)
1217+
***
1218+
1219+
### `self.program_owner`
1220+
1221+
```leo
1222+
async transition matches(owner: address) -> Future {
1223+
return check_program_owner(owner);
1224+
}
1225+
1226+
async function check_program_owner(owner: address) {
1227+
assert_eq(self.program_owner, owner);
1228+
}
1229+
```
1230+
1231+
1232+
The `self.program_owner` operator returns the address that submitted the deployment transaction for a program.
1233+
You may also refer to another program's owner with the following syntax:
1234+
```leo
1235+
import credits.aleo;
1236+
...
1237+
let ext_owner: u16 = Program::owner(credits.aleo);
1238+
```
1239+
1240+
:::info
1241+
* 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.
1242+
* The `self.program_owner` operator doesn't take any parameters.
1243+
* To reference another program's owner, you will need to import that program first.
1244+
:::
1245+
1246+
[Back to Top](#table-of-contents)
1247+
***
1248+
11531249
### `self.signer`
11541250

11551251
```leo

documentation/language/programs_in_practice/functions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ function foo(
125125
}
126126
```
127127

128-
## Inline
128+
## Inline Function
129129

130130
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.
131131

documentation/language/programs_in_practice/limitations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ snarkVM imposes the following limits on Aleo programs:
2222

2323
Some other protocol-level limits to be aware of are:
2424
- **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.
25-
- **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.
25+
- **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.
2626

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

0 commit comments

Comments
 (0)