获取当前账户NFT Token ID异常:误返回全部Token ID问题排查
解决获取当前账户NFT Token ID返回所有ID的问题
问题1:account变量未就绪时调用查询
你的代码直接在顶层执行test2(),此时Moralis的account可能还未完成初始化,传入getNFTs的是undefined。Web3.js遇到filter: { to: undefined }会忽略该过滤条件,导致返回所有Transfer事件。
修复方式:
通过useEffect监听account的变化,仅当账户地址存在时才执行查询:
// 删除顶层的 test2(); 调用 useEffect(() => { if (!account) return; const fetchUserNFTs = async () => { const userNFTs = await getNFTs(account); console.log(userNFTs); }; fetchUserNFTs(); }, [account]);
问题2:未排除已转出的NFT
仅过滤Transfer事件的to字段,会把曾经转入但后来转出的NFT也包含进去,结果包含非当前持有Token ID。需要同时处理转出事件,计算实际持有量。
修复方式:修改getNFTs函数,结合转入和转出事件计算当前持有NFT:
async function getNFTs(address) { // 获取所有转入当前地址的Transfer事件 const transferInEvents = await contract.getPastEvents("Transfer", { filter: { to: address }, fromBlock: 0, toBlock: "latest" }); // 获取所有从当前地址转出的Transfer事件 const transferOutEvents = await contract.getPastEvents("Transfer", { filter: { from: address }, fromBlock: 0, toBlock: "latest" }); // 用Set存储转入的tokenId,自动去重 const ownedTokens = new Set(transferInEvents.map(evt => evt.returnValues.tokenId)); // 移除已转出的tokenId transferOutEvents.forEach(evt => ownedTokens.delete(evt.returnValues.tokenId)); return Array.from(ownedTokens); }
额外验证点
- 确认合约的
Transfer事件符合标准ERC721/ERC1155定义,to和from字段类型为address,否则过滤条件会失效。 - 检查传入的
account地址格式是否与合约事件中记录的一致(Web3.js事件过滤对地址大小写敏感)。
内容的提问来源于stack exchange,提问作者bela jonas
相关产品推荐
相关产品推荐

