编按:本文是QuarkChain创始人&CEO周期博士在以太坊技术论坛ethresear.ch发布的一篇技术文章,介绍了一个高效的Merkle tree方案设计。
原文链接:
https://ethresear.ch/t/efficient-on-chain-dynamic-merkle-tree/11054
简介
- 遵循以太坊2.0的无状态客户端的思想,我们实现了一个高效的链上动态Merkle tree(默克尔树):
- 链上包含性验证;
- 链上添加/就地更新;
- O(1) 存储空间成本;
- 更新/添加操作的 O(1) 存储写入成本。
背景
- Merkle tree广泛用于以极低存储成本在链上大量成员身份验证,例如 Uniswap 链上空投。无需上传链上所有用户大量的空投信息(比如,地址、数量),空投可以通过以下方式显著节省成本:
- 将树的根哈希存储在链上
- 使用链下计算证明用户奖励
- 用户通过链上提交证明来获取奖励
基本想法
- 类似于现有的静态Merkle tree,它使用默克尔证明来验证包含性,链上动态树的基本思想是在包含验证后重用默克尔证明来更新树的根哈希。树更新的步骤如下:
- 给定 LeafIndex、oldLeafHash、newLeafHash、oldRootHash、proof
- 用 oldLeafHash 和 proof 计算 rootHash。如果计算出的rootHash != oldRoothHash,则包含验证失败;否则继续
- 使用 newLeafHash 和 proof 计算 newRootHash,其中证明被重用,newRootHash 将是更新后树的根哈希
应用
Merklized ERC20
链上投票——治理提案投票可以廉价地使用 ERC20 快照并根据快照计算链上投票,而不需要保留 ERC20 余额变化(Compound)或链下快照的所有历史记录。 远程流动性挖掘——远程链上的合约对本地 ERC20 用户进行空投/流动性挖矿,其中 ERC20 快照通过去中心化预言机定期转发到另一条链。
QuarkChain/DynamicMerkleTree/blob/abe6c7ee8f2fef105649943d5e329e5f5e697f8d/contracts/MerklizedERC20.sol
/SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "hardhat/console.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "./DynamicMerkleTree.sol";
contract MerklizedERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => uint256) private _indices1;
uint256 private _totalSupply;
string private _name;
string private _symbol;