Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added RNS Over and Spec updated content #92

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/01-concepts/rif-suite/rns/getting-started/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
sidebar_label: Getting Started
sidebar_position: 500
title: "Getting Started"
tags: [rif, rns, Getting Started]
description: ""
---

132 changes: 132 additions & 0 deletions docs/01-concepts/rif-suite/rns/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
---
sidebar_label: RNS
sidebar_position: 400
title: "RIF RNS: RIF Name Service | Rootstock (RSK)"
tags: [rif, rns, rif-name-service, rsk]
description: "Information about the RIF token, where to obtain it, how to transfer it, and technical details on its token standard"
---

RNS provides an architecture which enables the identification of blockchain addresses by human-readable names.

<form class="form" id="frm-rns-search">
<div class="form-group">
<div class="input-group">
<input type="text" id="txt-rns-name" class="form-control" placeholder="find your domain" />
<div class="input-group-append">
<span class="input-group-text">.rsk</span>
</div>
<div class="input-group-append">
<button class="btn btn-rns-register">Register!</button>
</div>
</div>
</div>
</form>

<div class="container the-stack">
<div class="row rif_blue_text">
<div class="col">
<div class="rns-index-box">
<a href="try-rns">Try the service</a>
<br />
<br />
<p>Register a domain in the Testnet, for free.</p>
</div>
</div>
<div class="col">
<div class="rns-index-box">
<a href="./integrate">Integrate with RNS</a>
<br />
<br />
<p>Easy guides on how to integrate RNS in your solution.</p>
</div>
</div>
</div>
<div class="row rif_blue_text">
<div class="col">
<div class="rns-index-box">
<a href="run-locally">Develop on top of RNS</a>
<br />
<br />
<p>Deploy RNS suite in your local development environment</p>
</div>
</div>
<div class="col">
<div class="rns-index-box">
<a href="libs">Use the libraries</a>
<br />
<br />
<p>Use simple libraries to interact with RNS service.</p>
</div>
</div>
</div>
</div>

## The stack

![image](/img/rif/rns/theStack.png)

## Motivation

By adding a name resolution service, also known as “alias”, the probability of errors is significantly reduced. In addition, centralizing the access to multiple resources associated with a human-readable name improves the blockchain platform user experience. As resource names may change over time, the system needs to be flexible to support frequent changes.

Currently over the World Wide Web, the Domain Name System (DNS) is responsible for mapping human-readable names to IP addresses. RNS is a decentralized and secure service that works over RSK's blockchain.

Here’s a refined version of your text, maintaining the same tone and voice:


## Design

RNS is a hierarchical namespace inspired by DNS, where the hierarchy roughly reflects organizational structure, with levels separated by the "." character.

The design of the RIF Name Service is shaped by specific goals:

- The primary objective is to establish a consistent namespace for referencing resources.
- Each piece of data associated with a name is tagged with a type, allowing queries to be limited to a specific type.
- To ensure the namespace is adaptable across different networks and applications, RNS supports the use of the same namespace with various protocol families or management systems. Data in RNS is tagged with both a class and a type, enabling the parallel use of different formats for data of type "address."
- There may be trade-offs between data acquisition costs, update speed, and cache accuracy. The domain owner, as the data source, should consider these trade-offs and decide what to store and how to cache it.

> [RNS specs](./specs)


## Elements of the RNS

RNS has three major components:

- **The RNS Registry**, which is specification for a tree structured name space and data associated with the names.

Conceptually, each node and leaf of the domain name space tree names a set of information, and query operations are attempts to extract specific types of information from a particular set. A query names the domain name of interest and describes the type of resource information that is desired.

[Specs](./specs/registry)

- **RNS Resolvers** are contracts that provide information from a name in response to client requests.

Resolvers must be able to answer a query directly, or pursue the query using referrals to other resolvers. A resolver will typically be a contract's public function that is directly accessible to user programs or other contracts; hence no protocol is necessary between the resolver and the user program.

[Specs](./specs/resolver)

- **RNS Registrar** is a critical component within the RIF Name Service, responsible for managing the registration of `.rsk` domain names. This contract is granted the authority to register names in the RSK Owner contract, ensuring that new domain registrations are handled securely and efficiently.
[Specs](./specs/registrar)

These three components roughly correspond to the three layers or views of the domain system:
- From the user's point of view, the domain system is accessed through a simple resolution operation. The domain space consists of a single tree and the user can request information from any section of the tree.
- From the resolver's point of view, the domain system is composed of an unknown number of names. Each name has a corresponding resolver that provides information for a set of resolution types directly.
- From the registry's point of view, the domain system consists of a hierarchical tree where each leaf has an owner (contract or account) and an associated resolver that provides information of the name.


## Guidelines on use

