체인의정석

ENS Namehash 만들고 Namehash로 컨트렉트에서 실제 지갑주소 뽑아보기 본문

블록체인/NFT & BRIDGE

ENS Namehash 만들고 Namehash로 컨트렉트에서 실제 지갑주소 뽑아보기

체인의정석 2023. 11. 27. 20:51
728x90
반응형

ENS는 실제로 어떻게 주소를 관리하고 실제 주소를 뽑아낼까? 실제로는 namehash라는 해시값을 통해서 컨트렉트에서 조회를 하고 상호작용을 하게 된다. 이번에는 Namehash를 실제로 만들어보고 이를 통해 공식 컨트렉트로 지갑 주소를 도출하는 로직을 만들어 보도록 하겠다.

Name hash 만들기

https://www.npmjs.com/package/@ensdomains/eth-ens-namehash

 

@ensdomains/eth-ens-namehash

A simple module for generating ENS namehashes per spec https://github.com/ethereum/EIPs/issues/137. Latest version: 2.0.15, last published: 2 years ago. Start using @ensdomains/eth-ens-namehash in your project by running `npm i @ensdomains/eth-ens-namehash

www.npmjs.com

name hash는 다음 라이브러리에서 확인이 가능하다.

var namehash = require('@ensdomains/eth-ens-namehash')
var hash = namehash.hash('foo.eth')
console.log("hash >>", hash);
// '0xde9b09fd7c5f901e23a3f19fecc54828e9c848539801e86591bd9801b019f84f'

// Also supports normalizing strings to ENS compatibility:
var input = 'chainstone.eth'
var input2 = 'chainstone.eth!!!'

var normalized = namehash.normalize(input)
console.log("normalized >>", normalized);

var normalized2 = namehash.normalize(input)
console.log("normalized2 >>", normalized2);

결국 namehash 라이브러리에서는 다음과 같이 네임해시를 만드는 부분과 네임해시를 만들기 전에 normalize를 체크하는 부분이 있어서 다음과 같이하니 확인이 가능하였다.

ERC137 Ethereum Domain Name Service

https://eips.ethereum.org/EIPS/eip-137

 

ERC-137: Ethereum Domain Name Service - Specification

 

eips.ethereum.org

해당 ENS의 함수에 대한 설명은 아래 링크에서 확인할 수 있다.

 

Registry 에서 Reslover 함수로 조회해보기

https://docs.ens.domains/contract-api-reference/ens

 

Registry - ENS Documentation

Returns the caching time-to-live of the name specified by node. Systems that wish to cache information about a name, including ownership, resolver address, and records, should respect this value. If TTL is zero, new data should be fetched on each query.

docs.ens.domains

먼저 resolver를 찾아야 한다.

function resolver(bytes32 node) external view returns (address);

resolver에 해당하는 node 주소가 나오게 되면 해당 resolver에다가 다시 요청을 하게 될 경우 해당 ens가 나와야 한다.

일단 실제 이더리움 메인네트워크에서 실제로 해당 로직대로 작동하는지 체크를 해보기 위하여서 먼저 Registry컨트렉트를 찾아보았다.

https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e#readContract

 

ENS: Registry with Fallback | Address 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e | Etherscan

The Contract Address 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e page allows users to view the source code, transactions, balances, and analytics for the contract address. Users can also interact and make transactions to the contract directly on Etherscan.

etherscan.io

    /**
     * @dev Returns the address of the resolver for the specified node.
     * @param node The specified node.
     * @return address of the resolver.
     */
    function resolver(bytes32 node) public view override returns (address) {
        if (!recordExists(node)) {
            return old.resolver(node);
        }

        return super.resolver(node);
    }

저 node가 무엇인지에 대해 고민을 하다가 정답을 소스 코드에서 찾았다. 바로 namehash였다.

https://github.com/ensdomains/reverse-records/blob/master/contracts/ReverseRecords.sol

 

해당 코드를 좀 뜯어보면

resolver에 namehash를 넣어서 지갑주소를 역산하는것을 볼 수 있다.

그렇다면 저 resolver안에 들어간 입력값은? 바로 namehash였다.

Reslover에서 addr 함수로 지갑주소 뽑아내기

그래서 위의 Resigstry 컨트렉트에서 resolver로 resolver주소를 뽑아냈고 해당 resolver에 들어가서 

https://etherscan.io/address/0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63#readProxyContract

 

ENS: Public Resolver | Address 0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63 | Etherscan

The Contract Address 0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63 page allows users to view the source code, transactions, balances, and analytics for the contract address. Users can also interact and make transactions to the contract directly on Etherscan.

etherscan.io

addr안에 namehash를 넣었더니 실제 내가 발급한 ENS주소가 나왔다.

 

실제활용?

하지만 우린 서비스를 만들때 아래 링크에 있는 정말 다양한 모듈들을 써서 주소를 조회해올 수가 있기 때문에 직접 위의 과정을 코드로 구현할 필요가 없다.

https://docs.ens.domains/dapp-developer-guide/working-with-ens

 

Working with ENS - ENS Documentation

Some web3 libraries - e.g., ethers.js, viem, web3j, and web3.py - have integrated support for name resolution. In these libraries, you can pass in an ENS name anywhere you can supply an address, meaning you do not need to interact directly with their ENS A

docs.ens.domains

 

728x90
반응형
Comments