如何在 Midnight 编写 smart contracts

发布: (2025年12月14日 GMT+8 06:52)
5 min read
原文: Dev.to

Source: Dev.to

心智模型:默认隐私

在写一行代码之前,需要改变思路。

在 Midnight:

  • 来自用户的所有数据默认是私有的。
  • 任何东西都不可能因“意外”而公开。
  • 隐私是显式控制的,而不是隐式的。

这得益于 Compact——Midnight 的智能合约语言,以及使用 Zero‑Knowledge Proofs (zkSNARKs) 在不泄露数据的情况下验证交易。

什么是 Compact?

Compact 是一种声明式语言,专门用于构建 隐私优先 的应用。

当你在 Compact 中编写合约时:

  1. 定义业务逻辑。
  2. 定义哪些数据是公开的。
  3. 定义哪些数据保持私有。

编译器会生成:

  • 用于你的 DApp 的 JavaScript / TypeScript API。
  • 生成零知识证明所需的加密工件。

所有这些都在开发者本地环境中完成。

Compact 合约的基本组成

Midnight 中的每个合约都由相同的模块构成:

Ledger state(公共状态)

存储在链上并对所有人可见的数据。

export ledger value: Uint;

Witnesses(私有输入)

witness 表示来自用户或前端的数据。默认私有,Compact 不允许意外泄露。

witness getSecret(): Bytes;

Circuits(可验证逻辑)

circuits 定义合约可以执行的操作。只有标记为 export 的 circuits 才能被外部调用。

export circuit get(): Uint {
  return value;
}

Constructor

在创建合约时执行一次。

constructor(sk: Bytes, v: Uint) {
  value = v;
}

选择性披露:disclose()

Compact 最重要的规则之一是:

不能在未明确声明的情况下将私有数据公开。

如果直接在账本中使用 witness 或作为返回值,编译器会报错。

正确写法:

export ledger publicData: Bytes;

export circuit record(): [] {
  publicData = disclose(getSecret());
}

错误写法(编译错误):

publicData = getSecret(); // ❌

这消除了其他生态系统中常见的一整类错误。

Opaque types:当 Compact 不应“查看”数据时

Compact 支持不透明类型,如 Opaque。这些类型:

  • 可以存储或转移。
  • 合约内部不能检查其内容。
  • 在前端(TypeScript)可见,但在 Compact 中不可操作。

它们适用于:

  • 消息
  • 元数据
  • 任意内容(例如公告板)
  • 承诺与哈希

用于无泄露数据验证的密码学原语

为了在不泄露数据的前提下验证属性,Compact 提供了:

persistentCommit(value, random);
transientCommit(value);

这些函数是以下场景的关键:

  • 私密投票
  • 可验证身份
  • 在不泄露凭证的情况下进行认证

Proof server 的角色

所有零知识魔法都在区块链之外完成。proof server

  • 在本地或受控基础设施上运行。
  • 永不向网络暴露私有数据。
  • 只返回有效的加密证明。

这使得区块链能够在 不知晓底层数据 的情况下验证事实。

在 Midnight 中如何思考合约

在 Midnight 编写合约时,建议自问:

  • 这条数据真的需要公开吗?
  • 网络需要验证什么,而不需要验证什么?
  • 我能在不泄露数值的情况下证明这个条件吗?
  • 谁在控制 proof server?

Compact 不仅提供工具,还强迫你仔细思考数据模型。

结论

在 Midnight 上编写智能合约不仅是学习一门新语言,更是采用一种全新的去中心化应用设计方式:

  • 默认隐私
  • 显式披露
  • 数据、逻辑与证明的清晰分离
  • 编译器层面的强化安全

如果你来自 Solidity、Plutus 等生态系统,Compact 起初可能会感觉不同。但一旦模型形成,你会发现很难回头。隐私不再是一个“特性”,而是语言本身的一部分。

Back to Blog

相关文章

阅读更多 »