Utilities
The following documentation provides reasoning and examples for functions and constants found in openzeppelin::utils
and openzeppelin::tests::utils
.
Expect this module to evolve (as it has already done). |
Core utilities
utils
use openzeppelin::utils;
Module containing core utilities of the library.
try_selector_with_fallback(target: ContractAddress, selector: felt252, fallback: felt252, args: Span<felt252>) → SyscallResult<Span<felt252>>
function
Tries to call a given selector on a given contract, and if it fails, tries to call a fallback selector.
It was designed for falling back to the camelCase
selector for backward compatibility in the
case of a failure of the snake_case
selector.
Returns a SyscallResult
with the result of the successful call.
Note that:
-
If the first call succeeds, the second call is not attempted.
-
If the first call fails with an error different than
ENTRYPOINT_NOT_FOUND
, the error is returned without falling back to the second selector. -
If the first call fails with
ENTRYPOINT_NOT_FOUND
, the second call is attempted, and if it fails its error is returned.
The fallback mechanism won’t work on live chains (mainnet or testnets) until they implement panic handling in their runtime. |
UnwrapAndCast
trait
Trait for exposing an unwrap_and_cast
function to SyscallResult
objects. This may be useful
when unwrapping a syscall result to a type implementing the Serde
trait, and you want to avoid the boilerplate of
casting and unwrapping the result multiple times.
Usage example:
use openzeppelin::utils::selectors;
use openzeppelin::utils::UnwrapAndCast;
fn call_and_cast_to_bool(target: ContractAddress, args: Span<felt252>) -> bool {
try_selector_with_fallback(
target, selectors::has_role, selectors::hasRole, args
).unwrap_and_cast()
}
fn call_and_cast_to_felt252(target: ContractAddress, args: Span<felt252>) -> felt252 {
try_selector_with_fallback(
target, selectors::get_role_admin, selectors::getRoleAdmin, args
).unwrap_and_cast()
}
Note that it can be automatically casted to any type implementing the Serde
trait.
cryptography
use openzeppelin::utils::cryptography;
Module containing utilities related to cryptography.
deployments
use openzeppelin::utils::deployments;
Module containing utility functions for calculating contract addresses through deploy_syscall and the Universal Deployer Contract (UDC).
DeployerInfo(caller_address: ContractAddress, udc_address: ContractAddress)
struct
Struct containing arguments necessary in utils::calculate_contract_address_from_udc for origin-dependent deployment calculations.
calculate_contract_address_from_deploy_syscall(salt: felt252, class_hash: ClassHash, constructor_calldata: Span<felt252>, deployer_address: ContractAddress) → ContractAddress
function
Returns the contract address when passing the given arguments to deploy_syscall.
compute_hash_on_elements(mut data: Span<felt252>) → felt252
function
Creates a Pedersen hash chain with the elements of data
and returns the finalized hash.
calculate_contract_address_from_udc(salt: felt252, class_hash: ClassHash, constructor_calldata: Span<felt252>, deployer_info: Option<DeployerInfo>) → ContractAddress
function
Returns the calculated contract address for UDC deployments.
Origin-independent deployments (deployed from zero) should pass Option::None
as deployer_info
.
Origin-dependent deployments hash salt
with caller_address
(member of DeployerInfo) and pass the hashed salt to the inner deploy_syscall as the contract_address_salt
argument.
selectors
use openzeppelin::utils::selectors;
Module containing constants matching multiple selectors used through the library. To see the full list of selectors, see selectors.cairo.
serde
use openzeppelin::utils::serde;
Module containing utilities related to serialization and deserialization of Cairo data structures.
SerializedAppend
trait
Importing this trait allows the ability to append a serialized representation of a Cairo data structure already
implementing the Serde
trait to a felt252
buffer.
Usage example:
use openzeppelin::utils::serde::SerializedAppend;
use starknet::ContractAddress;
fn to_calldata(recipient: ContractAddress, amount: u256) -> Array<felt252> {
let mut calldata = array![];
calldata.append_serde(recipient);
calldata.append_serde(amount);
calldata
}
Note that the append_serde
method is automatically available for arrays of felts, and it accepts any data structure
that implements the Serde
trait.
Cryptography
NoncesComponent
use openzeppelin::utils::cryptography::nonces::NoncesComponent;
Simple component for managing nonces.
nonces(self: @ContractState, owner: ContractAddress) → felt252
external
Returns the next unused nonce for an owner
.
use_nonce(ref self: ComponentState, owner: ContractAddress) → felt252
internal
Consumes a nonce, returns the current value, and increments nonce.
For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be decremented or reset. This guarantees that the nonce never overflows.
snip12
use openzeppelin::utils::snip12;
Supports on-chain generation of message hashes compliant with SNIP12.
For a full walkthrough on how to use this module, see the SNIP12 and Typed Messages guide. |
Test utilities
utils
use openzeppelin::tests::utils;
Module containing utilities for testing the library.
deploy(contract_class_hash: felt252, calldata: Array<felt252>) → ContractAddress
function
Uses the deploy_syscall
to deploy an instance of the contract given the class hash and the calldata.
The contract_address_salt
is always set to zero, and deploy_from_zero
is set to false.
Usage example:
use openzeppelin::presets::AccountUpgradeable;
use openzeppelin::tests::utils;
use starknet::ContractAddress;
const PUBKEY: felt252 = 'PUBKEY';
fn deploy_test_contract() -> ContractAddress {
let calldata = array![PUBKEY];
utils::deploy(AccountUpgradeable::TEST_CLASS_HASH, calldata)
}
deploy_with_salt(contract_class_hash: felt252, calldata: Array<felt252>, salt: felt252) → ContractAddress
function
Same as utils::deploy except this function accepts a salt
argument.
This utility is useful when tests require multiple deployed instances of the same contract.
pop_log<T>(address: ContractAddress) → Option<T>
function
Pops the earliest unpopped logged event for the contract as the requested type and checks that there’s no more keys or data left on the event, preventing unaccounted params.
Required traits for T
:
-
Drop
-
starknet::Event
Requirements:
-
No extra data or keys are left on the raw event after deserialization.
Usage example:
use openzeppelin::tests::utils;
use openzeppelin::token::erc20::ERC20Component;
use openzeppelin::token::erc20::ERC20Component::Transfer;
use starknet::ContractAddress;
fn assert_emitted_event(
target: ContractAddress, from: ContractAddress, to: ContractAddress, value: u256
) {
let event = utils::pop_log::<ERC20Component::Event>(target).unwrap();
let expected = ERC20Component::Event::Transfer(Transfer { from, to, value });
assert!(event == expected);
}
assert_indexed_keys<T>(event: T, expected_keys: Span<felt252>)
function
Asserts that expected_keys
exactly matches the indexed keys from event
.
expected_keys
must include all indexed event keys for event
in the order
that they’re defined.
If the event is not flattened, the first key will be the event member name
e.g. selector!("EnumMemberName") .
|
Required traits for T
:
-
Drop
-
starknet::Event
assert_no_events_left(address: ContractAddress)
function
Asserts that there are no more events left in the queue for the given address.