clvm
clvm 其实是 Contract Language Virtual Machine 的缩写,其实也是 Chia Lisp Virtual Machine 的缩写。
具体是哪个,取决于我们指向的是 有著作权 的还是 通用版本。
chia 区块链中的 puzzles 和 solutions 都是用这个语言来实现。
其实,clvm 是 chia 区块链的运行时语言。
编译器
clvm 目标是类似于汇编语言级别的编程,为了保持小而简单,刻意省略了大多数类似 LISP 的语言中的诸如 list 之类的运算符。
因为这些刻意的动作,使得写 clvm 程序变得复杂且困难。官方为了改善编程条件,提供编程便利性,开发了 clvm_tool 工具,使得可以使用高级的 Lisp 语法编程,并自动编译为 clvm
伪代码 opcodes
clvm 语言小而简单,从某些方面说是特定领域语言。它有点像 Lisp,其实不是有点像,看起来就是 Lisp 的子集。
当然了,如果你认为学习了 Lisp 就会 clvm 那,差距也大多了。
clvm 语言操作符很少,且大部分的操作符都是 单字母。
术语
cons
cons最早起源于Lisp语言,并在Erlang语言中发扬光大。cons在Lisp语言中一般用于 连接两个元素形成列表 的意思,用法一般为
lisp (cons 'a 'b) => (a . b)本质上是一个双向指针,分别指向待连接的两个元素。
另一方面,如果我们查字典,可以发现
cons是consist的缩写,意思是 构造。 用在列表处,连接两个元素构成新的列表
综上所述,cons 用于构造一个有序列表。
atom
atom原子,从某些方面说,就是不可变更的东西。
()
()表示false的意思。
列表操作运算符
c
cons (c A B) 只接受两个操作数( A 被称为左操作数,B 被称为右操作数)并返回一个包含两个对象组成的有序构造列表 ( cons box ) ,对象的顺序和操作数传递的顺序一样
f
first (f X) 只接受一个构造列表作为参数并返回构造列表的左操作数 A。
r
rest (r X) 只接受一个构造列表作为参数并返回构造列表的右操作数 B。
l
listp (l X) 用于判断参数是否为 atom 或是构造列表 cons。如果是 atom 则返回 () 否则返回 1
流程控制
i
if (i A B C) 接受三个操作数 A、B、C 。如果操作数 A 是 () (也就是 false ) 则返回操作数 C 否则返回操作数 B 。
x
raise (x X Y...) 用于抛出 python 异常。接受零个或多个任意数量的参数。所有的参数都会传递给抛出的异常。
=
equal (= A B) 用于比较两个操作数,如果两个操作数都是原子 atom 且相等则返回 1 表示 true,否则返回 () 表示 false
>
greater than (> A B) 用于比较两个有符号整数操作数,如果两个操作数都是原子 atom 且操作数 A 大于等于 B 则返回 1 表示 true,否则返回 () 表示 false。比较时会将操作数当做 有符号整数。
>s
greater than bytes (>s A B) 用于比较两个字节操作数,如果两个操作数都是原子 atom 且操作数 A 大于等于 B 则返回 1 表示 true,否则返回 () 表示 false。比较时会将操作数当做 字节(bytes)。
常量
q
quote (q x) 接受一个未求值的操作数并原样返回这个操作数。 作用就是保持操作数原样进入到下一轮计算。
整数操作符
+
(+ a0 a1...) 接受零个或多个任意数量的整型操作数并返回这些操作数的 和。
-
(- a0 a1...) 接受零个或多个任意数量的整型操作数并返回 a0 减去其它操作数之后的值。
*
(* a0 a1...) 接受零个或多个任意数量的整型操作数并返回所有操作数的 乘积 。
divmod
(divmod A B) 接受两个整型操作数并返回操作数 A 除以操作数 B 的 地板商和余数组成的列表。
流操作符
sha256
(sha256 A) 返回字节操作数的 sha256 的哈希值。一般是 32 bytes 长度。 A 必须是 bytes 类型。
椭圆曲线 ecdsa 操作符
point_add
(point_add a0 a1 ...) 接受零个或多个任意数量的 bls12_381 操作数并返回它们的和。
注意,参数要先经过
bls12_381计算。
pubkey_for_exp
(pubkey_for_exp A) 对操作数 A 进行 bls12_381 计算并返回计算后的值。