繁体   English   中英

如何查找 NFT 集合的所有者数?

[英]How to find the owner count of an NFT collection?

我正在尝试查找 NFT 收藏持有者计数(ERC721 令牌)。 例如,OpenSea 和 EtherScan 有这些数据,但我找不到本地 ERC721 方法来实现这一点。

这样做的最佳方法是什么?

谢谢

最好的方法是使用 Transfer 事件,因为这就是目的。 您可以查询所有传输事件,并按ID过滤。

然而,您也可以创建将在每次 nft 传输时调用的自定义function(id, address) ,在那里您可以推送到映射id -> address[]中的数组,其中数组表示拥有它的窥视者的地址NFT。

然后根据发送给函数的 id 创建另一个function(id)以返回该数组。

好吧,经过几个小时的研究,我找到了一些解决方案并想分享这些。

有一些方法可以做到这一点:

  1. 如果您正在处理特定合同并且此合同扩展ERC721Enumerable ,那么您的案例研究会更容易一些。 因为您可以使用totalSupply()找到令牌计数,所以您可以跳过下面代码的第一部分。
  2. 如果您想使用 3rd 方工具,您可能需要查看Moralis 它返回所有者计数以及地址列表和额外数据。 查看已经存在的答案
  3. 如果您想手动编写代码,这是我的代码:

async testGetOwnerCount({ }, payload) {
    // Connect the contract 
    let nftContract = new ethers.Contract(nftContractAddress, ERC721.abi, signer);

    // First find the mint count which is equal to the token count
    const transferFilter = nftContract.filters.Transfer("0x0000000000000000000000000000000000000000", null, null)
    const tokens = await nftContract.queryFilter(transferFilter)
    const tokenCount = tokens.length;

    // Iterate over tokens and store owner addresses in an array
    let owners = []
    for (let i = 0; i < tokenCount; i++) {
      // First, find the all transfers of the token 
      // from null` to `null` so we get all the transfers of `tokenId` 
      const transferFilter = nftContract.filters.Transfer(null, null, parseInt(tokens[i].args.tokenId))
      const tokenTransfers = await nftContract.queryFilter(transferFilter)

      // `args.to` of the last element gives the current owner of issued token
      let lastTransfer = tokenTransfers[tokenTransfers.length - 1]
      let currentOwner = lastTransfer.args.to

      // If the address has already found before, don't add it...
      if (!owners.includes(currentOwner)) {
        owners.push(currentOwner)
      }
    }
}

可能有更好的方法来实现这一点,但这是我能找到的最好的方法,因为我想处理所有合同,不仅是ERC721Enumerable并且不想使用其他工具。

您不需要任何第三方合同或服务。 您可以设置 3 个映射:

// each operation on mapping takes O(1) time

//keep track of how many tokens each address have
mapping(address => uint256) private ownedTokens

// from tokenId=>ownerAddress
// keep track of owner of each tokenId
mapping(uint256 => address) private tokenOwner

// keep track of how many tokens does an address own
mapping(address => uint256) private ownedTokensCount

映射对于优化代码非常有用。 当您编写 mint function 时,您必须相应地更新这些映射。

function mint(address to, uint256 tokenId) external {
    // ADD YOUR REQUIRE LOGIC
    ownedTokensCount[to] += 1;
    tokenOwner[tokenId] = to;
    ownedTokens[to] = tokenId;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM