在 Solidity 中随机选择铸造的 NFT 的最佳方法是什么?

What is the best way to randomize a selection of minted NFTs in Solidity?

我想随机生成不同级别的 NFT。如果总共有 3333 个和 20 个第 1 层(最好)、313 个第 2 层、1200 个第 3 层和 1800 个第 4 层,下面的代码是否可以解决问题?这会导致 1 级 NFTS 每隔 4 分钟铸造一次吗?

function _genTier(uint256 seed) internal view returns (uint256) {
        uint256 index = seed % probabilities.length;
        uint256 rarity = seed.mul(100).div(MAX_SUPPLY);
        if(rarity < probabilities[index]) {
        rarity = index;
    } else {
        rarity = aliases[index];
    }

    return rarity;
}

TL;DR 如果您已经在使用 oracle,则此方法将起作用。

您 post 中代码片段中的方法将导致稀有性,但 NFT 不会随机分配,而是根据提供的种子按顺序分配。我不知道种子是从哪里得到的。

通常,我喜欢使用“随机框”技术,您可以在其中创建特征框,随机播放并循环遍历它们。因此,您几乎可以生成特征并最终得到包含 3333 个项目的数组。如果你想保持精确的稀有度,喜欢

3333 in total and 20 Tier 1, 313 Tier 2, 1200 Tier 3 and 1800 Tier 4

这是执行生成的好方法。相反,该方法 _genTier 可能不会准确得出您提供的数字,只是生成稀有度中概述的每个 NFT 的可能性。

但是,“随机框”方法对于 Solidity 来说并不是最佳选择,因为存储这么多数据所需的内存量会产生多余的成本,而使用随机性可以避免这些成本。

另一方面,随机性也很难获得on-chain。要获得密码安全的随机数,您可以使用块哈希或 oracle。

使用块散列可能适用于此应用程序,但其核心是可预测的。意思是,有人可以获得随机数,知道即将到来的区块哈希值,并计算出他们将接收的 NFT 层级。

因此,我建议研究像 ChainLink 这样的预言机,以获得无法预测的真正加密随机数。来自oracles的RNG来自off-chain,符合安全标准。您可以使用这些数字并包含一个 if-statement 来检查每个层当前生成的 NFT 的数量。然后,re-roll如果说Tier 1的20个已经分配好了,以确保最后的3333个完全符合计划。