原英文文档链接: https://book.clarity-lang.org/ch03-00-keywords.html
Keywords 关键词
关键字是具有指定含义的特殊术语。我们在前面的章节中已经遇到过几个关键字:true 、false 和 none 。还有其他一些需要额外注意。
block-height 区块高度
将 Stacks 区块链的当前区块高度显示为无符号整数。如果我们想象链条尖端的高度为 5,我们可以在代码中的任何位置读取该数字。
block-height
burn-block-height 燃烧区块高度
将底层销毁区块链(在本例中为比特币)的当前区块高度显示为无符号整数。
burn-block-height
tx-sender
包含发送转账交易的主体用户。它可用于验证调用公共函数的主体用户。
tx-sender
请注意,如果使用特殊函数 as-contract 来改变发送文本,则 tx-sender 可能是智能合约程序的主体用户。
(as-contract tx-sender)
contract-caller
包含调用函数的主体用户。它可以是标准的主体用户或智能合约程序的主体用户。如果直接通过已签名的交易调用智能合约程序,则 tx-sender 和 contract-caller 将相等。如果合约程序依次调用另一个合约程序,则 contract-caller 将等于区块链链中的前一个合约程序。
在接下来的章节我们学习什么是 Public functions 公共函数。
Public functions
标准主体用户和合约主体用户都可以从外部调用公共函数。具有任何交互性的合约程序至少需要一个公共函数。它们可调用的事实并不意味着底层功能是公开的。开发人员可以包含断言以确保只有特定的合约程序调用者或输入是有效的。
公共函数必须返回响应类型值。如果函数返回 ok 类型,则函数调用被认为是有效的,并且对区块链状态所做的任何更改都将实现。这意味着只有在触发这些更改的合约程序调用返回 ok 时,才会将状态更改(例如更新一些变量或传输代币)提交到链中。
下面的示例说明了返回 ok 或 err 的结果。它是一个基本函数,它接受一个无符号整数作为输入,如果是偶数则返回 ok,如果不是偶数则返回 err 。它还将在函数开始时增加一个名为 even-values 的变量。为了检查数字是否为偶数,我们计算除以 2 的余数,并使用 is-eq 函数检查它是否等于 0 ( n mod 2 应等于 0 )。
(define-data-var even-values uint u0)
(define-public (count-even (number uint))
(begin
;; increment the "event-values" variable by one.
(var-set even-values (+ (var-get even-values) u1))
;; check if the input number is even (number mod 2 equals 0).
(if (is-eq (mod number u2) u0)
(ok "the number is even")
(err "the number is uneven")
)
)
)
;; Call count-even two times.
(print (count-even u4))
(print (count-even u7))
;; Will this return u1 or u2?
(print (var-get even-values))
你有没有注意到即使 count-even 函数被调用了两次,最终的打印表达式是如何返回 u1 而不是 u2 的?如果您习惯于使用不同的语言(例如 JavaScript )进行编程,那么它可能会让您感到奇怪:偶数值变量在函数开始时更新,因此似乎很直观可以认为数字应该在每次函数调用时递增。
编辑上面的示例并尝试进行以下迭代:
用像 u8 这样的偶数替换奇数 u7 。偶数值的打印输出是否包含 u1 或 u2 ?
将 if 表达式中的 err 类型更改为 ok 。那么偶数值的值是什么?
发生的情况是,一旦返回 err 值,整个公共函数调用就会回滚或恢复。就好像函数调用从未发生过一样!因此,在函数的开始或结束时更新变量并不重要。
了解响应以及它们如何影响链状态是成为一个合格的智能合约程序开发人员的关键。关于错误处理的章节将更详细地介绍如何保护您的函数和确切的控制流。
练习题:写一个函数“sum-three”,求 3 个正数的和
(define-public (sum-three)
)
(print (sum-three u3 u5 u9))
;; --- Exercise validation code ---
(asserts! (is-eq (sum-three u3 u5 u7) (ok u15)) "That does not seem right, try again...")
(asserts! (is-eq (sum-three u20 u30 u40) (ok u90)) "Almost there, try again!")