使用 ECDSA 签名实现白名单和空投
分析
在区块链项目中,常见的白名单(whitelist)和空投(airdrop)场景一般采用 Merkle 树结构来存储用户地址和分发凭证。这种方式通过在链上存储 Merkle 根节点、在链下生成 Merkle 证明来实现批量验证和节省 gas。但是,随着 EIP-712 等签名标准的普及,也可以用 ECDSA(椭圆曲线数字签名算法)签名来代替 Merkle 树实现相似的功能。
Merkle 树做白名单与空投
-
原理:将所有用户地址(及其分配额度等信息)构建为一棵 Merkle 树,链上只存储 Merkle 根节点。
-
流程:
-
项目方生成 Merkle 树,并公开 Merkle 根。
-
用户领取空投时,提交自己的地址、分配额度、以及 Merkle 证明(proof)。
-
合约通过 proof 验证该用户确实在白名单里,允许领取。
-
-
优点:链上存储少,批量验证高效。
-
缺点:每个用户都需要生成和上传 proof,操作复杂,proof 数据量较大(影响 gas)。
ECDSA 签名做白名单与空投
-
原理:项目方为每个白名单用户生成一份独立的签名(如 EIP-712),链上通过公钥验证签名真伪。
-
流程:
-
项目方用私钥对每个用户的地址(和分配信息)签名。
-
用户领取时上传自己的签名和相关信息。
-
合约通过公钥(或 recover)验证签名是否由项目方生成。
-
-
优点:用户上传的数据更小,验证简单、gas 较低;不需要 proof。
-
缺点:每个用户都要获取项目方签名,不能批量验证;如果私钥泄漏,所有签名失效。
测试
src/patterns/AirDrops.sol
文件位置:
src/patterns/AirDrops.sol
test/patterns/AirDrops.t.sol测试结果:
forge test --gas-report --mt test_ad_ -vvv --optimize
-
Merkle 树方案:验证 proof 需要多次哈希,proof 长度随白名单人数增长,gas 逐步上升。
-
ECDSA 签名方案:只需一次
ecrecover,且上传数据量固定,gas 更低。 -
实际测试:当人数超过512之后,也就树的高度达到10之后,基本就是ecdsa的方式gas消耗更低了。
总结
规模变大之后,ECDSA的gas消耗更少,但是ECDSA 需要为每个用户生成一个独立的签名文件,并确保分发到每个用户手中。对于 100,000 个用户,这是管理和分发上的噩梦。而 Merkle 树只需计算一个 Root,然后用户可以自己根据公共的白名单列表和开源工具生成 Proof。实际项目可结合两种方案,按需选择。
对应源码
本文配套代码固定到提交
8960383;Gas 数据会随编译器、优化器参数和 EVM 版本变化。