BLUR空投领取机制解析:交易嵌入Proof的原理与疑问
BLUR空投合约技术疑问解答
近期BLUR推出了需发布Twitter推文才能获得代币领取资格的空投活动,我分析了其合约代码,但仍有两个技术疑问。
领取函数代码
function claim( address account, uint256 amount, bytes32[] memory proof ) external { bytes32 leaf = keccak256(abi.encodePacked(account, amount)); require(!claimed[leaf], "Airdrop already claimed"); MerkleVerifier._verifyProof(leaf, merkleRoot, proof); claimed[leaf] = true; require(IERC20(token).transfer(account, amount), "Transfer failed"); emit Claimed(account, amount); }
Merkle验证库代码
pragma solidity 0.8.17; /** * @title MerkleVerifier * @dev Utility functions for Merkle tree computations */ library MerkleVerifier { error InvalidProof(); /** * @dev Verify the merkle proof * @param leaf leaf * @param root root * @param proof proof */ function _verifyProof( bytes32 leaf, bytes32 root, bytes32[] memory proof ) public pure { bytes32 computedRoot = _computeRoot(leaf, proof); if (computedRoot != root) { revert InvalidProof(); } } /** * @dev Compute the merkle root * @param leaf leaf * @param proof proof */ function _computeRoot( bytes32 leaf, bytes32[] memory proof ) public pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { bytes32 proofElement = proof[i]; computedHash = _hashPair(computedHash, proofElement); } return computedHash; } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash( bytes32 a, bytes32 b ) private pure returns (bytes32 value) { assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
疑问解答
1. 为何无法通过复制他人的proof绕过Twitter验证来作弊?
- 每个proof对应唯一的账户地址+空投金额组合:合约会用你调用
claim时传入的account和amount计算出leaf哈希值,这个值和原主人的leaf完全不同。用别人的proof验证自己的leaf,计算出的根节点会和合约里的merkleRoot不匹配,直接触发InvalidProof错误。 - 已领取的记录会被锁定:合约里的
claimed映射会记录每个leaf是否被领取过,就算你用原主人的地址和proof重复调用,只要对方已经领过,就会触发"Airdrop already claimed"的报错。
2. proof是如何生成的?在没有预言机的情况下,合约如何关联Twitter的用户行为?
- proof生成逻辑:BLUR的后台会先收集所有完成Twitter任务(发推文)的用户地址和对应空投金额,把这些
(account, amount)组合作为叶子节点构建Merkle树,计算出树的根节点merkleRoot并写入合约。每个用户的(account, amount)对应树里的一个叶子,后台会为这个叶子生成对应的Merkle证明(即proof数组),只有完成任务的用户才能从BLUR前端拿到自己的proof。 - Twitter行为的关联方式:合约本身不直接验证Twitter行为,所有Twitter任务的验证都是在BLUR的中心化后台完成的。用户发推文后,后台会检查推文内容、发布者是否绑定了对应钱包地址等条件,验证通过后才会把专属proof返回给用户,让用户可以调用
claim函数。合约只负责验证proof和merkleRoot的匹配性,以及地址、金额和proof的对应关系。
内容的提问来源于stack exchange,提问作者NFT_king
相关产品推荐
相关产品推荐

