# ENS技术解析(一) 注册流程

By [MarkTang's Blog](https://paragraph.com/@marktang-s-blog) · 2022-09-07

---

ENS技术解析(一) 注册流程
===============

最近在弄关于ENS这类DID的东西，准备记录一下基础流程，为了记忆更深刻，顺便写一些文章。

文章会主要以前端视角对接合约的方式进行，从前端对接到合约代码，不是全合约代码解析。

### ENS介绍

首先简单介绍一下ENS，ENS（Ethereum Name Service）是以太坊域名服务，是一个基于以太坊区块链的分布式、开放和可扩展的命名系统。ENS的主要作用就是将可读的域名如：marktang.eth 解析为可识别的标识符，比如钱包地址、元数据等。ENS还支持"反向解析"，也就可以让元数据和以太坊地址相关联成为可能。

ENS和DNS类似，但因为区块链的功能特点和限制条件，架构上有很大的不同。与DNS一样，ENS是一个层次结构的域名系统，不同层次域名之间以点作为分隔符，我们把层次的名称叫做域，一个域的所有者能够完全控制其子域。想了解更详细的可以去官网看看。

### ENS架构

主要由注册表和解析器组成

在ENS中解析一个域名需要两个步骤：首先，询问注册表是哪个解析器负责解析该域名，然后，向该解析器查询解析结果

接下来正式开始流程说明

注册
--

注册大致可以分为3个步骤

1.  获取凭证
    
2.  提交凭证
    
3.  注册
    

### 初始化

在说明获取凭证的步骤之前咱们需要先讲一下初始化，在注册操作还未发生时，我们需要预先获取一些东西：

*   获取当前域名的预估注册费用
    
*   获取minCommitmentAge，这个值在<提交凭证>时会用到，稍后说明
    
*   是否对Controller已Approve授权
    
*   生成 randomSecret，<获取凭证>时会用到
    

#### 获取当前域名的预估注册费用

调用RegistrarController的rentPrice方法来获取预估注册费用，需要传入两个参数，一个是当前需要注册的域名，另一个是时长。

根据注册域名长度得到一个基础价格，然后通过ETH/USD Price Oracle得到当前的ETH价格算出最终的预估注册费用(ETH)

#### 获取minCommitmentAge

> 获取最小时间间隔，这个比较简单，没什么可说明的

#### 是否对Controller已Approve授权

这个也很简单，通过allowance方法判断一下，方便根据状态进行UI的一些操作更新

#### 生成randomSecret

32随机字节，直接看代码

### 获取凭证

通过调用RegistrarController合约的makeCommitment方法来获取凭证，需要传递以下参数：

*   name 域名
    
*   owner 注册人地址
    
*   duration 时长
    
*   secret 之前在上一步<初始化>时生成的randomSecret
    
*   resolver 解析器合约地址
    
*   data 设置域名解析记录
    
*   reverseRecord 是否反解析
    
*   fuses 初始化的fuses
    
*   wrapperExpiry fuses过期时间
    

返回 abi encode后的 keccak256 hash作为凭证

### 提交凭证

通过调用RegistrarController合约的commit方法来预提交，需要传入刚才<获取凭证>拿到的hash

然后来看合约代码，这里先对重复提交进行了验证，时间如果未超过最大时间间隔就不需要重新更新时间戳。通过验证则记录本次transaction的时间戳。

> 预提交的目的

现在来说明一下这个预提交的目的是什么，为什么不是直接就注册了？预提交的目的是为了防止抢跑，如果没有这部分，直接就是注册操作的话，在MEV里就可以监听注册域名的tx，然后用gasPrice去抢跑，这样就会造成一些有价值的域名被机器人抢走。有了预提交步骤后，机器人要抢跑域名注册就需要监听commit方法，但这个方法的参数是解读不出tx是要注册哪个域名的，从而防止了抢跑操作。

在commit之后必须要等待最小间隔时间后才能进行注册操作，当前是60秒。这里需要setTimeout 一个<初始化>时获取的minCommitmentAge \* 1000 后再开始进行注册操作。

### 注册

在等待最小间隔时间后通过RegistrarController合约的register方法来注册，方法需要传入的参数同<获取凭证>的makeCommitment的方法一样。

然后一步一步来看看合约

1\. 首先验证账户是否有足够币来支付注册费用

2\. 消费commitment， 这里会检查是否满足最小间隔时间和是否超过最大间隔时间，验证当前域名是否可用、删除commitment，返还gas、时长不能小于最小时间(28天)

3\. 获取registrar expiry 新名称在.eth注册商的到期时间

4\. setRecords 设置域名解析记录，这里会对检查namehash做检查

5\. 是否设置反向解析，反向解析就是用地址反向解析出ENS域名

6\. 触发 NameRegistered Event，客户端可以监听该Event来实现一些后续操作

7\. 扣钱，注册完成

> Note: ENS域名也是ERC721的NFT，可以在各大市场进行交易，只是没有metadata。如果在市场交易成功后，新的owner需要调用一下reclaim方法重新认领才能管理自己的ENS域名。在域名过期后，设有90天的保护期，在保护期内owner是可以直接调用renew方法来续期的，过了保护期后就要重新commit去进行注册

目前先对注册流程进行了一个大体的整理，有空后下一篇会说明 地址/域名搜索、我拥有的域名列表、域名详情信息的流程。不知道具体会更新几篇，取决于之后我所了解到ENS功能的范围吧。

之后计划今年还会更新几篇最近在研究的前端可视化方面的文章、Web3项目前端主流技术栈中的一些package介绍、全栈写完一个完整的Web3项目(合约、前端、后端)能够完整体验整个流程，具体项目还在构思中，需要简单一点不会写太久又能体现每个部分的特点的。

Bye, All the best.

---

*Originally published on [MarkTang's Blog](https://paragraph.com/@marktang-s-blog/ens)*
