# SBT隐私模块

基于Semantic SBT和Lit Protocol实现隐私数据分享，用户可以给满足指定条件的地址分享自己的隐私数据。

使用Lit Protocol对数据进行加密与解密，arweave存储密文、加密后的密钥以及分享条件，Semantic SBT用于存储arweave的哈希以及定义分享条件。

分享的条件可以设置成：

* EOA地址
* 拥有来自特定集合NFT的用户
* 拥有来自特定SBT的用户
* 拥有一定 ERC20 代币余额的用户

## 隐私数据分享流程

### 加密

将待分享的隐私数据，通过[Lit Protocol](https://developer.litprotocol.com/sdk/explanation/encryption/#encrypting)进行加密，并将加密结果（accessCondition、encryptedSymmetricKey、encryptedObject）封装成encryptMetaDada上传至存储层(arweave等)，得到encryptMetaDada的地址。

* encryptMetaDada格式如下：

```json
{
 "encryptionBy": "lit-protocol",
 "accessCondition": [
   {
     "contractAddress": "${contract address of Semantic SBT}",
     "standardContractType": "ERC721",
     "chain": "polygon",
     "method": "isViewerOf",
     "parameters": [
       ":userAddress",
       "${tokenId}"
     ],
     "returnValueTest": {
       "comparator": "=",
       "value": true
     }
   }
 ],
 "encryptedSymmetricKey": "a hex string that LIT will use to decrypt your content as long as you satisfy the conditions",
 // encrypted content
 "encryptedObject": "AhgXUao1QU2iQg34UsCw0-ptkoy_fhifEoqEs3_Zj1s="
}

```

### Mint隐私SBT

基于Semantic SBT规范实现一个PrivacySemanticSBT合约，mint一个带隐私数据的SBT。其中该SBT的RDF中的object为arweave/ipfs的地址。

* SemanticSBTPrivacy合约方法调用流程

```javascript
const tokenId = await PrivacySemanticSBT.prepareTokenId();
//Mint SBT
PrivacySemanticSBT.mintWithPrivacy(tokenId, arweaveHash);
//添加viewer
await PrivacySemanticSBT.addViewer(address1, tokenId);
```

* 完整的RDF示例如下：

```
:Soul_0x0000000000000000000000000000000000000000 p:telgramAccount "[Privacy]ar://djbZ5l5Ij5zBEgFFnVlDDqa4z5ACtS_A9uWPmAVwRe"
```

* encryptedObject的组成
  * 固定前缀： \[Privacy]
  * web3存储系统,e.g: ar:// 或 ipfs\://
  * web3存储的哈希
* encryptedObject示例：

```
[Privacy]ar://djbZ5l5Ij5zBEgFFnVlDDqa4z5ACtS_A9uWPmAVwRe
```

### 解密

解密方从SBT的object中获取encryptMetaDada。调用[LitProtocol的解密方法](https://developer.litprotocol.com/sdk/explanation/encryption/#decrypting)，即可解密得到明文的object。

## Access Control Conditions Types

允许设置不同类型的访问条件，来控制用户访问隐私数据。

### User holds an NFT in a collection

如果解密者拥有指定NFT集合的token，则有权限解密隐私数据。

```
[
  {
    "contractAddress": "0x3110c39b428221012934A7F617913b095BC1078C",
    "standardContractType": "ERC721",
    "chain": "ethereum",
    "method": "balanceOf",
    "parameters": [ ":userAddress" ],
    "returnValueTest": { "comparator": ">", "value": "0" }
  }
]
```

#### User holds an SBT in a collection

如果解密者拥有指定SBT集合的token，则有权限解密隐私数据。

```
[
  {
    "contractAddress": "0x588368698213bdf05aa722936d7657df8f3abe27",
    "standardContractType": "ERC721",
    "chain": "polygon",
    "method": "balanceOf",
    "parameters": [ ":userAddress" ],
    "returnValueTest": { "comparator": ">", "value": "0" }
  }
]
```

### User owns a specific wallet address

如果解密者拥有指定的钱包地址，则有权限解密隐私数据。

```
[
  {
    "contractAddress": "",
    "standardContractType": "",
    "chain": "ethereum",
    "method": "",
    "parameters": [
      ":userAddress",
    ],
    "returnValueTest": {
      "comparator": "=",
      "value": "0x50e2dac5e78B5905CB09495547452cEE64426db2"
    }
  }
]
```

### User holds at least XX ERC20 Token

如果解密者拥有指定数量的ERC20token，则有权限解密隐私数据。

```
[
  {
    "contractAddress": "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2",
    "standardContractType": "ERC20",
    "chain": "ethereum",
    "method": "balanceOf",
    "parameters": [
      ":userAddress"
    ],
    "returnValueTest": {
      "comparator": ">",
      "value": "0"
    }
  }
]
```

### Using boolean operations (AND + OR) for any of the above

可以使用AND或OR任意组合上述条件。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://relationlabs.gitbook.io/semantic-sbt/semanticsbt-zh/untitled/sbt-yin-si-mo-kuai.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
