# Week 17 at BlockFuse Labs: My Journey into Cairo Programming This week marked my first deep dive into Cairo, the programming language designed for StarkNet's Layer 2 scaling solution. Coming from a Rust background, I found several fascinating parallels between the two languages while also discovering Cairo's unique approach to blockchain development. ## Chapter 1: Introduction to Cairo Cairo is a programming language designed specifically for creating provable programs that run on a virtual CPU. It's the backbone of StarkNet's Layer 2 solution that aims to scale Ethereum through the use of STARKs (Scalable Transparent ARguments of Knowledge). The first program I saw in Cairo book looked something like this: ```cairo #[starknet::contract] mod HelloWorld { #[storage] struct Storage {} #[external(v0)] fn say_hello(self: @ContractState) -> felt252 { 'Hello, StarkNet!' } } ``` The syntax immediately felt familiar as a Rust developer - the module system, the struct keyword, and the function declaration style all echo Rust's approach. However, I quickly noticed differences, particularly Cairo's use of the `felt252` type, which stands for "Field Element" and is fundamental to Cairo's mathematical operations. ## Chapter 2: Variables and Data Types Cairo's type system has some similarities to Rust but with important distinctions due to its focus on zero-knowledge proofs. ```cairo fn data_types_example() { // Integer types let a: felt252 = 5; // Field element - Cairo's native type let b: u8 = 255; // Unsigned 8-bit integer let c: u32 = 100000; // Unsigned 32-bit integer // Boolean let is_valid: bool = true; // Short string (stored as felt252) let greeting = 'hello'; // Arrays let mut arr = array![1, 2, 3, 4, 5]; // Tuples let point: (u32, u32) = (10, 20); } ``` Like Rust, Cairo emphasizes memory safety and immutability by default, with the `mut` keyword needed for mutable variables. The biggest difference is Cairo's reliance on the `felt252` type, which is a field element that can hold integers up to 252 bits. I found the transition from Rust's types to Cairo's relatively straightforward since both languages have strong, static typing. However, I had to adjust to the fact that Cairo doesn't have signed integers or floating-point numbers due to its mathematical constraints. ## Chapter 3: Control Flow Control flow in Cairo feels very comfortable for someone coming from Rust: ```cairo fn control_flow_example(x: u32) -> u32 { // If-else statements if x > 10 { return x * 2; } else { return x + 5; } } fn loop_example() { // Loop with break let mut counter = 0; loop { counter += 1; if counter >= 10 { break; } } // Match statement (similar to Rust) let value = 2; match value { 0 => { 'zero' }, 1 => { 'one' }, 2 => { 'two' }, _ => { 'many' }, }; } ``` Cairo's approach to loops and conditional statements strongly resembles Rust's syntax, making it easy to adapt. The pattern matching with `match` statements is particularly familiar and powerful, just like in Rust. One key difference I noticed is that Cairo's compiler is stricter about exhaustiveness checks and flow control due to the constraints of provable computation. ## Chapter 4: Functions and Traits Cairo's function syntax and trait system echo Rust's approach to modularity and code organization: ```cairo // Function definition fn add(a: felt252, b: felt252) -> felt252 { a + b } // Trait (similar to Rust traits) trait Printable { fn print(self: Self); } // Implementation for a type impl PrintableForU32 of Printable<u32> { fn print(self: u32) { // In a real scenario, this would print the u32 value } } // Generic function using trait bounds fn print_twice<T, impl TPrintable: Printable<T>>(value: T) { value.print(); value.print(); } ``` The trait system in Cairo works similarly to Rust's, allowing for polymorphism and code reuse. This made it easy for me to organize my code using familiar patterns from my Rust experience. ## Practicing with Starklings Starklings is an interactive tutorial for Cairo, similar to Rustlings for Rust. Working through these exercises helped solidify my understanding of the concepts: ### Starklings Exercises Highlights: 1. **Variables**: The first exercises had me declare and manipulate variables, which felt very similar to Rust with the familiar `let` keyword and type annotations. 2. **Functions**: I practiced writing and calling functions, passing arguments, and returning values. The syntax was comfortingly familiar. 3. **If Statements and Loops**: The control flow exercises reinforced how similar Cairo's syntax is to Rust's in this area. 4. **Arrays and Data Structures**: Working with arrays in Cairo required some adjustment as Cairo's memory model differs from Rust's, but the array syntax itself felt familiar. ## Rust vs. Cairo: Similarities and Differences Coming from Rust, I found several aspects of Cairo quite familiar: **Similarities:** - Strong static typing system - Expression-based syntax - Pattern matching with `match` - Module system for code organization - `impl` for implementing behavior - Trait-based polymorphism - Default immutability with `mut` for mutable variables - Ownership concepts (though implemented differently) **Key Differences:** - Cairo's focus on provable computation - The `felt252` type as Cairo's native numeric type - No signed integers or floating points in Cairo - Cairo's memory model is based on a virtual CPU - Different approach to ownership and borrowing due to Cairo's unique computational model - Cairo's storage model for contract state ## Conclusion My first week with Cairo has been a fascinating journey. As someone comfortable with Rust, I found many familiar patterns that helped me get up to speed quickly. The similarities in syntax and approach to types and traits made the learning curve less steep than it might have been otherwise. I'm looking forward to diving deeper into Cairo in the coming weeks, particularly exploring contract development, interactions, and more advanced StarkNet features. The foundation laid by my Rust experience has proven invaluable in this new learning journey at BlockFuse Labs.