1. 引言
Aztec的架构,不同于当前“通过EVM兼容执行环境”所实现的区块链水平扩容趋势。Aztec内部笑称其构建的为首个非zkEVM协议。
Aztec专注于实现:
- 成为理解和需要智能合约隐私的开发者的终极解决方案。
Aztec为开发者提供构建隐私优先app所需的网络和一系列工具:
- 默认是匿名的
- 私有状态读写功能
- 私有隐私合约函数执行
为此,Aztec发现,现有的类似EVM这样基于account的系统无法满足要求,这也是为何Aztec是非EVM兼容的主要原因。同时,Aztec需设法让习惯于EVM类环境的智能合约开发人员尽可能直观地处理私有状态环境的独特架构。
自Aztec创立之初,就追求智能合约隐私:
- 私有计算不需依赖可信第三方或可信硬件的安全模块。
而在完全链上智能合约隐私世界,私有状态是一等公民,这就意味着:
- 无EVM,
- 无Solidity
- 无基于account的区块链架构
因为这些都会造成隐私泄露。
2. 隐私不兼容EVM
“为何EVM无法兼容隐私?”尽管目前已有EVM合约提供了类似mixing的primitive, non-programmable隐私功能。
不过,Aztec关注的是智能合约隐私:
- 在状态变量和函数层面,将可编程隐私纳入合约本身的整个系统。
在以太坊模型中,状态变量存储于公共公开的account-based tree中,为改变其中某个变量,需向整个以太坊世界广播你想要修改该tree中的那个叶子,该叶子节点中包含了什么,以及你想如何修改。这样就存在以下缺陷:
- 每个状态变量的当前值和历史所有值都是公开的。
- 执行状态变化所调用的函数是公开的。
- 这些函数修改的状态变量是公开的。
- 等等。
3. UTXO和Nullifier:最佳拍档
Aztec依赖于encrypted UTXO (Unspent Transaction Object)数据架构——与Bitcoin存储网络状态的技术一致。
借鉴了ZCash协议的UTXO-nullifier设计思想,Aztec隐私设计的基石为:
- 包含了encrypted UTXO的append-only data tree
- 包含了相应nullifiers的append-only data tree
在本文,UTXO也称为“notes”。对非专业人员关于UTXO架构的介绍可参看:Fully Confidential Ethereum Transactions: Aztec Network’s Privacy Architecture。
为了操作所拥有的note(为encrypted UTXO对象),用户采取以下步骤:
- 调用某函数
- 该函数请求对某私有状态进行编辑
- 该函数查询该用户的note数据库,获取属于该私有状态的所有notes
- 该用户(实际为用户的Aztec节点)证明,在其本地机器上,每个retrieved notes都存在于tree machine中的某个叶子节点,而不泄露具体是哪个叶子节点。
- 该用户可该note内做读、改、删操作。
- 该用户提供a nullifier,以阻止重复操作,并避免该用户再次读取相同的叶子节点。
- 该用户插入一个新的叶子节点,包含新的值,以更新该私有状态的值。
4. Aztec的智能合约框架
智能合约隐私的要求之一就是隐藏函数输入,借助zkSNARKs,可实现函数输入隐藏。
然后,Aztec构建了Noir——用于编写输入可隐藏函数的ZK编程语言,不过Noir中并未内置状态存储和状态变量的概念。
Aztec的智能合约框架可在Noir之上创建状态变量。
为实现隐私,需要有私有状态,而为实现私有状态,则需要有私有状态变量。所谓私有状态变量,其不能是notes。notes存储数据或信息,当与nullifiers结合使用可保护隐私,但notes是常量的且不可修改的。
变量应该是可变的。通过合约函数来修改变量。为此,需在以notes为基石的基础之上,创建一个私有状态变量的概念。
目前,notes可被销毁和创建,为创建私有状态变量的抽象,也许可在幕后巧妙地销毁和创建notes。
为此,Aztec的解决方案为:
- 声明一个私有状态变量
- 写函数:手写读取当前状态,编辑该状态,最后再写入更新状态。
在该方案中,定义了如下私有状态变量结构体:
- 需收集private state tree中的哪些notes
- 需证明在该tree中存在的哪些notes
- 需对哪些notes进行nullify
- 需创建哪些新的notes并插入到该tree中
而对于开发者来说,这些变量看起来就是变量。
以private token为例。
开发者首先声明一个private_balance
状态变量,Aztec支持通过transfer
函数来修改该balance。
这样,暴露的private_state
结构会指出:
- 如何创建和销毁notes,来表示某用户balance的增加或减少,与此同时,(通过该函数释放nullifiers)不泄露用户的balance。
私有状态变量可表示任何东西:
- Values:某具有value和owner域的对象,如一张$100的钞票。
- NFTs:具有唯一标识的对象,或包含了所有唯一属性的NFT。
- Accounts:由一个或多个owner所有的对象。
- Votes、DeFi positions、身份对象等等所能想到的任何东西。
私有状态变量存储数据或信息,借助如下2个属性实现可编程性:
- 可为mutable(updatable)私有状态变量,或,immutable(non-updatable)私有状态变量。
- 可包含单个note(即singleton),或包含一组notes(该类型也称为set)来描述某状态变量。
需注意的是,notes仅用于存储信息,而并不存储函数或合约。
事实上,管理UTXO通常会有点复杂,并涉及一些“问题”,包括如何:
- 高效查找tree中某人所拥有的notes
- 组合notes
- 对组合notes进行修改
- 借助nullifiers,销毁和更新notes
与以太坊账户不同,以太坊账户可以简单地贷记和借记,notes必须被创建、组合和作废,这代表了一种截然不同的思考模式。以太坊的values就仅仅是values,而notes 包含了 values。
幸运的是,Aztec在设计时考虑了抽象,从而消除了编写Aztec合约的开发难度,使其与编写以太坊智能合约尽可能相似。
Aztec智能合约框架的好处之一就是帮助合约开发者管理note的复杂性,该设计的主要目的之一就是将notes从dApps中整个抽象走。
应用程序开发人员欢欣鼓舞!其根本不必考虑UTXO或notes,而是可以调用所期望的函数,如token.transfer(amount)
或token.getBalance()
。
因为在应用层传输特定notes将会非常痛苦,为此,Aztec智能合约框架帮助将其从dApp层中完整抽离了。
参考资料
[1] Aztec团队2023年9月博客 Privacy Abstraction with Aztec: Smart contract privacy without the brain damage