NFT

NFT空投预售的几种方法

2023-03-19  本文已影响0人  区块链董叔

预售是运营NFT的常见手段。

一、链上预售白名单

方法是在合约的存储中简单地包含一个地址映射变量,将每个地址映射到一个布尔值,或者每个地址映射到该地址允许的铸币数量。

1. mapping(address => uint8) _allowList;  

2. 

3.functionsetAllowList(

4.        address[] calldata addresses,  

5.         uint8 numAllowedToMint  

6.    ) external onlyOwner {  

7.for(uint256 i = 0; i < addresses.length; i++) {

8.            _allowList[addresses[i]] = numAllowedToMint;  

9.       }  

10.     } 

这种方法使用起来简单,但在配置白名单时,将会耗费大量的gas费用。

二、默克尔树

使用openzeppelin的MerkleProof.verify进行验证。

在合约中只需要存储roothash,验证时用户需传入默克尔树证明,新增叶子节点时,也只需要更新roothash。

验证通过后可领取空投,并将状态改为已领取,避免重复领取。

1.import'@openzeppelin/contracts/utils/cryptography/MerkleProof.sol';

2. ...  

3. // declare bytes32 variables to store each root (a hash)  

4. bytes32publicgenesisMerkleRoot;

5. bytes32publicauthorsMerkleRoot;

6. bytes32publicpresaleMerkleRoot;

7. ...  

8. // separate functions to set the roots of each individual Merkle Tree  

9. functionsetGenesisMerkleRoot(bytes32 _root) external onlyOwner {

10.  genesisMerkleRoot = _root;  

11. }  

12.functionsetAuthorsMerkleRoot(bytes32 _root) external onlyOwner {

13.  authorsMerkleRoot = _root;  

14.}  

15.functionsetPresaleMerkleRoot(bytes32 _root) external onlyOwner {

16.   presaleMerkleRoot = _root;  

17. }  

18. ...  

19. // create merkle leaves from supplied data  

20.function_generateGenesisMerkleLeaf(

21.   address _account,  

22.   uint256 _tokenId  

23. )  internal  pure  returns (bytes32) {  

24.returnkeccak256(abi.encodePacked(_tokenId, _account));

25. }  

26.function_generateAuthorsMerkleLeaf(

27.   address _account,  

28.   uint256 _tokenCount  

29. )  internal  pure  returns (bytes32) {  

30.returnkeccak256(abi.encodePacked(_account, _tokenCount));

31. }  

32.function_generatePresaleMerkleLeaf(

33.   address _account,  

34.  uint256 _max  

35. )  internal  pure  returns (bytes32) {  

36.returnkeccak256(abi.encodePacked(_max, _account));

37. }  

38. ...  

39. // function to verify that the given leaf belongs to a given tree using its root for comparison  

40.function_verifyMerkleLeaf(

41.   bytes32 _leafNode,  

42.   bytes32 _merkleRoot,  

43.   bytes32[] memory _proof ) internal view returns (bool) {  

44.returnMerkleProof.verify(_proof, _merkleRoot, _leafNode);

45. }  

然后,调用每个 mint/claim 函数都需要使用发送者的地址来生成和验证叶子节点。 例如,当使用 for loop 铸造多个代币时

1. require(  

2.   _verifyMerkleLeaf(  

3.      _generateGenesisMerkleLeaf(  

4.        msg.sender,  

5.         _tokenIds[i]),  

6.      genesisMerkleRoot,  

7.    _proofs[i]  

8. ), "Invalid proof, you don't own that Token ID");

上一篇 下一篇

猜你喜欢

热点阅读