# Name Service

在web3系统中，地址通常作为用户的身份标识。然而地址的可读性比较差，拿以太坊上的地址为例，一串16进制的数字，长度为40。不便于作为社交应用的身份展示。

为此，我们提供一个Relation Name Service合约，将可读名称(比如 "relation.soul")解析为计算机可以识别的表示符。

<figure><img src="/files/bxczhm0QZBhUYK8LN4gD" alt=""><figcaption><p>图 5-2 Name Service 数据流</p></figcaption></figure>

同时，我们利用Arweave作为去中心化存储，实现身份属性的扩展，构建完整的profile。用户可以将个人的其他信息存储到Arweave，并在Name Service合约上存储Arweave交易哈希。

<figure><img src="/files/6TUxnuMVJHRqPp1Rd9Vg" alt=""><figcaption><p>图 5-3 Profile 数据流</p></figcaption></figure>

Relation Name Service是Relation Protocol中的重要对象，RNS自身是一个SBT，该SBT允许让你控制你在Relation网络中的基础社交身份数据。

Name Service SBT被个人地址拥有，它包含以下两种状态：

* hold：hold状态下 ，Name Service SBT可以被转移，无法通过该名称搜索或查询到对应的地址。
* resolved：Name Service SBT的只有地址通过resolve动作将token与Soul绑定后，视为name与个人地址的绑定，此时，Name Service SBT与地址在社交网络中可以相互映射。resolved状态的Name Service SBT 不可被转移。

为了使社交图谱的推荐和查询可以得到唯一的结果，一个地址可以拥有多个Name Service SBT，但只能同时resolved一个。

## Schema

我们给出Relation Name Service的[schema](https://arweave.net/PsqAxxDYdxfk4iYa4UpPam5vm8XaEyKco3rzYwZJ_4E)。 schema以ttl文件的形式保存至Arweave，交易哈希将作为schemaURI，在初始化合约时传入，参数示例：

```
ar://PsqAxxDYdxfk4iYa4UpPam5vm8XaEyKco3rzYwZJ_4E
```

* schema 前缀列表

```
PREFIX : <http://relationlabs.ai/entity/>
PREFIX p: <http://relationlabs.ai/property/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
```

* class

```
:Soul a rdfs:Class ;
    rdfs:label "Soul" ;
    rdfs:comment "A soul." .

:Name a rdfs:Class ;
    rdfs:label "Name" ;
    rdfs:comment "A name." .
```

:Soul表示接受和绑定域名解析的地址;

:Domain用于表示域名

* predicate

```
p:hold a rdf:Property ;
    rdfs:label "hold" ;
    rdfs:comment "A Soul to own a name." ;
    rdfs:domain :Soul ;
    rdfs:range :Name .

p:resolved a rdf:Property ;
    rdfs:label "resolved" ;
    rdfs:comment "The resolved name of a soul." ;
    rdfs:domain :Soul ;
    rdfs:range :Name .

p:profileURI a rdf:Property ;
    rdfs:label "profileURI" ;
    rdfs:comment "The profileURI of a soul." ;
    rdfs:domain :Soul ;
    rdfs:range xsd:string .
```

p:hold表示地址持有域名，并未解析

p:resolved表示地址已经与域名建立联系，可通过域名解析出地址。

p:profileURI 表示用户的profileURI

## 合约

### 合约接口

Name Service的合约接口如下：

```solidity
interface INameService is ISemanticSBT {
    
    /**
     * 注册一个域名
     * @param owner 域名的owner
     * @param name 需要注册的域名
     * @param reverseRecord 是否设置解析记录
     * @returns tokenId
     */
    function register(address owner, string calldata name, bool reverseRecord) external returns (uint);

    /**
     * 设置解析记录，将域名跟地址建立关系
     * @param addr 域名的owner，如果owner为0地址，则认为是解绑关系
     * @param name 域名
     */
    function setNameForAddr(address addr, string calldata name) external;

    /**
     * 给调用者设置profileURI
     * @param profileURI arweave的交易哈希
     */
    function setProfileURI(string memory profileURI) external;

    /**
     * 解析域名
     * @param name 域名
     * @return addr 地址
     */
    function addr(string calldata name) virtual external view returns (address);

    /**
     * 反向解析
     * @param addr 地址
     * @return name 域名
     */
    function nameOf(address addr) external view returns (string memory);
 
    /**
     * 查询地址的profileURI
     * @param addr 地址
     * @return profileURI arweave的交易哈希
     */
    function profileURI(address addr) external view returns (string memory);
}

```

完整的合约代码可访问：

* [NameService](https://github.com/relationlabs/semanticSBT/blob/main/contracts/template/NameService.sol)

### 合约实现说明

我们对Name Service做了一些规则设置：

* 域名默认最小长度为3个字符
* 域名只有设置解析之后，才能被合约正确解析。设置解析有两个方式：
  * register时即设置解析
  * register之后，调用setNameForAddr设置解析
* 如果当前域名已经设置了解析，需要先解绑原地址，才能重新设置
* 合约默认transfer开关关闭，即所有token不能transfer。如果需要打开，可以调用setTransferable方法进行设置
* 只有没设置解析的token才能被transfer


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://relationlabs.gitbook.io/protocol/protocol-zh/contract-open-standard/identity/name-service.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
