Cairo VM

Cairo VM 是一个非常精简的虚拟机模型,它没有类似于x86的通用寄存器(%eax, %ebx 等等),并且它仅仅只支持有限域Fp上加法和乘法 (p = 0x800000000000011000000000000000000000000000000000000000000000001), 这篇文档提到了stark-curve 的参数设置。

Q1: 可能大家会好奇,仅仅只有加法、乘法,怎么就能够实现各种算术函数呢?

  1. 减法:a - b = a + (b * (-1))
  2. 布尔约束: a*(1-a) = 0
  3. 布尔运算: a & b = a*b
  4. 比特分解(bit-decompose): 比如得到一个u32 的32个比特,a = \sum_{i=0}^{31} 2^i * a_i;当然有更好的方法来实现这个功能,如使用builtin()。

Cairo 的加法指令和乘法指令的操作数都在内存上,Cairo 的内存比较特殊,是只读的(immutable)。这和大部分的虚拟机都不一样,比如:

  • EVM 的操作数通常是放在 stack 上,而 stack 是可以修改的;
  • x86 架构的操作数是在通用寄存器中。

大家可能会好奇,那么如何实现赋值(assignment)呢?

需要为赋值语句的左侧的变量 lhs 分配一个新的内存,然后使用assert_eq 建立这个新变量 lhs 与旧变量 rhs 之间的相等关系。

我们举个例子来说明,比如:

# equivalent to assert_eq(b, 3)
b = 3 

# equivalent to assert_eq(a, b+1)
a = b+1

# will alloc a new memory space for `a`(we call it `a2`) on the left side
# equivalent to assert_eq(a2, a+15)
a = a + 15

Cairo VM Instruction Set

Cairo VM 的指令集是

  • assert_eq:实现算术表达式;

    一个复杂的算术表达式会对应多条 VM 指令;例如,

    y = x^3 + 23*x^2 + 45*x + 67
    
    # the above compound expression is equivalent to 5 bytecodes, they cost 5 memory slots
    # 1*x+23
    [ap] = [ap-1] + 23; ap++ 
    # (1*x+23)*x
    [ap] = [ap-1]*[ap-2]; ap++ 
    # (x+23)*x + 45
    [ap] = [ap-1] + 45; ap++ 
    # ((x+23)*x + 45)*x
    [ap] = [ap-1]*[ap-4]; ap++
    # ((x+23)*x + 45)*x + 67
    [ap] = [ap-1] + 67; ap++
    
  • call/ret: 函数调用

  • jmp/jmpi: 条件跳转,用于支持控制流

在本节,我会以 call/ret 为例,讲解一下Cairo VM指令集如何支持 函数调用 这一实用功能。

  • 假设,函数A 的栈帧指针(stack frame pointer)为 fp

  • 假设,函数B 在执行到call B 之前的 allocation pointer 为 ap

  • 函数 B 的栈帧指针为 new_fp = ap + 2

  • 在函数 A 中调用函数 B 之前,需要先把入参放到 [new_fp - 3], [new_fp - 4], ...等区域中;

  • 将函数 A 的stack frame pointer 的值保存到 [new_fp-2]

  • 将函数 A 中在call 指令之后的那条指令的地址保存到[new_fp-1]

  • 当函数 B 结束执行之后,就可以通过读取[new_fp - 1] 然后更新 pc ,读取 [new_fp-2 来更新fp,回到函数 A 的执行。

以下图所示的函数调用示例,函数 f 调用了函数 g,函数g 调用了两次 h。需要注意的是,调用两次 h,产生的栈帧并没有重合(通常在x86架构中,它们的栈帧是要重合的)。

函数调用示例(图片取自Cairo VM 白皮书 - 图8)

函数调用示例(图片取自Cairo VM 白皮书 - 图8)

上述示例调用的栈帧如下图所示。

函数调用栈帧示例(图片取自 Cairo VM 白皮书 - 图9)

函数调用栈帧示例(图片取自 Cairo VM 白皮书 - 图9)

更多技术细节,大家可以看一下 Cairo VM 的白皮书[1]

Cairo 语言

从以上对 Cairo VM 的介绍,大家不难发现,Cairo 汇编代码其实比较简陋,我们开发者不可能手写Cairo assembly code。所以,我们在开发真实应用时,使用的是 cairo 语言,这个语言的词法形式与python类似。

参考资料

  1. Cairo VM whitepaper