1. 引言
Aztec团队11月发布了其设计的SST(Shared State Trees)数据结构,具体文档见:
并使用Noir做了一个censorable token的访问控制示例:
- https://github.com/AztecProtocol/aztec-packages/blob/master/yarn-project/noir-contracts/src/contracts/token_blacklist_contract/src/main.nr(Noir语言)
- 当前使用Merkle tree来commit
- 未来考虑使用其它链上多项式承诺方案来进一步减少storage需求,如https://github.com/geometryresearch/semacaulk(Solidity+Rust)。Semacaulk为定制的set membership proof Prover和Verifier,其使用链上多项式承诺来支持cheap insertion,且验证开销与验证单个Groth16 proof 相当。
SST(Shared State Trees)数据结构,支持:
- 在private execution上下文中访问状态信息,从而实现private状态管理。
- 在public execution上下文中访问状态信息,从而实现public状态管理。
SST的共享访问机制,在如下场景中尤其有用:
- 1)地址注册:支持合约与其他合约交互,更容易获取public execution和private execution中可访问的address storage。
- 2)不变值:特定常量值,如特定合约地址。受益于其存储在单个、不变位置,从而有public和private场景下的一致性。
- 3)访问控制:管理合约内权限,如token contract owner可mint新token,当在public execution和private execution中共享时效率更高。
2. single layer SST
contract specific SST为:
其中:
- C m \mathcal{C}_m Cm为:对特定合约 m m m的一组values V m , j ∀ j V_{m,j}\forall j Vm,j∀j的承诺值。【当前使用Merkle tree来commit。未来考虑使用其它链上多项式承诺方案来进一步减少storage需求,如https://github.com/geometryresearch/semacaulk(Solidity+Rust)。Semacaulk为定制的set membership proof Prover和Verifier,其使用链上多项式承诺来支持cheap insertion,且验证开销与验证单个Groth16 proof 相当。】
从single layer SST中读取某value:
- 公开读取:即直接读取 V m , j V_{m,j} Vm,j。
- private读取:即提供 V m , j ∈ C m V_{m,j}\in \mathcal{C}_m Vm,j∈Cm的membership proof。
更新single layer SST中某value V m , j V_{m,j} Vm,j为 V m , j ′ V_{m,j}' Vm,j′,需分2步:
- 1)证明 V m , j ∈ C m V_{m,j}\in \mathcal{C}_m Vm,j∈Cm,即当前value V m , j V_{m,j} Vm,j在state中。
- 2)当 V m , j V_{m,j} Vm,j替换为 V m , j ′ V_{m,j}' Vm,j′之后,计算新的承诺值 C m ′ \mathcal{C}_m' Cm′。
即每次更新single layer SST,需更新value V m , j V_{m,j} Vm,j值自身,以及,该single layer SST的承诺值 C m \mathcal{C}_m Cm。这种方式存在如下问题:
- 1)泄露合约:对某contract specific SST做查找时,会泄露所查找的是哪个合约。
- 2)使之前的membership proof失效。当有2个人同时更新同一个合约的值时,第一个完成的将使第二个的proof失效。
3. Multilayer SST
为解决合约泄露的问题,额外引入了一层,构建为Multilayer SST:
从Multilayer SST中读取某value:
- 公开读取:即直接读取 V i , j V_{i,j} Vi,j。
- private读取:即提供 V i , j ∈ C i V_{i,j}\in \mathcal{C}_i Vi,j∈Ci且 C i ∈ C \mathcal{C}_i\in \mathcal{C} Ci∈C 的membership proof。
更新Multilayer SST中某value V i , j V_{i,j} Vi,j为 V i , j ′ V_{i,j}' Vi,j′,需分3步:
- 1)证明 V i , j ∈ C i V_{i,j}\in \mathcal{C}_i Vi,j∈Ci且 C i ∈ C \mathcal{C}_i\in \mathcal{C} Ci∈C,即当前value V i , j V_{i,j} Vi,j在state中。
- 2)当 V i , j V_{i,j} Vi,j替换为 V i , j ′ V_{i,j}' Vi,j′之后,计算新的承诺值 C i ′ \mathcal{C}_i' Ci′。
- 3)基于新的 C i ′ \mathcal{C}_i' Ci′,计算新的承诺值 C ′ \mathcal{C}' C′。
这样, C i ∈ C \mathcal{C}_i\in \mathcal{C} Ci∈C的membership proof独立于其它合约。但在private execution中无法使用SST read,因其它合约的修改会使其membership proof失效。
4. slow update SST
为解决multilayered SST中的条件竞争问题,引入了“delayed” update 或 “slow” update的概念。逻辑上来说需维护跟踪2棵树:
- current tree:用于当前值
- pending tree:用于pending值
当epoch间隔达成时,会将当前current tree替换为pending tree,同时启用一棵新的pending tree。
这样大幅解决了读失效的问题,但仍有其它合约更高引起的更新失效的问题。同时,由于需跟踪2棵需同时更新的不同树,所需的storage changes量很高。
5. practical slow updates
为缓解更新所需的storage量,以及上面slow update SST的复杂性,在slow update SST的基础上进行了修改:
- 将epoch swap时的开销,摊销到整个updates中。
相应的更新流程为:
具体示例为:
参考资料
[1] Aztec 2023年11月 Shared State Trees - SST’s
Aztec系列博客
- Aztec Hybrid Rollup:混合zkRollup,而非zkEVM
- Proof Compression
- Aztec Connect即将主网上线
- Aztec connect bridge代码解析
- Aztec 征集 Rollup Sequencer去中心化提案
- Aztec的隐私抽象:在尊重EVM合约开发习惯的情况下实现智能合约隐私
- 完全保密的以太坊交易:Aztec网络的隐私架构
- Aztec.nr:Aztec的隐私智能合约框架——用Noir扩展智能合约功能
- Aztec交易架构解析
- 混合Rollup:探秘 Metis、Fraxchain、Aztec、Miden和Ola
- Claim Proof Bug——Aztec最大的45万美金bug bounty