Name Service (UNS1)

UNS1 (sometimes known just as UNS) provides the decentralized storage for key and contract name records that allows identification of keys, addresses and contract origins.


Each node keeps a table of registered names for the:

  • keys and addresses
  • contract origins

Very much like with Distributed storage, it is driven by special type of NS-contract, UNS1.

Each line in the names table should have expiration date and reference to the UNS1 contract that controls it. When the contract is being modified, it recalculates the expiration using the balance covered below.


One entry is one searchable record in the database, which can be either:

  • key record: short and long address of some key

  • origin record: origin id of some contract

The balance

The name storage works on the pre-paid basis. When UNS1 contract is first created, it must be accompanying with a initial payment in the paying parcel, which should cover at least 360 name-days, or ND. As states from its name, 1ND provides 1 day of 1 name registration.

So the initial balance is divided to the number of registration entries providing the number of paid days that is stored in the tables.

The ND unit cost should be set in node settings as for now and will be covered with a special contract type later. The initial ND rate is 4U/ND.

Minimum and maximum balances

When performing creation/updating UNS1 contracts, the fee must not be less than 100ND and the expiration time after recalculating the balance can not be longer than 3 years. The contract revision tha does not match these limitations must not be approved by the nodes.

Expiration and prolongation

Any revision of UNS1 contract may contain additional fee with its paying parcel that extends the registration time. When the name entries are expired, they are put on hold for 1 extra month. During the hosl period the corresponsing UNS1 contract could be updated with new payment. The name records on hold are not served wiht queryName() but also can not be taken by another UNS1 contract.

If the contract will not be repaid while the hold period, the stored copy of the UNS1 contract is deleted together with names record and the names become available to registration.


Unless is otherwise specified, all API calls are performed using Universa protected client channel using client keu authorization.

Get the ND rate

unsRate() -> { "U" : decimal_string }

Returns the rate at the call moment, the cost of 1 ND in U.

Create a UNS1 contract

The client creates a special contract type using the prepaid parcel with a minimum payment corresponding to 365 ND, which is payment for 1 year of 1 entry registration. As for now it is something close to €15.00. Depending on the number of entries in the contract, the actual prepaid time could be less.

The system reads names from the UNS1 contract from its array. Each name object represents one or more entries:

- name: text         # network-unique
  description: text  # optional
  url: text          # optinoal
    - addresses: [short_addr_binary, long_addr_binary]
    - origin: binary_origin

In this sample there are 1 name that makes 2 entries: one for a key, one for a origin. Name with no entries is simply ignored.

Entry is either address or origin. Address entry could take 1 short address and 1 long address.

IF all checks are passed (see below) and the network votes for this revision, the node returns with ItemResult#extra the result:

    expires_at: unixtime

Extra information about errors could be as:

    not_available: [name1,...] // for each name that is already registered by any other contract

obtaining Authorized Name Center signature

Obtaining Authorized Name Center signature is necessary to register UNS1 contract. The procedure is the following:

  • user creates UNS1 contract, fills all the information and puts it into paying parcel (no signing is required at this moment).
  • user sends packed transaction to Authorized Name Center for approval. Approval is either done automatically or required action of authorized person.
  • user receives packed transaction of UNS1 contract back. Contract contains additional field (reduced_name) for every name record. So its binary and its ID are changed at this moment. Approved contract binary is also signed with Authorized Name Center signature.
  • user adds necessary signatures (see below) to a contract and able to register paying parcel as usual at this moment.

Procedure guarantees that:

  • no homograph attack can be performed on Universa Name Service
  • no names from registered trademarks list can be taken without proper rights

additional checks while voting UNS1

For each entry the system checks:

  1. For each address entry, the transaction pack is signed with the matching key. On other words, only the key holder can register the name for it.

  2. For each origin entry, transaction pack includes a valid contract (as it is included as references, the system will already check its validity and active state) with this origin, and the UNS1 contract itself should be also signed by this contract issuer key. In other words, to register the origin, the issuer key of existing contract of that origin must be presented.

  3. The name is not yet taken. If the name is taken on the voting node, it takes it as PENDINGNEGATIVE and sees the consensus. If the consensus is ACCEPTED, it rewrites its tables accordingly and performs conflict resolution procedure (below). The name uniqueness is checked against _reduced strings_, see strings reduction

  4. Every name record contains special field reduced_name containing original name processed by special algorithm (see above) and contract itself is signed with a Authorized Name Center signature.

Accepting new revision

On network acceptance, the node recalculates expiration (see balance above) and updates its name tables accordingly.

Conflict resolution

If a node which has a local conflict with names recevies APPROVED state of the network, it should:

  1. find a conflicting UNS1 contract

  2. look for the updated version of it (ask other nodes), and either update or revoke it in local ledger, updating its names table as necessary.

Querying the name info

Is performed using an authenticated API call:

queryNameRecord(address: binary, origin: binary) 
    -> (slot state structure)

Only one of the arguments is allowed. Returned value is:

    name: string,
    description: string, // optional
    url:                 // optional

or empty structure if nothing was found.

Getting the UNS1 contract copy

queryNameContract(name: String)
   -> binary

returns last packed revision of the UNS1 contract.