A well-structured set of interview Questions for a Cairo programming developer position.

A well-structured set of interview Questions for a Cairo programming developer position.

The questions focus on Cairo syntax, Starknet development, zero-knowledge proofs, and integration with Ethereum ecosystems. Each answer is concise, practical, and tailored to demonstrate expertise for a Cairo developer role.

Beginner-Level Questions (1–15)

1. What is Cairo?

Answer: Cairo is a Turing-complete programming language for writing provable programs, optimized for zero-knowledge proofs (ZKPs) like STARKs. It’s used primarily for Starknet smart contracts, enabling scalable and secure computations on Ethereum’s Layer 2.

2. Why is Cairo used for Starknet?

Answer: Cairo is designed to generate efficient STARK proofs, which Starknet uses to batch and verify transactions off-chain, reducing Ethereum mainnet costs and improving scalability while maintaining security.

3. What is Starknet?

Answer: Starknet is a permissionless Layer 2 blockchain on Ethereum that uses STARK proofs for scalability. It supports general-purpose smart contracts written in Cairo, offering low-cost, high-throughput dApp development.

4. How does Cairo differ from Solidity?

Answer:

  • Cairo: Focused on provable computation, generates STARK proofs, used for Starknet.
  • Solidity: General-purpose language for Ethereum smart contracts, runs on the EVM.
  • Cairo emphasizes mathematical correctness and off-chain computation, while Solidity is more flexible for on-chain logic.

5. What is the basic structure of a Cairo program?

Answer: A Cairo program includes:

  • Functions: Defined with func and end.
  • Modules: Organized with mod for namespacing.
  • Imports: Using from … import.
  • Hints: Python-like code for guiding proof generation.
  • Return Values: Explicitly declared with return.

Example:

cairo

func add(a: felt, b: felt) -> (res: felt) {
    return (res=a + b);
}

6. What is a felt in Cairo?

Answer: felt (field element) is Cairo’s primary data type, representing an integer in a finite field (modulo a prime). It’s used for all arithmetic operations and is central to STARK proof generation.

7. How do you install Cairo?

Answer:

  1. Install prerequisites: Python, Rust, and a package manager (e.g., pip).
  2. Install the Cairo compiler:

bash

pip install cairo-lang
  1. Verify with cairo-compile –version.

8. What is the role of hints in Cairo?

Answer: Hints are Python-like code snippets embedded in Cairo programs (enclosed in %{ … %}) that guide the prover without affecting program correctness. They optimize proof generation by providing computational shortcuts.

Example:

cairo

%{
    memory[ap] = 42
%}

9. How do you compile a Cairo program?

Answer: Compile a Cairo file (program.cairo) to a JSON representation:

bash

cairo-compile program.cairo --output program.json

The output is used for execution or proof generation.

10. What is the purpose of the alloc function in Cairo?

Answer: alloc allocates memory for arrays or dynamic data structures in Cairo’s memory model. It returns a pointer to the allocated memory.

Example:

cairo

let (ptr: felt*) = alloc();

11. What is a Starknet contract?

Answer: A Starknet contract is a smart contract written in Cairo, deployed on Starknet. It defines storage, functions, and events, leveraging STARK proofs for scalable execution.

12. How do you declare a function in Cairo?

Answer: Use the func keyword, specify parameters, and declare return types:

cairo

func multiply(x: felt, y: felt) -> (result: felt) {
    return (result=x * y);
}

13. What is the assert statement in Cairo?

Answer: assert checks a condition and halts execution if false, ensuring program correctness. It’s critical for Cairo’s provable computation.

Example:

cairo

assert x > 0;

14. What is the Cairo memory model?

Answer: Cairo uses a linear, immutable memory model where memory cells are written once. It operates with pointers (ap, fp) and supports temporary and persistent allocations.

15. How do you run a Cairo program locally?

Answer:

  1. Compile the program:

bash

cairo-compile program.cairo --output program.json
  1. Run with:

bash

cairo-run --program=program.json

Use –layout=small for Starknet-compatible execution.


Intermediate-Level Questions (16–35)

16. What is a Starknet syscall?

Answer: Syscalls are Starknet-specific functions that allow contracts to interact with the blockchain (e.g., read storage, emit events). Examples include get_caller_address and storage_write.

17. How do you define a Starknet contract in Cairo?

Answer: Use the @contract decorator and define storage, external functions, and events:

cairo

%lang starknet
@contract
mod MyContract {
    @storage_var
    func balance() -> (res: felt) {
    }

