Cointime

Download App
iOS & Android

CertiK Report: An Introduction to the Cairo Programming Language

Validated Project

The landscape of Ethereum Layer 2 scaling solution is rapidly evolving. Broadly speaking, Layer 2 solutions include two main types: optimistic rollups and ZK (Zero Knowledge) rollups.

Within ZK rollups, the two primary ZK proof systems are ZK-SNARK (which stands for Zero-Knowledge Succinct Non-Interactive Argument of Knowledge) and ZK-STARK (Zero-Knowledge Scalable Transparent Argument of Knowledge).

StarkNet is a general purpose ZK-Rollup built using the STARK proof system. It uses the Cairo programming language for both its infrastructure and its smart contracts.

In this article, we provide an overview of the Cairo language, including some of its unique features. Note that Cairo is a relatively new language and is rapidly evolving. This article is based on the current version of Cairo (0.10.0) and its features might change in the future.

Starknet Architecture

It is helpful to have a general understanding of the architecture of Starknet before diving into the Cairo language. Exhibit 1 shows the main components of Starknet, its relationship with Ethereum, and a general transaction sequence. In this section we focus on the Sequencer, Prover, and Verifier which are indispensable in understanding how Starknet works.

 Exhibit 1: Starknet Architecture

The Sequencer is responsible for ordering, validating and bundling transactions into blocks. Currently, the sequencer is run by Starkware in a centralized manner, but the company plans to decentralize the sequencer in the future.

The Prover and the Verifier work closely together. The Prover generates a cryptographic proof on the validity of the execution trace from the Sequencer. Currently, this job is performed by a single prover, the “Shared Prover" or “SHARP”. The Verifier is a smart contract on Ethereum L1 that verifies the proof generated by the Starknet Prover, and if successful, updates the state on Ethereum L1 for record keeping.

As such, other users can then query the state of the Starknet Core smart contract on Ethereum L1 and verify that a certain transaction on Starknet has been executed successfully. It is worth noting that certain Cairo instructions can only be seen by the Prover, and not the Verifier. These are called “hint” – which is a piece of Python code embedded in a Cairo program.

Such asymmetry between the Prover and the Verifier enables some zero-knowledge applications. For example, a user can prove that he has the solution to a cryptographic problem, without disclosing the solution from the perspective of the Verifier on the Ethereum base layer.

Cairo Overview

In this section, we provide an overview of the Cairo language, including its building blocks such as its data types and memory model, as well as some unique features such as builtins, implicit arguments, hint, and embedded test functions.

Cairo Programs and Cairo Contracts

In Starknet, there is a clear distinction between Cairo programs and Cairo contracts. Cairo programs are stateless. As an example, a Cairo program can perform a hash operation on a given input, and prove that the output matches a specific target output. This does not require any state variable to persist on Starknet.

On the other hand, Cairo contracts are stateful. With Cairo contracts, state variables persist on the blockchain, enabling applications such as ERC20 tokens, automated market makers, etc. on the Starknet L2.

Data Types

The primitive data type in Cairo is “felt”, which stands for “field element”. The felt is an integer in the range −P/2 < x<P/2 where P is a very large prime number (currently a 252-bit number). Cairo does not have built-in overflow protection on arithmetic operations using “felt”. When there is an overflow, and the appropriate multiple of P is added or subtracted to bring the result back into this range, or effectively modulo P. Using felt as a building block, Cairo supports other data types including tuples, structs, and arrays. As a low level programming language, Cairo also uses pointers extensively. The brackets [x] are used to return the value in memory location x, whereas the ampersand sign &x is used to return the memory address of variable x. In the example shown in Exhibit 2, an array is declared with memory allocation, and the pointer returned is used along with offsets to indicate the memory location of different elements in the array.

 Exhibit 2: Arrays in Cairo

More complex data types such as hashmaps can be implemented as a function with the storage_var decorator, which allows read and write operations.

 Exhibit 3: Hashmap in Cairo

Memory Model

Cairo has read-only non-deterministic memory, which means that the value in each memory cell can only be written once, and cannot change afterwards during a Cairo program execution. As such, depending on whether a value has been written to a memory location, the instruction that asserts [x] == 7 can mean either:

  1. Read the value from the memory location x and verify the value is 7, or
  2. Write the value 7 to memory cell x, if memory cell x hasn’t been written to yet

There are three “registers" used in Cairo for low level memory access, namely “ap”, “fp”, and “pc”:

  • ap: the allocation pointer, to show where unused memory starts
  • fp: the frame pointer that points to the current function
  • pc: the program counter that points to the current instruction

Using the definition above, an expression such as [ap] = [ap-1] * [fp] would take the value in the previous allocation pointer, multiply it by the value in the frame pointer, and write the result to the memory location of the current allocation pointer.

Cairo commonly uses recursion instead of for loops, due to its read-only memory feature. As an example, the function shown in Exhibit 4 uses recursion to calculate the n’th fibonacci number:

 Exhibit 4: A Recursive Fibonacci Function

