1

我在智能合约和 Javascript(测试)中为 MerkleProof 获得了不同的哈希值

智能合约

pragma solidity ^0.8.0;

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

contract Token {
    bytes32 public merkleRoot;
    event MerkleRootChanged(bytes32 merkleRoot);
    event Leaf(bytes32 leaf);
    function setMerkleRoot(bytes32 _merkleRoot) external  {
        require(merkleRoot == bytes32(0), "Token: Merkle root already set");
        merkleRoot = _merkleRoot;
        emit MerkleRootChanged(_merkleRoot);
    }
    function claimToken(uint256 tokenId, bytes32[] memory merkleProof) public returns (bool){
        bytes32 leaf = keccak256(abi.encodePacked(msg.sender, tokenId));
        emit Leaf(leaf);
        return MerkleProof.verify(merkleProof, merkleRoot, leaf);
    }
}

令牌测试

require('@openzeppelin/test-helpers');

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

const token = artifacts.require('Token');

var testLeaves = [
    '0x627306090abaB3A6e1400e9345bC60c78a8BEf57 258831',
    '0x627306090abaB3A6e1400e9345bC60c78a8BEf57 166699',
    '0xf17f52151EbEF6C7334FAD080c5704D77216b732 889988',
    '0xC5fdf4076b8F3A5357c5E395ab970B5B54098Fef 707070',
    '0x821aEa9a577a9b44299B9c15c88cf3087F3b5544 566396',
    '0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2 888888',
    '0x2932b7A2355D6fecc4b5c0B6BD44cC31df247a2e 333666',
    '0x2191eF87E392377ec08E7c08Eb105Ef5448eCED5 658658',
    '0x0F4F2Ac550A1b4e2280d04c21cEa7EBD822934b5 130779',
    '0x6330A553Fc93768F612722BB8c2eC78aC90B3bbc 123456',
    '0x5AEDA56215b167893e80B4fE645BA6d5Bab767DE 9998888',
  ];

contract('Token', function (accounts) {
    beforeEach(async function () {
        this.token = await F24.new();
        console.log(accounts);
    });

    it('should return true for a valid leaf', async function () {
        //const leaves = accounts.map(x => keccak256(x));
        const leaves = testLeaves.map(x => keccak256(x));
        console.log(leaves);
        const merkleTree = new MerkleTree(leaves, keccak256, {sort: true});
        MerkleTree.print(merkleTree);
        const root = merkleTree.getRoot();
        console.log("root: ",root);
        var proof = merkleTree.getProof(leaves[0]).map(x => x.data);
        console.log("proof: ", proof);
        console.log("leaf: ", leaves[0]);
        console.log(merkleTree.verify(proof, leaves[0], root, keccak256));
        await this.token.setMerkleRoot(root, {from: accounts[0]});
        expect(await this.token.claimToken(258831, proof, {from: accounts[0]})).to.equal(true);
    });
});

它仅在散列 msg.sender 时有效,但不适用于连接数据和单个 uint256。我尝试使用带有以太坊地址和数量的 merkletree.js 创建一个 MerkleTree。MerkelTree 在链下创建(例如 node.js)并在链上验证。

有任何想法吗?

4

0 回答 0