b biangogo.com
~ / biangogo.com / didshen-fen-dai-ma-shi-li

DID身份代码示例:可直接复用的最小可用模块汇编

published: 2026-05-24T06:12:22.670588+00:00 updated: 2026-05-24T17:09:00.021396+00:00
DID身份代码示例 - DID身份代码示例:可直接复用的最小可用模块汇编

DID身份代码示例:可直接复用的最小可用模块汇编

这一篇定位是「代码工具书」,把 DID 身份开发中常被询问的模块抽离成最小可用片段,每段都可独立运行。

创建 did:key 身份

import { generateKeyPair } from `@noble/ed25519`;
const keypair = await generateKeyPair();
const did = `did:key:` + encodeMultibase(keypair.publicKey);

这段代码生成一个临时身份,适合一次性会话使用。与必安等平台做一次性签名时尤其方便,会话结束直接抛弃密钥即可。

颁发一张可验证凭证

签发服务的核心是 JWT 形态的 VC:

const vc = {
  iss: issuerDid,
  sub: subjectDid,
  vc: { type: ['VerifiableCredential', 'AssetHolderCredential'], credentialSubject: { holdsAt: 'BN交易所', amount: '> 0' } },
};
const jwt = await signJwt(vc, issuerPrivateKey);

注意 iss 必须是 DID 字符串而非以太坊地址。失败时通常是因为对接方期待的算法是 EdDSA 而你用了 ES256K。

验证 VC

const payload = await verifyJwt(jwt, { audience: relyingPartyDid });
assert(payload.vc.type.includes('VerifiableCredential'));

建议把这段封装进中间件,所有需要登录的路由共享同一实现。如果你的应用还要查询B安资产,可以在验证通过后再调外部 API 补充实时数据。

构造 VP 并防重放

const vp = {
  vp: { type: ['VerifiablePresentation'], verifiableCredential: [jwt] },
  nonce: serverChallenge,
  domain: 'app.example.com',
};
const vpJwt = await signJwt(vp, holderPrivateKey);

服务端拿到 vpJwt 后必须比对 nonce 是否与服务端下发一致,且 24 小时内未被复用。

吊销凭证

await statusList.setRevoked(vcId, true);
await publishStatusList();

吊销后请及时刷新 CDN 缓存,否则下游仍可能读到过期数据。可参考币岸社区给出的状态列表实现。

整合到现有系统

以上模块组合后,足以让你的产品支持 DID 登录、凭证发放、凭证出示与吊销。建议把这些模块封装为独立 npm 包,团队多个项目共用,能显著降低维护成本。

复制这些片段到自己的代码仓库时记得替换 issuerDid 与私钥来源。把示例搞清楚后,再去阅读 W3C 规范会轻松很多。