Journey through Cairo II — Mastering Cairo’s Syntaxes with Starklings

Darlington Nnam
Coinmonks
8 min readSep 3, 2022

--

Let’s journey through Cairo

In our last article found here, we went through setting up a local development environment for Cairo with Protostar, ArgentX and Voyager, today we’d be starting our journey to understanding the basic fundamentals of Cairo.

If you are just joining mid-flight welcome! In these series of blog posts titled “Journey through Cairo”, we’d be coursing through the world of Cairo, from the very basic fundamentals. I’d also suggest, you go back to check out our previous article, as we’d mostly continue from our last checkpoint!

While trying to come up with a good way to explain the fundamentals of how Cairo functions under the hood, i experimented with a few methods, and finally settled with Starklings.

Starklings by OnlyDust

Learning Cairo from the official docs, is a little quite complex for an average person. Whilst starting out, i struggled so much with understanding these fundamentals, until i came across Starklings.

Starklings is an interactive tutorial put together by the team at OnlyDust, that models the brilliant concept of progressive and interactive tutorial from the popular Rustlings for learning Rust. Today we’d get started on How Cairo works by solving the challenges from Starklings.

Setting Up

To effectively follow up with this tutorial, you’d need to setup your environment in advance. To do this:

  1. Visit the official Starklings Github repo here.
  2. Clone the repo to your local computer by running the git clone command.
git clone --branch stable --single-branch https://github.com/onlydustxyz/starklings.git

3. Install the necessary tools by running the following command:

curl -L https://raw.githubusercontent.com/onlydustxyz/starklings/master/install.sh | bash

4. navigate into the repo and open it in your code editor. You should have something similar to this:

NB: We are going to only be playing around with the contents of the exercises folder. It’s advisable you don’t touch any other files or folder.

5. To get started with the exercises, in your terminal, run:

starklings --watch
Voila! we’ve got our environment ready

Commands and Resources

Now we’ve got our development environment ready, before we dive into writing some Cairo, here are some necessary commands and resources that could help make our journey easier!

  1. To manually verify an exercise without the watch mode, run:
starklings --verify relative_path_to_the_exercise_file

2. If you get hooked up, to display the solution to a given exercise, run:

starklings --solution relative_path_to_the_exercise_file

3. Looking to play around, and try out new things? check out Cairo’s playground similar to remix for Solidity here.

P.S You could find all my starklings solutions for this particular article, here.

UNDERSTANDING CAIRO’S SYNTAXES

  1. syntax01.cairo — starting a Cairo contract

Getting started with Cairo, one of the first few things that confused me, was differentiating between Cairo programs and Cairo contracts. I wouldn’t want you to have confusions over that too, so here are quick definitions of the two:

Cairo programs: Cairo programs can be said to be a type of stateless contracts, meaning that, while writing programs, you do not have access to storage and cannot interact with other Cairo programs or even the L1 chain.

Cairo contracts: These in very simple words are programs that runs on the Starknet VM. Since they run on the VM, they have access to Starknet’s persistent state, can alter or modify variables in Starknet’s states, communicate with other contracts, and interact seamlessly with the underlying L1.

Having cleared that, to get started writing a Cairo contract, you must specify it’s a contract, by writing this at the topmost line:

%lang starknet

Now let’s do that in our Starklings, Syntax01.cairo, and check if it passes.

And yaah! it does.

Now we’d move unto the next challenge. Also remember to remove the #I AM NOT DONE, so Starklings understands that you’ve completed the challenge and moves over to the next!

2. syntax02.cairo — Modularity with Cairo

As with almost all programming language that exists, its quite bad practice, to keep all your program codes in a single file. You might also have needs to use other people’s codes rather than re-inventing the wheel, so every language tries to encourage code modularity, and Cairo is no different.

In this challenge, we are expected to study the test_ok function, and import every needed file to make the function work.

In Cairo, importing a file looks something like this:

from starkware.starknet.common.syscalls import get_contract_address

When you do this, Cairo searches for the file syscall.cairo, in the current directory and the standard library directory relative to the compiler path, and imports the get_contract_address function from it.

