Cairo 之旅 II : 通过 Starklings 掌握 Cairo 语法

作者:Darington Nnam
原文:Journey through Cairo II — Mastering Cairo’s Syntaxes with Starklings
翻译:Louis Wang
校对:「StarkNet 中文社区」

上篇文章中,我们用 Protostar、ArgentX 和 Voyager 为 Cairo 建立本地开发环境,我们将从今天开始了解 Cairo 的基本原理,并尝试用 Starklings 作为教材来解释 Cairo 的基本功能。

OnlyDust 的 Starklings

直接通过官方文档来学习 Cairo,对普通人比较困难。刚开始我努力的去理解这些基础知识,直到发现了 Starklings

Starklings 是由 OnlyDust 团队编写的互动式教程,其采纳流行的渐进互动式 Rust 教程 Rustlings 的长处。今天,我们将通过解决 Starklings 中的问题,开始了解 Cairo 如何工作

安装

为了高效学习本教程,需要提前设置你的计算机环境:

访问 Starklings 的官方 Github repo

复制运行 git clone 指令到本地计算机上。

git clone --branch stable --single-branch
<https://github.com/onlydustxyz/starklings.git>

安装指令运行的必需工具:

curl -L 
<https://raw.githubusercontent.com/onlydustxyz/starklings/master/install.sh> | bash

开始测试,打开终端并执行:

starklings --watch

命令和资源

现在我们已完成开发环境,在潜心编写 Cairo 前,这里一些必要指令和资源,会让开发更简单!

  1. 在没进入观察模式前手动验证测试,请运行以下:

    starklings --verify relative_path_to_the_exercise_file 
    
  2. 如果解决不了测试,可以检索答案:

    starklings --solution relative_path_to_the_exercise_file
    
  3. 如果想自由发挥尝试更多,可以试试与 Solidity Remix (以太坊智能合约开发 IDE)相似的 Cairo‘s playground

理解 Cairo 语法

syntax01.cairo — 从 Cairo 合约开始

开始使用 Cairo 时,如何区分 Cairo 程序和 Cairo 合约。为了避免相同的困惑,以下是两者的快速定义:

Cairo 程序:Cairo 程序可以理解为一种无状态合约,意味着在编写程序时,不能访问存储,不能与其他 Cairo 程序包括 L1 链进行交互。

Cairo 合约:简单来说,这是运行在 Starknet 虚拟机 (VM) 上的程序。由于在虚拟机上运行,因此他们可以访问 Starknet 的持续状态,改变或修改 Starknet 的变量状态,与其他合约交互,并与底层 L1 无缝交互。

理解后,就可以开始写一个 Cairo 合约,你必须指定它是一个合约并在最顶行写上:

%lang starknet

下一步,在 Starklings 的 Syntax01.cairo 中完成,并检查能否通过测试:

成功运行!

接下来是第二个测试,删掉 #I AM NOT DONE,Starkligns 会引导你进入下一个测试!

syntax02.cairo — Cairo 模块化

就像大部分现存的编程语言一样,把所有程序代码保存在一个文件里是非常不明智的做法。你也可能需要使用他人的代码,而不是重新发明轮子,所以每种语言都鼓励代码模块化,Cairo 也不例外。

在这个测试中,我们要研究 test_ok 函数,使该函数工作需要并导入所有重要文件。

在 Cairo 中导入一个文件:

from starkware.starknet.common.syscalls import get_contract_address

当你这样做时,Cairo 会在当前目录和相对于编译器路径的标准库目录中搜索文件 syscall.cairo,并从中导入 get_contract_address 函数。

我们的函数 test_ok 需要三个隐参数:syscall_ptr、pedersen_ptrrange_check_ptr(我们将在后文介绍隐参数)。但我们注意到,允许计算 Pedersen 哈希函数的 pedersen_ptr 需要一个 HashBuiltin,而这一参数并不存在于当前文件中,所以需要从 Cairo 函数库导入,我们要在代码中添加:

from starkware.cairo.common.cairo_builtins import HashBuiltin

成功运行!

func takes_two_arguments_and_returns_one(a: felt, b: felt) -> (c: felt):
return (a + b)  # Do not change
end

正如你所看到的,我们给 a,b,c… 参数传递了一个奇怪的数据类型 **felt,**没错!不同于 Solidity 有许多数据类型,如 uint256,字符串等,Cairo 使用的是一种被称为 felt 的数据类型(我们会在以后的文章中深入讨论这个问题)。

从我们的函数签名中,能发现我们传入了一个不被函数使用的 c 参数。这个参数就是该函数的返回值。你的返回值通过 -> 来指定。

Cairo 命名空间是在合约中使用模块的一种非常强大的方式。当从多个模块导入时,它允许你在一个标识符下定义函数范围,有助于防止冲突。它还有助于提高代码可读性。

在 Cairo 执行一个命名空间,要使用 namespace 关键字,为命名空间指定一个名字:

namespace starklings
    func starkling_exercise(a: felt, b:felt) -> (c: felt):
       return (a+b)
    end
end

从文件中使用命名空间中的函数:

starklings.starkling_exercise(3, 5)

为了通过执行了命名空间的测试,需要在命名空间 my_namespace 内调用 return_something 函数。

Cairo 和 Solidity 有着极度相似的结构体概念。

首先用 struct 关键字定义,然后用 member 关键字指定其属性。不同于 Solidity 的是,Cairo 中的结构体也有一个 size 属性,即其成员规模之和。

在 Cairo 中的结构体:

struct Starklings:
   member first: felt
   member second: felt
end

为了通过测试,我们要执行一个 Currency 结构体。

需要检查测试找出结构体的成员。调用结构体测试的第 13 行:

local euro : Currency = Currency('Euro', 2)

在此,我们注意到结构体有两个成员,可能分别是名称和 ID,但是 14 行出现:

assert euro.name = 'Euro'

修改结构体来通过测试:

struct Currency:
   member name: felt
   member id: felt
end

最后

到这里,我想你现在已经很好理解了 Cairo 的基本语法、函数参数、命名空间、结构体等。

在下一讲中,将通过字符串挑战,并深入了解什么是 felt

如果觉得本教程对你有帮助,转发分享给其他人吧~

Subscribe to Starknet 中文
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.