# Flowns intro
Flowns is a new generation of decentralized domain name service built on Flow network. It is a resource-oriented domain name service based on Cadence smart contract language.
The `[Resource model](https://docs.onflow.org/cadence/language/resources/)` in Flow makes the Flowns service flexible and extensible, and based on the domain name NFT asset, we can generate more usage scenarios.
> Flowns is not only a domain service, but also a protocol for opening identities and assets in digital world.
## Why Flowns
Readable names and rich-data on-chain identities are indispensable infrastructure in the digital world. Domain names are indexes and profile for owners.
Flowns domain could store more information and assets on chain, then it becomes a personalized expressions of their own.
In the future of blockchain applications and data explosion, we still need an open diverse digital identity service.
We defines an open protocol for data and assets, allowing any type of resource/asset nesting in domain NFT. Domain assets become a meta-assets defined by both users and developers.
## Features of Flowns
### Ownership
In Flow network, Flowns domain assets completely distribute storage in user's account, and the user can keep his domain but not use it.
Even if the domain expired, Flowns cannot destroy or revoke it without permission, therefore the domain is still under the user's control. This means that the domain resource will exist forever.
> It is the ownership of assets protected by Flow networks and encryption algorithms.
Users do not need Flowns service to define and manage their domain NFT. All operations are performed by users themselves. By calling the NFT resources [Capabilities] (https://docs.onflow.org/cadence/language/capability-based-access-control/) of domain NFT to management and custom.
Flowns itself only provides domain service addressing resolution, metadata rule definition, metadata resolution services.
The domain owner can renew his domain at any time after it expires to resume the service. Domain resources are not reclaimed but marked as inactive and available for registration by Flowns. Once another user registers an expired domain, Flowns will mint a new domain NFT for the new user. The original domain resource will be marked as deprecated in the Flowns service.
This not only ensures the dispersion of user assets, but also takes into account the continuity of domain services.
### Composable
Benefiting from the nesting ability of resources in Cadence, Domain can become the asset container for users, receive any type of fungible or non-fungible tokens, since it can help users store funds and other types of NFT assets from "active" to "passive." Subdomain are also nested resources in domain NFT resources, which are managed and maintained by users themselves.
One fascinating thing about composability is that any third party developer or server can embed NFT assets representing "proof", "authentication" or even "asset" into the domain resource, and these nested resources as the rights of the domain owner.
We can regard domain assets as virtual unlimited space of users, which can accommodate arbitrary data and asset collection and become a carrier of personalized data and asset.
### Multi Root
Flowns support multiple root domain names. This gives users and issuers more choices.
Each root domain has its own independent configuration, including the include, vault, prices, commission rate, max length of domain, minimum rent duration, forbid chars etc.
It also allows different root domains to accept different types of fungible tokens as payment currencies, which has the foundation for commercial applications.
### Community driven
Flowns is born in community and gets a lot of support from community. As an infrastructure and public good, Flonws will also belong to the community.
We regard the domain buyer as community member and supporters, most of the sale funds will be given back to the community by establish a DAO.
The Flow account model supports multi-public key binding. Therefore, when the Flowns service runs stably, the admin account becomes a multi-signed account by adding multiple public keys.
In the future, the admin account will also be upgraded to multi-signed account, and gradually transfer the management authority to the community.
---
## Explanation of terms
Before we go deep into the technical , we need to explain some terms:
### RootDomain
The root of the domain name, as we all known the domain in internet word has readable name with `github.com` or `google.com`, even more domain level as `test.google.com`, we can see the postfix of them are the root domain -- `com`. So in Flowns, RootDomain is the root for all domains as well.
And the RootDomain in Flowns,is managed by the administrator, and keep as a resource in collection resource of owner's account.
And Flow support multi key bind with a account, when Flowns service runs stably,the admin account will add more key to became a multiSig address.And yes,the management will also be handed over to the community
### Domain(NFT) —— 域名 NFT 资源
Domains is a NFT contract that implement the NonFungibleToken standard and define the Domain resoucre and Subdomain resource. The Domain resrouce is mint by the Root domain, we can see the register and renew functions in root domain resource ,that means the domains minted by RootDomain.
User can keep or transfer it as a normal NFT ,even trade in the market.
Because of the feature of resource-oriented , the domain resource is stored under the user's account, so Domain has a bunch of functions to let user customize his domain or create a Subdomain and manage them.
### Subdomain —— 子域名
Just like the example before: `test.google.com`, `test` is subdomain of `google.com` (SLD: second-level domain)and for sure `google` domain's root domain is `com`.
In Flowns, if user register a new domain called `user.flow` from `flow` root domain. He also have the ownership of his domain resource, and could mint a subdomain for him , such as `blog.user.flow` or `dev.user.flow` etc.
### NameHash -- 名称 hash
For more characters to support , Flowns use name hash to make every domain name unique in Flowns systems, and they all stored in Domains. records with a key-value mapping.
Every state change happend with domains ,need to be index to the specific domain records in Flowns contract.
## technical architecture —— 技术架构
As the content talk about before, the domains service has a inheritance relationship:
```
// ex. dev.user.flow
Root domain -> Domain -> subdomain
`flow` -> `user` -> `dev`
```
### Contract structure —— 合约结构
```
Flowns
|
-- Admin
|
-- RootDomainCollection
|
-- RootDomain
Domains
|
-- Domains.Collection
|
-- Domains
|
-- Subdomain
```
资源嵌套结构如下 :
```
Admin resource -- in admin account
|
-- server: &RootDomainCollection
|
-- domains: @{UInt64: RootDomain}
|
-- server: Domains.Collection (In order to create the Domain.NFT)
|
-- domainVault: @FungibleToken.Vault (Receive domain rent fee)
Domains resource -- in user account
|
-- Collection: @NonFungibleToken.Collection
|
-- ownedNFTs: @{UInt64: NonFungibleToken.NFT} as Domains.NFT(Domain)
|
-- subdomains: @{String: Subdomain}
|
-- vaults: @{String: FungibleToken.Vault}
|
-- collections: @{String: NonFungibleToken.Collection}
```
#### FLowns
Flowns is the core contract of Flowns ,it define the Root domains, and store them as a resrouce in `RootDomainCollection`(more like NFTs, but not the standard NFT), so if user want to rent their domain, they need to call the public function of the root domain to register from the root.
The **RootDomain** resource has three core props:
- vault -- the vault for each domain to receive the rent fee from user, can withdraw by admin, and can change to another type of vault witch implement the FungibleToken contract.
```
// Root domain create with a vault resource
access(account) fun createRootDomain(
name: String,
nameHash: String,
vault: @FungibleToken.Vault
)
```
- prices -- is the root domain's rent price set by admin, it define the rent price by domain length per second. If the prices of the length not set ,user cannot register or renew their domain under the root domain.
```
// set price with domain name length
access(account) fun setPrices(domainId: UInt64, len: Int, price: UFix64)
```
- server -- keep the `Domains.Collection` Capability in root domain resource for mint Domains.NFT when user register that.
```
// only use by Root domain itself, use Domains.Collection to call the mintdomain functions
access(self) var server: Capability<&Domains.Collection>?
// Domains.mintdomain
access(account) fun mintDomain(id: UInt64, name: String, nameHash: String, parentName: String, expiredAt: UFix64, receiver: Capability<&{NonFungibleToken.Receiver}>)
```
The **Admin** resource is the manager resource that has permissions to
- init root name
- createRootDomain
- add root domain collection capability as a server to Admin resource
```
// for admin resource to manage root domains under their account
pub fun addCapability(_ cap: Capability<&Flowns.RootDomainCollection>)
// init admin server
self.server!.borrow() can get the root `RootDomainCollection` reference
```
- add DomainsNFT collection capability as a server to Root domain resource (in order to mint Domain NFTs by using Domains.CollectionPrivate interface)
```
// for root domain manage domains, by call rootDomain.addCapability(cap)
pub fun addRootDomainCapability(domainId: UInt64, cap: Capability<&Domains.Collection>)
// in admin resource's function
self.server!.borrow()!.getRootDomain(domainId).addCapability(cap)
```
- setRentPrice of root domain
- changeRootDomainVault, for receive diffrent type of Fungible tokens
```
// could change the root domain's vault for receive new type of Fungible token
access(account) fun changeRootDomainVault(vault: @FungibleToken.Vault)
```
- updateRecords Domains NFT records
- mintDomain directly with out pay any rent fee( for private root domain only)
All Flowns management is define in the flowns contract, and it have more permissions restrictions.
Flowns also is the public entrance for user to register domain from Root Domain.
#### Domains
Domains contract does some expansions based on NFT contracts, it focus on the resource and domain capability, provider the domain manage interface to the owners and query interface for public data.
Domains has three central storage props in the contract :
- Domains.records
`records` keep the namehash and account mapping, as a registry records in order to do reverse addressing as well. The records could not change by the owner, but when the Domain NFT transfer to other user, the records will update automaticly. So the other third-party developer always can find the domain owner by the domain namehash.
- Domains.expired
`expired` store how long the domain's period of validity, It can be update by the renew interface from Flowns contract. When the domain got expired ,the service of Domains interface will stop, but the domain NFT resource will still exsit in users account.
User could renew it before domain got expired , otherwise their domain may marked as a deprecated resource.
- Domains.deprecated
Store the expired domains which is not renew by owner but register by another people.
When domain got expired, the owner can chose renew it or not, But when the domain expired ,even the user keep the resource, Flowns mark the domain as availabe for others user, so new user can register the expired domain.
**NFT(Domains.NFT)** -- the Domain resource, can mint by Domains.DomainCollection
NFT has some core props :
- addresses -- Domain's address list update by owner
- texts -- Domains metadata
- subdomains -- nest the subdomain that ownr created
- vaults -- store any type of Fungibel token for owner
- Deposit flow token to Domain resrouce as a nest resource [script ](https://github.com/flowns-org/flow-name-service-contracts/blob/main/cadence/transactions/deposit_domain_vault_with_flow.cdc)
- Withdraw token from Domain resource [script](https://github.com/flowns-org/flow-name-service-contracts/blob/main/cadence/transactions/withdraw_domain_vault_with_vault_type.cdc)
```
// store any Fungible token with the script
// eg. {'A.0ae53cb6e3f42a79.FlowToken.Vault': @FungibleToken.Vault}
pub var vaults: @{String: FungibleToken.Vault}
```
- collections -- store any type of NFT Collections for owner, even the `Domains.Collection` type.
- Send NFT to a Domain resource [script](https://github.com/flowns-org/flow-name-service-contracts/blob/main/cadence/transactions/send_nft_to_domain.cdc)
- Withdraw NFT from Domains nest collection [script](https://github.com/flowns-org/flow-name-service-contracts/blob/main/cadence/transactions/withdraw_nft_from_domain.cdc)
```
// store the nest NFT collection for Domain resource
// eg. {'A.f8d6e0586b0a20c7.Domains.Collection': @NonFungibleToken.Collection}
pub var collections: @{String: NonFungibleToken.Collection}
```
And some domain and subdomain records / texts manage functions
- Subdomain -- the child of domains, and store as a nest resource in Domains `subdomains: @{String: Subdomain}` props. The key will be namehash for each subdomain.
- `createSubDomain` -- add subdomain for domain owner
- `removeSubDomain` -- remove subdomain for domain owner
- Collection -- Domains.Collection responsible for Domain NFT storage and have some private fuctions.
- `borrowDomainPrivate` -- Borrow domain's reference for owner.
- `mintDomain` -- Mint domain resrouce for register.