'Merkle Proof in python using Keccak256
I'm trying to create a whitelist for an NFT using a Merkle tree to save on gas costs. I saw a great implementation here, in javascript, but I would like to do it in Python. Doesn't seem like I'm able to create a merkle tree using keccak hashing, which I think it necessary to do for the etheruem blockchain. Open-zeppelin's MerkleProof.sol uses kaccack hashing to verify a leaf. I'm guessing I can just change this to use sha256 instead, but I don't like these quick fixes.
Here is what I tried below:
from pymerkle import MerkleTree
from Crypto.Hash import keccak
from scripts.helpful_scripts import get_account
from brownie import NFTCollectible, network, config
def hash(address):
k = keccak.new(digest_bits=256)
k.update(address.encode("utf_8"))
return k.hexdigest()
def main():
account = get_account()
nft_collectible = NFTCollectible[-1]
whitelistedAddresses = [
"0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"0x78D6CF3DEF45AF458442E787FE6E64A03750AB94",
"0xA7B0E4CF55AF900F6E80D619AE1E00965044BC4E",
"0x38C4278F42A26A588176017F5E4F6ED831835EA2",
"0x9F9A0AA0507FE79CA1FF8F26A8D84BD8BB0EC9DF",
"0xDABF258F5619942D19AD87C3472FABE893B26D7D",
"0xD30ED9C457C7D32F3F7B949964191E4084C53F66",
]
leafNodes = []
for address in whitelistedAddresses:
hashedAddress = hash(address)
leafNodes.append(hashedAddress)
merkleTree = MerkleTree()
for leaf in leafNodes:
merkleTree.update(leaf)
print(merkleTree)
root = merkleTree.rootHash.decode("utf-8")
print(root)
It does return a Merkle tree, but hashed using sha256 as pymerkle doesn't have keccak hashing. (The keccak library above is used for hashing the wallets). Running this returns a different Merkle tree than the one in JS. I'm not even sure if the difference is because of the hashing.
This is how I would like to verify in solidity:
// using merkle tree for whitelist
bytes32 leaf = keccak256(abi.encodePacked(msg.sender)); // this will work good since the wallets are hashed by keccak
require(
MerkleProof.verify(merkleProof, whitelistedMerkleRoot, leaf), // this will fail
"Not on the whitelist"
);
Solution 1:[1]
Did you try overriding existing Pymerkle methods in order to be able to use a new encoding option ?
You would need to include type here https://github.com/fmerg/pymerkle/blob/6d4c9eb502fe7aa6117123e7f1ab8cf84a38e7b4/pymerkle/hashing/machine.py#L9
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Diego Iruretagoyena |