我在智能合约和 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)并在链上验证。
有任何想法吗?