name: midnight-core-concepts:smart-contracts description: 当询问关于Midnight智能合约、Compact语言基础、Impact虚拟机、合约状态分离、电路入口点、部署或交易执行模型时使用。
Midnight 智能合约
Midnight智能合约是复制状态机,通过处理交易来修改账本状态。与传统区块链不同,它们结合了零知识证明以实现数据隐私。
核心架构
合约 = 状态机 + ZK证明
交易 = 公共记录 + 零知识证明
- 公共记录:可见的状态变更
- ZK证明:遵循规则的加密验证
该证明在不暴露私有输入的情况下,展示了正确的执行过程。
Compact语言
Compact是Midnight用于编写隐私保护合约的领域特定语言。
合约结构
// 账本状态(链上,除非是MerkleTree否则公开)
ledger {
counter: Field;
commitments: MerkleTree<32, Bytes<32>>;
}
// 电路 = 带有ZK证明的入口点
export circuit increment(amount: Field): Void {
ledger.counter = ledger.counter + amount;
}
// 见证 = 带有私有输入的电路
export witness privateIncrement(
secret: Field // 私有,不公开
): Void {
assert secret > 0;
ledger.counter = ledger.counter + 1;
}
关键结构
| 结构 | 用途 |
|---|---|
ledger { } |
链上公共状态 |
export circuit |
公共入口点,生成ZK证明 |
export witness |
带有私有输入的入口点 |
assert |
必须满足的约束(通过ZK证明) |
公共状态与私有状态
公共状态(账本)
ledger { }中的所有内容都是公开可见的,除了MerkleTree的内容:
ledger {
public_counter: Field; // 所有人可见
public_address: Address; // 所有人可见
hidden_set: MerkleTree<32, T>; // 内容隐藏
}
私有状态
私有数据仅存在于用户的本地环境中:
- 见证输入(永远不上链)
- 电路执行中的局部变量
- Merkle树路径
export witness transfer(
secret_key: Bytes<32>, // 私有 - 仅在用户机器上
amount: Field // 私有 - 仅在用户机器上
): Void {
// 在不暴露密钥的情况下证明授权
const pub_key = persistentHash(secret_key);
assert pub_key == ledger.authorized;
// ... 其余逻辑
}
执行模型
交易阶段
-
格式良好性检查(无需账本状态)
- 格式验证
- ZK证明验证
- Schnorr证明验证
- 余额检查
-
保证阶段(必须成功)
- 合约查找
- Zswap报价应用
- 顺序合约调用执行
- 状态持久化
-
容错阶段(可能失败,但不回滚保证阶段)
- 类似机制,但失败不影响账本包含
- 保证阶段的效果无论如何都会保留
状态转换
旧状态 + 交易 → 新状态
↓
Impact程序执行
↓
效果必须与声明的效果匹配
↓
新状态存储
Impact虚拟机
Impact是执行合约逻辑的链上虚拟机。
特性
| 属性 | 描述 |
|---|---|
| 基于栈 | 操作从栈中压入/弹出 |
| 非图灵完备 | 有限执行,无无限循环 |
| 确定性 | 相同输入 → 总是相同输出 |
| 有Gas限制 | 程序有成本限制 |
栈结构
[上下文, 效果, 状态]
↓ ↓ ↓
交易数据 操作 合约数据
开发者须知
开发者编写的是Compact,而不是Impact。Impact是检查交易时可见的实现细节。
价值处理
合约通过Zswap与代币交互:
// 接收代币到合约
receive coins: Coin[];
// 从合约发送代币
send value: QualifiedValue, to: Address;
重要:代币操作记录在公共记录中,但不直接修改合约状态。它们是Zswap级别的操作。
合约部署
合约通过部署交易进行部署:
部署交易 = 合约状态 + Nonce
合约地址 = Hash(部署数据)
实用模式
简单计数器
ledger {
count: Field;
}
export circuit increment(): Void {
ledger.count = ledger.count + 1;
}
私有授权
ledger {
owner_hash: Bytes<32>;
value: Field;
}
export witness authorizedUpdate(
owner_secret: Bytes<32>,
new_value: Field
): Void {
assert persistentHash(owner_secret) == ledger.owner_hash;
ledger.value = new_value;
}
基于承诺的状态
ledger {
commitments: MerkleTree<32, Bytes<32>>;
nullifiers: Set<Bytes<32>>;
}
export witness spend(
amount: Field,
secret: Bytes<32>,
path: MerkleTreePath<32, Bytes<32>>
): Void {
const commitment = persistentCommit(amount, secret);
assert ledger.commitments.member(commitment, path);
const nullifier = persistentHash(commitment, secret);
assert !ledger.nullifiers.member(nullifier);
ledger.nullifiers.insert(nullifier);
}
参考资料
详细技术信息请参考:
references/compact-syntax.md- 完整的语言参考references/impact-vm.md- 虚拟机内部结构、操作码、Gas成本references/execution-semantics.md- 详细的交易执行流程
示例
工作合约:
examples/counter.compact- 最小合约示例examples/private-vault.compact- 私有状态管理