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

如何用web3.py获取单个钱包地址的所有ENS域名?

问题原因

ns.name(address) 是ENS的反向解析方法,仅当钱包地址主动设置了反向解析(将地址映射到某个ENS域名)时才会返回对应域名。而多个ENS域名指向同一个地址属于正向解析(域名→地址),两者是独立的系统:

  • 正向解析:任意数量的ENS域名都可以绑定到同一个地址
  • 反向解析:一个地址只能设置一个主域名作为反向解析结果

你的代码中ns.name()返回None,说明该钱包地址没有设置反向解析,或者反向解析的域名不是你预期的seeds.eth。

解决方案

方案1:设置反向解析(获取单个主域名)

如果你控制该钱包地址,可以通过web3.py设置反向解析,让ns.name()返回指定的域名(比如seeds.eth):

from web3 import Web3, HTTPProvider
from ens import ENS

infura_endpoint = f'https://mainnet.infura.io/v3/{infura_api_key}'
w3 = Web3(HTTPProvider(infura_endpoint))
ns = ENS.fromWeb3(w3)

target_address = '0xC99c2bdA0BEaA0B4c9774B48B81307C00e19CAde'
private_key = '你的钱包私钥'  # 仅当你控制该钱包时使用
account = w3.eth.account.from_key(private_key)

# 构造反向解析域名(格式为 地址去掉0x后的字符串.addr.reverse)
reverse_domain = f"{target_address[2:]}.addr.reverse"
resolver = ns.resolver(reverse_domain)

# 发送交易设置反向解析到seeds.eth
tx_hash = resolver.set_name('seeds.eth', transact={'from': account.address, 'gas': 150000})
w3.eth.wait_for_transaction_receipt(tx_hash)

# 再次查询反向解析
print(ns.name(target_address))  # 此时会返回'seeds.eth'

方案2:获取所有绑定到地址的ENS域名(无需反向解析)

如果需要获取所有正向绑定到该地址的ENS域名,可以通过查询ENS Registry合约的事件实现。ENS主网Registry合约地址为0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e,我们可以遍历NewResolver事件,检查每个域名的解析器是否指向目标地址:

from web3 import Web3, HTTPProvider
from ens import ENS

infura_endpoint = f'https://mainnet.infura.io/v3/{infura_api_key}'
w3 = Web3(HTTPProvider(infura_endpoint))
ns = ENS.fromWeb3(w3)

target_address = '0xC99c2bdA0BEaA0B4c9774B48B81307C00e19CAde'

# ENS Registry合约ABI(仅包含所需事件和方法)
registry_abi = [
    {
        "anonymous": False,
        "inputs": [
            {"indexed": True, "internalType": "bytes32", "name": "node", "type": "bytes32"},
            {"indexed": False, "internalType": "address", "name": "owner", "type": "address"},
            {"indexed": False, "internalType": "address", "name": "resolver", "type": "address"}
        ],
        "name": "NewResolver",
        "type": "event"
    }
]

resolver_addr_abi = [
    {
        "constant": True,
        "inputs": [{"internalType": "bytes32", "name": "node", "type": "bytes32"}],
        "name": "addr",
        "outputs": [{"internalType": "address", "name": "", "type": "address"}],
        "payable": False,
        "stateMutability": "view",
        "type": "function"
    }
]

registry_contract = w3.eth.contract(
    address="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
    abi=registry_abi
)

# 查询最近100000个区块的事件(可以根据需要调整区块范围)
events = registry_contract.events.NewResolver.get_logs(fromBlock='latest'-100000, toBlock='latest')

matching_domains = set()

for event in events:
    node = event['args']['node']
    resolver_addr = event['args']['resolver']
    
    try:
        resolver_contract = w3.eth.contract(address=resolver_addr, abi=resolver_addr_abi)
        resolved_addr = resolver_contract.functions.addr(node).call()
        
        if resolved_addr.lower() == target_address.lower():
            # 将ENS节点哈希转换为域名
            domain = ns.name_at(node)
            matching_domains.add(domain)
    except Exception as e:
        continue

print(f"绑定到该地址的所有ENS域名:{list(matching_domains)}")

注意事项

  • 方案2的事件查询可能较慢,建议限制区块范围(比如只查询最近N个区块),避免遍历全量区块。
  • 部分旧域名可能没有触发NewResolver事件,这种情况下需要额外处理,但大部分活跃域名会覆盖到。

内容的提问来源于stack exchange,提问作者Pablo Uboldi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:19:20