go+solidity 实现默克尔树并验证

golang 生成默克尔树 https://github.com/fachebot/merkle-distributor 

solidity 验证默克尔树并且用Bitmap限制每个证明只能用1次

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";


contract MerkleVerify {

    //记录当前默克尔树
    bytes32 public merkleRoot;

    //限制每个默克尔树,每个用户只能提现一次
    mapping(bytes32 => mapping(uint256 => uint256)) private merkleRootRecord;

    //计算 默克尔树。
    function withdraw(uint256 _index, uint256 _amount, bytes32[] calldata _proofs)
    external
    {

        //每个默克尔树,每个用户只能提现一次
        require(!_isClaimed(_index), "Multiple withdrawal is prohibited");

        //验证默克尔树
        bytes32 _node = keccak256(abi.encodePacked(_index, msg.sender, _amount));
        require(MerkleProof.verify(_proofs, merkleRoot, _node), "Validation failed");
        _setClaimed(_index);

    }

    //验证这个证明是否用过
    function _isClaimed(uint256 index) public view returns (bool) {
        uint256 claimedWordIndex = index / 256;
        uint256 claimedBitIndex = index % 256;
        uint256 claimedWord = merkleRootRecord[merkleRoot][claimedWordIndex];
        uint256 mask = (1 << claimedBitIndex);
        return claimedWord & mask == mask;
    }

    //添加用过的证明
    function _setClaimed(uint256 index) private {
        uint256 claimedWordIndex = index / 256;
        uint256 claimedBitIndex = index % 256;
        merkleRootRecord[merkleRoot][claimedWordIndex] = merkleRootRecord[merkleRoot][claimedWordIndex] | (1 << claimedBitIndex);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值