Public State
Mappings
There are several functions available to query and modify mappings. The examples below will reference the following mapping:
mapping balance: address => u64;
Querying
To simply check if a value has been set for a particular address in balance:
balance.contains(addr)
Mapping::contains(balance, addr); // Alternate syntax
To query a value for a particular address in balance:
balance.get(addr)
Mapping::get(balance, addr); // Alternate syntax
Note that if value at addr does not exist above, then the program will fail to execute. To query a value with a fallback for this case:
balance.get_or_use(addr,fallback_value)
Mapping::get_or_use(balance, addr, fallback_value); // Alternate syntax
A program can also query values from another program's mappings:
let balance1 = credits.aleo::account.get(addr);
let balance2 = credits.aleo::account.get_or_use(addr, 0u64);
Although values can be queried, a program cannot directly modify another program's mappings.
Modifying
To set a value for a particular address in balance:
balance.set(addr,value)
Mapping::set(balance, addr, value); // Alternate syntax
To remove the value set at particular address in balance:
balance.remove(addr)
Mapping::remove(balance, addr); // Alternate syntax
Usage
program map.aleo {
mapping balance: address => u64;
fn dubble() -> Final {
let addr: address = self.caller;
return final {
let current_value: u64 = balance.get_or_use(addr, 0u64);
balance.set(addr, current_value + 1u64);
let next_current_value: u64 = balance.get(addr);
balance.set(addr, next_current_value + 1u64);
};
}
}
Mapping operations are only allowed inside a final { } block or inside a final fn.
Storage Variables
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:
storage counter: u64;
Querying
To query the value currently stored at counter:
counter.unwrap();
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:
counter.unwrap_or(fallback_value);
Modifying
To set a value for counter:
counter = 5u64;
To unset the value at counter:
counter = none;
Usage
program storage_variable.aleo {
storage counter: u64;
fn increment() -> Final {
return final {
let current_value: u64 = counter.unwrap_or(0u64);
counter = current_value + 1u64;
};
}
}
Storage variable operations are only allowed inside a final { } block or inside a final fn.
External Access
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.
For example, suppose another program defines the following storage variable:
program external_program.aleo {
storage counter: u64;
...
}
You may query this value from your program using:
let value: u64 = external_program.aleo::counter.unwrap();
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:
let value: u64 = external_program.aleo::counter.unwrap_or(0u64);
External storage variables cannot be assigned to or unset. The following operations are invalid:
external_program.aleo::counter = 5u64; // invalid
external_program.aleo::counter = none; // invalid
Storage Vectors
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:
storage id_numbers: [u64];
Querying
To query the element currently stored in id_numbers at index idx:
id_numbers.get(idx);
This returns u64?. If idx is out of bounds, the result is none.
To get the current length of id_numbers:
id_numbers.len();
This always returns a u32 and cannot fail.
Modifying
To set an element at index idx in id_numbers:
id_numbers.set(idx, value);
To push an element onto the end of id_numbers:
id_numbers.push(value);
To pop and return the last element of id_numbers:
id_numbers.pop();
To remove the element at index idx, return it, and replace it with the final element of id_numbers:
id_numbers.swap_remove(idx);
To clear every element in id_numbers:
id_numbers.clear();
clear()does not actually remove any values from the vector. It simply sets the length to0.- Similarly,
swap_remove()andpop()do not physically remove values. They reduce the length by1, ensuring the final element is no longer accessible. :::
Usage
program storage_vector.aleo {
storage id_numbers: [u64];
fn add_id(new_id: u64) -> Final {
return final {
id_numbers.push(new_id);
};
}
fn remove_id(idx: u32) -> Final {
return final {
id_numbers.swap_remove(idx);
};
}
}
Storage vector operations are only allowed inside a final { } block or inside a final fn.
:::
External Access
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.
For example, suppose another program defines the following storage vector:
program external_program.aleo {
storage id_numbers: [u64];
}
You may query elements or the length of this vector from your program:
let first: u64? = external_program.aleo::id_numbers.get(0u32);
let length: u32 = external_program.aleo::id_numbers.len();
External storage vectors cannot be modified. The following operations are invalid:
external_program.aleo::id_numbers.push(5u64); // invalid
external_program.aleo::id_numbers.set(0u32, 5u64); // invalid
external_program.aleo::id_numbers.pop(); // invalid
external_program.aleo::id_numbers.swap_remove(0u32); // invalid
external_program.aleo::id_numbers.clear(); // invalid