NFT智能合约白名单机制
有很多方法来实现白名单机制。每种方式都有其优点和缺点。因此,开发者应该仔细考虑需求,并在每种方式之间找到平衡。
NFT智能合约白名单机制
翻译:团长(https://twitter.com/quentangle_)
介绍
白名单是推广NFT项目和奖励早期参与者的一个好方法。实现白名单机制的方法有很多,每种方法都有自己的优势和劣势。现在主要有3种实施白名单方法,我将在本文介绍它们,并谈谈它们的优点和缺点。
最原始的方式 — 储存在合约里
对于熟悉其他编程语言和现代计算系统的开发者来说,将数据存储在堆或存储器中是一种相当合理和简单的处理数据的方式。
因此,要将白名单存储在存储器中,可以声明一个映射来记录所有符合白名单条件的有效地址。然而,使用这种方式会使你产生大量的gas,是一种非常低效的方法。但是这样也有优势,通过etherscan或几行代码来测试他是否在白名单上会更容易。
优点:简单有效,容易编码,容易添加地址或删除地址
缺点:效率真的很低,对发行方来说真的很贵
聪明的方法 I — Merkle Tree Airdrop
执行白名单的另一种方式是利用Merkle树。Merkle树是区块链中的一个重要角色。Merkle树利用了哈希的特性,即输入的轻微变化将导致完全不同的输出,以及两个输入导致相同输出的概率几乎不可能。
Merkle树的结构如下所示。当前节点的哈希值等于其左侧子节点、右侧子节点及其数据的哈希值。因此,从哈希的属性来看,任何改变都会导致完全不同的输出;我们可以利用这个属性来实现白名单。
所以,想象一个场景,你想知道L1是否等于一个地址,你可以提取Hash 0–1,Hash 1,以及测试的地址。然后按照哈希规则,将哈希的输出与Top Hash进行比较。如果结果相同,你可以确保L1等于输入地址。
要做到这一点,需要生成一棵merkle树,并将一半的造币过程从链上拿走,以节省gas。我们将使用javascript来生成merkle树。如果你对ether.js比较熟悉,你也可以使用ethers.utils.solidityKeccak256来哈希配对。另外,记得要将JSON文件存储为以下内容。{“<address>”: <amount>, “<address>”: <amount>}。也可以根据需要,把这对数据改成另一种类型来调整。
需要通过solidity函数将根存储在合约中。然后用MerkleProof
库进行链上验证。每当有人想mint时,需要在前台或者后台为用户生成证明,用tree.getHexProof
函数生成bytes32[]
证明。查看checkTree
函数中的注释,了解更详细的实现。
每当调整白名单时,必须更新_freeClaimMerkleRoot
。
优点:经济效益高,易于使用
缺点:对用户来说,mint时gas的用量略大。每次希望改变白名单时都需要重置Root。
聪明的方法二 — 后台签名
最后一种方式也比第一种方式更便宜。然而,最后一种方式比前一种方式更中心化。这种方法利用了签署信息的机制。需要在后端设置一个地址,并保持它的可信度。每当一个白名单上的用户希望mint需要首先验证它。验证后,可以签署信息并将其传回给用户。然后,用户就可以使用签名的信息,并进行mint。
但你可能会问,如何确保没有人可以伪造签名信息?原因是,如果你用你的私钥签署信息,你将得到一个哈希的信息。然后,你可以用哈希的信息和哈希前的信息生成公钥。因此,如果你在合约处存储公钥,在后端用私钥签署消息,你可以确保没有人可以伪造消息。
然而,为了防止重放攻击,你可以使用一个nonce来确保签署的消息不会被恶意使用。因此,整个签名过程将如下所示:
https://gist.github.com/AlbertLin0327/ddc47c25f047d3fd54fe41459bbbd654#file-signmessage-js.js"
优点:对开发者来说更便宜,在后端更容易管理白名单。
缺点:造币需要更多的gas,不那么去中心化。
总结
有很多方法来实现白名单机制。每种方式都有其优点和缺点。因此,开发者应该仔细考虑需求,并在每种方式之间找到平衡。
原文:https://coinsbench.com/smart-contract-whitelist-mechanism-fbe3464159ed