英文原文档地址: https://book.clarity-lang.org/ch04-01-constants.html
常量
常量是一旦定义就不能更改的数据成员(因此称为常量)。它们可用于定义具体的配置值、错误代码等。通常定义常量的形式如下所示:
(define-constant constant-name expression)
constant-name 可以是任何有效的短语,expression 可以是任何有效的 Clarity 代码。
传递到定义中的 expression 在合约程序启动时按照提供的顺序进行评估。如果一个常量因此依赖于另一个,则需要以正确的顺序定义它们。
(define-constant my-constant "This is a constant value")
(define-constant my-second-constant
(concat my-constant " that depends on another")
)
(print my-constant)
(print my-second-constant)
您将遇到一个常见的情况是,定义一个常量来存储部署合约程序的主体用户:
(define-constant contract-owner tx-sender)
(print contract-owner)
常量也可用于为返回值和错误信息提供有意义的名称。
(define-constant err-something-failed (err u100))
;; And then use err-something-failed instead of (err u100) later in the code.
(print err-something-failed)
如果您对 print 函数感到好奇:它允许我们在 REPL 中将某些内容打印到屏幕上。有趣的是,print 函数实际上触发了一个自定义事件,可用于发出任何有效的数据结构。自定义应用程序扫描这个区块链并可以选择这些事件并进一步处理它们。Stacks 创世区块包含一个带有 print 打印表达式的简单智能合约,用于在区块链上编码一条消息,直到时间结束:
... to be a completely separate network and separate block chain, yet share CPU power with Bitcoin`` - Satoshi Nakamoto
...成为一个完全独立的网络和独立的区块链,但与比特币共享 CPU 算力`` - 中本聪
整个教程都会使用 print 打印功能来显示中间值。
变量
变量是可以随时间改变的数据成员。它们只能被当前的智能合约修改。变量具有一个预定义的类型和初始值。
(define-data-var var-name var-type initial-value)
其中 var-type 是类型签名,而 initial-value 是指定类型的有效值。尽管您几乎可以为变量命名任何名称,但您应该注意内置关键字。不要使用关键字作为变量名。
可以使用函数 var-get 读取变量,还可以使用 var-set 更改变量。
;; Define an unsigned integer data var with an initial value of u0.
(define-data-var my-number uint u0)
;; Print the initial value.
(print (var-get my-number))
;; Change the value.
(var-set my-number u5000)
;; Print the new value.
(print (var-get my-number))
注意到 uint 了吗?这就是类型签名。
类型签名
类型的章节涵盖了如何表达特定类型的值。另一方面,类型签名为变量或函数参数定义了允许的类型。让我们来看看签名是什么样子的。
类型 | 签名 |
---|---|
Signed integer | int |
Unsigned integer | uint |
Boolean | bool |
Principal | principal |
Buffer | (buff max-len),其中 max-len 是定义最大长度的数字。 |
ASCII string | (string-ascii max-len),其中 max-len 是定义最大长度的数字 |
UTF-8 string | (string-utf8 max-len),其中 max-len 是定义最大长度的数字 |
List | (list max-len element-type),其中 max-len 是一个定义最大长度的数字,element-type 是一个类型签名。示例:( list 10 principal ) |
Optional | ( optional some-type ),其中 some-type 是类型签名。示例:( optional principal ) |
Tuple | {key1: entry-type, key2: entry-type},其中 entry-type 是类型签名。每个 key 都可以有自己的类型。示例:{sender: principal, amount: uint} |
Response | (response ok-type err-type), 其中 ok-type 是返回 ok 值的类型,err-type 是返回 err 值的类型。示例:(response bool uint) |
我们可以看到某些类型表示最大长度。长度是严格执行的。传递太长的值会导致分析错误。尝试通过设置“This works”来更改以下示例。字符串太长。
(define-data-var message (string-ascii 15) "This works.")
与其他类型的定义语句一样,define-data-var 只能用于智能合约定义的顶层;也就是说,你不能在函数体的中间放置一个定义语句。
请记住,空格可用于使您的代码更具可读性。如果您正在定义一个复杂的元组类型,只需将其隔开即可:
(define-data-var high-score
;; Tuple type definition:
{
score: uint,
who: (optional principal),
at-height: uint
}
;; Tuple value:
{
score: u0,
who: none,
at-height: u0
}
)
;; Print the initial value.
(print (var-get high-score))
;; Change the value.
(var-set high-score
{score: u10, who: (some tx-sender), at-height: block-height}
)
;; Print the new value.
(print (var-get high-score))