---
# System prepended metadata

title: Untitled

---

SDN是一个去中心化的P2P聊天网络，在SDN网络中任意用户之间可以进行P2P聊天。对于一个建立在钱包地址之上的账户体系，需要保证用户在使用不同钱包登陆时能够对应到同一账户。如果每一个钱包地址都对应一个新的账号，那么当用户更换登录钱包时，他将丢失原账户中的所有社交关系。这种账号体系不具备承载一个Web3社交体系的基本能力。我们通过在其中引入DID系统来标识用户,验证消息发送方的真实身份,同时能够支持多一个钱包地址登录到同一个账户。

## DID简介
去中心化身份 (Decentralized Identity，DID）是结合区块链技术的信任发明，是未来在去中心化社会的身份凭证。去中心化身份验证不需要任何中心化的第三方参与，用户的身份标识完全由所有者控制，而不会是被锁定在单一的生态系或是单一实体中。

### DID 的标准<sup>[1]</sup>
W3C的DID规范是被广泛接受的标准，确保身份系统可以跨不同的网络和平台进行交互操作。其基本架构如下图所示：
![](https://i.imgur.com/b4rSmk8.png)
### DID标识（Identifier）
DID 属于统一资源标识符URI的一种，是一个不可变的字符串，用于标识用户的身份。
第一部分总是为`did`, 表明这是一个去中心化标识符。
第二部分是方法，用来表示这个 DID 标识是用哪一套方案（方法）来进行定义和操作的。
第三部分可以是任何字符串，是 DID 方法中特定的标识符，在整个 DID 方法命名空间是唯一的。
以SDN DID为例：`did:sdn:0dB058993Cf429B9bf3b84904e597b098EE60573` 就是一个DID标识。其中sdn是method name，指明了身份所在的域。`0dB058993Cf429B9bf3b84904e597b098EE60573`则是Method-Specific Identifier，表明了这个身份在域中的地址。
### DID文档
DID标识符只是表示一个身份的标识符，不包含身份的信息。而DID文档就是用于描述身份详细信息的文档，一个DID标识符关联到一个DID文档。
DID文档一般包含以下内容：
  1. DID标识符, 标识唯一的一个DID文档
  2. 验证方法集合
  3. 创建时间和更新时间

## SDN DID
### SDN DID建立背景
  Web3现阶段DID处在萌芽阶段，存在多种不同层面的解决方案，没有一个方案可以将其从应用层到底层贯穿，对于SDN来说，一套原生的，满足其所有能力的DID系统是非常必要的。所以，我们基于一下几个目标，对DID系统进行了设计。
  1. 多链支持：支持以太坊及以太坊兼容链
  2. 钱包与DID实现多对多的关系: 一个钱包地址A可以创建一个DID文档，那么A将作为这个DID文档的主钱包地址，然后再将子钱包B、C、D... 加入这个文档中。同时钱包B也可以创建一个文档，那么B将作为主钱包。
  3. 高效的证明机制: 帮助消息接收者快速验证消息发送者的真实身份。

### DID和钱包地址映射关系
一个钱包地址将在SDN网络内映射一个DID。DID设计了一个主钱包和子钱包的概念，只有DID Owner(主钱包)可以设置子钱包，使其能够用于登陆该DID。主钱包和子钱包可以是不同区块链上的地址, 实现了SDN网络内的DID跨链登陆。如下图所示，`Wallet A`创建了文档`DID 1`，那么`Wallet A`将作为主钱包，其可以增加子钱包`Wallet B`到文档中，从而使`Wallet B`也可以使用`DID 1`进行登录。 同时`Wallet B`可以创建文档`DID 2`, 此时`Wallet B`就是`DID 2`的主钱包。当用户使用`Wallet B`登录时，系统会提示用户选择登陆到`DID 1`或`DID 2`。
![](https://i.imgur.com/hZg0N7m.png)


### SDN DID文档结构
```
{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/suites/secp256k1recovery-2020/v2"
  ],
  // The uniqe identifier of this document.
  "id": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573",
  "authentication": [
    "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#controller",
    "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#controller-d51414ee0e"
  ],

  "verificationMethod": [
    {
      // The address of the owner wallet.
      "blockchainAccountId": "0db058993cf429b9bf3b84904e597b098ee60573",
      // The id of this did document.
      "controller": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573",
      // The identifier of this verificationMethod.
      "id": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#controller",
      "type": "EcdsaSecp256k1RecoveryMethod2020"
    },
    {
      "blockchainAccountId": "d51414ee0e7a45ccd7076dc665c49822789779ff",
      "controller": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573",
      "id": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#controller-d51414ee0e",
      "type": "EcdsaSecp256k1RecoveryMethod2020"
    },
    {
      "controller": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573",
      "id": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#key-FHVG9LamZ3",
      // The pubic key to sign messages.
      "publicKeyBase58": "FHVG9LamZ3gXzY9FAssqA2E2LTCdS4RcbkHz6YERPCQG",
      "type": "Ed25519VerificationKey2018"
    }
  ],
  "controllerSignature": "0xee...e1c",
  "keySignature": "0x75b...c1b",
  "controllerOperation": "link",
  "keyOperation": "link_key",
  "controllerUpdated": "2022-11-30T20:45:28Z",
  "keyUpdated": "2022-11-30T20:46:22Z"
}
```
#### 文档ID
  字段`"id": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573"`为DID的identifier。其中`0db058993cf429b9bf3b84904e597b098ee60573`是主钱包的地址，用户使用`did:sdn:0db058993cf429b9bf3b84904e597b098ee60573`作为id可以解析到唯一一个DID文档。用户在创建DID文档时需要使用地址`0db058993cf429b9bf3b84904e597b098ee60573`对应的私钥进行签名。SDN网络验证签名有效才会保存这个文档, 这样就可以防止其它用户伪造这个文档。同时在获取文档之后，可以通过文档中定义的签名验证算法，从controllerSignature中恢复出签名钱包的地址，判断文档是否被修改。
  
#### SDN DID文档中的两类地址
  1. ControllerAddress: 这类地址用于关联用户的的钱包，其`id`中`#`之后的字符串包含`controller`。这些地址有权限修改DID文档(增加Public key), 只有DID Owner才能增加或者删除 ControllerAddress。上述文档包含两个ControllerAddress: `0db058993cf429b9bf3b84904e597b098ee60573`和`d51414ee0e7a45ccd7076dc665c49822789779ff`,它们的id分别为: `did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#controller`，`did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#controller-d51414ee0e`。
  2. Public key: 由ControllerAddress增加的公钥,其`id`中`#`之后的字符串包含`key`。 Public Key用于对用户发送的消息进行验签。 DID的所有ControllerAddress都可以增加或者删除Public key。上述文档包含一个public key，即`FHVG9LamZ3gXzY9FAssqA2E2LTCdS4RcbkHz6YERPCQG`, 其id为`did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#key-FHVG9LamZ3`。
  
#### SDN DID文档中的签名
  1. controllerSignature: 更新文档时对除Public key之外的数据字段的签名, 只有DID owner的才能对这些数据签名，从此签名中恢复出的签名地址需要DID owner一致。示例DID文档中controllerSignature值为对以下内容进行序列化之后的签名。
```
 {
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/suites/secp256k1recovery-2020/v2"
  ],
  "id": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573",
  "authentication": [
    "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#controller",
    "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#controller-d51414ee0e"
  ],

  "verificationMethod": [
    {
      "blockchainAccountId": "0db058993cf429b9bf3b84904e597b098ee60573",
      "controller": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573",
      "id": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#controller",
      "type": "EcdsaSecp256k1RecoveryMethod2020"
    },
    {
      "blockchainAccountId": "d51414ee0e7a45ccd7076dc665c49822789779ff",
      "controller": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573",
      "id": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#controller-d51414ee0e",
      "type": "EcdsaSecp256k1RecoveryMethod2020"
    }
  ],
  "controllerOperation": "link",
  "controllerUpdated": "2022-11-30T20:45:28Z",
}
```
  2. keySignature：更新文档时对除ControllerAddress之外的数据字段的签名, 任意一个Controller都可以进行签名，用于验证文档中新增的Public Key是否由Controller添加。采用`EcdsaSecp256k1RecoveryMethod2020`签名算法。用户从签名中恢复出签名者的地址之后，需要判断这个地址是否在ControllerAddress列表中。示例DID文档中keySignature值为对以下内容进行序列化之后的签名。
```
{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/suites/secp256k1recovery-2020/v2"
  ],
  "id": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573",
  "verificationMethod": [
    {
      "controller": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573",
      "id": "did:sdn:0db058993cf429b9bf3b84904e597b098ee60573#key-FHVG9LamZ3",
      "publicKeyBase58": "FHVG9LamZ3gXzY9FAssqA2E2LTCdS4RcbkHz6YERPCQG",
      "type": "Ed25519VerificationKey2018"
    }
  ],
  "keyOperation": "link_key",
  "keyUpdated": "2022-11-30T20:46:22Z"
}
```


### SDN消息验证
在SDN网络中，客户端会生成一个用于签名消息的`private key`。用户使用主钱包登录或者子钱包登录时，客户端会将其对应的public key加入DID文档中，登录完成会以当前主钱包地址作为用户user id。发送消息时使用其设备上的private key签名。消息接收方接收到消息后，先根据发送者user id从SDN网络的Edge Node中获取DID 文档。判断文档是否被修改。如果未被修改，从文档获取public key，然后验证消息签名是否正确。如果签名合法，就可以判断当前发送者未伪造身份，接收者就可以接受这条消息。
![](https://i.imgur.com/r0k6b7m.png)


### CRUD Operation Definitions
#### 创建(注册)
为了创建一个sdn DID, 用户必须持有一个加密钱包地址,比如Ethereum address: 0dB058993Cf429B9bf3b84904e597b098EE60573。用户需要使用其私钥来签名数据来证明其是这个钱包地址所有者。完成注册之后，SDN会生一个如下所示的DID文档。
```
{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/suites/secp256k1recovery-2020/v2"
  ],
  "id": "did:sdn:0dB058993Cf429B9bf3b84904e597b098EE60573",
  "verificationMethod": [
    {
      "id": "did:sdn:0dB058993Cf429B9bf3b84904e597b098EE60573#controller",
      "type": "EcdsaSecp256k1RecoveryMethod2020",
      "controller": "did:sdn:0dB058993Cf429B9bf3b84904e597b098EE60573",
      "blockchainAccountId": "0dB058993Cf429B9bf3b84904e597b098EE60573"
    }，
     
  ],
  "authentication": [
    "did:sdn:0dB058993Cf429B9bf3b84904e597b098EE60573#controller"
  ]
}
```
用户新创建文档之后,会在DID的verificationMethod数字中新增一个验证方法, blockchainAccountId字段即为owner钱包地址。

#### 增加钱包地址
DID的owner可以在其文档中增加新的ControllerAddress。如下为其DID文档中增加了一个新的ControllerAddress, 其地址为`d51414ee0e7A45cCD7076DC665C49822789779fF`。增加钱包地址操作会在verificationMethod数组中增加一个新的验证方法，blockchainAccountId字段为新controller地址。
```
{
  "id": "did:ethr:0dB058993Cf429B9bf3b84904e597b098EE60573#controller-d51414ee0",
  "type": "EcdsaSecp256k1RecoveryMethod2020",
  "controller": "did:ethr:0dB058993Cf429B9bf3b84904e597b098EE60573",
  "blockchainAccountId": "d51414ee0e7A45cCD7076DC665C49822789779fF"
}
```
此后，`d51414ee0e7A45cCD7076DC665C49822789779fF`同样可以向文档中增加新的public key。
同样,DID的owner也可以从文档中删除其它ControllerAddress,已经被删除的ControllerAddress无法修改文档.

#### 增加公钥
在创建DID之后，ControllerAddress可以在文档中增加public key.
```
{
  "id": "did:sdn:0dB058993Cf429B9bf3b84904e597b098EE60573#key-2ru5PcgeQ",
  "type": "EcdsaSecp256k1RecoveryMethod2020",
  "controller": "did:sdn:0dB058993Cf429B9bf3b84904e597b098EE60573",
  "publicKeyBase58": "2ru5PcgeQzxF7QZYwQgDkG2K13PRqyigVw99zMYg8eML"
}
```
其中的公钥`2ru5PcgeQzxF7QZYwQgDkG2K13PRqyigVw99zMYg8eML` 用于验证后续用户发现消息时，验证签名是否有效，进而验证消息是否由用户`0dB058993Cf429B9bf3b84904e597b098EE60573`发送, 而非其他用户伪造。
#### 根据钱包地址获取文档
在SDN DID中，用户可以将一个钱包地址添加到多个DID文档中，同时也可以将多个钱包地址添加到同一个DID文档中。获取一个钱包地址的DID文档流程为:
   1. 通过钱包地址获取当前address绑定的DID列表， 如果列表为空，则当前地址未关联到任何文档
   2. 选择其中一个`DID`
   3. 使用该`DID`从Edge Node获取文档

### SDN DID优势
#### 支持多钱包登录
相比于其它直接以钱包地址作为DID标识符的实现方式，SDN DID能实设置主钱包和子钱包，用户的多个钱包可以登录到同一个DID，保持用户身份的稳定性。
#### 存储
SDN为了存储信息，建了一个分布式存储系统，其底层使用libp2p进行分发数据和查找数据。一份文档会在去中心化的Edge Node中保存多份副本, 保证在部分节点宕机时，仍然能够找到DID文档，保证DID系统的可靠性。避免了中心化存储造成的单点失效问题。同时用户可以选择将文档保存到公链上。
#### 安全与隐私
在SDN DID文档中，只会存储用户的钱包地址和用于验证签名的公钥，不会保存用户的任何私钥。因此用户使用注册SDN的过程不会有泄漏私钥的风险。同时用户在创建文档和更新时都需要进行签名，用户在获取文档之后也需要对文档签名进行验证。这样就能够防止其它用户伪造身份。同时在DID文档中也不会存储用户的个人信息, 避免隐私泄露的风险。

## 总结
通过在SDN中加入独立的DID系统，使用户可以拥有在钱包之上的另一层独一无二的数字化身份，用户可以使用不同链上的钱包地址绑定并登陆同一个DID，实现SDN网络特有的跨链能力，且使得用户能够根据不同需要创建不同的身份。该DID将会为整个SDN网路提供坚实的基础，在账号管理层面提供无限可能，在个人甚至群体信息拓展层面提供无限可能。

## 引用
[1] https://www.w3.org/TR/did-core/