ERC-181 ENS 주소 역방향 조회 지원 (ENS support for reverse resolution of Ethereum addresses)

Final · 이름·메타데이터 · 2016-12-01 작성

ENS에서 이더리움 주소로부터 사람이 읽을 수 있는 이름을 찾는 역방향 조회(reverse resolution) 방법을 정합니다. 이 이름은 주소 주인만 등록할 수 있어 조회하는 쪽이 믿을 수 있습니다.

왜 필요한가

이름 서비스는 보통 사람이 읽는 이름에서 기계가 쓰는 주소를 찾는 정방향 조회에 쓰입니다. 그런데 반대 방향이 필요한 경우도 많습니다. 계정을 지켜보는 앱은 처음에 주소로 추가한 계정이라도 이름으로 보여 주는 편이 알아보기 쉽습니다. 주소에 설명 같은 부가 정보를 붙여 두면 그 주소를 어떤 경로로 알게 되었든 그 정보를 꺼내 쓸 수 있습니다. 신뢰 문제가 더 중요합니다. 누구나 자기 이름이 남의 주소를 가리키도록 설정할 수 있어서 정방향 기록만으로는 어떤 이름이 그 주소의 진짜 이름인지 알 수 없습니다. 역방향 기록은 주소 주인만 만들 수 있으므로, 주인이 이 주소를 대표하는 이름이 무엇인지 직접 선언하는 수단이 됩니다.

구현해야 하는 것

심층 설명

역방향 기록이 저장되는 위치: addr.reverse

역방향 기록은 일반 ENS 기록과 같은 방식으로 ENS 계층 안에 저장되며 예약 도메인 addr.reverse 아래에 둡니다. 어떤 계정의 역방향 이름은 계정 주소를 소문자 16진수로 바꾼 뒤 addr.reverse를 붙여 만듭니다. 원문 예시로 ENS 레지스트리 주소 0x112234455c3a32fd11230c42e7bccd4a84e02010의 역방향 기록은 112234455c3a32fd11230c42e7bccd4a84e02010.addr.reverse에 저장됩니다. 따라서 컨트랙트 안에서 주소를 동적으로 역방향 조회하려면 16진수 인코딩을 컨트랙트 안에서 직접 해야 합니다. 부록 구현의 sha3HexAddress 함수가 어셈블리로 이 변환과 해시 계산을 한 번에 처리합니다.

레지스트라와 claim(address owner)

addr.reverse 도메인의 소유자는 레지스트라 컨트랙트이며 호출자가 자기 주소의 역방향 기록 소유권을 가져갈 수 있게 합니다. 계정 x가 claim(owner)를 호출하면 레지스트라는 ENS 레지스트리에 hex(x) + '.addr.reverse' 이름의 소유권을 owner로 넘기도록 지시하고 넘긴 기록의 namehash를 돌려줍니다. 호출자 자신이 아닌 다른 주소를 소유자로 지정할 수 있게 한 것은 컨트랙트를 위한 설계입니다. 정확한 역방향 기록이 필요한 컨트랙트는 생성자 안에 reverseRegistrar.claim(msg.sender) 한 줄만 넣어 기록 관리 권한을 배포자에게 위임할 수 있습니다. 부록 구현에서 claim은 claimWithResolver(owner, 0)을 호출하는 것과 같습니다.

claimWithResolver와 setName

claimWithResolver(owner, resolver)는 계정 x의 hex(x) + '.addr.reverse' 이름에 먼저 지정한 리졸버를 설정하고 그다음 소유권을 owner로 넘긴 뒤 namehash를 돌려줍니다. claim만 쓸 때보다 적은 트랜잭션으로 맞춤 리졸버와 소유자를 함께 설정하기 위한 함수입니다. setName(name)은 계정 x의 역방향 이름에 기본 리졸버를 설정하고 그 리졸버에 name 기록을 씁니다. 사용자가 트랜잭션 한 번으로 단순한 역방향 기록을 만들 수 있게 하는 함수입니다. 부록 구현에서 setName은 claimWithResolver(this, defaultResolver)를 호출해 이름의 소유권을 레지스트라 자신에게 두고 이어서 defaultResolver.setName(node, name)을 호출합니다. 즉 setName으로 만든 기록의 ENS 소유자는 호출자가 아니라 레지스트라입니다.

부록 구현의 claimWithResolver 동작 순서

부록 구현의 claimWithResolver는 먼저 sha3HexAddress(msg.sender)로 라벨을 만들고 sha3(ADDR_REVERSE_NODE, label)로 노드를 계산합니다. resolver가 0이 아니고 현재 리졸버와 다르면, 이름 소유자가 레지스트라 자신이 아닐 때 ens.setSubnodeOwner로 일단 자기 앞으로 가져온 뒤 ens.setResolver를 호출합니다. 마지막으로 현재 소유자가 요청한 owner와 다르면 ens.setSubnodeOwner로 소유권을 넘깁니다. resolver에 0을 주면 리졸버는 그대로 두고 소유권만 바꿉니다. ADDR_REVERSE_NODE는 namehash('addr.reverse') 값인 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2 상수이며 node(address addr) 함수로 임의 주소의 역방향 노드 해시를 계산할 수 있습니다.

리졸버 인터페이스 name(bytes32)

역방향 기록용으로 새 리졸버 인터페이스를 정의합니다. 함수는 name(bytes32 node) 하나이며 문자열을 돌려줍니다. 이 인터페이스를 구현한 리졸버는 요청한 노드에 대해 유효한 ENS 이름을 돌려주거나, 그 노드에 이름이 정의되어 있지 않으면 빈 문자열을 돌려줘야 합니다. 이 인터페이스의 ID는 0x691f3431입니다. 역방향 기록에 맞는 다른 기록 유형은 이후 EIP에서 정할 수 있다고 원문은 적습니다.

기본 리졸버의 소유자 검사

부록의 DefaultReverseResolver는 노드별 이름을 mapping(bytes32=>string) public name에 저장합니다. setName(bytes32 node, string _name)에는 owner_only(node) 제한자가 붙어 있어 msg.sender가 ens.owner(node)와 같을 때만 실행됩니다. 즉 ENS 레지스트리에서 그 노드의 소유자로 기록된 주소만 이름을 바꿀 수 있습니다. 레지스트라의 setName이 먼저 소유권을 자신에게 둔 뒤 기본 리졸버를 호출하는 것은 이 검사를 통과하기 위해서입니다. 코드는 pragma solidity ^0.4.10 기준으로 작성되어 있습니다.

ERC 원문 · ← ERCs