BTCR DIDs and DDOs

IN PROGRESS

By Kim Hamilton Duffy (Learning Machine), Ryan Grant, and Christopher Allen

This assumes you are familiar with DID terminology at a basic level.

Introduction

BTCR is a DID method that is based on the Bitcoin blockchain. The BTCR DID scheme uses a TX Ref-encoded (described below) transaction on the Bitcoin blockchain. The DID Description is constructed from a combination of the transaction details and an optional "continuation" DID Description, the address of which is stored in the OP_RETURN field. This could be a link to an IPFS address of a DID Description with additional entities.

The BTCR Hackathon readme has more context on BTCR DIDs beyond these basics. Note that at the time of the BTCR Hackathon, we were not yet using the new capabilities-based DID approach, so many details (e.g. control/owner keys) are out of date in the BTCR Hackathon repo.

BTCR Transaction Structure

Abbreviations: - Bi = bitcoin address i - Pi = public key i - Si = signing key i (or private key i)

Creating the initial BTCR DID: - Create key set (B0/P0/S0) - Create key set (B1/P1/S1) - Create Bitcoin transaction as follows: - Output: Change address B1 - Optional output: OP_RETURN <link to DDO continuation> - Signing key is S0, which reveals public key P0 in the transaction - Issue TX0 and wait for confirmation. Get TX Ref encoding of the transaction TXREF(TX0)

At this point we have a DID of the format did:btcr:<TXREF(TX0)>

The initial BTCR DID is shown in the left side of this diagram.

BTCR Transaction Structure

Definitions and details

BTCR DID Scheme

The standard scheme for DIDs is:

did:<method>:<specific-idstring>

In this case, the method is "btcr". In the BTCR DID method, specific-idstring is a TX Ref of confirmed transactions on a Bitcoin chain.

TX Refs