Built-Ins and Implicit Arguments

Similar to precompiled contracts in EVM, Cairo contains builtins which are optimized low-level execution units that perform predefined computations, such as hash functions, syscalls, and range-checks. Any function that uses the builtin is required to get the pointer to the builtin as an argument and return an updated pointer to the next unused instance. Since this pattern is so common, Cairo has created a syntactic sugar for it, called “Implicit arguments”. As shown in Exhibit 5 below, the curly braces declare hash_ptr0 as an “implicit argument”, allowing the function to call the predefined hash2() function. This automatically adds an argument and a return value to the function, so the programmer does not have to manually add them for every function that utilizes low-level execution units.

 Exhibit 5: Built-Ins and Implicit Arguments

Hint

“Hint” is a unique feature in the Cairo language. A hint is a block of Python code that is executed by the Starknet Prover right before the next instruction. The hint can interact with a Cairo program’s variables / memory, allowing the programmer to utilize Python’s extensive functionalities in a Cairo program. In order to use this feature, the Python code needs to be surrounded by %{ and %}, as shown in Exhibit 6 below. Note that the Starknet Verifier does not see “hints” at all in a Cairo program execution, which allows a user to generate a proof without providing any secret information to the Verifier on the Ethereum base layer. Additionally, “hints” should not be used in Cairo contracts (only use in Cairo programs), unless the contract is whitelisted by Starknet.

 Exhibit 6: Hint in Cairo

Test Functions

External functions with names that begin with test_ are interpreted as unit tests in Cairo. This allows programmers to integrate unit tests in Cairo directly, without having to write separate test files. As an example, Exhibit 7 shows a test function that verifies the result of a simple arithmetic operation.

 Exhibit 7: Test Functions in Cairo

Writing Smart Contracts in Cairo

Writing smart contracts in Cairo requires familiarity with some of its basic design patterns. This section introduces a few common (non-exhaustive) patterns, and compares them with Solidity where applicable.

Library Import Instead of Contract Inheritance

The Cairo language does not support inheritance like Solidity does. In order to use the logic or storage variable from another Cairo contract, the programmer needs to import the other contract (often called a “library”), and use the contract’s namespace followed by the relevant function or state variables instead. The libraries define reusable logic and storage variables which can then be exposed by contracts. As an example, the ERC20 library in Exhibit 8 contains implementation of the transfer function but cannot be called directly (functions without any decorator are by default internal), and the ERC20 contract in Exhibit 9 exposes the transfer function by using the “ERC20” namespace followed by the function name, along with the external decorator.

 Exhibit 9: transfer() Function in ERC20 Contract

Access Control

The Cairo language does not support modifiers like Solidity does. In order to implement access control on privileged functions, the programmer needs to extract the caller (equivalent to the msg.sender in Solidity) of a contract via the built-in get_caller_address() function, and check if the caller has the necessary privilege. An example is the ownership check in the Ownable library, shown in Exhibit 10 below.

 Exhibit 10: Access Control in Cairo

Upgradeable Contracts

Upgradeable contract is possible in Cairo, and it utilizes a proxy contract and an implementation contract, similar to the proxy pattern in Solidity. In Cairo, the proxy contract contains a __default__ function, as shown in Exhibit 11 below, similar to the fallback() function in Solidity. The implementation contract should import the “proxy” namespace and initialize the proxy, and include a mechanism for contract upgrade with proper access control, similar to the UUPS proxy pattern in Solidity. To deploy an upgradeable contract, one first needs to declare an implementation contract class and calculate its class hash. Then, the proxy contract can be deployed with the implementation contract’s class hash, and with inputs describing the call to initialize the proxy contract.

 Exhibit 11: Proxy Contract default Function

Cairo Roadmap

The Cairo language is under active development. A major upgrade of the Cairo language (Cairo 1.0) is scheduled for early 2023, and Starkware has very recently open-sourced the first version of Cairo 1.0 compiler.

Cairo 1.0 introduces “Sierra”, a Safe Intermediate Representation between Cairo 1.0 and Cairo bytecode that proves every Cairo run. Additionally, Cairo 1.0 will contain simplified syntax and easier to use language constructs. For example, “for” loops will be possible in Cairo, and there will be support for boolean expressions. Native uint256 data type will be introduced, along with regular integer division, and overflow protection for relevant types.

Cairo 1.0 will also include improved type safety guarantee, and more intuitive libraries such as dictionaries and arrays. There are indeed many exciting features to look forward to in Cairo 1.0 that aim to alleviate some developer pain points of the current version.

Conclusion

We hope this article has provided a useful introduction to the Cairo language and some of its unique features. Each programming language potentially introduces new security vulnerabilities. In future articles, we plan to explore the security aspects of the Cairo programming language, and provide our recommendations on how to write secure code in Cairo.

Comments

