本篇是一个学习记录,有任何错误和建议欢迎twitter私聊,我们共同进步
0x3c 推特:https://twitter.com/pangmadee
NFT黑魔法推特 :https://twitter.com/MrsZaaa
NFT黑魔法Youtube:https://www.youtube.com/c/NFT%E9%BB%91%E9%AD%94%E6%B3%95
合约案例PXN:
https://etherscan.io/address/0x160c404b2b49cbc3240055ceaee026df1e8497a0#code
721A合约
总量10000个,分别分配给荷兰拍、白名单、team、dev
荷兰拍:在区块时间1651719600开始,初始价格2ether,结束价格0.1ether,每隔900秒下降0.05ether,每个地址最多两个,总共4000个。
白名单:在荷兰拍开始一天后开始,时间限制1天,总共6000个,每个地址一个。
team:和白名单开始的时候,mint的数量加上目前已经被mint的数量不能超过10000个。
dev:白名单开始一天后开始,10000个减去已经mint的剩余的部分。
采用 hardhat部署
每一种mint都采用的_safeMint来防止Reentrancy
继承openzeppelin的Ownable合约,在需要设置权限的函数都做了限制
合约开启用的固定时间,不会被矿工操纵
callerIsUser禁止了荷兰拍、白名单用合约调用
recover 禁止了机器人调用
1、mintDutchAuction() 荷兰拍
require判断的条件:
DA_ACTIVE 是否为true,由owner触发开始,public类型可以查看
directMintAllowed 是否为true,private类型外部无法查看状态,主网合约才添加的,测试网没有。如果为true,recover(signature)验证

对地址进行编码和keccak256哈希得到散列地址,并由signerAddress钱包签名,除非拥有signerAddress的私钥,否则这个操作需要在前端完成,这是为了防止机器人mint。
block.timestamp >= DA_STARTING_TIMESTAMP,区块时间超过设定的时间
block.timestamp <= WL_STARTING_TIMESTAMP 荷兰拍时间是否结束
quantity <= 2 和
balanceOf(msg.sender) + quantity < 3_numberMinted(msg.sender) + quantity <= 2都是判断最多2个
msg.value >= quantity * _currentPrice 钱包金额足够支付
totalSupply() + quantity <= DA_QUANTITY 不超过最大的荷兰拍总数
当达到最大的荷兰拍总数时,计算此时的的价格,如果此时的价格小于白名单固定价格,此时价格+0.5是白名单的价格。

2、mintWL() 白名单
require判断的条件:
DA_FINAL_PRICE>0 荷兰拍结束
!userToHasMintedPublicWL[msg.sender] 是否已经mint
recover(signature) 防机器人mint
block.timestamp <= WL_STARTING_TIMESTAMP + 86400 时间判断
PUBLIC_WL_MINTED + 1 <= WL_QUANTITY 总数最多6000个
.recover(signature) 验证消息是否由给定地址的私钥持有者签名
msg.value >= WLprice 钱包足够支付
_safeMint(msg.sender, 1); 只能mint一个
3、teamMint()
require判断的条件:
block.timestamp >= WL_STARTING_TIMESTAMP 和白名单开始的时间相同
_teamList[msg.sender] >= quantity mint的数量不能超过限定
msg.value >= quantity * WLprice 钱包足够支付
totalSupply() + quantity <= 10000 mint后的数量不超过总数
_teamList[msg.sender] = _teamList[msg.sender] - quantity; team的地址减去已经mint的数量
这里是有owner设置团队的地址,每个地址可以mint同意的数量amount

4、devMint()
require判断的条件:
block.timestamp >= WL_STARTING_TIMESTAMP + 86400 白名单开始一天后
10000个减去已经mint的剩余的部分,这里有点特别是分了两次转

5、withdrawFunds()
合约里面的钱给了dev和founder分别转了一半

