Cairo 是STARK 证明系统的其中一个编程语言,让开发者能透过Cairo 来使用STARK,撰写效能更高的Dapp

背景介绍

建构于密码学的零知识证明能提供计算的隐私性,但同时在区块链生态系也被用来提升Scalability — 我可以用10 秒的运算资源来验证原本耗费1000 秒运算资源的计算过程 如同更多人熟悉的SNARK,STARK 也是一个零知识证明的证明系统,但当前的STARK 着重的是在Scalability ,而非大家比较习以为常零知识证明提供的隐私性特质 其实目前基于SNARK 的Rollup 项目,例如zkSync、Loopring、Aztec、zkopru,除了Aztec 外,其他都是利用SNARK 来增加Scalability — 这些Rollup 上资料都还是公开、没有隐私性的 StarkWare 是目前唯一基于STARK 的开发团队 STARK 要加上隐私保护不会太难,只是StarkWare 还没有把这项功能放在未来规划中

Cairo 简介

标榜为图灵完备的零知识证明系统语言,Cairo对原本熟悉Solidity的开发者来说还是会感到比较难上手和陌生的。再加上套件库还不够充足,目前支持的哈希函数是Pedersen,数位签章演算法是ECDSA(相对于SNARK,EdDSA的效能反而比较差所以没有支持)。

但Cairo还在早期开发的阶段,相信开发体验会越来越好的。

另外需要注意的是作为一个证明系统,会有Prover 和Verifier 的角色。而STARK 的Verifier 是开源的,但Prover 软体预计会有License 保护。Prover 一般情况下不得用于商业用途,除非将proof 上传至官方的Verifier。

CAIRO 字母分别代表的意思是

C: CPU AIR: Algebra Intermediate Representation O: One AIR(verifier smart contract) to rule them all

但O: One AIR(verifier smart contract) to rule them all代表的是:任何使用Cairo写的程式都能用同一个Verifier来验证,每个应用不再需要产生自己也只有自己能用的Verifier合约。

开发者不需要对自己的应用跑trusted setup(STARK本来就不需要),也不需要烦恼Verifier的部分,如果你有开发过基于SNARK的应用的话你会更有感觉。

最后要提及的是,第一版的Cairo是设计来方便开发者将Dapp的运算迁移至链下。不同于Rollup,这个链下只会有它自己一个Dapp。这个Dapp的项目方自己维护自己Dapp的state。( Rollup则是operator维护所有Dapp的state,Dapp开发者不需自己操烦)

这可能有点难懂。如果你有在写Solidity,想像一下今天你在合约要用到合约里宣告的storage变数时,你要自己提供merkle proof上来,证明这个storage变数真的是这个值。这个就是开发者要自己维护state的意思。

而第二版的Cairo则是StarkNet里使用的Cairo(第一和第二版是不同编译器),这版的Cairo就是作为Dapp在Rollup开发所使用—开发者可以在合约里宣告变数,变数的值不需开发者维护,可以直接假设存在。

注1:StarkWare不喜欢Rollup这个词,他们觉得Data Availability的需求是一段光谱:不一定得要把data全都送上L1,中间有其他方式可以做不同层级的Data Availability。

注2:第一版和第二版实际上在官方版本里是0.0.1及0.0.2,在撰文当前最新版即是0.0.2

官方网站:https://www.cairo-lang.org

开发者文件:https://www.cairo-lang.org/docs/

开发环境

Cairo有提供像是Remix的浏览器IDE:playground。里面提供各种范例练习和挑战,除了可以编译,还可以直接生成并上传proof。

注:但有些功能还是没办法在playground里使用,例如要给你的程式custom input时。这时候只能在本地端开发才能使用这个功能。

开发Cairo要先安装python,我将开发者文件整理出来的资料统整在这个hackmd文档里:https://hackmd.io/w690dpAQTsKeKZv3oikzTQ

里面包含简介、设置本地开发环境以及Cairo基础(因为篇幅原因,所以不将内容复制到这里)

注:我把开发者文件里的代码整理到这里:https://github.com/NIC619/cairo_practice/tree/master/practices

如果不想在研究开发者文件过程中,还要自己手动拼凑里面例子的话,可以直接用整理好的代码来执行。同时repo里还有包含一些额外自己测试Cairo功能的范例。

深入Cairo

在那份hackmd文档里的开头,可以连结到第二部分—深入Cairo的部分。里面也是从开发者文件里撷取出来我觉得比较重要的部分。如果你要读开发者文件的话,我建议从Hello Cairo开始,它会从例子切入,会比较好知道Cairo怎么使用。接着如果要更深入了解,再去读How Cairo Works。

StarkNet Cairo

第二版的Cairo其实功能和第一版的Cairo是差不多的,所以不必担心在开发者文件里学到的Cairo在StarkNet版本会不能用或差很多。在读完Hello Cairo/How Cairo works后,就可以接着看Hello StarkNet。会很顺利的切换到StarkNet版本的Cairo。

注1:我整理的文档里是按照第一版Cairo所写的

注2:如果你从开发者文件一路看下来,体验过非StarkNet版的Cairo,那你在体验StarkNet版的Cairo时一定会发现这更像一般智能合约的使用方式—你可以用view函数查询storage变数,可以用external函数去执行合约(非StarkNet版本不是这样操作Dapp的,这边因为篇幅原因没有详细介绍)。

非常建议尝试两种版本的Cairo,你会知道1. 操作一个单独在L2 的Dapp 和2. 操作与其他Dapp 共存在Rollup 上的Dapp 的不同。这对了解L2 怎么运行、需要哪些资料、为什么需要这些资料非常有帮助。

0.0.2 版的StarkNet Cairo 目前还缺少一些功能:

函数还没办法宣告阵列或struct 型态的参数 合约和合约之间还没办法互动 L1 没有办法读取到L2 的资料,L2 也没办法读取到L1 的资料。如果要建立跨L2 Bridge,这个功能非常重要。

补充及个人心得

STARK的proof size相比于SNARK系列的proof size大很多,又其证明所包含的交易数量对proof size和验证时间的影响不大,所以把很多笔交易一并做一个proof会是对STARK非常有利、节省成本的方式(SNARK、STARK比较表)。但这同时也是一个缺点,如果你的Dapp或Rollup的TPS不高,那就只能等更久时间搜集多一点的交易,要不然就只能提高成本来维持验证proof的频率。

StarkWare和zkSync 一样都有Rollup 宇宙的概念( Rollup 宇宙的用词并不精确,因为在他们的宇宙中不会所有子链都是Rollup,而是会有依照Data Availability 程度不同所区分的子链,像是Validium、zk Porter 的设计),个人觉得能够有(针对Data Availability 程度的)选择是会比只有一个选择(完全Data Available) 还好的方式,但实际上的可行性就要等其团队释出更多的资讯。

在Rollup 越趋成熟的情况下,能够提供快速跨Rollup 服务的流动性提供者的角色会越来越重要。zk Rollup(StarkNet、zkSync、etc…)比Optimistic Rollup (Optimism、Arbitrum、etc…)有着短上许多的finalize 时间,这对降低流动性提供者的风险有很大的帮助,但目前zk Rollup 支持合约功能甚至L1 <-> L2 互动的完成度都比Optimistic Rollup 还低上许多。短期内快速跨Rollup 的服务应该还是局限在Optimitic Rollup 之间。