Merkle Tree本地测试(js and solidity)

JS生成MerKle Tree

代码如下,需要安装merkletreejs keccak256

const { MerkleTree } = require('merkletreejs');
cost keccak256 = require('keccak256')

const whitelistAddress = ['0x5B38Da6a701c568545dCfcB03FcB875f56beddC4', 
'0xA5A18D604b438B405a1C5a11F1cb923DBaC7bA1B', ' 0x9470F6dE2A4787a534CD21C8E115CFE1513189DA']

const leafNodes = whitelistAddress.map((addr) => keccak256(addr))
const merkleTree = new MerkleTree(leafNodes, keccak256, { sortPairs: true })
const rootHash = merkleTree.getHexRoot()
console.log('merkleTree:', merkleTree.toString())
console.log('rootHash:', merkleTree.getHexRoot())


console.log("-----------------");
console.log("生成 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 proof");

const proof = merkleTree.getHexProof(keccak256("0x5B38Da6a701c568545dCfcB03FcB875f56beddC4"));
console.log("proof:",proof);  // 只有在列表中的才可以生成出proof

console.log("------------------");
console.log("认证 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 是否在白名单中");
const v = merkleTree.verify(proof,keccak256("0x5B38Da6a701c568545dCfcB03FcB875f56beddC4"),rootHash);
console.log(v);

针对whitelistAddress生成root,再针对0x5B38Da6a701c568545dCfcB03FcB875f56beddC4生成proof,最后用proof和0x5B38Da6a701c568545dCfcB03FcB875f56beddC4进行校验判断

运行之后得到下面的结果

merkleTree: └─ 50c87af1a426b59a17b6c16a9de10875012947e06ea6c89494fb3afe492e1d78
   ├─ 3fb0a9cab2f2350ff96e70c80f6797c9549662d480a67ec9a00abc31264c7bbb
   │  ├─ 5931b4ed56ace4c46b68524cb5bcbf4195f1bbaacbe5228fbd090546c88dd229
   │  └─ 67291d3d99b77ed052d1c50f719ae942e92c20b63f93fbad3bc707182f2256bf
   └─ 8c1b4d3f6998419f132d37bd1138d350ee57df13b6076744bccb5f6b8c8a305a
      └─ 8c1b4d3f6998419f132d37bd1138d350ee57df13b6076744bccb5f6b8c8a305a

rootHash: 0x50c87af1a426b59a17b6c16a9de10875012947e06ea6c89494fb3afe492e1d78
-----------------
生成 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 proof
proof: [
  '0x67291d3d99b77ed052d1c50f719ae942e92c20b63f93fbad3bc707182f2256bf',
  '0x8c1b4d3f6998419f132d37bd1138d350ee57df13b6076744bccb5f6b8c8a305a'
]
------------------
认证 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 是否在白名单中
true

solidity校验

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

import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MerkleTest is Ownable {
    bytes32 private root;
    function isWhiteList(address _address, bytes32[] calldata _merkleProof) public view returns (bool){
            bytes32 leaf = keccak256(abi.encodePacked(_address));
            require(MerkleProof.verify(_merkleProof, root, leaf), "Incorrect proof");
            return true; // Or you can mint tokens here
        }
    function setMercleRoot (bytes32 _merkleRoot) public onlyOwner {              
        root = _merkleRoot;
    }
 
}

1.先设置好root

2.输入address校验

输入proof的时候有坑,一定要双引号

["0x67291d3d99b77ed052d1c50f719ae942e92c20b63f93fbad3bc707182f2256bf","0x8c1b4d3f6998419f132d37bd1138d350ee57df13b6076744bccb5f6b8c8a305a"]

可以看到校验通过

参考:

Last updated