InfraBlockchain[1] is a blockchain solution
without cryptocurrency for the public sectors and enterprises.
Infra DID method is designed for the underlying InfraBlockchain network to be use as DID
The Infra DID method specification conforms to the requirements specified in
the DID specification[2], currently published by the
W3C Credentials Community Group.
The namestring that shall identify this DID method is: infra
A DID that uses this method MUST begin with the following prefix: did:infra
. Per the DID specification, this string
MUST be in lowercase. The remainder of the DID, after the prefix, is specified below.
The Infra DID method specific identifiers are categorized as two DID types,
public-key-based DID (PubKey DID
) and blockchain-account-based DID (Account DID
).
infra-did = "did:infra:" + infra-did-specific-idstring
infra-did-specific-idstring = network-id + ":" + public-key / blockchain-account
network-id = chain-name / chain-id-prefix(4bytes)
public-key = "PUB_K1_{base58-encoded-secp256k1-public-key-plus-checksum}" / "PUB_R1_{base58-encoded-secp256r1-public-key-plus-checksum"
blockchain-account = EOSIO-blockchain-account-name
- Infra DID examples
did | type | description |
---|---|---|
did:infra:test01:PUB_K1_7nxEa8qHEiy34d...h8n5ikapZZrzjx | PubKey DID | a did whose info can be checked from test01 blockchain network, network-specific id is base58-encoded secp256k1 public key |
did:infra:sentinel:PUB_R1_4vSVS9mQbiKu...bw8Mti7mc2F5 | PubKey DID | a did on sentinel network, id is secp256r1(p256) public-key |
did:infra:kornet:hu23nfowuehx | Account DID | a did representing blockchain account hu23nfowuehx on kornet blockchain network |
network-id
is a identifier representing a specific instance of InfraBlockchain network. Each InfraBlockchain network used as DID registry
must have standard Infra DID registry smart contracts deployed at publicly known addresses on the blockchain network.
Open source Infra DID registry contract codes are available on below repository.
Infra DID registry contracts [3] : /~https://github.com/InfraBlockchain/infra-did-registry
- Known InfraBlockchain
network-id
list
Name | network-id | DID Registry contract address |
---|---|---|
Yosemite | yos |
infradidregi |
Sentinel | sentinel |
infradidregi |
vapp testnet | vapptest1 |
fmapkumrotfc |
osong mainnet | 01 |
infradidregi |
.. |
Any public/private key pair generated by anyone off-chain is regarded as a valid DID on InfraBlockchain network.
Currently supported elliptic curves for public key types are secp256k1
and secp256r1
(p256).
The DID owner needs to securely save and manage the private key to verify the ownership
and to control the status and data of the 'PubKey DID' on a blockchain network.
PubKey DID
is designed to be used as light-weight DID method minimizing blockchain transactions.
A PubKey DID
with a public key encoded on the "did string" itself is a valid DID (not-revoked, active)
even if the public key of the DID is not recorded on a specific blockchain, i.e. no blockchain transaction
for basic DID creation (only key-pair creation on a device). The DID controlling public key can be retrieved
from the DID string itself if it can be checked that no special data for a DID is recorded on blockchain.
Blockchain transactions occur on DID registry smart contract only when the status of a DID is modified.
(e.g. DID is revoked, registered service endpoint for a DID, controller key is changed, and so on),
so the valuable blockchain data storage can be effectively saved by not writing public keys of simple (public-key only) DIDs.
PubKey DID
format
Infra DID uses EOSIO-compatible public key string format encoding public key and checksum data.
key type | public key string format |
---|---|
secp256k1 | "PUB_K1_" + BASE58( {33bytes_public_key_binary} + first_4_bytes( RIPEMD160("PUB_K1_"+{33bytes_public_key_binary}) ) ) |
secp256r1 (P-256) | "PUB_R1_" + BASE58( {33bytes_public_key_binary} + first_4_bytes( RIPEMD160("PUB_R1_"+{33bytes_public_key_binary}) ) ) |
InfraBlockchain (EOSIO-based) provides account system which has built-in key management, permission system, multi-sig features. EOSIO Accounts and Permissions
A blockchain account created on blockchain can be used a DID, account's active
key registered on blockchain is used as controller key for the DID.
DID related information(e.g. service endpoints) can be retrieved from the DID registry contract.
PubKey-DID
DID Doc example
{
"@context": "https://www.w3.org/ns/did/v1",
"id": "did:infra:sentinel:PUB_K1_7nxEa8qHEiy34dpuYH4yE2zRWaAoeT1gsdTnh8n5ikapZZrzjx",
"verificationMethod": [
{
"id": "did:infra:sentinel:PUB_K1_7nxEa8qHEiy34dpuYH4yE2zRWaAoeT1gsdTnh8n5ikapZZrzjx#controller",
"type": "EcdsaSecp256k1VerificationKey2019",
"controller": "did:infra:sentinel:PUB_K1_7nxEa8qHEiy34dpuYH4yE2zRWaAoeT1gsdTnh8n5ikapZZrzjx",
"publicKeyHex": "037e84547231650e816a32eb5b79028e71ac7459bbcd8e81e6697ac9022e64a407"
}
],
"authentication": [
"did:infra:sentinel:PUB_K1_7nxEa8qHEiy34dpuYH4yE2zRWaAoeT1gsdTnh8n5ikapZZrzjx#controller"
],
"service": [
{
"id": "did:infra:sentinel:PUB_K1_7nxEa8qHEiy34dpuYH4yE2zRWaAoeT1gsdTnh8n5ikapZZrzjx#service-1",
"type": "MessagingService",
"serviceEndpoint": "https://infradid.com/pk/3/mysvcr4"
}
]
}
Account-DID
DID Doc example
{
"@context": "https://www.w3.org/ns/did/v1",
"id": "did:infra:sentinel:bcaccount234",
"verificationMethod": [
{
"id": "did:infra:sentinel:bcaccount234#controller",
"type": "EcdsaSecp256k1VerificationKey2019",
"controller": "did:infra:sentinel:bcaccount234",
"publicKeyHex": "02eb633bb3dea58ca00330a2be557050e8889e69b8913c6f10966304c4aff91628"
}
],
"authentication": [
"did:infra:sentinel:bcaccount234#controller"
]
}
Infra DID is registered and managed on a dedicated DID Registry smart contract on a specific InfraBlockchain network. The owner of a Infra DID can manage Infra DID document by executing blockchain transactions on the DID Registry contract. Anyone can read (resolve) the DID documents by accessing public InfraBlockchain network nodes.
For creating PubKey-DID
consisting of DID and one controller key created on a client side, no blockchain transaction is needed.
Blockchain transactions are required only when additional information for a DID is required to set,
e.g. setting revocation status, service endpoints, additional keys.
All basic PubKey-DID
s with one controller key encoded on the DID itself are regarded as valid/active DIDs
before a DID is explicitly revoked on blockchain.
import InfraDID from 'infra-did-js';
const networkId = 'sentinel';
const pubKeyDID = InfraDID.createPubKeyDIDsecp256k1(networkId);
console.log({pubKeyDID});
/*
pubKeyDID: {
did: 'did:infra:sentinel:PUB_K1_7gidxemiW1PnCNZSGvrZWAoHLyMHYT7qjYyWofS7YLgrk7idMJ',
publicKey: 'PUB_K1_7gidxemiW1PnCNZSGvrZWAoHLyMHYT7qjYyWofS7YLgrk7idMJ',
privateKey: 'PVT_K1_2LL3aSW9KJVXVzBaKbPvwo3zMuXzBYRdC53tycA7AQfDzkFF1W'
}
*/
A blockchain account on an InfraBlockchain network can be used as a DID.
To create a Account-DID
, one can create a blockchain account on an InfraBlockchain network.
cleos create account accountsvc23 bcaccount234 PUB_K1_6kyc4xQizQmewF7J1wmmKkNoozD77nzCSRVaiKf2AA7g3SLc7J
// newaccount chain transaction action
{
account: 'infra',
name: 'newaccount',
authorization: [{
actor: 'accountsvc23',
permission: 'active',
}],
data: {
creator: 'accountsvc23',
name: 'bcaccount234',
owner: {
threshold: 1,
keys: [{
key: 'PUB_K1_6kyc4xQizQmewF7J1wmmKkNoozD77nzCSRVaiKf2AA7g3SLc7J',
weight: 1
}],
accounts: [],
waits: []
},
active: {
threshold: 1,
keys: [{
key: 'PUB_K1_6kyc4xQizQmewF7J1wmmKkNoozD77nzCSRVaiKf2AA7g3SLc7J',
weight: 1
}],
accounts: [],
waits: []
}
}
}
- extract network id from infra-did-specific-idstring and select a corresponding blockchain rpc api node address
- check if id string starts with "PUB_" and extract public key binary data from DID string
- retrieve public-key DID attributes from pubkeydid multi-index table of DID registry smart contract on the selected InfraBlockchain network
- if nonce value of public-key DID attribute is 65535(max 16bit integer value) then the DID is in revoked / detactivated status.
- extract service endpoint list from DID attributes map(attr field of pubkeydid table)
- retrieve owner key of the DID if present from pkdidowner multi-index table of DID registry contract, use the retrieved owner key as controller key of DID, if not present, the public key in DID string itself is the controller key.
- extract network id from infra-did-specific-idstring and select a corresponding blockchain rpc api node address
- use id string as blockchain account name
- retrieve blockchain account data from blockchain rpc api node, and use active key of the account as DID controller key
- retrieve account DID attributes from accdidattr multi-index table of DID registry smart contract on the selected InfraBlockchain network
- extract service endpoint list from DID attributes map(attr field of accdidattr table)
DIF-javascript-universal-resolver compatible Infra DID resolver is implemented on infra-did-resolver[4]
import { DIDResolutionResult, Resolver } from 'did-resolver'
import { getResolver } from "infra-did-resolver"
const infraDidResolver = getResolver(config)
const didResolver = new Resolver({ ...infraDidResolver })
const pubkeyDID: DIDResolutionResult = await didResolver.resolve("did:infra:sentinel:PUB_K1_7nxEa8qHEiy34dpuYH4yE2zRWaAoeT1gsdTnh8n5ikapZZrzjx")
const accountDID: DIDResolutionResult = await didResolver.resolve("did:infra:sentinel:bcaccountaaa")
The DID Document may be updated by invoking the relevant smart contract actions of DID Registry contract.
-
update Pub-Key DID attributes (currently service endpoint update is supported)
- contract action : pksetattr(public_key& pk, string& key, string& value, signature& sig, name& ram_payer)
-
set or update Pub-Key DID owner key
- contract action : pkchowner(public_key& pk, public_key& new_owner_pk, signature& sig, name& ram_payer)
- update Account DID attributes (currently service endpoint update is supported)
- contract action : accsetattr(name& account, string& key, string& value)
- revoke Pub-Key DID
- contract action : pkdidrevoke(public_key& pk, signature& sig, name& ram_payer)
- nonce value of public-key DID attribute is set as 65535(max 16bit integer value)
Every Infra DID blockchain transaction on Infra DID Registry contract to update a DID document is required to create a signature
for user action data concatenated with blockchain id
and monotonically increasing nonce
value.
A DID-document-modifying transaction executed on a DID registry contract of a specific blockchain network cannot be replayed on any known Infra DID Registry of Infra DID compatible blockchain networks by malicious attackers.
The DID owner should generate cryptographic proof (signature) signed by a private key paired with the public key in the blockchain by which non-repudiation is satisfied.
Infra DID method is implemented as smart contract on a InfraBlockchain(EOSIO-based) network. Any party can replicate blockchain data and send transactions for Infra DID management, hence if one blockchain api node is attacked, any other valid blockchain node can provide Infra DID services.
No personally identifiable information (PII) is included in a DID document retrieved by Infra DID resolver. DID Document details published on the blockchain ledger that are necessary only for authentication by other parties. Private keys are stored in a secure storage on local user devices owned and controlled by clients. Users can control any number of DIDs and may choose to store related data (e.g. verifiable credentials) locally or create encrypted online backups enabling self-sovereign identities.
If DID Controllers want to mitigate the risk of correlation, they should use unique DIDs with unique private keys for every interaction.
Infra DID provides Pub-Key DID
method to create any number of DIDs without blockchain transaction cost for DIDs having only one public key.
The code at infra-did-resolver[4] and infra-did-js[5] is intended to present a reference implementation of this DID method.
[1] https://infrablockchain.com
[2] https://www.w3.org/TR/did-core/
[3] /~https://github.com/InfraBlockchain/infra-did-registry