You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Ethers.js获取指定钱包地址下的所有ENS域名?

用Ethers.js获取特定钱包下的所有ENS域名

要获取特定地址下的所有ENS域名,由于ENS合约未直接提供“按地址查询域名”的方法,我们需要通过查询ENS注册表合约的相关事件来实现——每次域名注册或所有权转移时,都会触发对应事件,过滤出目标地址作为所有者的事件后,再去重验证即可。

步骤说明

  1. 依赖与环境准备
    先安装Ethers.js:

    npm install ethers
    

    同时需要连接一个以太坊节点(可使用Alchemy、Infura等第三方服务商节点,或本地节点)。

  2. ENS注册表合约信息
    ENS注册表的固定合约地址为:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e,我们需要用该地址创建合约实例,并加载包含所需事件的简化ABI。

  3. 事件过滤与查询
    核心关注两个事件:

    • NameRegistered(bytes32 indexed label, address indexed owner, uint expires):域名注册时触发,记录初始所有者
    • NameTransferred(bytes32 indexed label, address indexed owner):域名所有权转移时触发,记录新所有者

    过滤出这两个事件中owner为目标地址的记录,再将事件中的label转换为可读的域名前缀(比如label对应vitalik,则完整域名为vitalik.eth)。

  4. 去重与验证
    同一个域名可能多次转移,需用去重逻辑保留最新记录;同时建议验证每个域名当前的所有者确实是目标地址,避免因查询块范围不全导致的错误。

代码示例(Ethers.js v6)

import { ethers } from "ethers";

// 目标地址
const targetAddress = "0x8f635716982B836c4eB47e2F5c7B007Dde278F99";

// ENS注册表合约地址和简化ABI(仅包含所需事件与方法)
const ensRegistryAddress = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e";
const ensRegistryAbi = [
  "event NameRegistered(bytes32 indexed label, address indexed owner, uint expires)",
  "event NameTransferred(bytes32 indexed label, address indexed owner)",
  "function owner(bytes32 node) view returns (address)"
];

async function getENSNamesForAddress() {
  // 连接以太坊节点,替换为你的节点URL
  const provider = new ethers.JsonRpcProvider("https://eth-mainnet.g.alchemy.com/v2/your-api-key");
  
  // 创建合约实例
  const ensRegistry = new ethers.Contract(ensRegistryAddress, ensRegistryAbi, provider);
  
  // 构建事件过滤器,筛选目标地址作为owner的事件
  const filterRegistered = ensRegistry.filters.NameRegistered(null, targetAddress);
  const filterTransferred = ensRegistry.filters.NameTransferred(null, targetAddress);
  
  // 查询事件,可指定块范围,默认查询全部历史
  const registeredEvents = await ensRegistry.queryFilter(filterRegistered);
  const transferredEvents = await ensRegistry.queryFilter(filterTransferred);
  
  // 合并事件并去重,保留最新记录
  const allEvents = [...registeredEvents, ...transferredEvents];
  const domainMap = new Map();

  for (const event of allEvents) {
    const label = event.args.label;
    // 按块高排序,块高更大的事件为最新记录
    if (!domainMap.has(label) || event.blockNumber > domainMap.get(label).blockNumber) {
      domainMap.set(label, event);
    }
  }

  // 转换label为可读域名,并验证当前所有者
  const ensNames = [];
  for (const [label] of domainMap) {
    const name = ethers.decodeBytes32String(label);
    const fullDomain = `${name}.eth`;
    
    // 验证当前所有者是否为目标地址
    const node = ethers.namehash(fullDomain);
    const currentOwner = await ensRegistry.owner(node);
    
    if (currentOwner.toLowerCase() === targetAddress.toLowerCase()) {
      ensNames.push(fullDomain);
    }
  }

  return ensNames;
}

// 执行查询并输出结果
getENSNamesForAddress()
  .then(names => console.log("目标地址下的ENS域名:", names))
  .catch(err => console.error("查询出错:", err));

注意事项

  • 需将代码中的节点URL替换为你自己的API地址(如Alchemy/Infura的密钥地址)
  • 若查询历史事件量过大,建议分块查询以避免超时
  • 上述代码主要针对.eth后缀域名,其他后缀的ENS域名需额外处理解析逻辑

内容的提问来源于stack exchange,提问作者Ose Daniel Okojie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 10:40:30