9.5 KiB
layout | description | permalink |
---|---|---|
core | Blockstack naming service (BNS) | /:collection/:path.html |
Resolve a name
{:.no_toc}
This section explains resolving BNS names and provides instructions for methods you can use to accomplish namespace resolution.
- TOC {:toc}
Understand resolution
BNS names are bound to both public keys and to about 40Kb of off-chain state. The off-chain state is encoded as a DNS zone file, which contains routing information for discovering the user's Blockstack data (such as their profile and app data, which are hosted in the Gaia storage system).
The blockchain is not used to store this information directly. Instead, the blockchain stores the public key hash and the zone file hash. When indexing the blockchain, each BNS node builds a database with three columns: all the on-chain BNS names that have been registered, each name's public key hash, and each name's zone file's hash. In addition, each BNS node maintains the transaction history of each name. A developer can resolve a name to any configuration it was in at any prior point in time.
Below is an example name table pulled from a live BNS node:
Name | Public key hash | Zone File Hash |
---|---|---|
ryan.id |
15BcxePn59Y6mYD2fRLCLCaaHScefqW2No |
a455954b3e38685e487efa41480beeb315f4ec65 |
muneeb.id |
1J3PUxY5uDShUnHRrMyU6yKtoHEUPhKULs |
37aecf837c6ae9bdc9dbd98a268f263dacd00361 |
jude.id |
16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg |
b6e99200125e70d634b17fe61ce55b09881bfafd |
verified.podcast |
1MwPD6dH4fE3gQ9mCov81L1DEQWT7E85qH |
6701ce856620d4f2f57cd23b166089759ef6eabd |
cicero.res_publica.id |
1EtE77Aa5AA8etzF2irk56vvkS4v7rZ7PE |
7e4ac75f9d79ba9d5d284fac19617497433b832d |
podsaveamerica.verified.podcast |
1MwPD6dH4fE3gQ9mCov81L1DEQWT7E85qH |
0d6f090db8945aa0e60759f9c866b17645893a95 |
In practice, the zone file hash is the RIPEMD160
hash of the SHA256
hash of
the zone file, and the public key is the base58check
-encoded RIPEMD160
hash
of the double-SHA256
hash of the ECDSA public key (i.e. a Bitcoin address).
The BNS consensus rules ensure that a BNS name can only be registered if it is not already taken, and that only the user who owns the name's private key can change its public key hash or zone file hash. This means that a name's public key and zone file can be stored anywhere, since they can be authenticated using the hashes discovered by indexing the blockchain under the BNS consensus rules.
BNS nodes implement a decentralized storage system for zone files called the [Atlas network]({{ site.baseurl }}/core/atlas/overview.html). In this system, BNS nodes eagerly replicate all the zone files they know about to one another, so that eventually every BNS node has a full replica of all zone files.
The public keys for names are stored off-chain in Gaia. The user controls where their public keys are hosted using the zone file contents (if they are hosted online anywhere at all).
Developers can query this table via the BNS API. The API offers routes to do the following:
Look up a name's public key and zone file (reference)
$ curl https://core.blockstack.org/v1/names/muneeb.id
{
"address": "1J3PUxY5uDShUnHRrMyU6yKtoHEUPhKULs",
"blockchain": "bitcoin",
"expire_block": 599266,
"last_txid": "7e16e8688ca0413a398bbaf16ad4b10d3c9439555fc140f58e5ab4e50793c476",
"status": "registered",
"zonefile": "$ORIGIN muneeb.id\n$TTL 3600\n_http._tcp URI 10 1 \"https://gaia.blockstack.org/hub/1J3PUxY5uDShUnHRrMyU6yKtoHEUPhKULs/0/profile.json\"\n",
"zonefile_hash": "37aecf837c6ae9bdc9dbd98a268f263dacd00361"
}
Note that the zonefile
field is given with the off-chain data that hashes
to the zonefile_hash
field.
List all names the node knows about (reference)
$ curl https://core.blockstack.org/v1/names?page=0
[
"judecn.id",
"3.id",
"4.id",
"8.id",
"e.id",
"h.id",
"5.id",
"9.id",
"i.id",
"l.id",
"p.id",
"w.id",
"ba.id",
"df.id",
...
]
Each page returns 100 names. While no specific ordering is mandated by the protocol, the reference implementation orders names by their order of creation in the blockchain.
Look up the history of states a name was in (reference)
$ curl https://core.blockstack.org/v1/names/patrickstanley.id/history
{
"445838": [
{
"address": "1occgbip7tFDXX9MvzQhcnTUUjcVX2dYK",
"block_number": 445838,
"burn_address": "1111111111111111111114oLvT2",
"consensus_hash": "7b696b6f4060b792d41912068944d73b",
"op": "?",
"op_fee": 25000,
"opcode": "NAME_PREORDER",
"preorder_hash": "26bf7874706ac761afdd403ed6b3b9578fb01a34",
"sender": "76a91408d0dd44c1f0a3a4f0957ae95901929d7d66d55788ac",
"sender_pubkey": "039a8948d339ecbff44cf426cb85d90fce876f1658d385cdc47f007f279be626ea",
"txid": "6730ae09574d5935ffabe3dd63a9341ea54fafae62fde36c27738e9ee9c4e889",
"vtxindex": 40
}
],
"445851": [
{
"address": "17CbHgTgBG3kLedXNneEKBkCTgW2fyrnUD",
"block_number": 445838,
"consensus_hash": null,
"first_registered": 445851,
"importer": null,
"importer_address": null,
"last_creation_op": "?",
"last_renewed": 445851,
"name": "patrickstanley.id",
"name_hash128": "683a3e1ee5f0296833c56e481cf41b77",
"namespace_block_number": 373601,
"namespace_id": "id",
"op": ":",
"op_fee": 25000,
"opcode": "NAME_REGISTRATION",
"preorder_block_number": 445838,
"preorder_hash": "26bf7874706ac761afdd403ed6b3b9578fb01a34",
"revoked": false,
"sender": "76a9144401f3be5311585ea519c1cb471a8dc7b02fd6ee88ac",
"sender_pubkey": "039a8948d339ecbff44cf426cb85d90fce876f1658d385cdc47f007f279be626ea",
"transfer_send_block_id": null,
"txid": "55b8b42fc3e3d23cbc0f07d38edae6a451dfc512b770fd7903725f9e465b2925",
"value_hash": null,
"vtxindex": 54
}
],
"445873": [
{
"address": "17CbHgTgBG3kLedXNneEKBkCTgW2fyrnUD",
"block_number": 445838,
"consensus_hash": "18b8d69f0182b89ccb1aa536f83be18a",
"first_registered": 445851,
"importer": null,
"importer_address": null,
"last_creation_op": "?",
"last_renewed": 445851,
"name": "patrickstanley.id",
"name_hash128": "683a3e1ee5f0296833c56e481cf41b77",
"namespace_block_number": 373601,
"namespace_id": "id",
"op": "+",
"op_fee": 25000,
"opcode": "NAME_UPDATE",
"preorder_block_number": 445838,
"preorder_hash": "26bf7874706ac761afdd403ed6b3b9578fb01a34",
"revoked": false,
"sender": "76a9144401f3be5311585ea519c1cb471a8dc7b02fd6ee88ac",
"sender_pubkey": "039a8948d339ecbff44cf426cb85d90fce876f1658d385cdc47f007f279be626ea",
"transfer_send_block_id": null,
"txid": "dc478659fc684a1a6e1e09901971e82de11f4dfe2b32a656700bf9a3b6030719",
"value_hash": "02af0ef21161ad06b0923106f40b994b9e4c1614",
"vtxindex": 95
}
],
"445884": [
{
"address": "1GZqrVbamkaE6YNveJFWK6cDrCy6bXyS6b",
"block_number": 445838,
"consensus_hash": "18b8d69f0182b89ccb1aa536f83be18a",
"first_registered": 445851,
"importer": null,
"importer_address": null,
"last_creation_op": "?",
"last_renewed": 445851,
"name": "patrickstanley.id",
"name_hash128": "683a3e1ee5f0296833c56e481cf41b77",
"namespace_block_number": 373601,
"namespace_id": "id",
"op": ">>",
"op_fee": 25000,
"opcode": "NAME_TRANSFER",
"preorder_block_number": 445838,
"preorder_hash": "26bf7874706ac761afdd403ed6b3b9578fb01a34",
"revoked": false,
"sender": "76a914aabffa6dd90d731d3a349f009323bb312483c15088ac",
"sender_pubkey": null,
"transfer_send_block_id": 445875,
"txid": "7a0a3bb7d39b89c3638abc369c85b5c028d0a55d7804ba1953ff19b0125f3c24",
"value_hash": "02af0ef21161ad06b0923106f40b994b9e4c1614",
"vtxindex": 16
}
]
}
All of the above information is extracted from the blockchain. Each top-level field encodes the states the name transitioned to at the given block height (e.g. 445838, 445851, 445873, adn 445884). At each block height, the name's zone file hashes are returned in the order they were discovered in the blockchain.
Each name state contains a lot of ancillary data that is used internally by other API calls and client libraries. The relevant fields for this document's scope are:
address
: This is the base58check-encoded public key hash.name
: This is the name queried.value_hash
: This is the zone file hash.opcode
: This is the type of transaction that was processed.txid
: This is the transaction ID in the underlying blockchain.
The name's entire history is returned. This includes the history of the name under its previous owner, if the name expired and was reregistered.
Look up the list of names owned by a given public key hash (reference)
$ curl https://core.blockstack.org/v1/addresses/bitcoin/16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg
{
"names": [
"judecn.id",
"patrickstanley1.id",
"abcdefgh123456.id",
"duckduckgo_tor.id",
"jude.id",
"blockstacknewyear2017.id",
"jude.statism.id"
]
}
Note that this API endpoint includes names and subdomains.