# 【NFT黑魔法】第二期合约分析学习PXN **Published by:** [0x3c](https://paragraph.com/@gamfi/) **Published on:** 2022-05-06 **URL:** https://paragraph.com/@gamfi/nft-pxn ## Content 本篇是一个学习记录,有任何错误和建议欢迎twitter私聊,我们共同进步 0x3c 推特:https://twitter.com/pangmadee NFT黑魔法推特 :https://twitter.com/MrsZaaaNFT黑魔法Youtube:https://www.youtube.com/c/NFT%E9%BB%91%E9%AD%94%E6%B3%95合约案例PXN: https://etherscan.io/address/0x160c404b2b49cbc3240055ceaee026df1e8497a0#code合约类型721A合约合约结构(分配方式、mint手段)总量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)验证ECDSA验证对地址进行编码和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] 是否已经mintrecover(signature) 防机器人mintblock.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同意的数量amount4、devMint() require判断的条件:block.timestamp >= WL_STARTING_TIMESTAMP + 86400 白名单开始一天后10000个减去已经mint的剩余的部分,这里有点特别是分了两次转5、withdrawFunds() 合约里面的钱给了dev和founder分别转了一半 ## Publication Information - [0x3c](https://paragraph.com/@gamfi/): Publication homepage - [All Posts](https://paragraph.com/@gamfi/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@gamfi): Subscribe to updates - [Twitter](https://twitter.com/pangmadee): Follow on Twitter