Our function test_ok takes three implicit arguments: syscall_ptr, pedersen_ptr, and range_check_ptr (we’d cover implicit arguments in further articles), but we could notice that the pedersen_ptr which allows us to compute the Pedersen hash function, needs a HashBuiltin* which does not exist in our current file, so we’d need to import it from Cairo libraries. To do this, we’d add the following line to our code:

from starkware.cairo.common.cairo_builtins import HashBuiltin

Now let’s check if we passed the challenge.

yaahhh! we did.

PS: If your starklings — watch still refers back to syntax01.cairo, ensure to crosscheck that you removed the #I AM NOT DONE from syntax01.cairo.

3. syntax03.cairo — Function arguments

Functions are reusable units of codes, that take certain arguments, and returns a value.

In Cairo, you could pass different arguments into a function and get a return value. Our exercise here, demands that we pass the right arguments to the function that makes the test pass!

Similar to a strongly typed language like Typescript, you need to specify the data type of your arguments. We’d need to edit our function to look like this:

func takes_two_arguments_and_returns_one(a: felt, b: felt) -> (c: felt):return (a + b)  # Do not changeend

As you can see, we passed a strange data type felt to the a,b,c arguments…yeah that’s correct. Unlike Solidity which has numerous data types like uint256, strings etc, Cairo uses a data type known as felt.(we’d dive deeper into this in further articles).

From our function signature, you’d notice we passed in a certain c argument which is not being used by the function. This argument is the return value of the function. Your return values should be specified using the ->

Now edit, your syntax03.cairo passing in the various arguments we did over here, and let’s check if we pass the challenge.

yahhh! we did.

4. syntax04.cairo — namespaces in Cairo

Cairo namespaces are a very powerful way of using modules in your contracts. It allows you scope function identifiers under an identifier, helping to prevent collisions, when importing from multiple modules. It also goes a long way in helping code readability.

to implement a namespace in cairo, we’d use the namespace keyword, and then specify a name for our namespace like this:

namespace starklings
func starkling_exercise(a: felt, b:felt) -> (c: felt):
return (a+b)
end
end

And to use functions from our namespace in a file we’d do something like:

starklings.starkling_exercise(3, 5)

This exercise implements a namespace, and we are required to make the test pass by editing the test to call the returns_something function inside the namespace my_namespace.

To do this, we are going to implement what we just learnt. Edit your test function to instead of just call returns_something(), rather call my_namespace.returns_something().

Now let’s check to see if we passed the challenge.

Yeap! we do.

5. syntax05.cairo — structs in Cairo

The concept of struct in Cairo is very similar to what we know from Solidity.

we start by defining it with the struct keyword, and then specifying its attributes with the member keyword. But unlike solidity, a struct in Cairo, also has a size attribute, which is the sum of the sizes of its members.

A struct in Cairo, generally looks like this:

struct Starklings:
member first: felt
member second: felt
end

In this exercise, we are expected to implement a Currency struct, that makes the test pass.

To pass this exercise, we need to examine the test, to find out the members of the struct. Here’s line 13 of the exercise that calls the struct:

local euro : Currency = Currency('Euro', 2)

From here, we’d notice that our struct has 2 members, probably a name and an ID. But notice the assert function in line 14:

assert euro.name = 'Euro'

the assert function calls a name, assumed to be a member in our struct. This line indirectly tells us that our struct must contain a member called name, else if it doesn’t, we’d run into an error like this:

To pass this challenge, then our struct must look like this:

struct Currency:   member name: felt   member id: feltend

Now let’s check if we passed our challenge.

yeap we did!

Conclusion

If you got through to this point, i’d assume you now have a very good understanding of the basic syntaxes in Cairo, from function arguments, to namespaces, structs etc.

Remember if you ever got stuck with anything, i have the solutions to these exercises in my repo here.

In our next article, we’d go through the strings exercises, and also use that opportunity to dive deeper into what felts are.

If you got value from this article, do well to share with others.

You could also connect with me on the following socials, especially on Twitter, where i share my little findings on Cairo!

Twitter: https://twitter.com/0xdarlington

LinkedIn: https://www.linkedin.com/in/nnamdarlington

Github: https://github.com/Darlington02

New to trading? Try crypto trading bots or copy trading

--

--