Skip to content
This repository was archived by the owner on May 4, 2026. It is now read-only.

Commit 33290ad

Browse files
authored
Merge pull request #569 from ProvableHQ/mohammadfawaz/3.5-updates
Some Leo 3.5 updates
2 parents 38e4620 + 2c957b7 commit 33290ad

5 files changed

Lines changed: 133 additions & 22 deletions

File tree

documentation/language/02_structure.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,15 @@ mapping account: address => u64;
135135
```
136136

137137
### Storage
138-
A storage variable is declared as `storage {name}: {type}`. Storage variables contain singleton values. They are declared at program scope and are stored on chain, similar to mappings.
138+
A storage variable is declared as `storage {name}: {type}`. Storage variables contain singleton values. They are declared at program scope and are stored on chain, similar to mappings.
139+
139140
```leo
140141
// On-chain storage of an `counter` storage variable of type u32,
141142
storage counter: u32;
142143
```
144+
143145
A storage vector is declared as `storage {name}: [{type}]`. Storage vectors contain dynamic lists of values of a given type. They are declared at program scope and are stored on chain, similar to mappings.
146+
144147
```leo
145148
// On-chain storage of an `accounts` storage vector of type address,
146149
storage accounts: [address];
@@ -176,4 +179,4 @@ record Token {
176179
// The token amount.
177180
amount: u64,
178181
}
179-
```
182+
```