    @external
    func increase_balance(amount: felt) -> () {
        let (current) = balance.read();
        balance.write(current + amount);
        return ();
    }
}

18. What is the @storage_var decorator?

Answer: @storage_var defines a storage variable in a Starknet contract, mapping to persistent blockchain storage. It generates read and write methods.

Example:

cairo

@storage_var
func counter() -> (res: felt) {
}

19. How do you call another contract in Starknet?

Answer: Use the @contract_interface to define the target contract’s interface and call it with invoke or call:

cairo

@contract_interface
namespace ITarget {
    func increment() -> ();
}

func call_target(target: felt) -> () {
    ITarget.increment(target);
    return ();
}

20. What is the difference between @external and @view in Starknet?

Answer:

  • @external: Marks functions that modify state and can be called externally.
  • @view: Marks read-only functions that don’t modify state.

21. How do you handle errors in Cairo?

Answer: Use assert for critical checks or return custom error codes. For Starknet, use panic or revert with a message:

cairo

if (condition == 0) {
    panic('Condition not met');
}

22. What is the pedersen hash function in Cairo?

Answer: The Pedersen hash is a cryptographic hash function used in Starknet for secure data commitments (e.g., storage keys, merkle trees). It’s implemented via the pedersen built-in.

Example:

cairo

from starkware.crypto.signature import pedersen_hash
let (hash) = pedersen_hash(a, b);

23. How do you deploy a Starknet contract using Cairo?

Answer:

  1. Compile the contract:

bash

starknet-compile contract.cairo --output contract.json
  1. Deploy using the Starknet CLI or a wallet (e.g., Argent X):

bash

starknet deploy --contract contract.json --network alpha-goerli

24. What is the implicit keyword in Cairo?

Answer: implicit declares variables that are automatically passed to functions (e.g., syscall_ptr, pedersen_ptr) to manage syscalls and cryptographic operations.

Example:

cairo

func my_func{syscall_ptr: felt*, pedersen_ptr: felt*}() -> () {
    return ();
}

25. How do you write tests for a Cairo contract?

Answer: Use the pytest framework with the Starknet testing library:

  1. Write a test in Python:

python

from starkware.starknet.testing.starknet import Starknet

async def test_contract():
    starknet = await Starknet.empty()
    contract = await starknet.deploy("contract.cairo")
    await contract.increase_balance(10).execute()
    result = await contract.balance().call()
    assert result.result == (10,)
  1. Run with pytest.

26. What is the role of the range_check built-in?

Answer: The range_check built-in ensures that values are within a specific range (e.g., non-negative or bounded), critical for secure arithmetic in STARK proofs.

27. How do you emit events in a Starknet contract?

Answer: Define an @event and emit it using emit_event:

cairo

@event
func ValueChanged(old: felt, new: felt) {
}

@external
func update{syscall_ptr: felt*}(value: felt) -> () {
    ValueChanged.emit(old=0, new=value);
    return ();
}

28. What is the cairo-lang package?

Answer: cairo-lang is the Python package providing Cairo’s compiler, runtime, and tools for compiling, running, and testing Cairo programs and Starknet contracts.

29. How do you handle arrays in Cairo?

Answer: Use alloc to create arrays and manage them with pointers:

cairo

let (arr: felt*) = alloc();
assert [arr] = 1;  // Set first element
assert [arr + 1] = 2;  // Set second element

30. What is the starknet-rs library?

Answer: starknet-rs is a Rust library for interacting with Starknet, used for building dApps, wallets, or tools that call Cairo contracts.

31. How do you optimize gas costs in Starknet contracts?

Answer:

  • Minimize storage writes (most expensive).
  • Use compact data structures (e.g., felt over structs).
  • Batch operations to reduce syscalls.
  • Avoid complex loops in mappings.

32. What is a STARK proof, and how does Cairo support it?

Answer: A STARK (Scalable Transparent Argument of Knowledge) proof verifies computation integrity off-chain. Cairo generates execution traces that the STARK prover converts into proofs, ensuring correctness and scalability.

33. How do you use invoke vs. call in Starknet?

Answer:

  • invoke: Executes a state-changing function (e.g., @external).
  • call: Reads data from a @view function without modifying state.

34. What is the starknet.js library?

Answer: starknet.js is a JavaScript library for interacting with Starknet contracts, enabling dApps to call Cairo functions, query storage, and manage transactions.

35. How do you handle contract upgrades in Starknet?

Answer: Use a proxy pattern:

  1. Deploy a proxy contract that delegates calls to an implementation contract.
  2. Update the implementation address in the proxy to upgrade.
  3. Ensure storage compatibility between versions.

