Official link
14.type conversion
Cairo provides a safe type conversion mechanism using the Into and TryInto traits to convert between integer types (u8, u16, etc.) and felt252. You first need to import these traits:
use traits::Into;
use traits::TryInto;
use option::OptionTrait;
The Into trait provides the into() method for performing type conversions with guaranteed success. Conversions from smaller to larger types are guaranteed to succeed, e.g. u8 -> u16 -> u32 -> u64 -> u128 -> felt252. When using into(), the type of the new variable must be specified.
The TryInto trait provides the try_into() method for safe type conversion when the target type may not hold the source value. This usually happens when converting from larger to smaller types: u8 <- u16 <- u32 <- u64 <- u128 <- felt252. The try_into() method returns an Option type, and you need to call the unwrap() method to get the new value. Similar to into(), when using try_into(), the type of the new variable must be explicitly stated.
15.constructor
Similar to Solidity, the constructor in Cairo is a special function that automatically runs once during contract deployment. It is usually used to initialize the parameters of the contract, such as setting the owner address.
###rule
The constructor function must be marked with the #[constructor] attribute.
Each contract can have at most one constructor
#[starknet::contract]
mod owner{
use starknet::ContractAddress;
use starknet::get_caller_address;
#[storage]
struct Storage{
owner: ContractAddress,
}
#[constructor]
fn constructor(ref self: ContractState) {
self.owner.write(get_caller_address());
}
}
16.events
Similar to Solidity, events in Cairo are transaction logs stored on Starknet. Events are released when the function is called and can be accessed by external off-chain applications.
The event has the following characteristics:
Storing data in events is more cost-effective than storing it in stored variables.
Events cannot be read directly from within the contract.
Applications such as starknet.js can subscribe to these events via the RPC interface and trigger responses on the frontend.
To better illustrate events in Cairo, we extend the Owner contract example from the previous chapter. Specifically, we added a ChangeOwner event that is released every time the owner is changed.
In Cairo, events are enumerated via events. You need to use the #[event] and #[derive(Drop, starknet::Event)] attributes. Each event variant member must be a structure with the same name as the variant. Then, you need to define the event structure, which also needs to use the #[derive(Drop, starknet::Event)] attribute, and add the parameters you want to log as members. In the following example, we define a ChangeOwner event that takes two parameters: the address of the old owner and the new owner.
To release an event, you need to use the self.emit() method and pass the data to be logged as a parameter. In the following example, the ChangeOwner event is released after the owner changes in the change_owner() function.
Released events can be read using the Starknet.js library, a JavaScript library for Starknet similar to Ethereum's Ethers.js.
17.Exception handling
In Cairo, the assert() function is the recommended exception handling method. Its function is similar to the require() function in Solidity, accepting two parameters:
condition: condition, expected to be true when the program is running.
error message: exception message (short string type) displayed when condition is false.
assert() will verify at runtime whether the given condition is true, if not, it will throw an exception message.
In the following example, if input is not equal to 0, the program will be interrupted with the exception message 'Error: Input not 0!'.
#[external(v0)]
fn assert_example(self: @ContractState, input: u128){
assert( input == 0_u128, 'Error: Input not 0!');
}
The panic() function is another exception handling method provided by Cairo. Unlike assert(), panic() abruptly terminates the program without verifying any conditions. It accepts a felt252 array as parameter (exception message).
We can rewrite the assert_example() function and use panic() to throw an exception.
In addition, Cairo also provides a panic_with_felt252() function. The only difference between panic_with_felt252() and panic is that panic_with_felt252() accepts felt252 as a parameter, not an array.
Let's modify assert_example() to throw an exception using panic_with_felt252().
#[external(v0)]
fn panic_with_felt252_example(self: @ContractState, input: u128){
if input == 0_u128 {
panic_with_felt252('Error: Input not 0!');
}
Continually updated…