All Comments

Recommended for you

  • A Total of 37,212.18 DMD Permanently Burned Over the Past 7 Days

    July 9, 2026 — According to the latest on-chain data released by DMDAO, a total of 37,212.18 DMD has been permanently burned over the past seven calendar days through the protocol's predefined trading and wealth management burn mechanisms.

  • Whale Transfers 1,133 BTC to Coinbase Prime, Valued at $71.48 Million

    According to Onchain Lens monitoring, a whale transferred 1,133 BTC from Coinbase to Coinbase Prime through an intermediary wallet, valued at $71.48 million.

  • U.S. AI Chip Stocks Decline Before Market Open, Intel Falls Over 3%

    On July 7, U.S. AI chip stocks experienced widespread declines before the market opened. Intel dropped over 3%, while AMD, Qualcomm, and NXP fell more than 2%. TSMC, Broadcom, and Tesla decreased by over 1%, and NVIDIA declined by 0.7%.

  • China's Central Bank Increases Gold Reserves for the 20th Consecutive Month

    As of the end of June, China's gold reserves stood at 75.44 million ounces (approximately 2,346.446 tons), an increase of 480,000 ounces (about 14.93 tons) from the end of May, which reported 74.96 million ounces (approximately 2,331.52 tons). This marks the 20th consecutive month of gold accumulation.

  • China's Foreign Exchange Reserves in June at $341.6262 Billion

    On July 7, China's foreign exchange reserves for June stood at $341.6262 billion, a decrease of $26 billion from the end of May, representing a decline of 0.75%, with expectations set at $343.2 billion.

  • U.S. Storage Stocks Drop Pre-Market, SanDisk and Micron Down Over 4%

    On July 7, U.S. storage concept stocks collectively fell in pre-market trading. Western Digital dropped over 5%, SanDisk and Micron Technology fell over 4%, Seagate Technology declined over 3%, Rambus fell over 2%, and SMI fell over 1%.

  • U.S. Stocks in Optical Communication Sector Drop Pre-Market

    On July 7, stocks in the optical communication sector of the U.S. market collectively fell pre-market. Astera Labs dropped over 4%, while Marvell Technology, Credo Technology, and AXT Inc. fell more than 3%. Tower Semiconductor, MaxLinear, Corning, Applied Optoelectronics, GlobalFoundries, Lumentum, and Qorvo all declined by more than 2%. Coherent, Nokia, Amphenol, and Broadcom dropped over 1%.

  • Pre-market Decline in U.S. Storage Stocks

    In pre-market trading, U.S. storage concept stocks experienced a widespread decline, with Micron Technology falling by 4.8%, SanDisk dropping over 4%, Corning down more than 2%, and Intel decreasing by over 3%.

  • Two Departments: Support for Reinsurance Institutions to Increase Capital and Issue Supplementary Capital Tools

    On July 7, the National Financial Supervision and Administration Bureau and the Shanghai Municipal Government released several measures to accelerate the construction of the Shanghai International Reinsurance Center. Among these measures, they proposed to enhance the quality and efficiency of the reinsurance industry, support reinsurance institutions in increasing capital and expanding shares, and issuing supplementary capital tools to improve the capacity for internal capital accumulation and external capital supplementation, thereby strengthening the reinsurance industry's capabilities. The initiative aims to guide the insurance industry to focus on major national projects, strategic emerging industries, and livelihood security, consolidating insurance and reinsurance underwriting capabilities to enhance risk protection levels. It also supports reinsurance institutions in leveraging their professional technical advantages to assist the insurance industry in reducing risk.

  • Sources: Saudi Arabia Plans to Expand Oil Pipeline to Red Sea, Increasing Capacity by 2 Million Barrels Daily to Bypass Strait of Hormuz

    On July 7, five informed sources revealed that Saudi Arabia is considering expanding the crude oil pipeline capacity to its western coast on the Red Sea, allowing Saudi Arabia and its neighbors to transport more oil without passing through the Strait of Hormuz. This east-west pipeline, built in the early 1980s, has gained strategic importance since the outbreak of the Iran war in February and the disruption of shipping in the Strait of Hormuz. The pipeline can deliver up to 7 million barrels of crude oil per day to the Red Sea port. The CEO of Saudi Aramco stated in May that approximately 2 million barrels are supplied to west coast refineries, while about 5 million barrels are for export. Sources indicate that Saudi Arabia is in preliminary discussions with some neighboring countries regarding the pipeline expansion, aiming to add about 2 million barrels of pipeline capacity per day. It remains unclear whether Aramco's planned expansion involves upgrading existing infrastructure or constructing new pipelines. One source mentioned that the expansion plan also includes a smaller refined oil pipeline. Two sources indicated that the expansion scale could range from 1 million to 2 million barrels per day, with refined oil also being considered. Another source stated that the project would take several years and cost billions of dollars, requiring adjustments to Saudi crude pricing mechanisms.