For a merkle proof, how can I pass a Hex value into my solidity contract when it is expecting a bytes32 array?

1.1k views Asked by At

I have a functional merkle root/proof system that works flawlessly on etherscan. For example, I pass the proof that looks like this into the bytes32[] field, and it mints smoothly as long as the account is on the allowlist

0x7af845e970b0229e08846bfb99009787b76dcd04013f254aaeb2d9a088498318,0x1f957db768cd7253fad82a8a30755840d536fb0ffca7c5c73fe9d815b1bc2f2f,0x924862b314bd38813a325167aca7caee16318f07303bd8e9f81bbe5808575fbf,0xe5076a139576746fd34a0fd9c21222dc274a909421fcbaa332a5af7272b6dcb1,0x148c730f8169681c1ebfb5626eb20af3d2351445463a1fdc5d0b116c62dc58c8,0xf6a007a810573434e71c7550cc4458160fe5b66c03d050e6b5c4e400c131d82a

When I go to call the mint function via Ethers api, I cannot find a way to pass the proof into the function successfully. I'm getting the hex proof and passing that into the mint function like so:

const hashedAddress = keccak256(whitelistAddresses[1])
const proof = whitelistTree.getHexProof(hashedAddress)
const mintResp = await contract.mint(quantity, kdaAddress, proof);

The constant "proof" when I just do a simple console.log(proof) returns an object that looks like this

["0x7af845e970b0229e08846bfb99009787b76dcd04013f254aaeb2d9a088498318","0x1f957db768cd7253fad82a8a30755840d536fb0ffca7c5c73fe9d815b1bc2f2f","0x924862b314bd38813a325167aca7caee16318f07303bd8e9f81bbe5808575fbf","0xe5076a139576746fd34a0fd9c21222dc274a909421fcbaa332a5af7272b6dcb1","0x148c730f8169681c1ebfb5626eb20af3d2351445463a1fdc5d0b116c62dc58c8","0xf6a007a810573434e71c7550cc4458160fe5b66c03d050e6b5c4e400c131d82a"]

No matter what I try to convert this array to, I cannot get my mint function to accept it, I just get gas estimation errors. My question is: How do I pass my proof into the contract call?

const mintResp = await contract.mint(quantity, kdaAddress, proof);

1

There are 1 answers

0
Erim Varış On

As i understanding the problem is how to pass byte array parameter to the contract call. I am going to share with my past project's code which is very similar task that you want to do.

I am assuming that you successfully generated root hash and updated the smart contract.

let say we have an array of addresses on javascript like

let whitelist = ["0x0000....2", "0x0000....1", "0x0000....5"];

I am going to use two libraries

import { MerkleTree } from 'merkletreejs';
import keccak256 from 'keccak256';

First i get leaves from whitelist

const leaves = whitelist.map(x => keccak256(x));

Then create the merkleproof

const merkle = new MerkleTree(leaves, keccak256, {sortPairs : true});

Then create proof for selected address

const proof = merkle.getHexProof(keccak256(walletAddress.toString()))

Remember, walletAddress should be inside the whitelist array. You have to check it before doing all the process above.

And finally call the contract

const contract = new ethers.Contract(NFTContract, ABI, signer);
const call = await contract.mintPresale(1,proof,options);

If you dont know what options variable is then;

const options = {value: ethers.utils.parseEther((Number(whitelistPrice) * nftCount).toString())}

It simply add a value to transaction. Also it can be used for determining gasPrice and gasLimit.

I hope that answers your question :)

EDIT

I also mention my contract parameters

function mintPresale(uint numberOfTokens, bytes32[] calldata _merkleProof) public payable