documentation/language/03_data_types.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ program test.aleo {
126126
}
127127
```
128128

129+
Signature literals can be also be used. For example:
130+
131+
```leo
132+
let sig: signature = sign195m229jvzr0wmnshj6f8gwplhkrkhjumgjmad553r997u7pjfgpfz4j2w0c9lp53mcqqdsmut2g3a2zuvgst85w38hv273mwjec3sqjsv9w6uglcy58gjh7x3l55z68zsf24kx7a73ctp8x8klhuw7l2p4s3aq8um5jp304js7qcnwdqj56q5r5088tyvxsgektun0rnmvtsuxpe6sj
133+
```
134+
129135
## Composite Types
130136

131137
### Arrays
@@ -223,9 +229,9 @@ transition baz(foo: u8, bar: u8) -> u8 {
223229

224230
### Structs
225231

226-
Struct types are declared and constructed with a familiar syntax. Note that there is a global namespace for struct
227-
types across your program and its dependencies. If a dependency declares a struct type `T`, you may access that type
228-
without any qualifier.
232+
Struct types are declared and constructed with a familiar syntax.
233+
234+
Structs defined within a program can be referenced by their name. Structs defined in other programs must be referenced using the fully qualified form `program_name.aleo/StructName`.
229235

230236
```leo
231237
program test.aleo {
@@ -244,7 +250,17 @@ program test.aleo {
244250
}
245251
```
246252

247-
As of v3.0.0, Leo now supports **const generics** for struct types:
253+
Structs defined in external programs can be referenced and constructed using their fully qualified name:
254+
255+
```leo
256+
let s: external_program.aleo/S2 = external_program.aleo/S2 {
257+
x: 1field,
258+
y: 2u32,
259+
};
260+
```
261+
262+
Leo supports **const generics** for struct types:
263+
248264
```leo
249265
struct Matrix::[N: u32, M: u32] {
250266
data: [field; N * M],
@@ -253,7 +269,8 @@ struct Matrix::[N: u32, M: u32] {
253269
// Usage
254270
let m = Matrix::[2, 2] { data: [0, 1, 2, 3] };
255271
```
256-
Note that generic structs cannot currently be imported outside a program, but can be declared and used in submodules. Acceptable types for const generic parameters include integer types, `bool`, `scalar`, `group`, `field`, and `address`.
272+
273+
Acceptable types for const generic parameters include integer types, `bool`, `scalar`, `group`, `field`, and `address`. Const generic structs may be declared and used within a program and its submodules, but they cannot currently be imported from external programs.
257274

258275
### Records
259276

documentation/language/06_programs.md

Lines changed: 102 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,26 +75,33 @@ Mapping operations are only allowed in an [async function](#async-function) or a
7575

7676
## Storage Variables
7777

78-
Storage variables behave similar to option types. There are several functions available to query and modify singleton storage variables. The examples below will reference the following:
78+
Storage variables behave similar to option types. There are several functions available to query and modify singleton storage variables. The examples below will reference the following:
7979
```leo
8080
storage counter: u64;
8181
```
8282

8383
### Querying
84-
To query the value currrently stored at `counter`:
84+
To query the value currently stored at `counter`:
85+
8586
```leo
8687
counter.unwrap();
8788
```
89+
8890
Note that if `counter` has not been initialized, then the program will fail to execute. To query the value with a fallback for this case:
91+
8992
```leo
9093
counter.unwrap_or(fallback_value);
9194
```
95+
9296
### Modifying
9397
To set a value for `counter`:
98+
9499
```leo
95100
counter = 5u64;
96101
```
102+
97103
To unset the value at `counter`:
104+
98105
```leo
99106
counter = none;
100107
```
@@ -115,51 +122,105 @@ program storage_variable.aleo {
115122
116123
}
117124
```
125+
118126
:::info
119-
Storage variable operations are only allowed in an [async function](#async-function) or async block.
127+
Storage variable operations are only allowed in an [async function](#async-function) or `async` block.
120128
:::
121129

130+
### External Access
131+
132+
Storage variables defined in another program can be accessed using the fully qualified form `program_name.aleo/storage_name`. External storage variables are **read-only** and cannot be modified.
133+
134+
For example, suppose another program defines the following storage variable:
135+
136+
```leo
137+
program external_program.aleo {
138+
storage counter: u64;
139+
140+
...
141+
}
142+
```
143+
144+
You may query this value from your program using:
145+
146+
```leo
147+
let value: u64 = external_program.aleo/counter.unwrap();
148+
```
149+
150+
As with local storage variables, calling `unwrap()` will cause execution to fail if the storage variable has not been initialized. To safely query the value with a fallback:
151+
152+
```leo
153+
let value: u64 = external_program.aleo/counter.unwrap_or(0u64);
154+
```
155+
156+
External storage variables cannot be assigned to or unset. The following operations are invalid:
157+
158+
```leo
159+
external_program.aleo/counter = 5u64; // invalid
160+
external_program.aleo/counter = none; // invalid
161+
```
122162

123163
## Storage Vectors
124164

125-
Storage vectors behave like dynamic arrays of values of a given types. There are several functions available to query and modify storage vectors. The examples below will reference the following:
165+
Storage vectors behave like dynamic arrays of values of a given type. Several functions are available to query and modify storage vectors. The examples below reference the following declaration:
166+
126167
```leo
127168
storage id_numbers: [u64];
128169
```
129170

130171
### Querying
131-
To query the element currrently stored in `id_numbers` at index `idx`:
172+
173+
To query the element currently stored in `id_numbers` at index `idx`:
174+
132175
```leo
133176
id_numbers.get(idx);
134177
```
178+
179+
This returns `u64?`. If `idx` is out of bounds, the result is `none`.
180+
135181
To get the current length of `id_numbers`:
182+
136183
```leo
137184
id_numbers.len();
138185
```
186+
187+
This always returns a `u32` and cannot fail.
188+
139189
### Modifying
190+
140191
To set an element at index `idx` in `id_numbers`:
192+
141193
```leo
142194
id_numbers.set(idx, value);
143195
```
196+
144197
To push an element onto the end of `id_numbers`:
198+
145199
```leo
146200
id_numbers.push(value);
147201
```
202+
148203
To pop and return the last element of `id_numbers`:
204+
149205
```leo
150206
id_numbers.pop();
151207
```
208+
152209
To remove the element at index `idx`, return it, and replace it with the final element of `id_numbers`:
210+
153211
```leo
154212
id_numbers.swap_remove(idx);
155213
```
156-
To clear the every element in `id_numbers`:
214+
215+
To clear every element in `id_numbers`:
216+
157217
```leo
158-
id_numbers.clear()
218+
id_numbers.clear();
159219
```
220+
160221
:::note
161-
- `clear()` does not actually remove any values from the vector. It just sets the length to 0.
162-
- Similarly `swap_remove()` and `pop()` do not actually remove values either. They just reduce the length by 1 to make sure the last element is no longer accessible.
222+
- `clear()` does not actually remove any values from the vector. It simply sets the length to `0`.
223+
- Similarly, `swap_remove()` and `pop()` do not physically remove values. They reduce the length by `1`, ensuring the final element is no longer accessible.
163224
:::
164225

165226
### Usage
@@ -176,7 +237,6 @@ program storage_vector.aleo {
176237
id_numbers.push(new_id);
177238
}
178239
179-
180240
async transition remove_id(idx: u32) -> Future {
181241
return remove_id_onchain(idx);
182242
}
@@ -186,10 +246,39 @@ program storage_vector.aleo {
186246
}
187247
}
188248
```
249+
189250
:::info
190-
Storage vector operations are only allowed in an [async function](#async-function) or async block.
251+
Storage vector operations are only allowed in an [async function](#async-function) or `async` block.
191252
:::
192253

254+
### External Access
255+
256+
Storage vectors defined in another program can be accessed using the fully qualified form `program_name.aleo/storage_name`. External storage vectors are **read-only** and cannot be modified.
257+
258+
For example, suppose another program defines the following storage vector:
259+
260+
```leo
261+
program external_program.aleo {
262+
storage id_numbers: [u64];
263+
}
264+
```
265+
266+
You may query elements or the length of this vector from your program:
267+
268+
```leo
269+
let first: Option<u64> = external_program.aleo/id_numbers.get(0u32);
270+
let length: u32 = external_program.aleo/id_numbers.len();
271+
```
272+
273+
External storage vectors cannot be modified. The following operations are invalid:
274+
275+
```leo
276+
external_program.aleo/id_numbers.push(5u64); // invalid
277+
external_program.aleo/id_numbers.set(0u32, 5u64); // invalid
278+
external_program.aleo/id_numbers.pop(); // invalid
279+
external_program.aleo/id_numbers.swap_remove(0u32); // invalid
280+
external_program.aleo/id_numbers.clear(); // invalid
281+
```
193282

194283
## Functions
195284

@@ -381,9 +470,9 @@ snarkVM imposes the following limits on Aleo programs:
381470

382471
Some other protocol-level limits to be aware of are:
383472
- **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.
384-
- **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.
473+
- **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.
385474

386-
As with the above restructions. these limits can only be increased via the governance process.
475+
As with the above restrictions, these limits can only be increased via the governance process.
387476

388477
## Compiling Conditional On-Chain Code
389478
Consider the following Leo transition.

documentation/language/08_cheatsheet.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ let sender_address: address = msg.sender;
156156
let object_value: u64 = msg.object;
157157
```
158158

159+
An struct `ExternalStruct` defined in program `external_program.aleo` can be referred outside the program using the syntax `external_program.aleo/ExternalStruct`.
160+
159161
### Const Generics
160162
```leo
161163
struct Matrix::[N: u32, M: u32] {
@@ -482,4 +484,4 @@ let ecdsa_eth: bool = ECDSA::verify_keccak256_eth(sig, eth_addr, msg); // Verify
482484
483485
let ecdsa_digest: bool = ECDSA::verify_digest(sig, addr, digest); // Verify an ECDSA signature against an ECDSA public key and a prehashed message
484486
let ecdsa_digest_eth: bool = ECDSA::verify_digest_eth(sig, eth_addr, digest); Verify an ECDSA signature against an Ethereum address and a prehashed message
485-
```
487+
```

documentation/language/programs_in_practice/limitations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ 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.
2525
- **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

27-
As with the above restructions. these limits can only be increased via the governance process.
27+
As with the above restrictions, these limits can only be increased via the governance process.
2828

2929
## Compiling Conditional On-Chain Code
3030
Consider the following Leo transition.

0 commit comments

Comments
 (0)