Before RNS can be used to hold naming information for some kind of object, two needs must be met:
- A convention for mapping between object names and domain names. This describes how information about an object is accessed. Find specs [here](specs#name-mapping-convention)
- Resource record types and data formats for describing the object. Find specs.

The guideline for finding a specific record for a name is as follows:
1. Calculate the name identifier with [`namehash` function](specs#name-mapping-convention).
2. Get the name's resolver address via [`resolver(bytes32)`](specs/registry#AcessFunctions).
3. Determine if resolver supports desired resource record via [ERC-165 interface detection](https://eips.ethereum.org/EIPS/eip-165).
4. Get the desired resource record. Find currently standardized [resolvers](./specs/resolver).

> Guidelines on integration

### Resource records

A domain name identifies a node. Each node has a set of resource information, which may be empty. The set of resource information associated with a particular name is composed of separate resource records (RRs). The order of RRs in a set is not significant. Resource records associated with a name are found in the domain's resolver
66 changes: 66 additions & 0 deletions docs/01-concepts/rif-suite/rns/specs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
sidebar_label: Spec
sidebar_position: 400
title: "Specification"
tags: [rif, rns, spec]
description: "The domain name space is a tree structure. Each node and leaf on the tree corresponds to a resource set (which may be empty)."
---

The domain name space is a tree structure. Each node and leaf on the tree corresponds to a resource set (which may be empty).

The domain system makes no distinctions between the uses of the interior nodes and leaves, and this memo uses the term "node" to refer to both.

The domain name of a node is the list of the labels on the path from the node to the root of the tree. By convention, the labels that compose a domain name are printed or read left to right, from the most specific (lowest, farthest from the root) to the least specific (highest, closest to the root).

When a user needs to type a domain name, the length of each label is omitted and the labels are separated by dots `(.)`.

Since a complete domain name ends with the root label, this leads to a printed form which ends in a dot, that is omitted. For example, a valid domain name is `wallet.alice.rsk`.

## Valid names
For simplicity, a valid RNS domain is defined as follows:

- TLD is one of the predefined TLDs, which currently may only be `rsk`
- The first label is compulsory
- Any second and subsequent labels are optional
- All labels must be alphanumeric and lower case
- All labels and the TLD are delimited by `.`

The reference implementation for RNS domain validation can be found in `rns.js`

- AVAILABLE_TLDS in src/constants.ts
- isValidDomain and isValidLabel in src/utils.ts


Example #1: uno2tres.rsk is valid:

✔️ TLD is rsk
✔️ First label is uno2tres; which is present and lowercase alphanumeric
✔️ Second and subsequent labels are not present

Example #2: rss.website.alice.rsk is valid:

- ✔️ TLD is rsk
- ✔️ First label is alice; which is present and lowercase alphanumeric
- ✔️ Second label is website; which is present and lowercase alphanumeric
- ✔️ Third label is rss; which is present and lowercase alphanumeric

Example #3: my_illegal_domain.com is invalid:

- ❌ TLD is com
- ❌ First label is my_illegal_domain; which is present, however contains non-alphanumeric characters
- ✔️ Second and subsequent labels are not present

## Name mapping convention
Each domain name has a node identifier in the RNS Registry, that is obtained via `namehash` functions, that is as follows:

```python
def namehash(name):
if name == '':
return '\0' * 32
else:
label, _, remainder = name.partition('.')
return sha3(namehash(remainder) + sha3(label))
```

Given a `node`, a `subnode` can be identified by using its label: `sha3(namehash(node) + sha3(label))`

88 changes: 88 additions & 0 deletions docs/01-concepts/rif-suite/rns/specs/registrar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
sidebar_label: Registrar Specs
sidebar_position: 400
title: "Registry Specs"
tags: [rif, rns, rif-name-service, Registrar Specs]
description: "The registry contract provides a simple mapping between a domain and its resolver. "
---

### FIFSRegistrarBase.sol Contract Specification

The `FIFSRegistrarBase` contract implements a First-In-First-Served (FIFS) registration mechanism for domain names within the RNS system. The contract follows a structured process to ensure secure and fair registration of domain names. Below is a detailed breakdown of the registration process and key functions:

#### Registration Steps

1. **Calculate Commitment Hash (Off-chain)**
- The first step in registering a domain name is to calculate a commitment hash off-chain using the `makeCommitment` function. This hash ensures that the registration process remains secure by preventing front-running attacks.
- **Function: `makeCommitment`**
- **Parameters**:
- `label`: The keccak256 hash of the domain name to be registered.
- `nameOwner`: The address of the owner of the domain name.
- `secret`: A secret value to protect the name registration.
- **Returns**: The commitment hash (`bytes32`).
- **Usage Note**: This function should be used off-chain and not on-chain when committing.

```solidity
function makeCommitment(bytes32 label, address nameOwner, bytes32 secret) public pure returns (bytes32) {
return keccak256(abi.encodePacked(label, nameOwner, secret));
}
```

2. **Commit the Calculated Hash**
- Once the commitment hash is calculated, it must be submitted to the contract to initiate the registration process.
- **Function: `commit`**
- **Parameters**:
- `commitment`: The valid commitment hash obtained from `makeCommitment`.
- **Usage Note**: The commitment must be unique, and the function ensures that no duplicate commitments are made.

```solidity
function commit(bytes32 commitment) external {
require(commitmentRevealTime[commitment] < 1, "Existent commitment");
commitmentRevealTime[commitment] = now.add(minCommitmentAge);
}
```

3. **Wait for the Commitment to Mature**
- After committing, there is a mandatory waiting period (`minCommitmentAge`) to ensure the commitment is valid and secure. During this time, the commitment cannot be revealed or used to register the domain.
- **Function: `canReveal`**
- **Parameters**:
- `commitment`: The commitment hash to be queried.
- **Returns**: `true` if the commitment can be revealed, `false` otherwise.

```solidity
function canReveal(bytes32 commitment) public view returns (bool) {
uint revealTime = commitmentRevealTime[commitment];
return 0 < revealTime && revealTime <= now;
}
```

4. **Execute Registration**
- Once the commitment is ready to be revealed, the actual registration of the domain can be performed. The `FIFSRegistrarBase` contract supports multiple ways to execute this registration, such as using ERC-20 or ERC-677 tokens.
- **Function: `register`**
- **Parameters**:
- `name`: The domain name to register.
- `nameOwner`: The owner of the domain.
- `secret`: The secret used in the commitment process.
- `duration`: The registration duration in years.
- **Usage Note**: The registration cost is calculated based on the domain name and is transferred using RIF tokens.

```solidity
function register(string calldata name, address nameOwner, bytes32 secret, uint duration) external {
uint cost = executeRegistration(name, nameOwner, secret, duration);
require(rif.transferFrom(msg.sender, pool, cost), "Token transfer failed");
}
```

- **Function: `tokenFallback`**
- **Parameters**:
- `from`: The address sending the tokens.
- `value`: The amount of tokens sent.
- `data`: Additional data for the registration process.
- **Returns**: `true` if the transaction is successful.

```solidity
function tokenFallback(address from, uint value, bytes calldata data) external returns (bool) {
require(msg.sender == address(rif), "Only RIF token");
require(data.length > 88, "Invalid data");
}
```
68 changes: 68 additions & 0 deletions docs/01-concepts/rif-suite/rns/specs/registry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
sidebar_label: Registry Specs
sidebar_position: 400
title: "Registry Specs"
tags: [rif, rns, rif-name-service, Registry Specs]
description: "The registry contract provides a simple mapping between a domain and its resolver. "
---

The registry contract provides a simple mapping between a domain and its resolver.

This contract manages all aspects of domain ownership, including transferring ownership and creating subdomains.

Each entry in the registry points to a resolver, which handles the resolution between the name domain and the desired resource.

The RNS Registry contract provides both data access and modification capabilities through the following functions:


## Access Functions

- Ownership
```
function owner(bytes32 node) constant returns (address);
```

Retrieves the owner (registrar) of the specified node.

- Resolution
```
function resolver(bytes32 node) constant returns (address);
```

Returns the resolver for the specified node.

- Caching
```
function ttl(bytes32 node) constant returns (uint64);
```
Retrieves the time-to-live (TTL) of the specified node. The TTL defines the maximum period during which the node's information can be cached.

## Modify Functions
The RNS Registry contract also allows for the modification of node data through the following functions:

- Ownership
```
function setOwner(bytes32 node, address owner);
```

Transfers ownership of a node to another registrar. This function may only be called by the current owner of node. A successful call to this function logs the `Transfer(bytes32 indexed, address)` event.

```
function setSubnodeOwner(bytes32 node, bytes32 label, address owner);
```

Creates a new node `label.node` and sets its owner to owner, or updates the node with a new owner if it already exists. This function may only be called by the current owner of node. A successful call to this function logs the `NewOwner(bytes32 indexed, bytes32 indexed, address)` event.

- Resolution
```
function setResolver(bytes32 node, address resolver);
```

Sets the Resolver address for node, the contract that handles the desired resolutions. This function may only be called by the owner of node. A successful call to this function logs the `NewResolver(bytes32 indexed, address)` event.

- Caching
```
function setTTL(bytes32 node, uint64 ttl);
```
Sets the TTL for a node. A node's TTL applies to the 'owner' and 'resolver' records in the Registry, as well as to any information returned by the associated resolver.

Loading