Advanced-Level Questions (36–50)

36. What is the cairo-syscalls library?

Answer: The cairo-syscalls library provides low-level access to Starknet syscalls (e.g., get_block_number, storage_read), enabling contracts to interact with the blockchain environment.

37. How do you implement a factory contract in Cairo?

Answer: A factory contract deploys new contracts using deploy syscall:

cairo

@external
func deploy_contract{syscall_ptr: felt*}(class_hash: felt) -> (address: felt) {
    let (address) = deploy(class_hash, contract_data);
    return (address=address);
}

38. What is the class_hash in Starknet?

Answer: A class_hash is a unique identifier for a compiled Cairo contract’s bytecode. It’s used for deploying or referencing contract classes on Starknet.

39. How do you implement access control in a Starknet contract?

Answer: Use storage variables and modifiers to restrict access:

cairo

@storage_var
func owner() -> (res: felt) {
}

func only_owner{syscall_ptr: felt*}() -> () {
    let (caller) = get_caller_address();
    let (owner_addr) = owner.read();
    assert caller = owner_addr;
    return ();
}

40. What is the cairo-bootloader?

Answer: The cairo-bootloader is a tool for executing multiple Cairo programs in a single proof, used in Starknet for batching transactions to optimize proof generation.

41. How do you integrate Cairo contracts with Ethereum L1?

Answer: Use Starknet’s L1-L2 messaging bridge:

  1. Send messages from L1 to L2 via the Starknet core contract.
  2. Handle messages in Cairo using consume_message_from_l1.
  3. Send L2-to-L1 messages with send_message_to_l1.

42. What is the cairo-vm?

Answer: The cairo-vm (Cairo Virtual Machine) executes Cairo programs and generates execution traces for STARK proofs. It’s implemented in Rust and powers Starknet’s runtime.

43. How do you implement a Merkle tree in Cairo?

Answer: Use the Pedersen hash to build a Merkle tree:

cairo

func compute_merkle_root(leaves: felt*, len: felt) -> (root: felt) {
    if (len == 1) {
        return (root=leaves[0]);
    }
    let (left) = compute_merkle_root(leaves, len / 2);
    let (right) = compute_merkle_root(leaves + len / 2, len / 2);
    let (root) = pedersen_hash(left, right);
    return (root=root);
}

44. How do you handle reentrancy in Starknet contracts?

Answer: Starknet’s sequential execution model prevents reentrancy by default. Still, use a non_reentrant modifier to ensure safety:

cairo

@storage_var
func locked() -> (res: felt) {
}

func non_reentrant{syscall_ptr: felt*}() -> () {
    assert locked.read() = 0;
    locked.write(1);
    return ();
}

45. What is the starknet-foundry tool?

Answer: starknet-foundry is a Rust-based development framework for Cairo, providing tools for compiling, testing, and deploying Starknet contracts, similar to Hardhat for Ethereum.

46. How do you optimize proof generation in Cairo?

Answer:

  • Minimize hint usage to reduce prover overhead.
  • Use efficient algorithms (e.g., avoid nested loops).
  • Leverage built-ins (e.g., pedersen, range_check).
  • Batch syscalls to reduce trace size.

47. What is the account abstraction model in Starknet?

Answer: Starknet’s account abstraction treats accounts as contracts, allowing custom logic for transaction validation (e.g., multi-sig, session keys), implemented in Cairo.

48. How do you implement a governance contract in Cairo?

Answer:

  1. Define storage for proposals and votes.
  2. Use @external functions for proposing, voting, and executing.
  3. Implement access control and time locks:

cairo

@storage_var
func proposals(id: felt) -> (yes_votes: felt, no_votes: felt, deadline: felt) {
}

@external
func vote{proposal_id: felt, support: felt}() -> () {
    // Voting logic
}

49. How do you debug a Cairo contract?

Answer:

  • Use print statements in hints for runtime values.
  • Test locally with starknet-devnet.
  • Analyze execution traces with cairo-vm or starknet-foundry.
  • Check Starknet’s transaction status on Voyager (block explorer).

50. How do you contribute to the Cairo ecosystem?

Answer:

  • Write open-source Cairo contracts or libraries.
  • Contribute to cairo-lang, starknet-rs, or starknet-foundry on GitHub.
  • Create tutorials or subgraphs for Starknet data (e.g., using The Graph).
  • Participate in Starknet’s developer hub or hackathons.

Comments

No comments yet. Why don’t you start the discussion?

    Leave a Reply

    Your email address will not be published. Required fields are marked *