本文将从合约、后端、前端三个方面讲述如何在 NFT 发售阶段做到尽量公平,尽可能让真实用户 Mint 成功。文章结构如下:
一、合约NFT 的发售中大家讨论最多的问题归纳一下分为以下几种:
禁止合约调用如果合约允许其他合约调用 Mint ,那大概率就会变成科学家秀 *** 作的舞台。即使每个地址限量也可通过工程合约创建出期望数量的地址进行 Mint。
防范手段: 通过判断 TX 的发出方和发售合约收到请求的来源是否一致来判断,是否来自于其他合约的调用。如 Azuki 中的验证如下:
注:关于 msg.sender
and tx.origin
的区别示例可以查看 Phishing with tx.originhttps://solidity-by-example.org/hacks/phishing-with-tx-origin/
常见的白名单验证方式分为两种:
合约记录白名单对于白名单数量较少或对 Merkle tree 不太熟悉的项目方可能会采用这种方式,优点就是逻辑简单,可以随时添加或删除。缺点也很明显,就是项目方需要支付修改白名单数据的费用。如 Azuki 中可以批量设置白名单地址及对应的数量,gas 消耗数量可以参考 seedAllowlist Tx 。
示例:Azuki seedAllowlist
验证Merkle Proof比较常见同时推荐使用的的方式是合约验证 Merkle Proof,通过提交链下生成的 Proof 在合约中进行验证。这个方案也是经过了很多次验证,能够充分满足实际需求,除了验证白名单地址外还可以添加 Mint 数量、空投数量等信息。
Mint 过程中用户获取 Proof 的方法可以使用 API 或将 Merkle Tree 公开让用户自行获取,下面的资源中提供了 API 的示例。
这里有很多现成的方案可以参考,资源如下:
视频教程: OpenZeppelin Building an NFT Merkle AirdropLibrary: Merkletreejs LibraryDemo: nft-merkle-drop注意事项:
白名单地址判断:有的项目白名单形同虚设在合约中并没有验证。白名单 Mint 数量判断:Mint 数量应记录在合约中而不应使用地址的 balanceOf 进行判断,否则会出现白名单重复 Mint 的问题。 签名参数验证对于公开发售阶段(非白名单),一般会采用参数验证的方式来检验用户数据是否合法,从过往的案例中经常出现的问题有以下几个:
统一的参数值所有用户使用同一个参数值进行验证,这将降低机器人批量 *** 作的难度。参数提前暴露顾名思义当科学家们提前获取到验证参数,就有足够的时间准备机器人。私钥泄漏这种情况虽然很少出现但是也应该引起项目方的重视,不要将私钥在前端暴露,将签名过程及参数的生成过程放在后端执行。参数验证环节,推荐的开发模式:在参数验证环节推荐的开发模式为每个地址的生成不同的调用参数,以防止重放攻击。
参考资源:
Openzeppelin 的ECDSA
library: Checking Signatures On-Chainsolidity-by-example: signature-replay
针对后续两个问题我们放在后端章节进行讨论
合约闭源项目方为了降低合约被攻击或滥用的可能选择不公开合约源代码,不单单是在 NFT 领域在 GameFi 项目中也是如此。如果将此作为防御手段并不能够很好的防范机器人 *** 作,举例说明:
SuperGucci 采用合约闭源的方式进行发售,其参数较为简单所以被聪明的科学家朋友攻破是必然的事情,只是时间的早晚而已。最终由于被科学家拿走了太多筹码,而不得不将最后一轮调整为了抽签发售。从链上调用数据可以看出参数和地址无关,没有其他特别的参数,因此对于此类合约存在使用相同参数重放调用的可能。
个人并不推荐这种方式进行发售,对于没有知名 IP 的项目来说未开源的项目并不能够给用户足够的信心,同样这样一点也不 Crypto 。
想要实现真正公平的发售是个挺复杂的问题,项目方可能也没办法把大部分精力放在技术层面。在可以遇见的将来,会出现比较完善的发售平台使得艺术家或项目方只需关注作品层面,而不需要直面技术中的种种困难。
NFT 的发售其实只是 NFT 项目其中一部分,除了上述的注意事项外还有很多细节值得重视,比如版税的设置、合约及前后端的测试、NFT Metadata 的部署、属性的随机性和稀有性、开图的公平性、还有 NFT 质押机制的设计、NFT 衍生品的设计等。
祝愿大家都能够 Mint 到自己喜欢的 NFT。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)