# How BNSv2 Works

## Architecture Overview

BNSv2 is implemented amongst two Clarity contracts: `.BNS-V2` and `.zonefile-resolver` . These two Clarity contracts collectively manage:

1. Namespace registration and management
2. Name registration (preorder/reveal and fast-claim)
3. Record storage (via zonefile-resolver)
4. Ownership transfers
5. Renewals
6. Marketplace (list, unlist, buy)
7. Primary name designation

All state lives on-chain and is publicly verifiable.

<table><thead><tr><th width="162.8984375"></th><th>Mainnet</th><th>Testnet</th></tr></thead><tbody><tr><td>BNSv2</td><td><code>SP2QEZ06AGJ3RKJPBV14SY1V5BBFNAW33D96YPGZF.BNS-V2</code></td><td><code>ST2QEZ06AGJ3RKJPBV14SY1V5BBFNAW33D9SZJQ0M.BNS-V2</code></td></tr><tr><td>Zonefile Resolver</td><td><code>SP2QEZ06AGJ3RKJPBV14SY1V5BBFNAW33D96YPGZF.zonefile-resolver</code></td><td><code>ST2QEZ06AGJ3RKJPBV14SY1V5BBFNAW33D9SZJQ0M.zonefile-resolver</code></td></tr></tbody></table>

#### Resolution of names

Resolution works as follows:

1. A user queries the zonefile-resolver contract with a name and namespace
2. The resolver checks the name is valid, not revoked, and within its renewal period (cross-contract call to BNS-V2)
3. Returns the zonefile data (owner, zonefile buffer, revoked status)
4. Applications parse the zonefile JSON to extract addresses, profiles, etc.

For name ownership/properties (without zonefile data), you query the BNS-V2 contract directly. There are no centralized DNS servers or off-chain dependencies required for correctness.

{% hint style="info" %}
BNSv2 discontinued V1-style off-chain subdomains (Atlas network / TXT records) and DID compliance. Subdomains are now defined within a name's zonefile, stored on-chain. For legacy documentation on BNSv1, navigate [here](https://docs.stacks.co/learn/network-fundamentals/bitcoin-name-system).
{% endhint %}

***

## Zonefiles

Zonefiles also look significantly different in this upgrade.

Previously, BNS zonefiles are built on top of the “atlas” network. Atlas is a protocol built in to Stacks node’s software for replication and distribution of zonefiles. In BNSv1, BNS apps and APIs only recognized zonefiles that are part of the Atlas network.

The `zonefile-resolver` contract stores a `(optional (buff 8192))`. The contract itself has no IPFS-specific logic. It stores raw bytes — which at the application layer could be a full JSON zonefile or a CID/URL pointing to external storage.

Overall, this architecture delivers a flexible and scalable solution, combining the security and immediacy of on-chain storage with the extensibility and efficiency of decentralized off-chain storage.

These changes can summarized in two ways:

1. Zonesfiles, or links to zonefiles, now live on-chain
2. Zonefiles are now decoupled from the BNS-V2 contract. Zonefiles now live-onchain & in their own contract: `.zonefile-resolver`. This contract is fairly limited with a single map & only three functions: `resolve-name`, `update-zonefile` & `revoke-name`.

Under this design, a dedicated smart contract is responsible for managing all zonefile-related functionality. The contract supports storing zonefiles of up to 8,192 bytes (8 KB) directly on-chain, associating the zonefile deterministically with its corresponding name and namespace. This ensures that smaller zonefiles are immediately available, tamper-resistant, and secured by the underlying blockchain guarantees.

{% code title="Data map for a name’s zonefile information" %}

```clarity
;; zonefile map: Stores zonefile information for each name in a namespace
;; Key: {name: (buff 48), namespace: (buff 20)}
;; Value: {owner: principal, zonefile: (optional (buff 8192)), revoked: bool}
(define-map zonefile {name: (buff 48), namespace: (buff 20)} 
    {
        owner: principal,
        zonefile: (optional (buff 8192)),
        revoked: bool
    }
)
```

{% endcode %}

Zonefiles are technically stored as a hex-encoded UTF-8 JSON. The maximum length if defined in the contract to be 8,192 bytes (8 KB). The following JSON schema is the standard format used by BNSv2 applications and the official API. The contract itself stores raw bytes and does not enforce this structure.

{% code title="Zonefile structure" expandable="true" %}

```json
{
	"owner": "SP...",
	"btc": "bc1...",
	"bio": "User bio...",
	"website": "www.url.com",
	"pfp": "www.mypfp.com/image.png", // must be a valid image format (e.g. .png, .jpg, .svg)
	"name": "User Name",
	"location": "City, Country",
	"social": [
		{
			"platform": "x", 
			"username": "username"
		},
		{
			"platform": "telegram", 
			"username": "username"
		}
		// ...
	],
	"addresses": [
		{
			"network": "btc",
			"address": "bc1...",
			"type": "payment"
		},
		{
			"network": "btc",
			"address": "bc1...",
			"type": "ordinal"
		},
		{
			"network": "eth",
			"address": "0x123...",
			"type": "wallet"
		}
		// ...
	],
	"meta": [
		{
			"name": "example",
			"value": "custom datas"
		}
		// ...
	],
	"subdomains": [
		{
			"test": {
				"owner": "SP....",
				"bio": "Subdomain bio..",
				"website": "www.url.com",
				"pfp": "www.mypfp.com/image.png",
				"name": "User Name",
				"location": "City, Country",
				"social": [
					{
						"platform": "x",
						"username": "@username"
					}
				],
				"addresses": [
					{
						"network": "Bitcoin",
						"address": "bc1...",
						"type": "payment"
					}
				]
			}
		}
		// ...
	],
	"externalSubdomainsFile": "www.url.com/subdomains.json" // optional: external file containing subdomain definitions
}
```

{% endcode %}

The API layer abstracts the resolution logic, automatically determining whether to retrieve the zonefile data directly from the contract or via IPFS using the stored CID. As a result, clients can resolve zonefile information for any given name and namespace through a consistent interface without needing to manage storage distinctions manually.

Check out the [BNSv2 SDK](https://github.com/Strata-Labs/bns-v2-sdk) for more info on zonefiles.


---

# 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://docs.stacks.co/learn/network-fundamentals/bitcoin-name-system/architecture.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.
