ERC-1185 ENS에 DNS 레코드 저장 (Storage of DNS Records in ENS)

Review · 이름·메타데이터 · 2018-06-26 작성

이더리움 이름 서비스(ENS) 컨트랙트 안에 DNS 레코드를 저장하고 조회하는 리졸버 표준입니다. ENS를 신뢰할 수 있는 DNS 정보 저장소로 쓸 수 있게 합니다.

왜 필요한가

인터넷 주소 체계인 DNS는 위계형 구조라서 상위 기관이 그 아래 도메인의 가용성을 통제합니다. 예를 들어 .org를 관리하는 쪽이 ethereum.org가 계속 살아 있을지를 좌우합니다. 또 전통적인 DNS에서는 도메인 소유와 그 도메인 정보를 권위 있게 제공하는 역할이 한데 얽혀 있습니다. 이더리움 이름 서비스(ENS)를 저장소로 쓰면 이 두 가지를 분리할 수 있습니다. 도메인 소유자가 자신의 DNS 레코드를 스스로 완전히 통제하고 스마트 컨트랙트를 통해 하위 도메인을 다른 주체에게 되돌릴 수 없게 넘겨줄 수도 있습니다. 하지만 ENS에는 DNS 레코드를 어떤 형식으로 넣고 꺼낼지 정한 공통 규격이 없었기 때문에, 이를 표준화한 리졸버 프로필이 필요합니다.

구현해야 하는 것

심층 설명

존이 아니라 레코드셋 단위로 저장합니다

전통적인 DNS는 한 존(zone)의 모든 레코드를 한 파일에 모아 두는 존 기반 시스템입니다. 단순하고 갱신이 원자적이라는 장점이 있지만 이를 ENS에 그대로 옮기면 작은 변경에도 가스 비용이 커집니다. 그래서 이 리졸버는 (domain, name, resource record type) 튜플로 정의되는 레코드셋 단위로 동작합니다. 예를 들어 (example.com, www.example.com, A)는 example.com 도메인에서 www.example.com 이름의 A 레코드셋을 가리키고, A 레코드가 1.2.3.4와 5.6.7.8이면 이 레코드셋은 값 두 개를 가집니다. 레코드셋 수준에서 동작하기 때문에 존 전송이나 DNSSEC 같은 일부 DNS 기능은 완전히 지원할 수 없습니다. 존 수준 리졸버도 만들 수는 있지만 갱신 비용이 매우 커서 이 EIP에서는 다루지 않습니다.

setDNSRecords: 쓰기와 삭제를 한 함수로 처리합니다

setDNSRecords(bytes32 node, bytes data)는 주어진 노드에 대해 DNS 레코드 1개 이상을 설정, 갱신, 삭제합니다. 함수 시그니처는 0x0af179d7입니다. node는 ENS의 완전한 도메인 이름에 대한 네임해시(ERC-137에 정의)이고 data는 DNS 와이어 포맷으로 인코딩된 레코드들입니다. 값 없이 제공된 레코드는 삭제됩니다. 같은 RRset에 속한 레코드들은 데이터 안에서 연속으로 배치해야 합니다. 그렇지 않으면 뒤에 나오는 RRset이 앞의 것을 덮어씁니다. 참조 구현의 주석도 A 레코드 두 개 사이에 CNAME이 끼어들면 두 번째 A 레코드가 첫 번째를 덮어쓰는 예를 보여 줍니다.

clearDNSZone: 존 전체를 한 번에 지웁니다

clearDNSZone(bytes32 node)는 도메인의 모든 DNS 레코드를 제거합니다. 함수 시그니처는 0xad5780af입니다. setDNSRecords로도 레코드를 하나씩 지울 수는 있지만 리졸버에는 도메인의 레코드를 순회하는 방법이 없어서 소유자가 설정했던 레코드를 모두 알고 있어야 하고 트랜잭션이 여러 번 필요할 수 있습니다. clearDNSZone은 한 번의 연산으로 존 정보 전체를 제거합니다. 참조 구현은 노드별 버전 번호를 올리는 방식으로 이를 구현해 어떤 레코드를 넣었는지 잊은 사용자도 존 전체를 사실상 삭제할 수 있게 합니다.

dnsRecords와 hasDNSRecords: 조회용 두 함수

dnsRecords(bytes32 node, bytes32 name, uint16 resource)는 노드, 이름, 리소스에 해당하는 레코드를 모두 DNS 와이어 포맷으로 반환하며 없으면 아무것도 반환하지 않습니다. 시그니처는 0x2461e851입니다. name은 DNS 와이어 포맷으로 된 레코드 이름의 keccak256() 해시이고 resource는 RFC 1035와 후속 RFC들이 정의한 리소스 레코드 ID입니다. hasDNSRecords(bytes32 node, bytes32 name)는 해당 이름에 레코드가 하나라도 있으면 true를 반환합니다. 시그니처는 0x4cbf6ba4입니다. 이 함수는 RFC 4592가 정의한 와일드카드 리소스를 처리하는 DNS 리졸버에 필요합니다.

참조 구현: 버전 매핑과 존해시

참조 구현은 레코드를 node => version => name => resource => data 매핑에 바이너리 RRSET으로 저장하고 이름별 레코드 수를 nameEntriesCount에 따로 세어 와일드카드 조회에 씁니다. 레코드가 바뀌면 DNSRecordChanged, 지워지면 DNSRecordDeleted, 존이 초기화되면 DNSZoneCleared 이벤트를 냅니다. 별도로 setZonehash와 zonehash 함수로 존해시를 관리하는데, 존해시는 존 파일 하나를 담은 리소스를 가리키는 ERC-1577 콘텐츠 해시(바이너리 형식)입니다. 인터페이스 ID는 DNS 레코드가 0xa8fa5682, DNS 존이 0x5c47637c입니다.

기존 인터페이스와 충돌하지 않는 새 프로필입니다

이 표준은 ERC-137이 정의한 ENS 리졸버 명세를 따르는 새 리졸버 프로필을 추가할 뿐, 기존 프로필이나 인터페이스를 수정하지 않으므로 하위 호환성 문제가 없습니다. 원문은 탈중앙화된 DNS라면 상위 기관의 통제 없이 ENS 안의 레코드가 있는 어떤 도메인이든 직접 조회할 수 있다는 점을 설계 근거로 듭니다. 이 제안은 현재 Review 상태라서 내용이 아직 바뀔 수 있습니다.

쓸 때 주의할 점

ERC 원문 · ← ERCs