티스토리 뷰
NFT 민팅할때 보통 화이트리스트에게 먼저 NFT를 민팅할 권리를 준다.
솔리디티에서 이부분을 구현할때
메모리나 맵에 올리면
가스비로 아주 큰 비용을 지불해야한다.
이 문제를 해결하는것이 머클트리이다
사용법
https://medium.com/@ItsCuzzo/using-merkle-trees-for-nft-whitelists-523b58ada3f9
간략하게말하면
js단:
(1) WL 리스트를 암호화해서(keccak256쓰던 SHA쓰던 본인선택) 머클트리에 넣는다.
그럼 암호화된 전체 노드가 나오는데 Root Node만 키처럼 들고있음
const leaves = whitelistAddresses.map(addr => keccak256(addr));
tree = new MerkleTree(leaves, keccak256, { sort: true });
const root_merkle = tree.getRoot();
(2) 실제로 민팅할때는 주소를 암호화한 값을 머클트리에 넣었을때 proof값을 받아서,
컨트랙트로 보낸다.
const hexProof = tree.getHexProof(keccak256(addr1.address));
// console.log('hex: '+hexProof.toString());
await nft_contract.connect(addr1).whitelistMint(hexProof);
솔리디티:
Root Node의 값과 머클트리 proof 값, 그리고 지갑주소값이 필요하다
MerkleProof 라이브러리로 두 값이 verify되는지 확인한다.
contract Merkle is Ownable{
bytes32 public merkleRoot;
mapping(address => bool) public whitelistClaimed;
function whitelistMint(bytes32[] calldata _merkleProof) external{
require(!whitelistClaimed[msg.sender], "Address has already claimed.");
bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
//Verify the provided _merkleProof
require(MerkleProof.verify(_merkleProof, merkleRoot, leaf), "Invalid Proof, No WL");
whitelistClaimed[msg.sender] = true;
//실제민팅하는곳
}
function setMerkleRoot(bytes32 _merkleRoot) public {
merkleRoot = _merkleRoot;
}
}
꼭 이런순서로 짤 필요는 없지만
어떤 구성요소가 필요한지 보고 시작하면 편하다
'dev > Solidity' 카테고리의 다른 글
Hardhat vs Truffle (0) | 2022.06.02 |
---|---|
deploying contract, Compiler specific version warnings (0) | 2022.05.20 |
Storage, Memory and Calldata (0) | 2022.03.27 |
Events (0) | 2022.03.15 |
Contract to Contract (0) | 2022.03.15 |
댓글