Developer Hub
Relation ProtocolRelation ONE APIRelation Graph API
English
English
  • Overview
  • QUICK START
    • Deploy a Semantic SBT contract leveraging Relation Protocol
    • Deploying query services using Graph Indexer
  • KEY CONCEPTS
    • RDF
    • Semantic SBTs
    • Social Graph
  • Architecture
  • Schema Standard
    • Overview
    • How schemas limit smart contracts
    • Store schema
    • List of schemas
  • Contract Open Standard
    • Overview
    • Identity
      • Name Service
    • Relationship
      • Follow
      • Dao
    • Publication
      • Content
      • Privacy Content
  • Open Standard API
    • Introduction
    • EIP-6239
    • Business Interface
      • Identity
      • Relationship
      • Publication
  • Graph Indexer
    • Definition and usage
    • Listen to events
    • To parse RDF data
    • To build a social graph
  • Integrations
    • Quick start
    • Construct a social graph with Relation Protocol
    • List of resources
    • NameService contract guide
    • Follow contract guide
    • Dao contract guide
    • Content contract guide
    • PrivacyContent contract guide
  • Relation Name Service
    • Name Service Api
  • Use Case
  • APPENDIX
    • Deploy a contract using Hardhat
    • SemanticSBT Deployment tool
Powered by GitBook
On this page
  • Schema
  • Contract
  • The process for sharing private data
  • Encryption
  • Minting a privacy-preserving SBT
  • Decryption
  • AccessConditions
  • User owns a specific wallet address
  • User holds an NFT in a collection
  • User holds at least XX ERC20 Token
  • Using boolean operations (AND + OR) for any of the above
  1. Contract Open Standard
  2. Publication

Privacy Content

Last updated 1 year ago

The module leverages Semantic SBT and to enable privacy-preserving data sharing, with users being able to share their private data with addresses meeting certain conditions.

In this mechanism, Lit Protocol is used to encrypt and decrypt data. Afterwards, will store the encrypted data, encrypted key, and conditions for data sharing. Then, Semantic SBT will be used to store the hash pointing to Arweave and define the conditions for data sharing.

The conditions for data sharing can be defined as:

  • EOA addresses

  • Users with certain NFT collections

  • Users with certain SBTs

  • Users owning a certain amount of a specified ERC20 token.

Schema

The for privacy content sharing works as follows: The schema is stored on Arweave in the form of a ttl with the transaction hash as the schemaURI to be passed to the contract during its initialization stage. For example:

ar://DeM6LRONjAUYr3qixkguLuFvYSHkykN7ZRKHn2HR5Gs

A schema consists of the follow three parts:

  • The list of prefixes.

PREFIX : <http://relationlabs.ai/entity/>
PREFIX p: <http://relationlabs.ai/property/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
  • Class

"Soul" represents an address entity.

:Soul a rdfs:Class ;
    rdfs:label "Soul" ;
    rdfs:comment "A soul." .
  • Predicate

The predicate p:privacyData describes private data.

p:privacyContent a rdf:Property ;
    rdfs:label "privacyContent" ;
    rdfs:comment "The privacy content." ;
    rdfs:domain :Soul ;
    rdfs:range xsd:string .

Contract

interface IPrivacyContent is ISemanticSBT {

    /**
     * Prepare a tokenId.
     * @return tokenId 
     */
    function prepareToken() external returns (uint256);
    
    /**
     * Query the prepared tokenId.
     * @param owner
     * @return tokenId
     */
    function ownedPrepareToken(address owner) external view returns (uint256);
    
    /**
     * Post a content.
     * @param content  The content should be the hash on Arweave. The actual encrypted content and authorization records are stored on Arweave.
     */
    function post(string memory content) external;
    
    /**
     * Whether the address is authorized to be the view of the token.
     * @param viewer 
     * @param tokenId 
     * @param isViewer 
     */
    function isViewerOf(address viewer, uint256 tokenId) external view returns (bool);
    
    /**
     * View the hash on Arweave corresponding to the token
     * @param tokenId
     * @return content 
     */
    function contentOf(uint256 tokenId) external view returns (string memory);
}

For a complete contract implementation, please refer to:

The process for sharing private data

Encryption

  • The encryptMetaData has a following format:

{
  "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="
}

Minting a privacy-preserving SBT

A PrivacySemanticSBT contract is built based on the Semantic SBT specification. We are to mint a privacy-preserving SBT, with its RDF object as the address on Arweave/ipfs.

  • How to call the method of the SemanticSBTPrivacy contract:

import {ethers, providers} from 'ethers'

const accounts = await ethereum.request({method: 'eth_requestAccounts'})

await PrivacySemanticSBT.prepareTokenId();
const tokenId = await PrivacySemanticSBT.ownedPrepareToken(accounts[0]);
PrivacySemanticSBT.mintWithPrivacy(tokenId, arweaveHash);

await PrivacySemanticSBT.addViewer(address1, tokenId);
  • A complete RDF example is provided as follows:

:Soul_0x0000000000000000000000000000000000000000 p:privacyContent "ar://djbZ5l5Ij5zBEgFFnVlDDqa4z5ACtS_A9uWPmAVwRe"
  • The construct of the encryptedObject:

    • web3 storage layer, e.g: ar:// or ipfs://

    • web3 hash for the storage

  • example of an encryptedObject:

ar://djbZ5l5Ij5zBEgFFnVlDDqa4z5ACtS_A9uWPmAVwRe

Decryption

AccessConditions

Different conditions can be set to control users' access to private data.

User owns a specific wallet address

Users owning certain addresses can decrypt the private data.

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

User holds an NFT in a collection

Users owning certain NFT collections can decrypt the private data.

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

User holds an SBT in a collection

Users owning certain SBT collections can decrypt the private data.

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

User holds at least XX ERC20 Token

Users owning a certain amount of a specified ERC20 token can decrypt the private data.

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

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

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

The private data awaiting sharing should be encrypted via . The result (accessCondition,encryptedSymmetricKey,encryptedObject) should then be sealed as the "encryptMetaData" and uploaded to a storage layer (like Arweave), generating a address for the "encryptMetaData".

Users who want to decrypt the private data should obtain the "encryptMetaData" from SBT's object. By calling , they can decrypt the data and obtain the object in plain-text.

Lit Protocol
Arweave
schema
PrivacyContent
Lit Protocol
LitProtocol's Decryption process