You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
4.4 KiB

---
layout: core
description: "Blockstack naming service (BNS)"
permalink: /:collection/:path.html
---
# Decentralized Identifiers (DIDs)
BNS nodes are compliant with the emerging
[Decentralized Identity Foundation](http://identity.foundation) protocol
specification for decentralized identifiers (DIDs).
Each name in BNS has an associated DID. The DID format for BNS is:
```
did:stack:v0:{address}-{index}
```
Where:
* `{address}` is an on-chain public key hash (e.g. a Bitcoin address).
* `{index}` refers to the `nth` name this address created.
For example, the DID for `personal.id` is
`did:stack:v0:1dARRtzHPAFRNE7Yup2Md9w18XEQAtLiV-0`, because the name
`personal.id` was the first-ever name created by
`1dARRtzHPAFRNE7Yup2Md9w18XEQAtLiV`.
As another example, the DID for `jude.id` is `did:stack:v0:16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg-1`.
Here, the address `16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg` had created one earlier
name in history prior to this one (which happens to be `abcdefgh123456.id`).
The purpose of a DID is to provide an eternal identifier for a public key.
The public key may change, but the DID will not.
Stacks Blockchain implements a DID method of its own
in order to be compatible with other systems that use DIDs for public key resolution.
In order for a DID to be resolvable, all of the following must be true for a
name:
* The name must exist
* The name's zone file hash must be the hash of a well-formed DNS zone file
* The DNS zone file must be present in the BNS [Atlas Network]({{ site.baseurl }}/core/atlas/overview.html)
* The DNS zone file must contain a `URI` resource record that points to a signed
JSON Web Token
* The public key that signed the JSON Web Token (and is included with it) must
hash to the address that owns the name
Not all names will have DIDs that resolve to public keys. However, names created by the [Blockstack
Browser](https://github.com/blockstack/blockstack-browser) will have DIDs that
do.
Developers can programmatically resolve DIDs via the Python API:
```Python
>>> import blockstack
>>> blockstack.lib.client.resolve_DID('did:stack:v0:16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg-1', hostport='https://node.blockstack.org:6263')
{'public_key': '020fadbbcea0ff3b05f03195b41cd991d7a0af8bd38559943aec99cbdaf0b22cc8'}
```
A RESTful API is under development.
# DID Encoding for Subdomains
Every name and subdomain in BNS has a DID. The encoding is slightly different
for subdomains, so the software can determine which code-path to take.
* For on-chain BNS names, the `{address}` is the same as the Bitcoin address
that owns the name. Currently, both version byte 0 and version byte 5
addresses are supported (i.e. addresses starting with `1` or `3`, meaning `p2pkh` and
`p2sh` addresses).
* For off-chain BNS subdomains, the `{address}` has version byte 63 for
subdomains owned by a single private key, and version byte 50 for subdomains
owned by a m-of-n set of private keys. That is, subdomain DID addresses start
with `S` or `M`, respectively.
The `{index}` field for a subdomain's DID is distinct from the `{index}` field
for a BNS name's DID, even if the same created both names and subdomains.
For example, the name `abcdefgh123456.id` has the DID `did:stack:v0:16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg-0`,
because it was the first name created by `16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg`.
However, `16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg` *also* created `jude.statism.id`
as its first subdomain name. The DID for `jude.statism.id` is
`did:stack:v0:SSXMcDiCZ7yFSQSUj7mWzmDcdwYhq97p2i-0`. Note that the address
`SSXMcDiCZ7yFSQSUj7mWzmDcdwYhq97p2i` encodes the same public key hash as the address
`16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg` (the only difference between these two
strings is that the first is base58check-encoded with version byte 0, and the
second is encoded with version byte 63).
You can see this play out in practice with the following code snippit:
```python
>>> import blockstack
>>> blockstack.lib.client.get_name_record('jude.statism.id', hostport='https://node.blockstack.org:6263')['address']
u'16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg'
>>> import virtualchain
>>> virtualchain.address_reencode('16EMaNw3pkn3v6f2BgnSSs53zAKH4Q8YJg', version_byte=63)
'SSXMcDiCZ7yFSQSUj7mWzmDcdwYhq97p2i'
>>> blockstack.lib.client.resolve_DID('did:stack:v0:SSXMcDiCZ7yFSQSUj7mWzmDcdwYhq97p2i-0', hostport='https://node.blockstack.org:6263')
{'public_key': '020fadbbcea0ff3b05f03195b41cd991d7a0af8bd38559943aec99cbdaf0b22cc8'}
```