# Clarity

<div data-with-frame="true"><figure><img src="/files/9e7ff9ed20c997bf96fe34d93b7f6fbab61ec60a" alt=""><figcaption></figcaption></figure></div>

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

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

Clarity 背后的设计决策在很大程度上借鉴了对常见 Solidity 漏洞的经验教训，并创造出一种从一开始就将安全性和可靠性作为核心目标的语言。

### 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，然后由不同的智能合约去实现这些 trait。这使合约能够以更大的灵活性适配不同的接口。无需担心复杂的类树以及具有隐式继承行为的合约。

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

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


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

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

The question should be specific, self-contained, and written in natural language.
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.
