批量数据组成默克尔树,合约进行验证空投。

  • Verin
  • 更新于 2022-04-15 20:11
  • 阅读 4923

批量数据组成默克尔树,合约进行验证空投。

前端

之前写空投太暴力了,直接就是批量转账,后来发现手续费极高,老板不愿意了;后来看到有方案是将空投名单全部生成默克尔根交给合约,然后用户自己去领取的时候合约根据数据验证,这样老板就不需要出gas费了,用户可以用自己的钱去换空气币啦👀️ !放出代码供大家交流学习;

1.一般空投的数据格式都是: [{address:0xxxxxxxxxx...xxx,value:10000},{address:0xxxxxxxxxx...xxx,value:10000}]

2.我们先设置默克尔根供合约使用:

let leafs = [];
  for (let k = 0; k < list.length; k++) {
    let leaf = ethers.utils.solidityKeccak256(["address", "uint256"], [list[k].address, list[k].value]);
    leafs.push(leaf);
  }
  let tree = new MerkleTree(leafs, keccak256, { sort: true });
  let root = tree.getHexRoot();

3.设置结点数据让合约验证领空投的数据:

//叶子结点数据
  let leafs = [];
  for (let k = 0; k < list.length; k++) {
    let leaf = ethers.utils.solidityKeccak256(["address", "uint256"], [list[k].address, list[k].value]);
    leafs.push(leaf);
  }

  //树根
  let tree = new MerkleTree(leafs, keccak256, { sort: true });
  //叶子proof
  let proofs = [];
  leafs.map((item) => {
    proofs.push(tree.getHexProof(item));
  });

  let res = [];
  for (let index = 0; index < list.length; index++) {
    res.push([list[index].address, list[index].value, proofs[index]]);
  }

合约

4.空投合约:

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.9.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

contract Airdrop is Ownable {
    using SafeERC20 for IERC20;
    bytes32 root;
    mapping(address => bool) isGet;
    address tokenAdress;

    function hasGet(address _address) public view returns (bool) {
        return isGet[_address];
    }
    //设置根
    function setMerkleRoot(bytes32 _root) external onlyOwner {
        root = _root;
    }
   //验证和获取空投
    function getDrop(
        address _address,
        uint256 _amount,
        bytes32[] calldata _proofs
    ) external {
        require(isGet[_address] == false, "has got");
        bytes32 _leaf = keccak256(abi.encodePacked(_address, _amount));
        bool _verify = MerkleProof.verify(_proofs, root, _leaf);
        require(_verify, "fail");
        isGet[_address] = true;
        IERC20 dropToken = IERC20(tokenAdress);
        require(
            dropToken.balanceOf(address(this)) >= _amount,
            "Insufficient balance"
        );
        dropToken.safeTransfer(_address, _amount);
    }

    function setTokenAddress(address _address) public {
        tokenAdress = _address;
    }
}

以上就是空投的主要代码,在rinkeby上测试成功;

点赞 5
收藏 12
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

8 条评论

请先 登录 后评论
Verin
Verin
discord:Verin#2256 v: daqingchong-pro 备注来意