DID method at identity.foundation


#1

I read a bit at https://identity.foundation about distributed identities. Are there any drafts for a spec for blockstack’s methods? What is missing?


#2

Yes, we are members.

You can resolve our DIDs with the blockstack Python library. For example, the DID for my name judecn.id is did:stack:v0:1KVzcgurJmTr4Cr44h6raEVtoGhm7ZZxzm-0. You can resolve it to my public key as follows:

>>> import blockstack
>>> blockstack.lib.client.resolve_DID('did:stack:v0:1KVzcgurJmTr4Cr44h6raEVtoGhm7ZZxzm-0', hostport='https://node.blockstack.org:6263')                                                                                                                                                                                                  
{'public_key': '020fadbbcea0ff3b05f03195b41cd991d7a0af8bd38559943aec99cbdaf0b22cc8'} 

#3

So it is only a question about putting the spec together and send a pull request…


#4

We have a draft document about BNS in general here: https://github.com/blockstack/blockstack-core/blob/feature/docs-bns/docs/blockstack_naming_service.md

We have a section on DIDs here: https://github.com/blockstack/blockstack-core/blob/feature/docs-bns/docs/blockstack_naming_service.md#decentralized-identifiers-dids

Is there anything you’d like to see added to it?


#5

We’ve been trying to incorporate use of Blockstack’s DID (via subdomains) in our work, but haven’t been able to find a spec and library that provides the ability to perform the expected functions in the DID lifecycle - such as create with a DID doc, update a DID with a new key, service endpoint, auth method, etc.

Can you point to the spec and library that detail how these operations are performed? Specifically, on the library/resolver front, it’s not clear if there’s an official library that does the DIDs ops and DID Document modifications - if this exists, can you point me to it? In looking through the code, the Universal Resolver appears hard-coded to return a default service URL: https://github.com/decentralized-identity/universal-resolver/blob/master/implementations/java/driver-did-stack/src/main/java/uniresolver/driver/did/stack/DidStackDriver.java#L216


#6

Create a DID doc: Create a JWT that encodes the DID doc by signing it with your secp256k1 private key. You can use the jsontokens package to do the heavy lifting, if you want. You’d store the JWT to the URL that your DID’s associated Blockstack ID resolves to (e.g. dweb2018.id.blockstack points to https://gaia.blockstack.org/hub/1DEgVRD265SBPvfaQeNAVZr8Pmiz1v2Mkf/profile.json). The DID doc contains the public key, and the JWT’s payload is the implementation-specific metadata.

Update a DID with a new key: This is a NAME_TRANSFER transaction (for on-chain names) or a subdomain transfer (for off-chain names). The former can be done with the Blockstack CLI (run blockstack-cli help transfer for details). The latter doesn’t have any library support or live service endpoints yet, but the server-side protocol is in production and if you’re willing to run a subdomain registrar, it’s pretty straight-forward to do (see all these integration tests). Basically, you’d have the client generate the subdomain-transfer TXT record, and your subdomain registrar would include it in the next zone file update it sends out (see the Python method blockstack.lib.subdomains.make_subdomain_txt() for how to create the TXT record, and see the integration tests for how to combine the TXT records into a single new zone file for the registrar’s on-chain name).

Service endpoints: https://node.blockstack.org:6263 is a Blockstack peer network endpoint you can access. https://core.blockstack.org is a RESTful API endpoint you can access. https://registrar.blockstack.org is the subdomain registrar for id.blockstack. See this document for deploying your API endpoints, and this document for deplying a subdomain registrar of your own.

Auth method: This is discussed in our documentation for blockstack.js

You can use blockstack.lib.client to look up a DID doc from a DID, and to convert between your Blockstack ID (on-chain or off-chain) and its DID. The API is self-explanatory:

>>> import blockstack
>>> my_node = 'https://node.blockstack.org:6263'
>>>
>>> # convert Blockstack ID to DID, if necessary
>>> blockstack.lib.client.get_name_DID('dweb2018.id.blockstack', hostport=my_node)
u'did:stack:v0:SZXgXFzApSdNvET2x5MF3Tzh3YxQoSGyWy-0'
>>>
>>> # get DDO for a DID
>>> blockstack.lib.client.resolve_DID('did:stack:v0:SZXgXFzApSdNvET2x5MF3Tzh3YxQoSGyWy-0', hostport=my_node)
{'public_key': '03ecc154902505c4e16c1e59d03d9b6dcbe4c4de166ab296af25be07876d2fc508'}
>>>
>>> # get DID's implementation-specific metadata by converting back to a name and doing a lookup
>>> blockstack.lib.client.get_DID_record('did:stack:v0:SZXgXFzApSdNvET2x5MF3Tzh3YxQoSGyWy-0', hostport=my_node)['name']
u'dweb2018.id.blockstack'
>>>  blockstack.lib.client.resolve_profile('dweb2018.id.blockstack', hostport=my_node)
{'profile': {u'apps': {u'https://app.graphitedocs.com': u'http://localhost:4000/hub/1KwPLXerCovpJ6RTu4YqA8FxSLc2qHXDvE/', u'http://35.231.45.59:1900': u'http://localhost:4000/hub/1FPZy8MNMdgD9nNEnwvt4drg1455c1BQoi', u'http://localhost:1900': u'http://localhost:4000/hub/13KUu2ioNiRUGjtiDjHZA4cyWzKK5NnSsJ'}, u'account': [], u'type': u'@Person'}, 'zonefile': '$ORIGIN dweb2018.id.blockstack\n$TTL 3600\n_http._tcp\tIN\tURI\t10\t1\t"https://gaia.blockstack.org/hub/1DEgVRD265SBPvfaQeNAVZr8Pmiz1v2Mkf/profile.json"\n\n', 'public_key': '03ecc154902505c4e16c1e59d03d9b6dcbe4c4de166ab296af25be07876d2fc508'}

#7

Not sure I am understanding how the answer above supports the DID lifecycle in the way that I would expect. For example:

You talked about adding a key to a DID Document by creating a TXT record for a Zone File, but where is the DID Method spec that defines the procedural steps this entails? Do I just add a TXT where the value is a stringified version of whatever state I want to set the DID Doc to? What is the recovery method for the blockstack DID Method, and where is the process of performing that specified?

In terms of service endpoints, you talked about what appears to be a blockstack-centric endpoint, but I wanted to understand how you specify any type of DID Service Endpoint, as the spec defines here: https://w3c-ccg.github.io/did-spec/#service-endpoints. Is this accomplished via the same type of generic update to the TXT record in which the strigified DID Document resides?


#8

To me it sounds like we need some “middleware service” to translate between Blockstack way of doing things and the DID-spec. Might be a very light-weight, straight-forward service.


#9

@muneeb Which project within blockstack would implement that? Where is a good place to follow how/when this middleware service is built?


#10

@jude represents Blockstack at the DIF meetings and is the right person to check with for updates – thanks!


#11

Documented the Blockstack DID method here: https://github.com/blockstack/blockstack-core/blob/master/docs/blockstack-did-spec.md