FROM : https://docs.blockstack.org/core/smart/overview.html
Clarity是Blockstack的智能合约语言,用于Stacks区块链。Clarity支持通过编程控制栈区块链中的数字资产(例如,BNS名称、Stacks令牌等等)。本节讨论以下主题:
谁应该使用智能合约?
语言与程序设计
编程环境
清晰合同的基本构件
hello world示例
语言规则和限制
Clarity在预发布中
Clarity及其附带的工具集和SDK都在预发行版中。如果您遇到有关Clarity的问题或有特性请求,请在blockstack/blockstack-core存储库上创建一个问题。要阅读以前的或加入正在进行的关于智能合约的讨论,特别是关于Clarity的讨论,请访问Blockstack论坛中的智能合约主题。
谁应该使用智能合约?
您可以使用Clarity编写独立的合约,或者编写使用blockstack.js库编写的去中心化应用程序(DApps)的一部分合约。智能合约允许双方以一种自动化的、可审计的、安全的方式交换任何有价值的东西(钱、财产、股票),而不需要中间人的服务。尼克•萨博(Nick Szabo)介绍了智能合约的典型比喻——自动售货机。
用尼克•萨博(Nick Szabo)的比喻来说,自动售货机就是一份智能合约。买方和机器所有者是双方。当购买者使用自动售货机时,它会执行一组硬编码的操作。机器显示商品及其价格。购买者将钱输入机器,机器将决定这些钱是否没有达到或超过商品的价格。根据金额,机器要求更多的钱,分发一个项目,或分发和项目和变化。
并不是每个应用程序都需要智能合约。如果您不确定或不熟悉智能合约的概念,那么在清晰地工作之前,您应该阅读关于智能合约的良好的一般解释。
语言与程序设计
Clarity与大多数其他智能合约语言有两个基本区别:
- 该语言不需要被编译。
- 语言不是图灵完备的。
这些差异允许对程序进行静态分析,以确定运行时成本和数据使用情况等属性。
Clarity智能合约由两部分组成——数据空间和一组函数。只有关联的智能合约才可以修改区块链上相应的数据空间。函数是私有的,除非它们被定义为公共函数。用户通过在调用公共函数的区块链上广播事务来调用智能合约的公共函数。
合约还可以从其他智能合约调用公共函数。对智能合约进行静态分析的能力允许用户确定合约之间的依赖关系。
编程环境
Clarity是一种列表处理(LISP)语言,因为它是不编译的。省略编译可以防止在编译器级别引入错误或bug的可能性。你可以用文本编辑器在任何操作系统上编写Clarity智能合约程序。您可以使用任何您熟悉的编辑器,比如Atom、Vim,甚至Notepad。使用编辑器创建的Clarity文件具有.clar扩展名。
Clarity是预发行版,还没有直接与实时Stacks区块链交互。对于预发布阶段,您需要一个测试环境来运行Clarity合约。Blockstack提供了一个名为clear -developer-preview的Docker映像,您可以使用它,也可以用代码在本地构建一个测试环境。Docker映像或本地环境都足以测试独立合约的Clarity编程。
您可以使用clear -cli命令行来检查、启动和执行独立的Clarity合约。您可以使用相同的命令行创建模拟挖掘堆栈并检查区块链。
Blockstack预计,一些去中心化的应用程序(DApp)将希望使用Clarity合约作为其应用程序的一部分。为此,您应该使用Clarity SDK,它也在预发行版中。SDK是一个开发环境、测试框架和部署工具。它提供了一个库,用于与使用blockstack.js库编写的DApp的Clarity合约进行安全交互。
Clarity合约的基本构件
Clarity的基本组成部分是原子和列表。原子是一个连续字符的数字或字符串。原子的一些例子:
- token-sender
- 10000
- SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR
原子可以是程序中出现的本机函数、用户定义函数、变量和值。按约定更改数据的函数以!结束。例如insert-entry!函数。
列表是用()括号括起来的原子序列。列表可以包含其他列表。列表的一些例子是:
- (get-block-info time 10)
- (and 'true 'false)
- (is-none? (get id (fetch-entry names-map (tuple (name "blockstack")))))
您可以使用;;(双分号)。支持独立注释和内联注释。
;; Transfers tokens to a specified principal
(define-public (transfer (recipient principal) (amount int))
(transfer! tx-sender recipient amount)) ;; returns: boolean
使用clear -cli命令检查并启动Clarity (.clar)程序。
hello-world例子
任何语言中最容易运行的程序是hello world程序。清楚地说,您可以编写hello-world.clar”程序。
(begin
(print "hello world"))
这个程序定义了一个hello-world表达式,它在合约启动时被执行。begin是一个原生的Clarity函数,它计算输入到它的表达式并返回最后一个表达式的值。这里有一个print表达式。begin和print都包含在()括号中。
对于预发布版本,Blockstack测试环境包括clear -cli命令,用于与合约进行交互,并支持SQLite以支持数据空间。您可以创建一个SQLLite数据库来保存与Clarity合约相关的数据。这个数据库通过记录合约活动来模拟区块链。
如果不首先初始化数据库中的clear合约的数据空间,您甚至不能运行一个hello-world程序。可以使用clear -cli initialize命令设置数据库。
clarity-cli initialize /data/db
此命令初始化驻留在容器/data目录中的db数据库。您可以为数据库命名任何您喜欢的名称,不需要db这个名称。你可以使用SQLite查询这个数据库:
sqlite> .open db
sqlite> .tables
contracts maps_table type_analysis_table
data_table simmed_block_table
sqlite>
初始化合约的数据空间后,可以检查Clarity程序是否存在问题。
clarity-cli check ./hello.clar /data/db
顾名思义,检查确保合约定义通过类型检查;传递程序将返回0(0)的退出码。一旦合约通过检查,就可以启动它。
root@4224dd95b5f5:/data# clarity-cli launch hello ./hello.clar /data/db
Buffer(BuffData { data: [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] })
Contract initialized!
因为Clarity不支持简单字符串,所以它将hello world字符串存储在缓冲区中。打印出该字符串将显示每个字符的ASCII表示形式。你可以在相应的数据库中看到这个合同的启动记录:
sqlite> select * from contracts;
1|hello|{"contract_context":{"name":"hello","variables":{},"functions":{}}}
sqlite> select * from type_analysis_table;
1|hello|{"private_function_types":{},"variable_types":{},"public_function_types":{},"read_only_function_types":{},"map_types":{}}
sqlite>
语言规则和限制
Clarity智能合约有以下局限性:
- 惟一的原子类型是布尔值、整数、固定长度缓冲区和主体
- 递归是非法的,没有lambda函数。
- 循环只能通过map、filter或fold来执行
- 支持原子类型列表,但是,语言中唯一的可变长度列表作为函数输入出现;不支持append或join之类的列表操作。
- 变量是通过let绑定创建的,不支持对set这样的函数进行修改。
网友评论