TX Refs are described in BIP 136 "Bech32 Encoded Transaction Position References" (https://github.com/bitcoin/bips/pull/555). Among other advantages, they provide a concise way to refer to the confirmed transaction on a specific chain (testnet or mainnet) as a function of the block height and index.

The important difference is that txid is just a hash of the transaction, which may not yet be confirmed, and does not encode the chain, whereas TX Ref must be confirmed (since it is based on the block height and index).

Looking up a BTCR DID

DID consumers need to be able to construct a DID Description from a DID. In BTCR that works as follows:

Updating a DID Descripton

An entity updates the BTCR DID Description by spending the current transaction output. The BTCR Transaction Structure diagram shows how that is done in this second transaction.

Example from the BTCR Playground

This section demonstrates BTCR DIDs and DID Descriptions using the default example shown in the BTCR Playground.

The playground supports looking up BTCR DID Description for both mainnet and testnet chains. In general, we work with the testnet chain in these examples as we experiment with and develop BTCR.

The playground supports 3 means of entering a transaction: - TX Ref (note that we don't need to enter the chain; described below) - TXID and chain (testnet or mainnet) - TX block height, index, and chain (testnet or mainnet)

To start, click "Convert from TX Ref" on the site with the default TX Ref.

DID Description

The DID Description resulting from DID txtest1-xkyt-fzgq-qq87-xnhn is listed below.

Output

{
    "@context": [
        "https://schema.org/",
        "https://w3id.org/security/v1"
    ],
    "authorization": [
        {
            "capability": "UpdateDidDescription",
            "permittedProofType": [
                {
                    "proofType": "SatoshiBlockchainSignature2017",
                    "authenticationCredential": [
                        {
                            "type": [
                                "EdDsaSAPublicKey",
                                "CryptographicKey"
                            ],
                            "hash-base58check": "mvq9zXGAr76uSoRG5ybEdECuXoPGY42ihh"
                        }
                    ]
                }
            ]
        },
        {
            "capability": "IssueCredential",
            "permittedProofType": [
                [
                    {
                        "type": [
                            "EdDsaSAPublicKey",
                            "CryptographicKey"
                        ],
                        "publicKeyHex": "0280e0b456b9e97eecb8028215664c5b99ffa79628b60798edd9d562c6db1e4f85",
                        "owner": "did:btcr:xkyt-fzgq-qq87-xnhn",
                        "id": "did:btcr:xkyt-fzgq-qq87-xnhn/keys/fundingKey"
                    }
                ]
            ],
            "entity": "did:btcr:xkyt-fzgq-qq87-xnhn"
        },
        {
            "capability": "IssueCredential",
            "entity": "did:btcr:xkyt-fzgq-qq87-xnhn",
            "permittedProofType": [
                [
                    {
                        "id": "did:example:12345678/keys/1",
                        "type": "RsaCryptographicKey",
                        "owner": "did:example:12345678",
                        "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
                    }
                ]
            ]
        }
    ],
    "authenticationCredential": [
        {
            "type": [
                "EdDsaSAPublicKey",
                "CryptographicKey"
            ],
            "curve": "secp256k1",
            "publicKeyHex": "0280e0b456b9e97eecb8028215664c5b99ffa79628b60798edd9d562c6db1e4f85",
            "owner": "did:btcr:xkyt-fzgq-qq87-xnhn",
            "id": "did:btcr:xkyt-fzgq-qq87-xnhn/keys/fundingKey"
        },
        {
            "id": "did:example:12345678/keys/1",
            "type": "RsaCryptographicKey",
            "owner": "did:example:12345678",
            "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
        }
    ],
    "signature": {
        "type": "SatoshiBlockchainSignature2017",
        "id": "did:btcr:xkyt-fzgq-qq87-xnhn",
        "chain": "testnet"
    }
}

Constructing a BTCR DID Description

The DID Description for DID txtest1-xkyt-fzgq-qq87-xnhn was determined as follows.

From the TX Ref, we look up details about the Bitcoin transaction. To see how to do this, refer to the transaction details for the TXID this resolves to, 67c0ee676221d9e0e08b98a55a8bf8add9cba854f13dda393e38ffa1b982b833.

This transaction has an OP_RETURN data output. For Blockcypher this is in the data_string field: https://raw.githubusercontent.com/kimdhamilton/did/master/ddo.jsonld](https://raw.githubusercontent.com/kimdhamilton/did/master/ddo.jsonld]). That means this DID Description will include additional authorizations and authenticationCredentials listed in the target of that URL.

Parse the partial DID Description

Important: the steps below assume that the partial DID Description is stored in an immutable store as opposed to github. If this were stored in github, the partial DID Description should be signed.

This partial DID Description grants the following abilities: 1. Two entities may issue credentials. - One is an entity (currently) without an id, but described by its authentication method (SatoshiBlockchainSignature2017) and its hex-encoded public key. Note this is the same as the key used to sign the transaction. - One is an entity defined in a separate DID Description, with a proofType of RsaSignature2017 2. Two entities may authenticate (as a TBD DID). These entities are similar to above.


{
  "@context": "https://w3id.org/btcr/v1",
  "authorization": [
    {
        // gives the entity with TBD DID the ability to issue credentials where the "issuer" field is TBD DID. TODO: This could be a default ability.
      "capability": "IssueCredential",
      "permittedProofType": [
        {
      // Would we need a different type for off-chain signatures?
          "proofType": "SatoshiBlockchainSignature2017",
          "authenticationCredential": [
            {
              "type": [
                "EdDsaSAPublicKey",
                "CryptographicKey"
              ],
              "publicKeyHex": "0280e0b456b9e97eecb8028215664c5b99ffa79628b60798edd9d562c6db1e4f85"
            }
          ]
        }
      ]
    },
    {
      // enables an entity to issue credentials where the "issuer" field is TBD DID as long as this specific RSA key is used
      "capability": "IssueCredential",
      "entity": "did:example:12345678",
      "permittedProofType": [
        {
          "proofType": "RsaSignature2017",
          "authenticationCredential": [
            {
              "id": "did:example:12345678/keys/1",
              "type": "RsaCryptographicKey",
              "owner": "did:example:12345678",
              "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
            }
          ]
        }
      ]
    }
  ],
  "authenticationCredential": [
    {
      "type": [
        "EdDsaSAPublicKey",
        "CryptographicKey"
      ],
      "curve": "secp256k1",
      "publicKeyHex": "0280e0b456b9e97eecb8028215664c5b99ffa79628b60798edd9d562c6db1e4f85"
    },
    {
      "id": "did:example:12345678/keys/1",
      "type": "RsaCryptographicKey",
      "owner": "did:example:12345678",
      "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
    }
  ]
}

About missing ids, entities, and owners

Again we're assuming the partial DID Description is stored in an immutable store. Because the content is immutable, the transaction signature signs the content hash as well. If not using content-addressable store, then another LD signature scheme would be used.

Because changing the content changes the address, and because the DID depends on the Bitcoin transaction reference, we have a bootstrapping problem where we cannot yet use the DID in the DID Description fragment shown above. We avoid this problem by omitting id, entity, and owner where the DID is not yet known.

It's valid for a Linked Data object to omit an id; this is called a "blank node" and is the way you indicate you don't know the identifier yet, but you know its attributes.

Merging the partial DID Description and transaction details

With the partial DID Description and transaction details, we can form the complete DID Description.

Comments