The Veres One Blockchain is a permissionless public ledger designed specifically for the creation and management of decentralized identifiers (DIDs). Veres One DIDs are self-administered identifiers that may be used by people, organizations, and digital devices to establish an identifier that is under their control. Veres One DIDs are useful in ecosystems where one needs to issue, store, and use Verifiable Credentials. This specification defines how a developer may create and manage DIDs in the Veres One Blockchain.
Comments regarding this document are welcome. Please file issues directly on GitHub, or send them to public-credentials@w3.org (subscribe, archives).
Work on this specification has been funded in part by the United States Department of Homeland Security's Science and Technology Directorate under contract HSHQDC-17-C-00019. The content of this specification does not necessarily reflect the position or the policy of the U.S. Government and no official endorsement should be inferred.
Work on this specification has also been supported by the Rebooting the Web of Trust group facilitated by Christopher Allen, Shannon Appelcline, Kiara Robles, Kaliya Young, Brian Weller, Betty Dhamers, and Joe Andrieu.
Work on this specification has also been supported by the Internet Identity Workshop co-founded by Phil Windley, Kaliya Young, and Doc Searls and energized by true believers in the user-centric identity movement.
The Veres One Project envisions a world where people and organizations control their identifiers and their identity data. The Veres One Blockchain is a fit-for-purpose blockchain optimized for identity on the Web. The network ecosystem is designed to be self-sufficient through the use of an innovative operational and funding model. The operational model ensures openness, prevents attacks against the network, and financially rewards individuals and organizations that choose to run software to ensure the security of the network. Human dignity demands that every individual be able to participate equally in our increasingly digital society. That means everyone deserves the ability create and administer unique, globally resolvable identifiers. For that reason, the network is global and open to the public; anyone may participate.
To date, every identifier you use online does not belong to you; it belongs to someone else.
The Internet was not designed with interoperable identity systems in mind. This inevitably forced websites to create their own solutions, which are not interoperable.
When you sign up to a website, you typically create a username and a password. The website asks you for this information so that it can start to associate data with you. The more benevolent use of this data is to customize an experience suited to your needs. This identifier and data, however, are locked away on the site; they are not portable. Even the global identifiers that websites use, such as your email address, are not owned by you. The email address "you@bigcorp.com" isn’t owned by you, it’s owned by BigCorp. You do not have control over your identifier nor your data.
Since this data is not portable, you must rebuild your identity information -- your identifiers and data -- from scratch on many different websites. Duplicating that information often means sharing more than intended, allowing websites to learn things and infer things about you that you didn’t expect. It also means that each website accumulates toxic data about you, inviting behavior like spam, financial fraud, data siloing, data warehousing, and identity theft. Initiatives like the European Union’s General Data Protection Regulation (GDPR) only increase the pressure to address these problems.
In addition to risks from the information we explicitly share with websites, there is also a vast amount of identity information already out there, with few mechanisms for managing it. This outside information is often combined with the information we share to create surprisingly detailed profiles, used for everything from ad targeting to site customization to custom pricing (not always for lower prices). The result is a strong economic incentive for large data warehousing companies to store and sell your information, often without your consent.
The Veres One Blockchain's purpose is to enable all people and organizations in the world to:
Achieving this vision will enable a Web where:
This vision is shared among a large community of people working within global organizations such as the Internet Identity Workshop, World Wide Web Consortium, Internet Engineering Task Force, United Nations ID2020, Decentralized Identity Foundation, and the Rebooting the Web of Trust project. This DID Method specification is a realization of this vision.
The Veres One Blockchain is a fit-for-purpose blockchain built specifically for Decentralized Identifiers. This specialization enables the blockchain to be faster, more cost effective, and more privacy enhancing compared to existing blockchains that are being repurposed for identity management. The Veres One Blockchain was designed and built with the following goals in mind:
Based on the goals stated in the previous section, benchmarking has been performed on the reference Veres One implementation that is able to achieve the following performance characteristics.
Benchmarking is a poor substitute for measurements taken over long periods of time in hostile environments such as the public Internet. Attacks, routing inefficiencies, packet drops, misconfigured software, and annoying physical limitations such as the speed of light all contribute to degraded performance in real world settings. This section should be taken with a large grain of salt until we have dependable real world data.
The configuration for the benchmarks used 1 database with 7 electors configured. The database was an AWS AWS i3.large instance consisting of 2 vCPUs, 15.25GB RAM and Local NVME Storage. Each node was an AWS c5.large instance with 2 vCPUs and 4GB RAM.
The Veres One Blockchain uses a leaderless, non-blocking, byzantine fault tolerant consensus algorithm called Continuity. There are 3f+1 nodes in the system where f is the number of byzantine failures the network can tolerate. Since the algorithm is non-blocking and nodes can progress at their own pace, the limiting factor is how quickly events can be gossiped around the network. This approach results in very high throughputs. Transactions are limited by two factors: 1) the fastest 2/3rds of elector's database write speeds and 2) the time it takes to distribute 12f + 1 merge events to every elector in the network, the rate of which is an exponential function.
Metric | Capability | Description |
---|---|---|
Throughput | 209/sec, 18M/day, 6.6B/year | The throughput is a function of how quickly 12f+1 events can be transmitted to each elector. Limiting factors include database write speed, communication speed, and digital signature verification speed. |
Consensus Latency | ~15-30 seconds | The latency is a function of how many electors there are in the system. How many electors there are in the system is a function of the risk tolerance of the network. |
This document is organized as follows:
There are two conformance classes described in this specification. The first are clients that use the HTTP API to perform operations. The second are Veres One Nodes, which expose the HTTP API to clients. Clients and Veres One Nodes MUST implement all mandatory features as listed by this specification and SHOULD implement optional features.
The Veres One Data model is a graph-based data model. The syntax used for the data model is [[!JSON-LD]], which is based on 18+ years of Linked Data standardization work at the W3C. The ledger portions of the data model build upon the [[!WEB-LEDGER]] specification. The digital signatures and proofs data models build upon the, [[!LD-PROOFS]] and [[!LD-SIGNATURES]] specifications. The Decentralized Identifiers portion of the data model builds upon the [[!DID]] specification.
The core data model is fairly simple and consists of a Ledger. The Ledger contains Blocks. The Blocks contain Operations. The Operations contain instructions that modify the state of the ledger. For example, there are Operations to create a DID Document and update a DID Document.
The data model also consists of a state machine that is modified as Operations execute. The state machine can be queried using Veres One DIDs, which will return the current DID Document associated with the Veres One DID.
Veres One DIDs have the following format:
The ABNF below needs to be tightened up. For example, it should enforce the UUID format if UUID-based Veres One DIDs are used.
v1-did = "did:v1:" v1-did-type ": " v1-identifier [ ";" did-service ] [ "/" did-path ] [ "?" did-query ] [ "#" did-fragment ] v1-did-type = ( "nym" / "uuid" ) v1-identifier = %x41-5A / %x61-7A / %x5F / %2D
There are two primary classes of DID-based identifiers in Veres One. The first
type of identifier is called a cryptonym-based identifier. This identifier
is a SHA-256 hash of a public key. Cryptonym-based identifiers are not required
to be registered on the ledger and may be used as unregistered pseudonymous
pairwise identifiers. These identifiers may also be registered on the
ledger and MUST contain a authentication
key with a public key
fingerprint equal to the value of the cryptonym-based identifier.
did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ
The second type of identifier on Veres One is a UUID-based identifier and may be used by entities that want to store metadata on the ledger. These sorts of identifiers are often used, but not limited to, storing and refering to Capabilities and Revocation lists.
did:v1:uuid:804c6ac3-ce3b-46ce-b134-17175d5bee74
Authentication is the process the ledger uses to determine if an entity is associated with a DID.
{
"@context": "https://w3id.org/veres-one/v1",
"id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
"authentication": [... array of acceptable authentication suites ...]
}
A detailed example of a valid set of authentication credentials follows:
{ "@context": "https://w3id.org/veres-one/v1", "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ", "authentication": [{ "type": "Ed25519SignatureAuthentication2018", "publicKey": { "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#authn-key-1", "type": "Ed25519VerificationKey2018", "owner": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ", "publicKeyBase58": "HURvcFiZbmtaQQMhkVVoq1JpxxRe8UrBS5wBQMJhXkfM", } }], ...
The Veres One Ledger uses Linked Data Object Capabilities to authorize operations to be performed on DID Documents.
Granting a capability is equivalent to giving someone your car keys. Your car doesn't know who the person is with the key, it just knows that when the key is turned in the ignition, the car should start. The benefit of object capabilities is that, unlike a car key, you can set arbitrary restrictions on the usage of a capability. For example, setting an expiration time for the capability, or a geofenced zone in which it can be used.
The Veres One data model supports two types of capability suites, one for granting capabilities and the other for invoking capabilities.
{ "@context": "https://w3id.org/veres-one/v1", "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ", "grantCapability": [... array of capability grant suites ...] "invokeCapability": [... array of capability invocation suites ...] }
A detailed example of a valid set of authorization capability descriptions follows:
{ "@context": "https://w3id.org/veres-one/v1", "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ", ... "grantCapability": [{ "type": "Ed25519SignatureCapabilityAuthorization2018", "publicKey": { "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#ocap-grant-key-1", "type": "Ed25519VerificationKey2018", "owner": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ", "publicKeyBase58": "HURvcFiZbmtaQQMhkVVoq1JpxxRe8UrBS5wBQMJhXkfM" } }], "invokeCapability": [{ "type": "Ed25519SignatureCapabilityAuthorization2018", "publicKey": { "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#ocap-invoke-key-1", "type": "Ed25519VerificationKey2018", "owner": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ", "publicKeyBase58": "Gu5yfYsbYvmSeSsAbBBNafy9i6G3o5kiX5PxUGPg1iFJ" } }] }
Every conforming Veres One Blockchain Node MUST expose at least the following HTTP endpoints:
Service | Example URL | Description |
---|---|---|
veresOneOperationsService | POST /ledger-agents/123/operations | Create or update a DID Document. |
veresOneReadService | GET /dids/{did} | Gets an existing DID Document. |
A website may provide HTTP API endpoint discovery by embedding JSON-LD in their
top-most HTML web page (e.g. at https://example.com/
):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Example Website</title> <link rel="stylesheet" href="style.css"> <script src="script.js"></script> <script type="application/ld+json"> { "@context": "https://w3id.org/veres-one/v1", "id": "https://example.com/", "name": "Example Website", "veresOneOperationsService": "https://example.com/ledger-agents/123/operations", "veresOneReadService": "https://example.com/veres-one/dids/" } </script> </head> <body> <!-- page content --> </body> </html>
Service descriptions may also be requested via content negotiation.
In the following example a JSON-compatible service description is provided
(e.g. curl -H "Accept: application/json" https://example.com/
):
{ "@context": "https://w3id.org/veres-one/v1", "id": "https://example.com/", "name": "Example Website", "veresOneOperationsService": "https://example.com/ledger-agents/123/operations", "veresOneReadService": "https://example.com/veres-one/dids/" }
A DID is created by performing an HTTP POST of a signed operation
to the veresOneOperationsService
. The following HTTP status codes
are defined for this service:
HTTP Status | Description |
---|---|
202 |
DID creation request was accepted. The HTTP Location header will
contain the URL for the newly created ledger operation. The operation is not
guaranteed to succeed. You can check to see if the operation succeeded by
requesting the operation, which will eventually refer to an event and a block
if it was successful.
|
400 | Operation failed. |
409 | Create operation failed because a duplicate DID exists. |
An example exchange of DID creation request is shown below:
POST /ledger-agents/123/operations HTTP/1.1 Host: example.com Content-Type: application/ld+json Content-Length: 1062 Accept: application/ld+json, application/json, text/plain, */* Accept-Encoding: gzip, deflate { "@context": "https://w3id.org/veres-one/v1", "type": "CreateWebLedgerRecord", "record": { "@context": "https://w3id.org/veres-one/v1", "id": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ", "authentication": [{ "type": "Ed25519SignatureAuthentication2018", "publicKey": { "id": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#authn-key-1", "type": "Ed25519SigningKey2018", "owner": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ", "publicKeyBase58": "Gu5yfYsbYvmSeSsAbBBNafy9i6G3o5kiX5PxUGPg1iFJ" } }], "grantCapability": [{ "type": "Ed25519SignatureCapabilityAuthorization2018", "publicKey": { "id": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#ocap-grant-key-1", "type": "Ed25519SigningKey2018", "owner": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ", "publicKeyBase58": "HURvcFiZbmtaQQMhkVVoq1JpxxRe8UrBS5wBQMJhXkfM" } }], "invokeCapability": [{ "type": "Ed25519SignatureCapabilityAuthorization2018", "publicKey": { "id": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#ocap-invoke-key-1", "type": "Ed25519SigningKey2018", "owner": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ", "publicKeyBase58": "FPa3QX9pPk1Qw75CAnhF2Qv2HwuWke4yxbqxzQbU5PLU" } }] }, "proof": [{ "type" : "Ed25519Signature2018", "created" : "2018-02-24T22:23:44Z", "creator" : "did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv#ocap-invoke-key-1", "capability" : "did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv", "capabilityAction" : "RegisterDid", "jws" : "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19.. _h3x8FRH6GXbSBGgtqtGRQc_HabNgYSv4M124oFG-1dzi4nJzJyXTXcNt8vb7mJV3fj Izyt0jhO8hsmMJWf8Cw", "proofPurpose" : "invokeCapability" }, { "type" : "EquihashProof2018", "created" : "2018-02-24T22:23:45Z", "equihashParameterK" : 3, "equihashParameterN" : 64, "nonce" : "AgAAAA==", "proofValue" : "AAAVYwABwK8AAME7AAGOjAAAVkIAATc9AAFDLQABrc8=" }] }
If the creation of the DID was successful, an HTTP 201 status code is expected in return:
HTTP/1.1 202 Accepted Location: https://ledger.example.com/ledger-agents/123/operations/ni%3A%2F%2F%2Fsha-256%3BXk0ruJlbQTpFOyzbsl_KL8vKQiahMj7t9h-v70BMwAQ Cache-Control: no-cache, no-store, must-revalidate Pragma: no-cache Expires: 0 Date: Fri, 14 Oct 2016 18:35:33 GMT Connection: keep-alive Transfer-Encoding: chunked
A DID is updated by performing an HTTP POST of a signed DID Document
to the veresOneUpdateService
. The following HTTP status codes
are defined for this service:
HTTP Status | Description |
---|---|
200 | DID update request was successful. |
400 | DID update request failed. |
An example exchange for a DID update request is shown below:
POST /ledger-agents/123/operations HTTP/1.1 Host: example.com Content-Type: application/ld+json Content-Length: 1062 Accept: application/ld+json, application/json, text/plain, */* Accept-Encoding: gzip, deflate { "@context": "https://w3id.org/veres-one/v1", "type": "UpdateWebLedgerRecord", "patch": [{ "op": "add", "path": "/authentication", "value": { "type": "Ed25519SignatureAuthentication2018", "publicKey": { "id": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#authn-key-2", "type": "Ed25519SigningKey2018", "owner": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ", "publicKeyBase58": "BpJk2oxtkm99ubKqhtLF7fB2fCM1bETgpJLFg8QEuQK2" } } }, { "op": "remove", "path": "/services/3", }], "proof": [{ "type" : "Ed25519Signature2018", "created" : "2018-02-24T22:23:42Z", "creator" : "did:v1:test:nym:91LAKSKtybvFjUdkTitBVXEF1kz9s24TCARuLfWBKGmw#ocap-invoke-key-1", "capability" : "did:v1:test:nym:91LAKSKtybvFjUdkTitBVXEF1kz9s24TCARuLfWBKGmw", "capabilityAction" : "RegisterDid", "jws" : "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..Ldx 5HbvS7-SvKTPGbRwBhc5xub95th__2-pphFRZUHFNd4Qs6R3u9j5elQkHciuLhvKB6a0 fURMa4puZNWLLDg", "proofPurpose" : "invokeCapability" }, { "type": "EquihashProof2017", "equihashParameterN": 64, "equihashParameterK": 3, "nonce": "AQAAAA==", "proofValue": "AAAOgAA0jcAEAAXbA1EsQMgAAGfF7TwABAfNiAA78QA=" }] }
If the update request for the DID Document was successful, an HTTP 202 status code is expected in return:
HTTP/1.1 202 Accepted Location: https://ledger.example.com/ledger-agents/123/operations/ni%3A%2F%2F%2Fsha-256%TpFOyzbsl_KL83BXk0ruJlbQ9h-v70BMwAQvKQiahMj7t Cache-Control: no-cache, no-store, must-revalidate Pragma: no-cache Expires: 0 Date: Fri, 14 Oct 2016 18:35:33 GMT Connection: keep-alive Transfer-Encoding: chunked
The core consensus algorithm for Veres One utilizes the Ed25519 cryptographic suite. This algorithm is a well vetted and widely deployed cryptographic system that represents the state of the art in modern cryptographic systems. The algorithm depends on the hardness of factoring large numbers, which is expected to become easier given operational quantum computers. These computers are not expected to be feasible in the next decade, but might eventually become feasible.
If new cryptographic primitives are needed, the Veres One consensus algorithm is upgradable in order to provide cryptographic agility. If the current cryptographic system breaks, a new one can be deployed and the consensus algorithm is designed to smoothly upgrade to the new cryptographic system well in advance of the failure of the current cryptographic system.
The consensus mechanism used by the Veres One blockchain is designed to make censoring individuals or organizations incredibly difficult. The consensus algorithm operates on a directed acyclic graph that resembles the Git version control system. Adding new blocks to the blockchain consists of merging various event streams, which are DAGs themselves, into the existing DAG. When an individual wants to perform an operation on the blockchain, they submit that operation to the network. If an attacker wanted to censor that operation, they would have to censor everyone that saw the operation happen on the network. This would lead to censoring not only the individual, but everyone that talked to the individual. While this might be possible to do on small, tightly controlled networks, it is extremely difficult to do on large active networks.
Individual censorship is easily detected by the individual, as operations gossiped to the network are not included in the next block. This sort of censorship has to happen at every node in the network (which is highly unlikely).
If an individual is concerned about censorship, they are urged to gossip with as many nodes in the network as possible. This ensures that any attacker node that desires to censor will be easily detected and the rest of the non-attacking nodes will get the operation into the network.
Decentralized Identifiers are global and often long-lived and are thus susceptible to being tracked across multiple interactions. Implementers are urged to be wary of using long lived identifiers where tracking protection is a system requirement. If strong anti-correlation properties and/or strong tracking-protection are required, pairwise identifiers such as the did:key method or bearer tokens are a better design choice.
Veres One is designed to be GDPR compliant. As such, it is very strict with regard to what data can be written to the blockchain and what data is required to exist off-ledger. As a general rule, any field that could possibly encode any personally identifiable information is not allowed. It is still possible to tie this information to a DID by using an external service, pointed to by a service description in the DID Document, that supports the GDPR Right to be Forgotten mandate. This approach is more strict than other blockchains due to privacy failures on other blockchains to keep Personally Identifiable Information offchain. While this approach is more strict, the functionality of appending information to a DID Document in a GDPR compliant manner is still achieved.
There are a number of accessibility considerations implementers should be aware of when processing data described in this specification. As with any web standards or protocols implementation, ignoring accessibility issues makes this information unusable to a large subset of the population. It is important to follow accessibility guidelines and standards, such as [[WCAG21]], to ensure all people, regardless of ability, can make use of this data. This is especially important when establishing systems utilizing cryptography, which have historically created problems for assistive technologies. While DID Documents stored on Veres One are not allowed to contain human readable information due to GDPR concerns, it is possible to publish extended information to the DID Document through service endpoints and/or other publishing mechanisms. This section relates to extended information that can be associated with a base Veres One DID Document.
This section details the general accessibility considerations to take into account when utilizing this data model.
When utilizing this data model to create DID Documents, it is suggested that data model designers use a data first approach. For example, given the choice of using data or a graphical image to depict a some information, designers should express every element of the image in a machine-readable way instead of relying on a viewer's interpretation of the image to convey this information. Using a data first approach is preferred because it provides the foundational elements of building different interfaces for people with varying abilities.
There are a number of internationalization considerations implementers should be aware of when publishing data described in this specification. As with any web standards or protocols implementation, ignoring internationalization makes it difficult for data to be produced and consumed across a disparate set of languages and societies, which would limit the applicability of the specification and significantly diminish its value as a standard. While DID Documents stored on Veres One are not allowed to contain human readable information due to GDPR concerns, it is possible to publish extended information to the DID Document through service endpoints and/or other publishing mechanisms. This section relates to extended information that can be associated with a base Veres One DID Document.
This section outlines general internationalization considerations to take into account when utilizing this data model.
When expressing human-readable text content in the data model, it is important for presentation, accessibility, and further processing to specify the language of the text, as follows:
@language
feature, as described in [[!JSON-LD]] 1.1,
Section 4.2.3: String Internationalization.
rdf:HTML
string literal type, as described in [[!JSON-LD]] 1.0,
Section 4.2.1: Typed Values.
This mechanism enables developers to use the internationalization features
present in HTML to express language information. For example, consider the
following key-value pair:
"nameHtml": "<span lang="jp">和美</span>"
If the JSON-LD Context expressed that any value associated with the
nameHtml
property as being of type rdf:HTML
, then
software agents rendering the property can deterministically identify the
language in use.
When expressing human-readable text content in the data model, it is important to be able to explicitly encode the text direction. JSON and its derived formats use the UTF-8 encoding of [Unicode] for serializing and transmitting text. This enables text direction to be directly determined in simple cases, but the mechanism is insufficient for general use.
[[!JSON-LD]] supports the expression of text layout information using the
rdf:HTML
string literal type, as described in [[!JSON-LD]] 1.0,
Section 4.2.1: Typed Values.
This mechanism enables developers to use the internationalization features
present in HTML to express language information. For example, consider the
following key-value pair:
"nameHtml": "<span dir="rtl" lang="ar">HTML و CSS: تصميم و إنشاء مواقع الويب</span>"
If the JSON-LD Context states that any value associated with the
nameHtml
property is of type rdf:HTML
, then software
agents have sufficient information to deterministically identify the text
direction of the language.
In some situations it is common to use Ruby characters to ensure text information is clear and as useful as possible. [[!JSON-LD]] support for HTML data allows text to be encoded with ruby, supporting these cases.
The W3C Internationalisation document [string-meta] gives more information about the need to be able to provide reliable metadata about text to support internationalization.
The following is a complete example of a typical Veres One DID Document:
{ "@context":"https://w3id.org/veres-one/v1", "id":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv", "authentication":[{ "type":"Ed25519SignatureAuthentication2018", "publicKey":[ { "id":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv#authn-key-1", "type":"Ed25519VerificationKey2018", "owner":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv", "publicKeyBase58":"5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv" } ] }], "grantCapability":[{ "type":"Ed25519SignatureCapabilityAuthorization2018", "publicKey":[ { "id":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv#ocap-grant-key-1", "type":"Ed25519VerificationKey2018", "owner":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv", "publicKeyBase58":"6kQvEZxCiMMVaV4ywczC1LbXGiG3Gv27hVvs4gd7CGLH" } ] }], "invokeCapability":[{ "type":"Ed25519SignatureCapabilityAuthorization2018", "publicKey":[ { "id":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv#ocap-invoke-key-1", "type":"Ed25519VerificationKey2018", "owner":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv", "publicKeyBase58":"AEht5v3xudqJs9qo5jC88fAsAGhPr6zLYJ3yfuKsAY7K" } ] }] }
The Veres One ledger was launched in 2015, predated this specification, and as a result has a number of legacy objects that developers should be aware of. The typical format for these objects are shown below:
{ "@context": "https://w3id.org/identity/v1", "id": "did:8743453f-e45e-4ac6-b85f-4513ba4c1460", "idp": "did:d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1", "accessControl": { "writePermission": [{ "id": "did:8743453f-e45e-4ac6-b85f-4513ba4c1460/keys/1", "type": "CryptographicKey" }, { "id": "did:d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1", "type": "Identity" }] }, "publicKey": [{ "id": "did:8743453f-e45e-4ac6-b85f-4513ba4c1460/keys/1", "type": "CryptographicKey", "owner": "did:8743453f-e45e-4ac6-b85f-4513ba4c1460", "publicKeyPem": "-----BEGIN PUBLIC KEY-----\r\nMIIBIjA...DAQAB\r\n-----END PUBLIC KEY-----\r\n", "@context": "https://w3id.org/identity/v1" }], "signature": { "type": "LinkedDataSignature2015", "created": "2017-07-25T17:29:49Z", "creator": "did:8743453f-e45e-4ac6-b85f-4513ba4c1460/keys/1", "signatureValue": "LJoxpV...daOLHbA==" } }