DID测试套件
介绍
名称
- DID Test Suite
网址
https://github.com/w3c/did-test-suite
功能
- 用于验证DID实现是否符合W3C DID Core规范的一系列测试
- 反映各DID方法(如
did:orb
、did:key
、did:web
等)的实现对DID Core规范的遵从程度 - 确保不同DID方法、解析器和URL解引用器之间的互操作性
技术架构
- 编程语言:HTML+JavaScript
- 框架: Jest
维护团队
W3C的DID工作组(DID Working Group)
项目价值
- W3C制定DID标准非常权威
- 合作方众多,包括3Box Labs、ART GROUP LIMITED ARTRACX.COM、cheqd、ConsenSys Mesh、Knox Networks、Spruce Systems、Transmute 、EBSI等
项目组织结构
使用方式
- 拉取代码
git clone git@github.com:w3c/did-test-suite.git
- 安装依赖(请注意nodejs版本,16+)
npm i
- 将要测试的json文件放置到对应目录下,并添加到对应的default.js文件中
./packages/did-core-test-server/suites/implementations/
- DID输入文件名称添加到相应测试套件的default.js文件中
- DID方法应当将其自身添加至
did-identifier
、did-core-properties
、did-production
和did-consumption
测试套件 - DID解析器实现只需添加至
did-resolution
测试套件 - DID url解析器实现只需添加至
did-url-dereferencers
测试套件
- 切换到工作目录
cd ./packages/did-core-test-server
- 测试并生成报告
npm run test-and-generate-report
报告生成在./docs
文件夹下,格式为html
其他测试方式:
a. 通过http启动
npm run start
![[Pasted image 20240417091111.png]]
b. 只测试不生成报告
npm run test
DID方法示例
参考文档: did-example-didwg.json
详细描述了 “Example DID Method” 的基本信息、支持的 DID 参数示例,以及 DID did:example:123
在不同内容类型(JSON 和 JSON-LD)下的表示及其相关元数据。
{
### DID 方法基本信息
"didMethod": "did:example", 定义了所使用的 DID 方法前缀。
"implementation": "Example DID Method", 描述了具体的 DID 方法实现名称
"implementer": "DID Working Group", 指出负责实现和维护此 DID 方法的组织或团队
"supportedContentTypes": [ 列出了该 DID 方法支持的文档表示格式:
"application/did+json", 以 JSON 格式表示 DID 文档。
"application/did+ld+json" 以 JSON+ld 格式表示 DID 文档,包含链接数据上下文。
],
### DID 参数示例
"dids": ["did:example:123"], 提供了一个使用该 DID 方法的实际 DID 示例列表
"didParameters": { 展示了与 DID 关联的可选查询参数的示例
"hl": "did:example:123?hl=zQmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e", 高亮(Highlight)参数
"service": "did:example:123?service=agent&relativeRef=%2Fpath%2Fto%2Fresource", 服务查询参数,指定了服务类型(`agent`)和相对引用路径。
"relativeRef": "did:example:123?service=agent&relativeRef=%2Fpath%2Fto%2Fresource",相对引用参数,与上述服务查询参数相同,但作为独立条目列出。
"versionId": "did:example:123?versionId=0.1.0", 版本标识符参数,提供了一个版本号
"versionTime": "did:example:123?versionTime=2020-09-26T20:14:02Z" 版本时间戳参数,给出了一个具体的时间点
},
### DID `did:example:123` 的详细信息
"did:example:123": {
#### DID Document Data Model (通用属性)
"didDocumentDataModel": {
"properties": {
"id": "did:example:123", DID 文档的唯一标识符。
"verificationMethod": [ 包含两个公钥对象,每个对象代表一种可用于验证签名的密钥
{
"id": "did:example:123#key-0", key-0:使用 Ed25519 曲线的 JsonWebKey2020 类型密钥
"type": "JsonWebKey2020",
"controller": "did:example:123",
"publicKeyJwk": {
"kty": "OKP",
"crv": "Ed25519",
"x": "VDXDwuGKVq91zxU6q7__jLDUq8_C5cuxECgd-1feFTE"
}
},
{
"id": "did:example:123#key-1", key-1:使用 X25519 曲线的 JsonWebKey2020 类型密钥
"type": "JsonWebKey2020",
"controller": "did:example:123",
"publicKeyJwk": {
"kty": "OKP",
"crv": "X25519",
"x": "3kY9jl1by7pLzgJktUH-e9H6fihdVUb00-sTzkfmIl8"
}
}
],
"authentication": ["#key-0"], 指定 `#key-0` 为身份认证所使用的密钥。
"assertionMethod": ["#key-0"], 同样指定 `#key-0` 为断言方法所使用的密钥
"capabilityInvocation": ["#key-0"], 指定 `#key-0` 为能力调用所使用的密钥
"capabilityDelegation": ["#key-0"], 指定 `#key-0` 为能力委托所使用的密钥
"keyAgreement": ["#key-1"], 指定 `#key-1` 为密钥协商所使用的密钥
"bespokeDatetime": "2020-09-26T20:14:02Z", 一个定制的日期时间字符串
"bespokeDouble": 1.2, 一个定制的双精度浮点数
"bespokeInteger": 5, 定制的整数
"bespokeBoolean": true, 定制的布尔值
"bespokeNull": null 定制的空值
}
},
#### application/did+json 表示
"application/did+json": {
"didDocumentDataModel": {
}
},
"representation": "{\"id\":\"did:example:123\",\"verificationMethod\":[{\"id\":\"did:example:123#key-0\",\"type\":\"JsonWebKey2020\",\"controller\":\"did:example:123\",\"publicKeyJwk\":{\"kty\":\"OKP\",\"crv\":\"Ed25519\",\"x\":\"VDXDwuGKVq91zxU6q7__jLDUq8_C5cuxECgd-1feFTE\"}},{\"id\":\"did:example:123#key-1\",\"type\":\"JsonWebKey2020\",\"controller\":\"did:example:123\",\"publicKeyJwk\":{\"kty\":\"OKP\",\"crv\":\"X25519\",\"x\":\"3kY9jl1by7pLzgJktUH-e9H6fihdVUb00-sTzkfmIl8\"}}],\"authentication\":[\"#key-0\"],\"assertionMethod\":[\"#key-0\"],\"capabilityInvocation\":[\"#key-0\"],\"capabilityDelegation\":[\"#key-0\"],\"keyAgreement\":[\"#key-1\"],\"bespokeDatetime\":\"2020-09-26T20:14:02Z\",\"bespokeDouble\":1.2,\"bespokeInteger\":5,\"bespokeBoolean\":true,\"bespokeNull\":null}",
提供了以纯 JSON 格式表示的 DID 文档字符串,与 DID Document Data Model 中的通用属性一致。
"didDocumentMetadata": { 描述了 DID 文档的元数据
"canonicalId": "did:example:one-two-three", 与 DID 文档 ID 相同
"equivalentId": "did:example:one-two-three", 与 DID 文档 ID 相同,
"created": "2020-09-26T20:14:02.000Z", 创建的时间戳
"updated": "2020-09-27T20:14:02.000Z", 更新的时间戳
"nextUpdate": "2020-09-28T20:14:02.000Z", 下次更新的时间戳
"versionId": "0.1.0", 版本标识号
"nextVersionId": "0.2.0" 下一版本标识号
},
"didResolutionMetadata": {
"contentType": "application/did+json" 描述了 DID 解析过程中的元数据,仅包含 **contentType** 字段,其值为
}
},
#### application/did+ld+json 表示
"application/did+ld+json": {
"didDocumentDataModel": {
"representationSpecificEntries": {
"@context": ["https://www.w3.org/ns/did/v1"]
}
},
"representation": "{\"@context\":[\"https://www.w3.org/ns/did/v1\"],\"id\":\"did:example:123\",\"verificationMethod\":[{\"id\":\"did:example:123#key-0\",\"type\":\"JsonWebKey2020\",\"controller\":\"did:example:123\",\"publicKeyJwk\":{\"kty\":\"OKP\",\"crv\":\"Ed25519\",\"x\":\"VDXDwuGKVq91zxU6q7__jLDUq8_C5cuxECgd-1feFTE\"}},{\"id\":\"did:example:123#key-1\",\"type\":\"JsonWebKey2020\",\"controller\":\"did:example:123\",\"publicKeyJwk\":{\"kty\":\"OKP\",\"crv\":\"X25519\",\"x\":\"3kY9jl1by7pLzgJktUH-e9H6fihdVUb00-sTzkfmIl8\"}}],\"authentication\":[\"#key-0\"],\"assertionMethod\":[\"#key-0\"],\"capabilityInvocation\":[\"#key-0\"],\"capabilityDelegation\":[\"#key-0\"],\"keyAgreement\":[\"#key-1\"],\"bespokeDatetime\":\"2020-09-26T20:14:02Z\",\"bespokeDouble\":1.2,\"bespokeInteger\":5,\"bespokeBoolean\":true,\"bespokeNull\":null}",
提供了以 JSON-LD 格式表示的 DID 文档字符串,包含了 `"@context"` 属性,其值为 `"https://www.w3.org/ns/did/v1"`,确保文档符合 W3C DID 规范的语义。
"didDocumentMetadata": {},
"didResolutionMetadata": {
"contentType": "application/did+ld+json"
}
}
}
}
DID解析器示例
参考文档: resolver-example-didwg.json
详细描述了 “Example Resolver” 解析器的基本信息、预期结果分类,以及在不同条件下解析 DID 的七个执行案例及其输入、输出细节。这些案例涵盖了成功解析、DID 格式错误、DID 不存在、DID 已撤销等不同场景,以及对 JSON、JSON-LD 和 CBOR 等不同内容类型的支持
{
"implementation": "Example Resolver", 指定解析器的名称。
"implementer": "DID Working Group", 明确解析器由 DID Working Group 开发和维护
"didMethod": "did:example", 指出该解析器适用于以 `did:example` 为前缀的 DID
"expectedOutcomes": { 定义了解析过程中可能出现的几种典型结果类别,并关联了执行案例的索引
"defaultOutcome": [ 0, 4, 5, 6 ], 对应成功解析且无特殊状态的案例(索引为 0、4、5、6)
"invalidDidErrorOutcome": [ 1 ], 对应解析时因 DID 格式不正确导致的错误案例(索引为 1)
"notFoundErrorOutcome": [ 2 ], 对应解析时因 DID 不存在导致的错误案例(索引为 2)
"representationNotSupportedErrorOutcome": [ ], 未关联任何案例,可能表示此解析器目前不处理任何特定表示不支持的情况
"deactivatedOutcome": [ 3 ] 对应解析到已撤销/停用的 DID 的案例(索引为 3)
},
"executions": [ 包含多个解析器执行案例
{
"function": "resolve", 调用的解析器函数,resolve为 解析 DID 并返回 DID 文档
"input": {
"did": "did:example:111", 待解析的 DID
"resolutionOptions": { 解析选项,可能包含接受的内容类型(`accept`)
}
},
"output": { 函数调用的预期输出
"didResolutionMetadata": { 解析过程的元数据,可能包含错误信息(`error`)或内容类型(`contentType`)
},
"didDocument": { 成功解析时返回的 DID 文档,包含 `id`、`verificationMethod` 和 `service` 等字段;若解析失败,则为 `null`
"id": "did:example:111",
"verificationMethod": [],
"service": []
},
"didDocumentMetadata": { 与 DID 文档相关的元数据,如 `canonicalId`(规范化的 DID)、`equivalentId`(等价的 DID 列表)或 `deactivated`(是否已撤销/停用)。
"canonicalId": "did:example:oneoneone",
"equivalentId": ["did:example:one1one", "did:example:1one1"]
}
}
},
{
"function": "resolve",
"input": {
"did": "did:example_222",
"resolutionOptions": {
}
},
"output": {
"didResolutionMetadata": {
"error": "invalidDid"
},
"didDocument": null,
"didDocumentMetadata": {
}
}
},
{
"function": "resolve",
"input": {
"did": "did:example:333",
"resolutionOptions": {
}
},
"output": {
"didResolutionMetadata": {
"error": "notFound"
},
"didDocument": null,
"didDocumentMetadata": {
}
}
},
{
"function": "resolve",
"input": {
"did": "did:example:444",
"resolutionOptions": {
}
},
"output": {
"didResolutionMetadata": {
},
"didDocument": {
"id": "did:example:444",
"verificationMethod": [],
"service": []
},
"didDocumentMetadata": {
"deactivated": true
}
}
},
{
"function": "resolveRepresentation", 解析 DID 并返回特定内容类型的 DID 文档流
"input": {
"did": "did:example:555",
"resolutionOptions": {
"accept": "application/did+json" 接受内容类型: `"application/did+json"`
}
},
"output": {
"didResolutionMetadata": {
"contentType": "application/did+json"
},
"didDocumentStream": "{\"id\":\"did:example:555\",\"verificationMethod\":[],\"service\":[]}",
"didDocumentMetadata": {
}
}
},
{
"function": "resolveRepresentation",
"input": {
"did": "did:example:666",
"resolutionOptions": {
"accept": "application/did+ld+json" 接受内容类型: `"application/did+cbor"`
}
},
"output": {
"didResolutionMetadata": {
"contentType": "application/did+ld+json"
},
"didDocumentStream": "{\"@context\":\"https://www.w3.org/ns/did/v1\",\"id\":\"did:example:666\",\"verificationMethod\":[],\"service\":[]}", 返回一个 CBOR 编码的 DID 文档流
"didDocumentMetadata": {
}
}
},
{
"function": "resolveRepresentation",
"input": {
"did": "did:example:777",
"resolutionOptions": {
"accept": "application/did+cbor"
}
},
"output": {
"didResolutionMetadata": {
"contentType": "application/did+cbor"
},
"didDocumentStream": "62a36469646f6469653a6178706d656c313a3332767272656669636974616f694d6e74656f68806473677265697665630080",
"didDocumentMetadata": {
}
}
}
]
}
DID URL-解引用器示例
参考文档: dereferencer-example-didwg.json
详细描述了 “Example Dereferencer” 解析器的基本信息、预期结果分类,以及在不同条件下解析 DID URL 的四个执行案例及其输入、输出细节。这些案例涵盖了成功解析 DID 文档和其内部资源、DID URL 格式错误以及资源未找到等不同场景,所有案例都要求解析结果以 JSON 格式返回。
{
"implementation": "Example Dereferencer",
"implementer": "DID Working Group",
"didMethod": "did:example", 指出该解析器适用于以 `did:example` 为前缀的 DID URL
"expectedOutcomes": { 定义了解析过程中可能出现的几种典型结果类别,并关联了执行案例的索引
"defaultOutcome": [ 0, 1 ], 对应成功解析且无特殊状态的案例(索引为 0、1)。
"invalidDidUrlErrorOutcome": [ 2 ], 对应解析时因 DID URL 格式不正确导致的错误案例(索引为 2)。
"notFoundErrorOutcome": [ 3 ] 对应解析时因请求的资源不存在导致的错误案例(索引为 3)
},
"executions": [
{
"function": "dereference",
"input": {
"didUrl": "did:example:222", 待解析的 DID URL
"dereferenceOptions": {
"accept": "application/did+json" 解析选项,包含接受的内容类型(`accept`)
}
},
"output": {
"dereferencingMetadata": { 解析过程的元数据,可能包含错误信息(`error`)或内容类型(`contentType`)。
"contentType": "application/did+json"
},
"contentStream": "{\"id\": \"did:example:222\",\"verificationMethod\": [{\"id\": \"did:example:222#key-1\",\"controller\": \"did:example:222\",\"publicKeyBase58\": \"F6NxfeuPJ5NhmDM6QT2TeSFxcnnkQBgtv6yfQziS5NPM\"}],\"service\": []}",
返回一个完整的 DID 文档内容,包含 `id`、一个 `verificationMethod`(公钥信息)和空的 `service` 列表
"contentMetadata": {
}
}
},
{
"function": "dereference",
"input": {
"didUrl": "did:example:222#key-1",
"dereferenceOptions": {
"accept": "application/did+json"
}
},
"output": {
"dereferencingMetadata": {
"contentType": "application/did+json"
},
"contentStream": "{\"id\": \"did:example:222#key-1\",\"controller\": \"did:example:222\",\"publicKeyBase58\": \"F6NxfeuPJ5NhmDM6QT2TeSFxcnnkQBgtv6yfQziS5NPM\"}",
"contentMetadata": {
}
}
},
{
"function": "dereference",
"input": {
"didUrl": "did:example_333",
"dereferenceOptions": {
"accept": "application/did+json"
}
},
"output": {
"dereferencingMetadata": {
"error": "invalidDidUrl"
},
"contentStream": "",
"contentMetadata": {
}
}
},
{
"function": "dereference",
"input": {
"didUrl": "did:example:444",
"dereferenceOptions": {
"accept": "application/did+ld+json"
}
},
"output": {
"dereferencingMetadata": {
"error": "notFound"
},
"contentStream": "",
"contentMetadata": {
}
}
}
]
}
测试内容解析
文档中列举的“✅”符号表示特定测试已成功通过,即某个DID方法在特定测试点上符合DID Core规范要求。例如:
-
Metadata Structure 测试表明,对于给定的DID(如
did:orb:bafkreiazah4qrybzyapmrmk2dhldz24...
),其文档中的元数据结构正确采用了application/did+ld+json
格式,且属性值均为字符串,符合规范。 -
DID Document Metadata 测试关注的是DID文档元数据中的
canonicalId
属性。结果显示,预期的规范化标识符(canonicalId)在解析过程中得到了正确的生成或验证,与规范中的预期结果一致。 -
did-core-properties 测试集中于DID文档中核心属性的结构和内容。例如,针对
did:key:z6LSn9Ah7d33uokFv2pg66BMN5UY72Wt...
,其所有属性值均为字符串,并且整个元数据结构符合规范要求。 -
MATTR Internal Libraries 示例展示了MATTR公司内部库对
did:sov
和did:web
两种方法的支持情况。测试结果显示,这些库在处理特定DID时能够正确生成或验证相关的密钥、类型、链接等信息。
did-core-properties测试
此类测试主要关注DID文档中定义的核心属性是否符合DID Core规范。这包括:
-
DID Subject(主体):验证DID文档中的
id
属性(即DID本身)是否正确设置,格式是否符合规范定义的ABNF(Augmented Backus-Naur Form)规则。 -
Controller(控制器):检查DID文档中是否存在可选的
controller
属性,并确认其值是否为有效的DID或DID URL,代表了对DID文档具有控制权的实体。 -
Verification Methods(验证方法):确保文档中列出的验证方法(如公钥、加密密钥等)结构正确,包括方法类型、公钥材料、关联的密钥用途标签等,并验证它们是否遵循规范的约束,如不包含保留字符等。
-
Service Endpoints(服务端点):验证服务端点对象的完整性,包括类型、服务URL、关联的DID URL等属性是否正确设定,且类型为字符串。
-
Metadata(元数据):检查DID文档的元数据(如创建时间、更新时间、版本标识符等)是否符合规范要求,格式正确且含义清晰。
did-identifier测试
这类测试专注于验证DID标识符本身的结构和语义。包括:
-
Syntax(语法):确保DID字符串遵循规范定义的通用语法,如由
did:
前缀、方法名、方法特定的标识符段(可能包含路径、查询参数等)组成,各部分之间使用冒号分隔。 -
Parameters(参数):检查DID中可能存在的版本标识符(versionId)、版本时间戳(versionTime)等参数是否符合规范定义的格式和使用规则。
-
Relative DID URLs(相对DID URL):验证相对DID URL在解析和使用过程中的正确性,包括其相对于基DID的构建方式、解析后的绝对DID URL是否符合预期。
did-production测试
这类测试评估DID生成工具或库是否能正确地依据DID方法规范创建合法的DID文档。包括:
-
Document Creation(文档创建):验证生成的DID文档是否包含所有必需的属性,并且属性值符合各自的格式要求。
-
Method-Specific Rules(方法特定规则):确保在创建DID文档时,针对特定DID方法(如
did:tz
、did:orb
等)的特殊要求得到满足,如特定的密钥格式、链上注册过程等。 -
Consistency(一致性):检查生成的DID文档在多次独立生成过程中保持一致,除非有明确的更新意图。
did-resolution测试
此类测试关注DID解析器能否正确解析DID文档,包括:
-
Resolution Process(解析过程):验证解析器能否通过DID找到对应的DID文档,解析过程符合规范定义的步骤。
-
Content Retrieval(内容检索):检查解析器是否能从指定位置(如分布式账本、IPFS等)正确获取DID文档内容。
-
Content Format(内容格式):验证获取的DID文档是否以规定的JSON-LD格式呈现,且内容结构符合DID Core规范。
did-url-dereferencing测试
这些测试围绕DID URL的解引用操作进行,包括:
-
DID URL Syntax(DID URL语法):确认DID URL的构造符合规范定义,包括DID部分、路径、查询参数和片段等。
-
Resource Retrieval(资源检索):测试解析器能否根据DID URL定位并返回相应的资源(如验证材料、服务端点指向的资源等)。
-
Metadata Handling(元数据处理):验证在解引用过程中,解析器能否正确处理并返回与DID URL相关的元数据,如HTTP状态码、Content-Type等。
参考资料
- W3C Decentralized Identifier Specification v1.0 DID主要规范文档
- Home page of the Decentralized Identifier Working Group 负责开发和维护DID规范的工作组官网
- Specs and documentation for all DID-related /.well-known resources 关于DID上下文中使用的标准化资源的详情
- W3C Decentralized Characteristics Rubric v1.0 用于评估DID系统去中心化特性的量表
- Decentralized Identifier Use Cases v1.0 展示DIDs在各种情境中应用的一系列用例
- W3C DID Test Suite and Implementation Report DID测试套件以及已通过测试、表明符合DID规范的实现记录
其他
- 可以向仓库提交pull request将did实现加入到测试套件(可提升web3影响力)
- DID解析器 Universal Resolver (uniresolver.io)