Cairo’s Function Exercise I

Compile and run (with at least 10 steps) the following code. Use the –print_memory and –relocate_prints flags for cairo-run.

func main():
    call foo
    call foo
    call foo

    ret
end

func foo():
    [ap] = 1000; ap++
    ret
end

Try to think what happens when the cpu gets to the ret instruction (which of the registers ap, fp, pc should change when ret is executed and to what values?).

Continue reading “Cairo’s Function Exercise I”

Cario’s Reassigned and Revoked Reference Example

The example code found on this section of the Cairo docs helps us understand why references created with the let keyword are fundamentally different to values created with the tempvar and local keywords and why references are sometimes revoked when performing jumps.

func foo(x):
    let y = 1
    jmp x_not_zero if x != 0

    x_is_zero:
    [ap] = y; ap++  # y == 1.
    let y = 2
    [ap] = y; ap++  # y == 2.
    jmp done

    x_not_zero:
    [ap] = y; ap++  # y == 1.
    let y = 3
    [ap] = y; ap++  # y == 3.

    done:
    # Here, y is revoked, and cannot be accessed.
    ret
end
Continue reading “Cario’s Reassigned and Revoked Reference Example”

Cairo’s Local Variables Exercise II

Can you spot an inefficiency in the following code? Hint: take a look here. Fix the inefficiency in two ways (implement each of the following fixes separately):

  1. Move the instruction alloc_locals.
  2. Use tempvar instead of local.
func pow4(n) -> (m : felt):
    alloc_locals
    local x

    jmp body if n != 0
    [ap] = 0; ap++
    ret

    body:
    x = n * n
    [ap] = x * x; ap++
    ret
end

func main():
    pow4(n=5)
    ret
end
Continue reading “Cairo’s Local Variables Exercise II”

Cairo’s Local Variables Exercise I

What’s wrong with the following code? (Hint: try to replace ap += SIZEOF_LOCALS with alloc_locals and see what happens) Can you fix it without changing the order of the variable definitions in the code?

func main():
    tempvar x = 0

    local y
    ap += SIZEOF_LOCALS
    y = 6
    ret
end
Continue reading “Cairo’s Local Variables Exercise I”

Cairo’s Temporary Variables Exercise

Rewrite the solution to Exercise – A simple Cairo program using temporary variables.

func main():
    [ap] = 100; ap++
    [ap] = [ap - 1] * [ap - 1]; ap++ # x * x (x^2)
    [ap] = [ap - 1] * [ap - 2]; ap++ # x^2 * x (x^3)
    [ap] = [ap - 2] * 23; ap++       # x^2 * 23
    [ap] = [ap - 4] * 45; ap++       # x * 45
    [ap] = [ap - 3] + [ap - 2]; ap++ # x^3 + x^2 * 23
    [ap] = [ap - 1] + [ap - 2]; ap++ # x^3 + x^2 * 23 + x * 45
    [ap] = [ap - 1] + 67; ap++       # x^3 + x^2 * 23 + x * 45 + 67
    ret
end
Continue reading “Cairo’s Temporary Variables Exercise”

Cairo’s Labeled Jump Exercise II

Edit the loop my_loop in the exercise below so that it starts by writing 10 to [ap], continues by writing the decreasing sequence  and then returns. Don’t forget the ret instruction. Verify that your code works as expected by looking at the memory.

func main():
    [ap] = 2; ap++

    my_loop:
    [ap] = [ap - 1] * [ap - 1]; ap++
    [ap] = [ap - 1] + 1; ap++
    jmp my_loop
end
Continue reading “Cairo’s Labeled Jump Exercise II”

Cairo’s Continuous Memory Exercise I

Run the following program:

func main():
  [ap] = 100
  [ap + 2] = 200
  ret
end

Explain why the execution of this program creates a memory gap, and therefore an inefficiency (given what you’ve just read in the above section). Add one instruction at the end of the function (just before ret) so that there won’t be a memory gap.

Continue reading “Cairo’s Continuous Memory Exercise I”

Starknet’s Architecture Review

StarkNet's logo

The architecture shown in this article has inaccuracies. Do not use it as a reference until updated (if ever). In the meantime, refer to the official Starknet docs.

tl;dr

  • Starknet’s user accounts (wallets) are implemented as smart contracts.
  • The system has 3 off-chain components (Sequencer, Prover and Full Nodes) and 2 on-chain (Verifier and Core).
  • The current system architecture is able to handle more transactions than Ethereum but with a higher delay for finality.
  • A dual checkpoint mechanism has been proposed to reduce time to finality without compromising cost.
  • An L2 transaction can be on any of these states: NOT_RECEIVED, RECEIVED, PENDING, ACCEPTED_ON_L2, ACCEPTED_ON_L1 or REJECTED.
Continue reading “Starknet’s Architecture Review”