# Cairo 1.0 开源发布！

By [Starknet 中文](https://paragraph.com/@starknet-zh) · 2022-11-29

---

> 原文：[Open Sourcing Cairo 1.0!](https://medium.com/starkware/open-sourcing-cairo-1-0-b3100a664bb0) 作者：StarkWare 翻译：[「StarkNet 中文」社区](https://twitter.com/StarkNet_ZH)

概要
--

*   **Cairo 1.0 开源啦！这还仅仅只是开源 StarkNet 堆栈的第一步**
    
*   现公开 Cairo 1.0 编译器的[预览版](https://github.com/starkware-libs/cairo)，可以尝试基本的 Cairo 1.0 代码了
    
*   Cairo 1.0 核心和 Rust 非常类似
    
*   这只是预览版本，并不是正式发布。还有更多改进正在进行中，第一版编译器预计在明年第一季度上线
    
*   Cairo 1.0 现不支持 StarkNet，但将在明年第一季度实现 StarkNet 支持
    

Cairo 回顾介绍
----------

在 2020 年，我们发布了支持可验证计算的图灵完备编程语言 [Cairo](https://eprint.iacr.org/2021/1063.pdf)。Cairo 最初作为一种汇编语言，随着不断的开发变得极具表现力。两个月前，我们曾公开表示 [Cairo 1.0](https://medium.com/starkware/cairo-1-0-aa96eefb19a0) 解决了当前形势中一些重要问题：

*   虽然 Cairo 的语法相比初阶段已经有了显著的改进，但开发者体验仍可以不断改善。Cairo 1.0 作为受 Rust 启发的全类型语言，便于编写相同的逻辑和减低出错概率。
    
*   现有的编译器与 StarkNet 的开发同属一个 Repo，难以追踪其语言更改。而 Cairo 1.0 编译器重新编写，允许更快捷的开发功能和更多社区参与。
    
*   现在每一次计算都是可证明的。目前，Cairo 程序可能在特定的输入指令时失败（如在某些计算分支中得到 `assert 1=2` 指令），导致无法证明计算。在 Cario 1.0 中，程序在每一个分支都是可证明的，这对于 StarkNet 中的 DOS 保护是至关重要的。
    

今天，我们实现了上述目标中的第一个里程碑，将开发转移至公共 Repo 并**开源 Cairo 1.0**！尽管现阶段还无法在 StarkNet 部署，开发者们可以尝试使用 Cairo 1.0 和体验新功能。

现有功能
----

现在可以编译和执行基础的原生 Cairo 程序。尽管很多语法/语言仍在改进，但可以先熟悉 Cairo 1.0，感受未来升级的乐趣。

**请注意，暂不支持编写 StarkNet 合约**。StarkNet 语法（存储变量/调用合约/事件和其他系统调用）将在未来几周添加。

代码示例
----

为展示旧版语法和 Cairo 1.0 之间的差异，我们在下面展示了找到第 n 个斐波那契数的几种不同实现/偏好。

### 示例一：匹配表达式

在 Cairo 1.0 中，你可以使用类似 rust 的[匹配](https://doc.rust-lang.org/rust-by-example/flow_control/match.html?highlight=match#match)表达式。再也不用怕可能导致引用撤销的 if/else 命题了！

![](https://storage.googleapis.com/papyrus_images/1a0e7e3d3e5f0149028b4512dd86d9b85371ff39b09a096a9f97cf3e0da661f4.png)

### 示例二：数据类型

Cairo 0 中使用 felt 和指针，而在 Cairo 1.0 中我们有复杂数据类型的原生访问形式了。在下面你可以看到生成前 n 个斐波那契数列的示例。

![](https://storage.googleapis.com/papyrus_images/f56a3f6da44506dff25d8361ca1909ab347ce9240277a6cda9a1f89f83021433.png)

在上图可见，不再是直接用内存指针，而是使用 `Array::<felt>` 类型和 `array_append` 函数。

### 示例三：结构和所有权

以下代码说明了 Cairo 1.0 中结构的用法。

![](https://storage.googleapis.com/papyrus_images/f9e2ea09843339d7ee513211cf29446e3589ec61382a173d8df18fde3ffdbe29.png)

> 以下内容仅针对 Rust 爱好者。Cairo 1.0 使用和 Rust 类似的方式管理内存。特别是所有权和借用的概念。因此，通过访问 `FibResult` 结构的成员（在此例中为 `result.value`），我们移除了 `result`，这就意味着除非 FibResult 是可复制的，否则我们无法在 `result.index` 中再次访问它。为克服这个问题，我们添加了 `FibResult` 类型的 `#[derive(Copy)]` 属性。在未来版本中，我们还会为结构添加自动解构，这样就可以在不触及其他成员的情况下移动一个成员的[所有权](https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html)（特别是，即使 `FibResult` 没有复制属性，上述代码也会编译）。

**特别要注意的是，Cairo 1.0 完全抽象掉了 Cairo 原本的（非确定性只读）内存模型**。

### 示例四：误差传播

以下代码计算第 n 个斐波那契数，但与之前的示例不同，这里所有的输入都是 uint128 类型。请注意，这里解决了在 Cairo 0 中处理 uint 的一大痛点。此处的 uint128（以及未来的 uint256）都是原生数据类型。

![](https://storage.googleapis.com/papyrus_images/9dab1271fab9b7b5679dd15ae9002634400f75da38051a39dd56d645176548e4.png)

两个 128 位的整数相加会导致溢出。以上代码使用了 [Option 枚举](https://doc.rust-lang.org/rust-by-example/std/option.html)和[问号运算符](https://doc.rust-lang.org/rust-by-example/std/result/question_mark.html)来处理其中一个中间加法运算的溢出情况。而目前的 uint256 加法语法，必须调用 `uint256_check` 来保证可靠性。另外，我们未来将添加 panic 概念（与 Rust 中的 [panic](https://doc.rust-lang.org/rust-by-example/std/panic.html) 宏类似），并且加法溢出等简单错误将无法匹配并自动传播，也就意味着在相加 uint 时不必使用`Option`或`?`了。

自己试试
----

现在来自己动手尝试编译和运行当前所支持的 Cairo 1.0 程序吧。按照[说明教程](https://github.com/starkware-libs/cairo/tree/main/crates/runner)，学会 `cairo-run` 指令。请注意后台将由 [Lambdaclass](https://lambdaclass.com/) 开发的 [Rust Cairo VM](https://github.com/lambdaclass/cairo-rs) 执行指令。

点击查看[入门示例](https://github.com/starkware-libs/cairo/tree/main/examples)，请注意这只是编译器开发的预览版本，我们将会在几周内改进编译器以及 CLI。

未来计划
----

编译器的第一个版本将着重支持 Cairo 1.0 中 StarkNet 的所有现存功能，该版本计划于明年第一季度推出。除此之外，我们正在扩展 Cairo 1.0 编译器性能。将在几周内上线：

*   StarkNet 性能：编写智能合约系统调用功能
    
*   循环
    
*   全新库函数
    
*   改进语言服务器
    
*   原生 StarkNet Gas 概念
    

敬请关注编译器最新进展！

---

*Originally published on [Starknet 中文](https://paragraph.com/@starknet-zh/cairo-1-0-2)*
