我最近在学cairo-lang
,巩固一下细节,也写一个WTF Cairo极简教程
,供小白们使用。教程基于cairo 0.10.2
版本
WTF Academy 社群:Discord|微信群|官网 wtf.academy
所有代码和教程开源在 github: github.com/WTFAcademy/WTF-Cairo
felt
felt
(field element,域元素)是 cairo
的基本类型,数字,字符串,地址通通由它表示。它是定义在 $[0, P]$ 的整数,其中 P
是一个非常大的质数。在目前的版本中,$P = 2^{251}+17*2^{192}+1$,大小为252 bit
。P
具有一些很好的数学性质用于零知识证明,因此没有选择和Solidity
一致的256 bit
。
felt
可以被整型赋值,下面的例子中,我们将 7828582
赋值给 res
:
@view
func int() -> (res: felt) {
return (res=7828582);
}
felt
可以被 bytes
(十六进制数)赋值,下面的例子中,我们将 0x777466
赋值给 res
:
@view
func bytes() -> (res: felt) {
return (res=0x777466);
}
felt
可以被短字符串(31个字符以内)赋值,太长的字符串需要借助外部的库(cairo-lang 1.0 版本可能会改善)。下面的例子中,我们将 wtf
赋值给 res
:
@view
func shortString() -> (res: felt) {
return (res='wtf');
}
上面三个变量 7828582
,0x777466
,和 'wtf'
对应的felt
值其实是相等的,你可以将合约部署到测试网,然后在区块链浏览器的Read Contract
页面分别点击Decimal
,Hex
,和Text
看看同一个值的不同格式输出。
如果你需要使用布尔值,将felt
赋值为0
或1
。
felt
类型支持加,减,乘,除四则运算,但是除法与整数除法有区别。
如果x
能被 y
整除,那么非常好,结果也是整数。下面的例子中,变量 divide
= 10/5
= 2
。
如果 x
不能被 y
整除,比如 3/2
,那么很不好,结果既不是 1
,2
,或 1.5
。而是:
1809251394333065606848661391547535052811553607665798349986546028067936010242
是的,非常长的一串数字,为了方便,咱们称这个数字为 $x$,那么 $x$ 代表什么?首先,felt
除法是乘法的逆运算,其实 $x = (P+3)/2$,满足$x$为整数且$2 * x (\mod P) = 3$。
在下面的代码中,我们尝试了felt
的四则运算,其中 divide1
变量存储了$x$的值。在 playground 编译并部署到测试网之后,我们可以看到 recover = divide1 * 2 = 3
。
@view
func operations() -> (add: felt, minus: felt, multiply: felt, divide: felt, divide1: felt, recover: felt) {
let x = 10;
let y = 5;
let add = x + y;
let minus = x - y;
let multiply = x * y;
let divide = x/y;
// note the division of felt is different from integers.
let divide1 = 3/2;
let recover = divide1*2;
return (add, minus, multiply, divide, divide1, recover);
}
这一讲,我们介绍了cairo
的基本类型felt
,和它支持的运算符。特别要注意的是felt
的除法与整数除法不同,可能会得到预期之外的结果。如果想进行整数运算,可以利用math库的unsigned_div_rem()
函数。