# Build a Bitcoin Name System

Let's build the Bitcoin Name System (BNS), a decentralized, open, and permissionless naming system on Bitcoin.

* buy and sell BNS name
* register a human-readable name like 'alice.tc' or 'bob.sat'
* map a human-readable name like 'bob.sat' to a machine-readable id like a Bitcoin address

## Write the BNS smart contract

It turns out that writing the Bitcoin Name System smart contract is very simple. Here is a basic contract to provide a DNS-like naming system on Bitcoin Virtual Machine.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract BNS is ERC721 {

        using Counters for Counters.Counter;
        Counters.Counter private _tokenIds;

        mapping(bytes => uint256) public registry;
        mapping(bytes => bool) public registered;

        mapping(uint256 => address) public resolver;

        constructor() ERC721("Bitcoin Name System", "BNS") {}

        function register(address owner, bytes memory name) 
                public 
                returns (uint256) 
        {
                require(!registered[name]);

                uint256 id = _tokenIds.current();
                _mint(owner, id);
                registry[name] = id;
                registered[name] = true;
                resolver[id] = owner;

                _tokenIds.increment();
                return id;
        }

        function map(uint256 tokenId, address to) public {
                require(msg.sender == ownerOf(tokenId));
                resolver[tokenId] = to;
        }
}
```

Extending ERC-721, we only need to implement the `register()` function to register a new name as an NFT and the `map()` function to map a human-readable name like 'bob.sat' to a machine-readable id like a wallet address.

Sending and receiving a BNS name is now as simple as sending and receiving an NFT. You can also trade the BNS name on open markets since it's an ERC-721.

## Clone the smart contract examples

We've prepared a few different examples for you to get started. The BNS example is located at **smart-contract-examples/contracts/BNS.sol**.

```bash
git clone https://github.com/trustlesscomputer/smart-contract-examples.git
```

## Compile the contracts

To compile your contracts, use the built-in `hardhat compile` task.

```bash
cd smart-contract-examples
npm install
npx hardhat compile
```

## Deploy the contracts

Review config file `hardhat.config.ts`. The network configs should look like this.

```js
  networks: {
    mynw: {
      url: "http://localhost:10002",
      accounts: {
        mnemonic: "<your mnemonic with funds>"
      },
      timeout: 100_000,
    },
    blockscoutVerify: {
      blockscoutURL: "http://localhost:4000", // your explorer URL
      ...
    }
  }
```

Run the deploy scripts using `hardhat-deploy`.

```bash
npx hardhat deploy --tags BNS
```

{% hint style="warning" %}
Make sure the accounts in hardhat.config.ts have some $BVM.
{% endhint %}

## Interact with the contracts

Once the contracts are deployed, you can interact with them. We've prepared a few `hardhat tasks` to make it easy for you to interact with the contracts.

```bash
# register a name
npx hardhat register --domain "bob.sat"

# create a mapping
npx hardhat map "bob.sat" <a-wallet-address>

# resolve a human-readable name to a machine-readable id
npx hardhat resolve --domain "bob.sat"
```

## Register your domain

```bash
git clone https://github.com/trustlesscomputer/smart-contract-examples
cd smart-contract-examples
npm install
npx hardhat compile
npx hardhat register --domain yourname.tc \
--contract 0x8b46F89BBA2B1c1f9eE196F43939476E79579798 \
--privatekey 0xafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaf # your private key
```

This will output the transaction hash, which can be used to track its status via the [explorer](http://explorer.trustless.computer). After it is confirmed, you can try resolving that name by calling the BNS contract

```bash
npx hardhat resolve --domain yourname.tc \
--contract 0x8b46F89BBA2B1c1f9eE196F43939476E79579798 \
```


---

# 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.bvm.network/bvm/bitcoin-dapps/evm-code-tutorials/build-a-bitcoin-name-system.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.
