> For the complete documentation index, see [llms.txt](https://docs.stacks.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stacks.co/learn/zh/clarity.md).

# Clarity

一种为可读性和可预测性而构建的智能合约语言。

<div data-with-frame="true"><figure><img src="https://629346125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH74xqoobupBWwBsVMJhK%2Fuploads%2FhNoJj4p1Tn1ICZ3RHBqb%2Fclarity-cover.png?alt=media&amp;token=bfe03cb2-6bc9-4bd7-840c-bd5a5b3d6e84" alt=""><figcaption></figcaption></figure></div>

{% hint style="info" %}
前往 [Clarity 速成课程](/get-started/clarity-crash-course.md) 以构建你的第一个 Clarity 智能合约。
{% endhint %}

Clarity 是一种 **可判定的** 智能合约语言，侧重可预测性和安全性，专为 Stacks 区块链设计。它从一开始就为开发者更容易编写安全、可靠的智能合约而构建。Clarity 具有若干独特特性，使其成为编写智能合约的理想选择。

Clarity 背后的设计决策在很大程度上借鉴了 Solidity 常见漏洞中的经验教训，并创造出一种专门以安全为首要目标的语言。

{% hint style="info" %}
当前的语言版本是 Clarity 6，它随 Epoch 4.0 在比特币区块 960,230（[SIP-044](https://github.com/stacksgov/sips/blob/main/sips/sip-044/sip-044-clarity6.md)）时激活。未设置版本的合约部署将使用 Clarity 6。部署交易仍然可以固定到更早的版本，而工具也可以设置自己的默认值： `@stacks/transactions` 7.6.0 部署时使用 Clarity 4，除非你传入 `clarityVersion`。 [函数参考](https://docs.stacks.co/reference/clarity/functions) 会为每个内置函数标注其引入时的版本。
{% endhint %}

### Clarity 有何不同

以下部分摘自 [Clarity 书籍](https://book.clarity-lang.org/ch00-00-introduction.html):

智能合约语言的数量逐年增长。选择第一门语言可能很有挑战，尤其对初学者而言。选择在很大程度上取决于你感兴趣的生态系统，尽管有些语言不仅适用于单一平台。每种语言都有其优点和缺点，逐一讨论它们已超出本书范围。相反，我们将聚焦于 Clarity 的独特之处，以及为什么如果你需要极致的安全性和透明度，它是首选。

Clarity 的核心原则之一是其设计即安全。设计过程受到对智能合约工程整体领域中常见陷阱、错误和漏洞的研究所指导。现实世界中有无数例子表明，开发者失误会导致大量代币被盗或损失。举两个重要例子：一个后来被称为 Parity 漏洞的问题导致了价值数百万美元的以太坊不可挽回地损失。其次，对 The DAO（“去中心化自治组织”）的攻击造成了如此巨大的经济损失，以至于以太坊基金会决定进行一次颇具争议的硬分叉来撤销这次盗窃。这些以及许多其他错误，本可以在语言本身的设计中得到避免。

#### Clarity 是解释型而非编译型

Clarity 代码会被解释执行，并且会按原样提交到链上。Solidity 和其他语言在提交到链上之前会先被编译为字节码。编译型智能合约语言的危险有两方面：首先，编译器会增加一层复杂性。编译器中的错误可能导致生成与预期不同的字节码，从而带来引入漏洞的风险。其次，字节码对人类不可读，这使得验证智能合约实际在做什么变得非常困难。问问你自己，你会签署一份你读不懂的合同吗？如果你的回答是否，那么为什么智能合约会有不同？在 Clarity 中，所见即所得。

#### Clarity 是可判定的

可判定语言具有这样一种特性：仅从代码本身，你就能确切知道程序会做什么。这避免了诸如停机问题之类的问题。使用 Clarity，你可以确信，对于任何输入，程序都会在有限步内停机。简单来说：程序执行一定会结束。可判定性还允许对调用图进行完全的静态分析，因此你能在执行前准确了解精确成本。Clarity 调用不可能在调用过程中“耗尽 gas”。我们会在关于可判定性的安全深度解析中进一步探讨这一理念，以及图灵完备性的讨论。

#### Clarity 不允许重入

重入是指一个智能合约调用另一个智能合约，而后者又回调到第一个合约——该调用“重新进入”了同一逻辑。它可能允许攻击者在合约尚未来得及更新内部余额表之前，多次触发代币提取。Clarity 的设计将重入视为一种反特性，并在语言层面禁止它。

#### Clarity 防止溢出和下溢

当一次计算得到的数值过大或过小，以致无法存储时，就会发生溢出和下溢。此类事件会使智能合约陷入混乱，且可能被攻击者在编写糟糕的合约中故意触发。通常这会导致合约被冻结或代币被掏空。在 Clarity 中，任何类型的溢出或下溢都会自动导致交易中止。

#### 内置支持自定义代币

发行自定义同质和非同质代币是智能合约的一个流行用例。自定义代币功能已内置于 Clarity 语言中。开发者无需担心创建内部余额表、管理供应量以及发出代币事件。后续章节将深入介绍如何创建自定义代币。

#### 在 Stacks 上，交易通过后置条件保障安全

为了进一步保护用户代币，可以为交易附加后置条件，以在交易完成后断言链状态已按某种方式发生变化。例如，调用智能合约的用户可以附加一个后置条件，声明调用完成后，恰好有 500 STX 应从一个地址转移到另一个地址。如果后置条件检查失败，则整个交易会回滚。由于自定义代币支持已直接内置于 Clarity 中，后置条件也可以以同样的方式用于保护任何其他代币。

#### 返回响应不能被忽视

公共合约调用必须返回所谓的响应，用以表示成功或失败。任何调用另一个合约的合约都必须正确处理该响应。未能如此的 Clarity 合约是无效的，无法部署到网络上。像 Solidity 这样的其他语言允许在不要求检查返回值的情况下使用底层调用。例如，如果开发者忘记检查结果，代币转账可能会静默失败。在 Clarity 中，不可能忽略错误，尽管这显然也会阻止开发者一方出现有缺陷的错误处理。有关响应和错误处理的内容在函数和控制流章节中有大量介绍。

#### 组合优于继承

Clarity 采用组合优于继承的方式。这意味着 Clarity 智能合约不像 Solidity 等语言中那样彼此继承。开发者改为定义 trait，然后由不同的智能合约来实现它们。这样合约就能以更大的灵活性符合不同的接口。无需担心复杂的类树以及具有隐式继承行为的合约。

#### 访问底层链：比特币

Clarity 智能合约可以读取比特币底层链的状态。这意味着你可以将比特币交易作为智能合约的触发器！Clarity 还内置了若干函数，用于验证 secp256k1 签名并恢复密钥。

### Clarity 6 新增内容

后置条件从外部保护交易。自 Clarity 4 起，合约也可以通过以下方式从内部保护自己的调用 `restrict-assets?` 以及 `as-contract?`，它们列出了一段代码允许移动的资产。在 Clarity 6 中，它们的质押许可是 [`with-staking`](https://docs.stacks.co/reference/clarity/functions#with-staking)，这是 Clarity 6 对 `with-stacking`的名称，它限制一次对 `pox-5` 的调用可锁定的总微 STX（uSTX）数量；此外还新增了 [`with-pox`](https://docs.stacks.co/reference/clarity/functions#with-pox)，它允许更改质押状态但不再额外锁定的调用，例如 `unstake`.

现在有两个内置函数负责执行过去由合约委托给库合约的比特币交易检查： [`get-bitcoin-tx-output?`](https://docs.stacks.co/reference/clarity/functions#get-bitcoin-tx-output) 解析一笔原始比特币交易，并连同 txid 一起返回某个输出的脚本和金额， [`verify-merkle-proof`](https://docs.stacks.co/reference/clarity/functions#verify-merkle-proof) 检查某个 txid 是否位于区块的默克尔树中。Clarity 6 还新增了 [`ed25519-verify`](https://docs.stacks.co/reference/clarity/functions#ed25519-verify) 以及 [`secp256k1-decompress?`](https://docs.stacks.co/reference/clarity/functions#secp256k1-decompress)，以及 `concat` 接受两个以上的参数。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.stacks.co/learn/zh/clarity.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
