去中心化社群協定深度技術分析:DeSoc 協議棧、Frens 網路與社交圖譜的密碼學基礎

本文深入分析 DeSoc 領域的核心技術組件,包括去中心化身份系統(DID)、社交圖譜存儲協定、隱私保護機制、經濟模型設計、以及跨平台互通性標準。從密碼學原理出發,逐步構建對 DeSoc 技術棧的完整理解,涵蓋 Lens Protocol、Farcaster、CyberConnect 等代表性項目的技術實作分析。

去中心化社群協定深度技術分析:DeSoc 協議棧、Frens 網路與社交圖譜的密碼學基礎

執行摘要

去中心化社交(Decentralized Social,DeSoc)代表了社交網路架構的根本性轉變。與傳統 Web2 平台依賴中心化伺服器不同,DeSoc 協議棧構建在開放的密碼學基礎設施之上,將社交關係的的控制權歸還給用戶本身。本文深入分析 DeSoc 領域的核心技術組件,包括去中心化身份系統(DID)、社交圖譜存儲協議、隱私保護機制、經濟模型設計、以及跨平台互通性標準。

本文的重點在於技術實作層面的深度解析,而非表面的協議比較。我們將從密碼學原理出發,逐步構建對 DeSoc 技術棧的完整理解,涵蓋從底層的身份驗證到上層的應用構建。透過分析 Lens Protocol、Farcaster、CyberConnect、Friendship Protocol 等代表性項目的技術實作,本文為開發者和研究者提供了一份詳盡的 DeSoc 技術地圖。

第一章:去中心化身份系統(DID)

1.1 DID 基礎理論

去中心化識別符(Decentralized Identifier,DID)是由 W3C 標準化的新型數位身份系統。與傳統的集中式身份系統不同,DID 不依賴任何中心化的註冊機構或身份提供者。每一個 DID 都是由其所有者獨立創建的,存儲在去中心化系統(如區塊鏈或分散式账本)中。

DID 的核心組成包括三個部分:DID 主體是 DID 指向的實體,可以是個人、組織或物體;DID 文檔是描述 DID 主體的公開信息的 JSON-LD 文檔,包括公鑰、身份驗證方法、服務端點等;DID 解析器是將 DID 轉換為 DID 文檔的軟體元件。

以下是 W3C DID 規範中定義的標準 DID URL 格式:

did-example = "did:" method-name ":" method-specific-id
example     = "did:example:123456789abcdefghi"

DID 方法定義了在特定區塊鏈或網路上創建和解析 DID 的具體機制。目前已註冊的 DID 方法超過 100 種,其中與以太坊生態相關的主要包括:did:ethr 使用以太坊地址作為 DID 的基礎;did:web 使用 DNS 域名作為 DID 的基礎;did:key 使用密碼學公鑰作為 DID 的基礎。

1.2 Ethereum DID 方法(did:ethr)

did:ethr 是以太坊生態系統中最廣泛使用的 DID 方法之一,其核心思想是將以太坊錢包地址作為身份的基礎。以下是 did:ethr 的技術規範。

DID 文檔結構遵循 W3C DID Core 規範,但添加了以太坊特有的元素:

{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://ns.did.ai/security/v1"
  ],
  "id": "did:ethr:0xf3beac30c498d9e26865f34ddcaaad92d57a413a",
  "verificationMethod": [
    {
      "id": "did:ethr:0xf3beac30c498d9e26865f34ddcaaad92d57a413a#controller",
      "type": "EcdsaSecp256k1RecoveryMethod2020",
      "controller": "did:ethr:0xf3beac30c498d9e26865f34ddcaaad92d57a413a",
      "ethereumAddress": "0xf3beac30c498d9e26865f34ddcaaad92d57a413a"
    }
  ],
  "authentication": ["did:ethr:0xf3beac30c498d9e26865f34ddcaaad92d57a413a#controller"],
  "service": [
    {
      "id": "did:ethr:0xf3beac30c498d9e26865f34ddcaaad92d57a413a#linkedDomains",
      "type": "LinkedDomains",
      "serviceEndpoint": "https://example.com/.well-known/did.json"
    }
  ]
}

DID 解析過程涉及以下步驟:首先解析器根據 DID 的 method-specific-id 確定智能合約地址;然後查詢區塊鏈上的 DID 合約獲取最新的 DID 文檔;最後將文檔轉換為符合 W3C 規範的格式。

1.3 ENS 域名作為身份

以太坊名稱服務(Ethereum Name Service,ENS)是 DeSoc 生態系統中另一個重要的身份基礎設施。ENS 將人類可讀的名稱(如 alice.eth)映射到以太坊地址、內容哈希、和其他元數據。

ENS 域名結構包括多個層次:頂層域名(.eth)是基於區塊鏈的原生生態系統;二層域名由域名持有者自由註冊和管理;三層域名可以進一步細分。

ENS 的技術架構包含以下核心合約:

// ENS 核心合約介面
interface ENS {
    // 查詢域名所有者
    function owner(bytes32 node) external view returns (address);
    
    // 查詢域名解析器
    function resolver(bytes32 node) external view returns (address);
    
    // 查詢域名 TTL
    function ttl(bytes32 node) external view returns (uint64);
    
    // 設置域名所有者
    function setOwner(bytes32 node, address owner) external;
    
    // 設置域名解析器
    function setResolver(bytes32 node, address resolver) external;
    
    // 設置域名 TTL
    function setTTL(bytes32 node, uint64 ttl) external;
    
    // 設置子域名
    function setSubnodeOwner(
        bytes32 node,
        bytes32 label,
        address owner
    ) external;
}

公共Resolver合約提供了域名解析的標準實現:

// PublicResolver 合約核心功能
contract PublicResolver {
    // 名稱到地址的映射
    mapping(bytes32 => address) public addr;
    
    // 地址到名稱的反向映射
    mapping(address => bytes32) public reverseResolver;
    
    // 內容哈希映射
    mapping(bytes32 => bytes) public contenthash;
    
    // ABI 記錄
    mapping(bytes32 => uint256) public ABI;
    mapping(bytes32 => bytes) public recordData;
    
    // 設置地址記錄
    function setAddr(bytes32 node, address addrValue) external authorized(node) {
        addr[node] = addrValue;
        emit AddressChanged(node, addrValue);
    }
    
    // 設置內容哈希
    function setContenthash(bytes32 node, bytes calldata hash) external authorized(node) {
        contenthash[node] = hash;
        emit ContenthashChanged(node, hash);
    }
    
    // 設置反向解析
    function setName(bytes32 node, string calldata name) external {
        reverseResolver[msg.sender] = node;
        recordData[node] = bytes(name);
        emit NameChanged(node, name);
    }
}

1.4 錢包簽名身份驗證

在 DeSoc 應用中,錢包簽名是驗證用戶身份的主要方法。這種機制允許用戶在不暴露私鑰的情況下,證明自己對某個錢包地址的控制權。

EIP-191 簽名標準定義了以太坊簽名消息的格式:

\nthereum Signed Message:\n{version}{message}

驗證流程包括以下步驟:用戶使用錢包對挑戰消息進行簽名;應用伺服器使用 ecrecover 函數從簽名中恢復簽名者的地址;比較恢復的地址與用戶聲稱的地址是否一致。

以下是完整的簽名驗證實現:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/**
 * @title SignatureVerifier
 * @notice 錢包簽名身份驗證合約
 */
contract SignatureVerifier {
    
    // 簽名有效期(秒)
    uint256 public constant SIGNATURE_VALIDITY_PERIOD = 5 minutes;
    
    // 使用的 nonce
    mapping(address => uint256) public nonces;
    
    // 事件
    event SignatureUsed(address indexed signer, uint256 indexed nonce);
    event MessageAuthenticated(address indexed signer, bytes32 messageHash);
    
    /**
     * @notice 驗證簽名並認證消息
     * @param signer 簽名者地址
     * @param message 原始消息
     * @param signature 簽名數據
     */
    function verifyAndAuthenticate(
        address signer,
        bytes memory message,
        bytes memory signature
    ) external returns (bool) {
        // 構造 EIP-191 格式的消息
        bytes32 messageHash = keccak256(abi.encodePacked(
            "\x19Ethereum Signed Message:\n",
            Strings.toString(bytes(message).length),
            message
        ));
        
        // 驗證簽名
        address recoveredSigner = ECDSA.recover(messageHash, signature);
        require(recoveredSigner == signer, "Invalid signature");
        
        emit MessageAuthenticated(signer, messageHash);
        
        return true;
    }
    
    /**
     * @notice 帶 nonce 的挑戰-響應認證
     * @param signer 簽名者地址
     * @param message 消息
     * @param signature 簽名
     * @param targetNonce 目標 nonce
     */
    function verifyWithNonce(
        address signer,
        bytes memory message,
        bytes memory signature,
        uint256 targetNonce
    ) external returns (bool) {
        require(nonces[signer] == targetNonce, "Invalid nonce");
        
        // 構造包含 nonce 的消息
        bytes32 messageHash = keccak256(abi.encodePacked(
            message,
            signer,
            targetNonce
        ));
        
        // EIP-191 格式化
        bytes32 ethSignedHash = keccak256(abi.encodePacked(
            "\x19Ethereum Signed Message:\n32",
            messageHash
        ));
        
        // 驗證簽名
        address recoveredSigner = ECDSA.recover(ethSignedHash, signature);
        require(recoveredSigner == signer, "Invalid signature");
        
        // 增加 nonce
        nonces[signer]++;
        
        emit SignatureUsed(signer, targetNonce);
        
        return true;
    }
    
    /**
     * @notice 生成認證挑戰消息
     * @param appId 應用程序 ID
     * @param action 要執行的操作
     */
    function generateChallenge(
        string memory appId,
        string memory action
    ) external view returns (bytes32) {
        return keccak256(abi.encodePacked(
            appId,
            action,
            address(this),
            block.chainid,
            nonces[msg.sender],
            block.timestamp
        ));
    }
}

第二章:社交圖譜存儲協議

2.1 社交圖譜的資料結構

社交圖譜(Social Graph)是 DeSoc 系統的核心資料結構,它表示用戶之間的關注、被關注、轉發、點讚等社交關係。社交圖譜的設計直接影響了系統的可擴展性、隱私性和抗審查性。

圖論基礎為社交圖譜提供了數學框架。在圖論中,社交圖譜可以表示為一個有向圖 G = (V, E),其中 V 是頂點集合(代表用戶),E 是邊集合(代表社交關係)。對於關注關係,邊的方向從關注者指向被關注者。

常見的圖資料結構表示包括:鄰接表(Adjacency List)儲存每個頂點的鄰居列表,空間效率高但查詢需要遍歷;鄰接矩陣(Adjacency Matrix)使用二維矩陣表示邊的連接,空間複雜度 O(V²) 但查詢效率高;壓縮稀疏行(CSR)格式適合儲存大型稀疏圖。

2.2 Lens Protocol 技術架構

Lens Protocol 是 DeSoc 領域最具影響力的協議之一,其設計強調模組化和可組合性。以下是 Lens Protocol 的核心技術組件分析。

Profile NFT 是 Lens 身份系統的基礎。每個 Lens 用戶需要先創建一個 Profile NFT,這個 NFT 代表用戶在 Lens 生態中的身份。

// Lens Protocol Profile 合約核心介面
interface ILensHub {
    
    // 創建 Profile
    function createProfile(ProfileCreationParams calldata params) 
        external 
        returns (uint256);
    
    // 設置 Follow 模組
    function setFollowModule(
        uint256 profileId,
        address followModule
    ) external;
    
    // 設置個人資料元數據 URI
    function setFollowNFTURI(
        uint256 profileId,
        string calldata followNFTURI
    ) external;
    
    // 關注
    function follow(
        uint256[] calldata profileIds,
        bytes[] calldata datas
    ) external returns (uint256[] memory);
    
    // 收集(收藏)
    function collect(
        uint256 profileId,
        uint256 pubId,
        bytes calldata data
    ) external returns (uint256);
    
    // 轉發
    function mirror(
        uint256 profileId,
        uint256 pubId,
        bytes calldata data
    ) external returns (uint256);
    
    // 發布
    function post(
        PostParams calldata params
    ) external returns (uint256);
    
    // 評論
    function comment(
        CommentParams calldata params
    ) external returns (uint256);
}

/**
 * @dev Profile 創建參數
 */
struct ProfileCreationParams {
    address to;                    // Profile NFT 接收者
    string handle;                 // 用戶名(唯一)
    string imageURI;               // 頭像 URI
    string followModule;           // Follow 模組地址
    bytes followModuleData;        // Follow 模組初始化數據
    string followNFTURI;           // Follow NFT URI
    string metadata;               // 元數據 URI
}

Follow 系統採用 NFT 機制來表示關注關係。當用戶 A 關注用戶 B 時,A 會獲得一個 Follow NFT,這個 NFT 代表了 A 對 B 的關注。

// Follow NFT 合約
contract FollowNFT is ERC721, AccessControl {
    
    // 發布者(被關注的 Profile)
    address public profileId;
    
    // 關注者列表
    mapping(address => bool) public followers;
    
    // 區塊號到 Token ID 的映射
    mapping(uint256 => uint256) public blockToTokenId;
    
    // 事件
    event Followed(address indexed follower, uint256 tokenId);
    event Unfollowed(address indexed follower, uint256 tokenId);
    
    constructor(address _profileId) {
        profileId = _profileId;
    }
    
    /**
     * @notice 鑄造 Follow NFT
     */
    function mint(address to) external onlyMinter returns (uint256) {
        uint256 tokenId = totalSupply() + 1;
        _mint(to, tokenId);
        
        followers[to] = true;
        blockToTokenId[block.number] = tokenId;
        
        emit Followed(to, tokenId);
        
        return tokenId;
    }
    
    /**
     * @notice 燒毀 Follow NFT
     */
    function burn(uint256 tokenId) external onlyMinter {
        address owner = ownerOf(tokenId);
        _burn(tokenId);
        
        followers[owner] = false;
        
        emit Unfollowed(owner, tokenId);
    }
    
    /**
     * @notice 檢查是否關注
     */
    function isFollowing(address user) external view returns (bool) {
        return followers[user];
    }
}

Collect(收藏)機制允許用戶「購買」某條內容。Collect NFT 代表了用戶對該內容的所有權,可以用於構建付費牆、獨家內容等應用場景。

2.3 鏈上 vs 鏈下存儲策略

社交圖譜的存儲策略需要在去中心化、安全性和性能之間取得平衡。

全鏈上存儲將所有社交圖譜數據直接存儲在區塊鏈上。這種方法的優點是數據完全去中心化、抗審查、不可篡改;缺點是存儲成本高昂,且查詢效率受限於區塊鏈的性能。

IPFS/Arweave 存儲將社交圖譜數據存儲在去中心化文件系統上,只在區塊鏈上存儲數據的哈希引用。這種方法降低了存儲成本,但引入了數據可用性風險。

混合存儲策略是目前的最佳實踐:將高價值的、驗證性的數據(如身份、關注關係)存儲在鏈上;將大規模的、動態的數據(如內容、互動記錄)存儲在鏈下。

以下是混合存儲的實現示例:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/**
 * @title HybridGraphStorage
 * @notice 混合圖譜存儲合約
 * @dev 將核心社交圖譜存儲在鏈上,內容存儲在 IPFS
 */
contract HybridGraphStorage {
    
    // 核心圖譜數據結構
    struct GraphData {
        // 關注關係(鏈上)
        mapping(address => mapping(address => bool)) follows;
        mapping(address => address[]) followers;
        mapping(address => address[]) following;
        
        // 點讚/轉發計數
        mapping(bytes32 => uint256) likesCount;
        mapping(bytes32 => uint256) mirrorsCount;
        
        // 內容引用(IPFS CID)
        mapping(bytes32 => string) contentHashes;
    }
    
    GraphData public graphData;
    
    // 事件
    event Follow(address indexed follower, address indexed target);
    event Unfollow(address indexed follower, address indexed target);
    event ContentPublished(bytes32 indexed contentId, string ipfsCid);
    event ContentDeleted(bytes32 indexed contentId);
    
    /**
     * @notice 關注用戶
     */
    function follow(address target) external {
        require(!graphData.follows[msg.sender][target], "Already following");
        
        graphData.follows[msg.sender][target] = true;
        graphData.followers[target].push(msg.sender);
        graphData.following[msg.sender].push(target);
        
        emit Follow(msg.sender, target);
    }
    
    /**
     * @notice 取消關注
     */
    function unfollow(address target) external {
        require(graphData.follows[msg.sender][target], "Not following");
        
        graphData.follows[msg.sender][target] = false;
        // 注意:這裡不移除數組元素,而是標記為無效
        
        emit Unfollow(msg.sender, target);
    }
    
    /**
     * @notice 發布內容(僅存儲 IPFS 哈希)
     */
    function publishContent(
        bytes32 contentId,
        string calldata ipfsCid,
        uint256 contentType
    ) external {
        graphData.contentHashes[contentId] = ipfsCid;
        
        emit ContentPublished(contentId, ipfsCid);
    }
    
    /**
     * @notice 獲取內容 IPFS 哈希
     */
    function getContentHash(bytes32 contentId) external view returns (string memory) {
        return graphData.contentHashes[contentId];
    }
    
    /**
     * @notice 檢查關注關係
     */
    function isFollowing(address follower, address target) external view returns (bool) {
        return graphData.follows[follower][target];
    }
    
    /**
     * @notice 獲取粉絲列表
     */
    function getFollowers(address user) external view returns (address[] memory) {
        return graphData.followers[user];
    }
    
    /**
     * @notice 獲取關注列表
     */
    function getFollowing(address user) external view returns (address[] memory) {
        return graphData.following[user];
    }
}

第三章:隱私保護機制

3.1 選擇性披露

選擇性披露(Selective Disclosure)是 DeSoc 系統中保護用戶隱私的關鍵技術。用戶可以證明自己滿足某些條件(如年齡、所在地區、持有特定代幣)而不需要透露具體的身份信息。

零知識證明(ZKP)是實現選擇性披露的主要技術手段。以下是使用 zkSNARK 實現年齡驗證的示例:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/utils/cryptography/SimpleZkpVerifier.sol";

/**
 * @title AgeVerifier
 * @notice 年齡驗證零知識證明合約
 */
contract AgeVerifier {
    
    // 驗證者合約地址(由設置的 zkSNARK 電路生成)
    address public verifierAddress;
    
    // 信任的發布者
    mapping(address => bool) public trustedIssuers;
    
    // 一次性承諾
    mapping(bytes32 => bool) public usedCommitments;
    
    // 事件
    event AgeProofVerified(
        address indexed prover,
        uint8 minAge,
        bool isValid
    );
    
    constructor(address _verifierAddress) {
        verifierAddress = _verifierAddress;
    }
    
    /**
     * @notice 驗證年齡證明
     * @param proof ZK 證明
     * @param ageCommitment 年齡承諾
     * @param minAge 最小年齡要求
     */
    function verifyAgeProof(
        uint256[2] calldata a,
        uint256[2][2] calldata b,
        uint256[2] calldata c,
        bytes32 ageCommitment,
        uint8 minAge
    ) external returns (bool) {
        // 檢查承諾未被使用
        require(!usedCommitments[ageCommitment], "Commitment already used");
        
        // 準備公共輸入
        uint256[3] memory inputs = [
            uint256(ageCommitment),
            uint256(minAge),
            uint256(block.chainid)
        ];
        
        // 調用 ZK 驗證者
        IZKPVerifier verifier = IZKPVerifier(verifierAddress);
        bool isValid = verifier.verifyProof(a, b, c, inputs);
        
        // 標記承諾為已使用
        usedCommitments[ageCommitment] = true;
        
        emit AgeProofVerified(msg.sender, minAge, isValid);
        
        return isValid;
    }
    
    /**
     * @notice 生成年齡承諾
     * @param dateOfBirth 出生日期
     */
    function generateAgeCommitment(
        uint256 dateOfBirth
    ) external pure returns (bytes32) {
        return keccak256(abi.encodePacked(dateOfBirth));
    }
}

3.2 群體簽名

群體簽名允許群組成員以群組的名義簽名,而外部驗證者只知道簽名來自群組成員,但無法確定具體是哪個成員。

這種機制適用於 DeSoc 場景中的「DAO 成員投票」、「社群成員評論」等場景,既保證了參與的真實性,又保護了參與者的身份隱私。

群體簽名協議的基本流程如下:群組成員使用自己的私鑰和群組公鑰生成簽名;驗證者使用群組公鑰驗證簽名來自有效成員;可選的群組管理者可以追蹤具體的簽名者。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/**
 * @title GroupSignature
 * @notice 簡化的群體簽名實現
 * @dev 基於 BBS+ 簽名的群體簽名
 */
contract GroupSignature {
    
    // 群組結構
    struct Group {
        bytes32 groupId;
        uint256 memberCount;
        mapping(uint256 => address) members;  // index -> member address
        mapping(address => bool) isMember;
        mapping(address => uint256) memberIndex;
        address manager;
        bool isActive;
    }
    
    // 群組映射
    mapping(bytes32 => Group) public groups;
    
    // 成員撤銷列表
    mapping(bytes32 => mapping(address => bool)) public revokedMembers;
    
    // 事件
    event GroupCreated(bytes32 indexed groupId, address indexed manager);
    event MemberAdded(bytes32 indexed groupId, address indexed member);
    event MemberRemoved(bytes32 indexed groupId, address indexed member);
    event SignatureVerified(bytes32 indexed groupId, bool isValid);
    
    /**
     * @notice 創建新群組
     */
    function createGroup(bytes32 groupId) external returns (bool) {
        require(groups[groupId].manager == address(0), "Group already exists");
        
        groups[groupId].groupId = groupId;
        groups[groupId].manager = msg.sender;
        groups[groupId].isActive = true;
        
        emit GroupCreated(groupId, msg.sender);
        
        return true;
    }
    
    /**
     * @notice 添加群組成員
     */
    function addMember(bytes32 groupId, address member) external {
        Group storage group = groups[groupId];
        require(msg.sender == group.manager, "Not group manager");
        require(!group.isMember[member], "Already a member");
        
        uint256 index = group.memberCount;
        group.members[index] = member;
        group.isMember[member] = true;
        group.memberIndex[member] = index;
        group.memberCount++;
        
        emit MemberAdded(groupId, member);
    }
    
    /**
     * @notice 移除群組成員
     */
    function removeMember(bytes32 groupId, address member) external {
        Group storage group = groups[groupId];
        require(msg.sender == group.manager, "Not group manager");
        require(group.isMember[member], "Not a member");
        
        group.isMember[member] = false;
        revokedMembers[groupId][member] = true;
        
        emit MemberRemoved(groupId, member);
    }
    
    /**
     * @notice 驗證群體簽名
     * @param groupId 群組 ID
     * @param signer 簽名者地址
     * @param messageHash 消息哈希
     * @param signature 簽名
     */
    function verifyGroupSignature(
        bytes32 groupId,
        address signer,
        bytes32 messageHash,
        bytes calldata signature
    ) external returns (bool) {
        Group storage group = groups[groupId];
        
        // 檢查簽名者是否為有效成員
        bool isValidMember = group.isMember[signer];
        
        // 檢查是否已被撤銷
        bool isRevoked = revokedMembers[groupId][signer];
        
        bool isValid = isValidMember && !isRevoked;
        
        emit SignatureVerified(groupId, isValid);
        
        return isValid;
    }
}

3.3 匿名互動機制

DeSoc 系統需要支持用戶之間的匿名互動,同時防止垃圾信息和滥用。以下是一種基於零知識證明的匿名互動實現。

資格證明允許用戶在不透露身份的條件下,證明自己滿足某些資格要求(如持有特定 NFT、質押了一定數量的代幣等)。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/**
 * @title AnonymousInteraction
 * @notice 匿名互動合約
 * @dev 使用 ZK 證明實現匿名但有資格的互動
 */
contract AnonymousInteraction {
    
    // 互動記錄
    struct Interaction {
        bytes32 interactionId;
        bytes32 groupId;       // 資格群組 ID
        uint256 timestamp;
        bytes32 messageHash;   // 互動內容哈希
        bytes proof;          // ZK 證明
    }
    
    // 互動記錄映射
    mapping(bytes32 => Interaction[]) public interactions;
    
    // 用戶的承諾映射(防止雙重互動)
    mapping(bytes32 => mapping(bytes32 => bool)) public userCommitments;
    
    // 資格驗證器介面
    IQualificationVerifier public qualificationVerifier;
    
    // 事件
    event AnonymousInteractionPosted(
        bytes32 indexed interactionId,
        bytes32 indexed groupId,
        uint256 timestamp
    );
    
    constructor(address _qualificationVerifier) {
        qualificationVerifier = IQualificationVerifier(_qualificationVerifier);
    }
    
    /**
     * @notice 發布匿名互動
     * @param groupId 資格群組 ID
     * @param messageHash 消息哈希
     * @param proof 資格 ZK 證明
     * @param nullifier 一次性 nullifier(用於防止雙重互動)
     */
    function postAnonymousInteraction(
        bytes32 groupId,
        bytes32 messageHash,
        bytes calldata proof,
        bytes32 nullifier
    ) external returns (bytes32 interactionId) {
        // 檢查 nullifier 是否已使用
        require(
            !userCommitments[msg.sender][nullifier],
            "Nullifier already used"
        );
        
        // 驗證 ZK 證明
        bool isQualified = qualificationVerifier.verifyQualification(
            msg.sender,
            groupId,
            proof
        );
        require(isQualified, "Not qualified");
        
        // 標記 nullifier 為已使用
        userCommitments[msg.sender][nullifier] = true;
        
        // 創建互動記錄
        interactionId = keccak256(abi.encodePacked(
            groupId,
            messageHash,
            nullifier,
            block.timestamp
        ));
        
        interactions[groupId].push(Interaction({
            interactionId: interactionId,
            groupId: groupId,
            timestamp: block.timestamp,
            messageHash: messageHash,
            proof: proof
        }));
        
        emit AnonymousInteractionPosted(interactionId, groupId, block.timestamp);
    }
    
    /**
     * @notice 獲取群組的互動數量
     */
    function getInteractionCount(bytes32 groupId) external view returns (uint256) {
        return interactions[groupId].length;
    }
}

/**
 * @title IQualificationVerifier
 * @notice 資格驗證器介面
 */
interface IQualificationVerifier {
    function verifyQualification(
        address user,
        bytes32 groupId,
        bytes calldata proof
    ) external view returns (bool);
}

第四章:Frens 網路與社交代幣經濟

4.1 Frens 協議的概念

Frens(朋友)網路是 DeSoc 生態中用於表示和獎勵真實社交關係的機制。與簡單的關注/被關注不同,Frens 網路強調關係的強度和質量,試圖將現實世界的社交影響力轉換為網路效應。

Frens 與普通關注的區別體現在以下幾個方面:普通關注可以是單向的、冷漠的;Frens 關係通常是雙向的、互惠的;Frens 關係可能伴隨著更深層的信任和互動記錄;Frens 可以被量化為「友誼積分」或代幣。

Frens 積分系統可以激勵用戶建立和維護真實的社交關係:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/**
 * @title FrensProtocol
 * @notice Frens 友誼積分協議
 * @dev 量化和管理用戶之間的社交關係
 */
contract FrensProtocol {
    
    // Frens 積分結構
    struct FrensBalance {
        uint256 directFrens;     // 直接友誼積分
        uint256 indirectFrens;   // 間接友誼積分
        uint256 lastUpdateTime;
    }
    
    // 用戶 Frens 映射
    mapping(address => mapping(address => uint256)) public frensBalances;
    mapping(address => FrensBalance) public totalFrens;
    
    // 互動記錄
    struct Interaction {
        uint256 timestamp;
        uint8 interactionType;  // 0=DM, 1=Comment, 2=Like, 3=Share
        uint256 weight;
    }
    
    mapping(address => mapping(address => Interaction[])) public interactionHistory;
    
    // 積分權重配置
    uint8[] public interactionWeights = [10, 3, 1, 2];  // DM, Comment, Like, Share
    
    // 積分衰減參數
    uint256 public constant HALF_LIFE = 180 days;  // 半衰期
    
    // 事件
    event FrensUpdated(
        address indexed from,
        address indexed to,
        uint256 change,
        uint8 interactionType
    );
    event FrensDecayed(
        address indexed user,
        uint256 oldBalance,
        uint256 newBalance
    );
    
    /**
     * @notice 記錄互動並更新 Frens
     */
    function recordInteraction(
        address from,
        address to,
        uint8 interactionType
    ) external {
        require(interactionType < interactionWeights.length, "Invalid type");
        
        // 記錄互動
        Interaction memory interaction = Interaction({
            timestamp: block.timestamp,
            interactionType: interactionType,
            weight: interactionWeights[interactionType]
        });
        
        interactionHistory[from][to].push(interaction);
        
        // 更新 Frens
        uint256 frensChange = interaction.weight;
        frensBalances[from][to] += frensChange;
        totalFrens[from].directFrens += frensChange;
        totalFrens[from].lastUpdateTime = block.timestamp;
        
        // 增加間接 Frens
        _updateIndirectFrens(from, to, frensChange);
        
        emit FrensUpdated(from, to, frensChange, interactionType);
    }
    
    /**
     * @notice 更新間接 Frens(共同好友)
     */
    function _updateIndirectFrens(
        address from,
        address to,
        uint256 change
    ) internal {
        // 找到 from 和 to 的共同好友
        // 共同好友獲得少量的間接 Frens
        address[] memory fromFriends = _getFriends(from);
        address[] memory toFriends = _getFriends(to);
        
        for (uint256 i = 0; i < fromFriends.length; i++) {
            for (uint256 j = 0; j < toFriends.length; j++) {
                if (fromFriends[i] == toFriends[j]) {
                    // 共同好友獲得間接 Frens(權重較低)
                    uint256 indirectChange = change / 10;
                    frensBalances[fromFriends[i]][to] += indirectChange;
                    totalFrens[fromFriends[i]].indirectFrens += indirectChange;
                }
            }
        }
    }
    
    /**
     * @notice 應用 Frens 衰減
     */
    function applyDecay(address user) external {
        FrensBalance storage balance = totalFrens[user];
        
        uint256 timePassed = block.timestamp - balance.lastUpdateTime;
        if (timePassed >= HALF_LIFE) {
            uint256 decayFactor = 2 ** (timePassed / HALF_LIFE);
            uint256 oldBalance = balance.directFrens + balance.indirectFrens;
            uint256 newBalance = oldBalance / decayFactor;
            
            balance.directFrens = newBalance * balance.directFrens / oldBalance;
            balance.indirectFrens = newBalance * balance.indirectFrens / oldBalance;
            
            emit FrensDecayed(user, oldBalance, newBalance);
        }
    }
    
    /**
     * @notice 獲取好友列表
     */
    function _getFriends(address user) internal view returns (address[] memory) {
        // 實現好友查詢邏輯
        // 這裡需要整合社交圖譜數據
        return new address[](0);
    }
    
    /**
     * @notice 獲取用戶總 Frens
     */
    function getTotalFrens(address user) external view returns (uint256) {
        FrensBalance storage balance = totalFrens[user];
        return balance.directFrens + balance.indirectFrens;
    }
    
    /**
     * @notice 獲取與特定用戶的 Frens
     */
    function getFrensWith(address user, address other) external view returns (uint256) {
        return frensBalances[user][other];
    }
}

4.2 社交代幣經濟模型

社交代幣(Social Token)是 DeSoc 生態中的重要經濟組件,它允許創作者建立自己的微型經濟系統。

個人代幣是最常見的社交代幣類型,每個創作者可以發行自己的代幣。粉絲購買這些代幣可以獲得各種特權和權利。

代幣經濟模型設計需要考慮以下因素:

代幣分配結構需要平衡創作者、投資者和社區成員的利益;流動性機制確保代幣可以方便地買賣;價值捕獲機制將社交影響力轉換為代幣價值;激勵設計鼓勵用戶參與和貢獻。

以下是社交代幣合約的實現:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

/**
 * @title SocialToken
 * @notice 社交代幣合約
 * @dev 支援鑄造限額、流動性鎖定、價值捕獲等特性
 */
contract SocialToken is ERC20, AccessControl {
    
    // 角色
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
    
    // 創作者地址
    address public creator;
    
    // 最大供應量
    uint256 public maxSupply;
    
    // 流動性鎖定信息
    address public liquidityReserve;
    uint256 public liquidityUnlockTime;
    
    // 價值捕獲比例(basis points)
    uint256 public valueCaptureRatio = 2500;  // 25%
    
    // 價值捕獲池
    uint256 public valueCapturePool;
    
    // 白名單(用於特殊權利)
    mapping(address => bool) public whitelist;
    
    // 事件
    event ValueCaptured(address indexed from, uint256 amount);
    event LiquidityLocked(uint256 unlockTime);
    event CreatorSet(address indexed oldCreator, address indexed newCreator);
    
    constructor(
        string memory name,
        string memory symbol,
        uint256 _maxSupply,
        address _creator
    ) ERC20(name, symbol) {
        require(_creator != address(0), "Invalid creator");
        
        maxSupply = _maxSupply;
        creator = _creator;
        
        _grantRole(DEFAULT_ADMIN_ROLE, _creator);
        _grantRole(MINTER_ROLE, _creator);
        _grantRole(BURNER_ROLE, _creator);
    }
    
    /**
     * @notice 鑄造新代幣
     */
    function mint(address to, uint256 amount) 
        external 
        onlyRole(MINTER_ROLE) 
    {
        require(totalSupply() + amount <= maxSupply, "Exceeds max supply");
        _mint(to, amount);
    }
    
    /**
     * @notice 燃燒代幣
     */
    function burn(uint256 amount) external onlyRole(BURNER_ROLE) {
        _burn(msg.sender, amount);
    }
    
    /**
     * @notice 價值捕獲(交易時調用)
     */
    function captureValue(address from, address to, uint256 amount) 
        external 
        onlyRole(DEFAULT_ADMIN_ROLE) 
    {
        uint256 captureAmount = (amount * valueCaptureRatio) / 10000;
        if (captureAmount > 0) {
            _transfer(from, address(this), captureAmount);
            valueCapturePool += captureAmount;
            emit ValueCaptured(from, captureAmount);
        }
    }
    
    /**
     * @notice 提取價值捕獲池(僅創作者)
     */
    function withdrawValueCapture() external {
        require(msg.sender == creator, "Not creator");
        require(valueCapturePool > 0, "No value captured");
        
        uint256 amount = valueCapturePool;
        valueCapturePool = 0;
        _transfer(address(this), creator, amount);
    }
    
    /**
     * @notice 設置流動性儲備
     */
    function setLiquidityReserve(address _reserve, uint256 _unlockTime) 
        external 
        onlyRole(DEFAULT_ADMIN_ROLE) 
    {
        require(liquidityUnlockTime == 0, "Liquidity already locked");
        
        liquidityReserve = _reserve;
        liquidityUnlockTime = _unlockTime;
        
        emit LiquidityLocked(_unlockTime);
    }
    
    /**
     * @notice 添加到白名單
     */
    function addToWhitelist(address account) external onlyRole(DEFAULT_ADMIN_ROLE) {
        whitelist[account] = true;
    }
    
    /**
     * @notice 從白名單移除
     */
    function removeFromWhitelist(address account) external onlyRole(DEFAULT_ADMIN_ROLE) {
        whitelist[account] = false;
    }
    
    /**
     * @notice 檢查是否在白名單
     */
    function isWhitelisted(address account) external view returns (bool) {
        return whitelist[account];
    }
}

4.3 社交影響力量化

社交影響力的量化是 DeSoc 系統中的一個核心問題。不同的應用場景可能需要不同的影響力衡量標準。

影響力指標體系可能包括:直接粉絲數量、互動率(點讚、評論、轉發的比例)、內容質量分數、Frens 網路權重、付費支持者數量、以及歷史內容價值。

以下是影響力量化合約的實現:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/**
 * @title SocialInfluence
 * @notice 社交影響力量化合約
 * @dev 多維度衡量用戶的社交影響力
 */
contract SocialInfluence {
    
    // 影響力權重配置
    uint256 public constant FOLLOWER_WEIGHT = 30;
    uint256 public constant ENGAGEMENT_WEIGHT = 25;
    uint256 public constant CONTENT_WEIGHT = 25;
    uint256 public constant FRENS_WEIGHT = 20;
    
    // 用戶影響力結構
    struct InfluenceMetrics {
        uint256 followerScore;
        uint256 engagementScore;
        uint256 contentScore;
        uint256 frensScore;
        uint256 totalScore;
        uint256 lastUpdateTime;
    }
    
    // 用戶指標映射
    mapping(address => InfluenceMetrics) public userMetrics;
    
    // 歷史記錄
    mapping(address => uint256[]) public scoreHistory;
    
    // 社交圖譜合約引用
    address public socialGraph;
    
    // Frens 合約引用
    address public frensProtocol;
    
    // 事件
    event InfluenceUpdated(
        address indexed user,
        uint256 totalScore,
        uint256 change
    );
    
    constructor(address _socialGraph, address _frensProtocol) {
        socialGraph = _socialGraph;
        frensProtocol = _frensProtocol;
    }
    
    /**
     * @notice 更新用戶影響力
     */
    function updateInfluence(address user) external returns (uint256) {
        InfluenceMetrics storage metrics = userMetrics[user];
        
        uint256 oldTotal = metrics.totalScore;
        
        // 計算各維度分數
        metrics.followerScore = _calculateFollowerScore(user);
        metrics.engagementScore = _calculateEngagementScore(user);
        metrics.contentScore = _calculateContentScore(user);
        metrics.frensScore = _calculateFrensScore(user);
        
        // 計算總分
        metrics.totalScore = 
            (metrics.followerScore * FOLLOWER_WEIGHT +
            metrics.engagementScore * ENGAGEMENT_WEIGHT +
            metrics.contentScore * CONTENT_WEIGHT +
            metrics.frensScore * FRENS_WEIGHT) / 100;
        
        metrics.lastUpdateTime = block.timestamp;
        
        // 記錄歷史
        scoreHistory[user].push(metrics.totalScore);
        
        emit InfluenceUpdated(user, metrics.totalScore, 
            metrics.totalScore > oldTotal ? metrics.totalScore - oldTotal : oldTotal - metrics.totalScore);
        
        return metrics.totalScore;
    }
    
    /**
     * @notice 計算粉絲分數
     */
    function _calculateFollowerScore(address user) internal view returns (uint256) {
        // 從社交圖譜合約獲取粉絲數
        // 應用對數函數以避免馬太效應
        uint256 followerCount = ISocialGraph(socialGraph).getFollowerCount(user);
        
        if (followerCount == 0) return 0;
        
        return sqrt(followerCount * 1000);  // 簡化計算
    }
    
    /**
     * @notice 計算互動分數
     */
    function _calculateEngagementScore(address user) internal view returns (uint256) {
        // 計算點讚、評論、轉發的總數和比率
        uint256 totalInteractions = ISocialGraph(socialGraph).getTotalInteractions(user);
        uint256 followerCount = ISocialGraph(socialGraph).getFollowerCount(user);
        
        if (followerCount == 0) return 0;
        
        // 互動率 = 互動總數 / 粉絲數
        uint256 engagementRate = (totalInteractions * 10000) / followerCount;
        
        return engagementRate;
    }
    
    /**
     * @notice 計算內容分數
     */
    function _calculateContentScore(address user) internal view returns (uint256) {
        // 計算內容數量和質量
        uint256 contentCount = ISocialGraph(socialGraph).getContentCount(user);
        uint256 collectedCount = ISocialGraph(socialGraph).getTotalCollected(user);
        
        // 質量加權
        return contentCount * 10 + collectedCount * 50;
    }
    
    /**
     * @notice 計算 Frens 分數
     */
    function _calculateFrensScore(address user) internal view returns (uint256) {
        return IFrensProtocol(frensProtocol).getTotalFrens(user);
    }
    
    /**
     * @notice 獲取用戶影響力
     */
    function getInfluence(address user) external view returns (InfluenceMetrics memory) {
        return userMetrics[user];
    }
    
    /**
     * @notice 獲取影響力排名
     */
    function getInfluenceRank(address user) external view returns (uint256) {
        uint256 userScore = userMetrics[user].totalScore;
        uint256 rank = 1;
        
        // 這裡應該優化為使用排序數據結構
        // 簡化實現
        
        return rank;
    }
    
    // 數學輔助函數
    function sqrt(uint256 x) internal pure returns (uint256) {
        uint256 z = (x + 1) / 2;
        uint256 y = x;
        while (z < y) {
            y = z;
            z = (x / z + z) / 2;
        }
        return y;
    }
}

// 介面定義
interface ISocialGraph {
    function getFollowerCount(address user) external view returns (uint256);
    function getTotalInteractions(address user) external view returns (uint256);
    function getContentCount(address user) external view returns (uint256);
    function getTotalCollected(address user) external view returns (uint256);
}

interface IFrensProtocol {
    function getTotalFrens(address user) external view returns (uint256);
}

第五章:互通性與標準

5.1 跨平台社交圖譜

DeSoc 生態的一個重要目標是實現跨平台的社交圖譜可攜性。用戶應該能夠將其社交關係帶到任何支持該標準的應用程序中。

Graphite Protocol 是一個正在開發中的跨平台社交圖譜標準。該協議定義了通用的圖譜數據格式和交換機制。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/**
 * @title CrossPlatformGraph
 * @notice 跨平台社交圖譜合約
 * @dev 允許用戶導入和導出其社交圖譜
 */
contract CrossPlatformGraph {
    
    // 平台註冊
    struct Platform {
        string name;
        string graphEndpoint;
        bool isTrusted;
        uint256 registeredAt;
    }
    
    mapping(address => Platform) public platforms;
    address[] public registeredPlatforms;
    
    // 用戶授權
    mapping(address => mapping(address => bool)) public userAuthorizations;
    
    // 跨平台關注記錄
    struct CrossPlatformFollow {
        address platform;
        address user;
        address target;
        uint256 timestamp;
        bool isActive;
    }
    
    mapping(bytes32 => CrossPlatformFollow) public crossPlatformFollows;
    bytes32[] public crossPlatformFollowIds;
    
    // 事件
    event PlatformRegistered(
        address indexed platform,
        string name,
        uint256 timestamp
    );
    event AuthorizationGranted(
        address indexed user,
        address indexed platform
    );
    event CrossPlatformFollowRecorded(
        bytes32 indexed followId,
        address indexed platform,
        address indexed user,
        address target
    );
    
    /**
     * @notice 註冊新平台
     */
    function registerPlatform(
        string calldata name,
        string calldata graphEndpoint
    ) external returns (address platformAddress) {
        platformAddress = msg.sender;
        
        platforms[platformAddress] = Platform({
            name: name,
            graphEndpoint: graphEndpoint,
            isTrusted: false,
            registeredAt: block.timestamp
        });
        
        registeredPlatforms.push(platformAddress);
        
        emit PlatformRegistered(platformAddress, name, block.timestamp);
    }
    
    /**
     * @notice 授權平台訪問
     */
    function authorizePlatform(address platform) external {
        require(platformes[platform].registeredAt > 0, "Platform not registered");
        userAuthorizations[msg.sender][platform] = true;
        
        emit AuthorizationGranted(msg.sender, platform);
    }
    
    /**
     * @notice 記錄跨平台關注
     */
    function recordCrossPlatformFollow(
        address platform,
        address user,
        address target
    ) external returns (bytes32 followId) {
        require(userAuthorizations[user][platform], "Not authorized");
        
        followId = keccak256(abi.encodePacked(
            platform,
            user,
            target,
            block.timestamp
        ));
        
        crossPlatformFollows[followId] = CrossPlatformFollow({
            platform: platform,
            user: user,
            target: target,
            timestamp: block.timestamp,
            isActive: true
        });
        
        crossPlatformFollowIds.push(followId);
        
        emit CrossPlatformFollowRecorded(followId, platform, user, target);
    }
    
    /**
     * @notice 導出用戶的社交圖譜
     */
    function exportGraph(address user, address targetPlatform) 
        external 
        view 
        returns (bytes memory) 
    {
        require(userAuthorizations[user][targetPlatform], "Not authorized");
        
        // 構造導出數據
        // 這裡返回標準化的圖譜數據
        return abi.encode(user, getFollows(user), getFollowers(user));
    }
    
    // 輔助函數
    function getFollows(address user) internal view returns (address[] memory) {
        // 返回用戶關注的列表
        return new address[](0);
    }
    
    function getFollowers(address user) internal view returns (address[] memory) {
        // 返回用戶的粉絲列表
        return new address[](0);
    }
}

5.2 Lens 和 FARCASTER 互通性

Lens Protocol 和 FARCASTER 是目前最具影響力的兩個 DeSoc 協議,它們之間的互通性是一個重要的發展方向。

實名驗證機制允許用戶在 Lens 和 FARCASTER 上驗證其身份的一致性:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/**
 * @title LensFarcasterBridge
 * @notice Lens 和 FARCASTER 身份橋接合約
 * @dev 實現兩個生態之間的身份映射
 */
contract LensFarcasterBridge {
    
    // 身份映射
    mapping(address => address) public lensToFarcaster;
    mapping(address => address) public farcasterToLens;
    
    // 驗證記錄
    mapping(address => uint256) public lastVerification;
    uint256 public constant VERIFICATION_COOLDOWN = 30 days;
    
    // Lens Hub 合約
    address public lensHub;
    
    // FARCASTER ID 合約
    address public farcasterIdContract;
    
    // 事件
    event IdentityLinked(
        address indexed lensProfile,
        uint256 indexed farcasterId
    );
    event IdentityUnlinked(address indexed lensProfile);
    
    constructor(address _lensHub, address _farcasterIdContract) {
        lensHub = _lensHub;
        farcasterIdContract = _farcasterIdContract;
    }
    
    /**
     * @notice 鏈接 Lens 和 FARCASTER 身份
     * @param lensProfile Lens Profile ID
     * @param farcasterId FARCASTER ID
     * @param signature 簽名證明
     */
    function linkIdentity(
        uint256 lensProfile,
        uint256 farcasterId,
        bytes calldata signature
    ) external returns (bool) {
        // 獲取 Lens Profile 的所有者
        address lensOwner = ILensHub(lensHub).ownerOf(lensProfile);
        require(lensOwner == msg.sender, "Not Lens profile owner");
        
        // 驗證 FARCASTER ID 屬於同一用戶
        address farcasterOwner = IFarcasterId(farcasterIdContract).ownerOf(farcasterId);
        require(farcasterOwner == msg.sender, "Not FARCASTER ID owner");
        
        // 創建雙向映射
        lensToFarcaster[msg.sender] = toAddress(farcasterId);
        farcasterToLens[toAddress(farcasterId)] = msg.sender;
        
        emit IdentityLinked(msg.sender, farcasterId);
        
        return true;
    }
    
    /**
     * @notice 解除身份鏈接
     */
    function unlinkIdentity() external {
        address farcaster = lensToFarcaster[msg.sender];
        
        if (farcaster != address(0)) {
            delete farcasterToLens[farcaster];
            delete lensToFarcaster[msg.sender];
            emit IdentityUnlinked(msg.sender);
        }
    }
    
    /**
     * @notice 查詢 Lens 身份對應的 FARCASTER ID
     */
    function getFarcasterId(address lensOwner) external view returns (uint256) {
        return toUint256(lensToFarcaster[lensOwner]);
    }
    
    /**
     * @notice 查詢 FARCASTER ID 對應的 Lens 所有者
     */
    function getLensOwner(uint256 farcasterId) external view returns (address) {
        return farcasterToLens[toAddress(farcasterId)];
    }
    
    // 輔助函數
    function toAddress(uint256 id) internal pure returns (address) {
        return address(uint160(id));
    }
    
    function toUint256(address addr) internal pure returns (uint256) {
        return uint256(uint160(addr));
    }
}

// 介面
interface ILensHub {
    function ownerOf(uint256 tokenId) external view returns (address);
}

interface IFarcasterId {
    function ownerOf(uint256 id) external view returns (address);
}

結論

DeSoc 技術棧代表了社交網路架構的重大創新。從底層的 DID 身份系統到上層的 Frens 網路激勵,DeSoc 為用戶提供了一種全新的數位社交範式。

本文深入分析了 DeSoc 系統的核心技術組件:去中心化身份系統提供了用戶主權的基礎;社交圖譜存儲協議確保了社交關係的可攜性;隱私保護機制在保持透明的同時保護了用戶的敏感信息;Frens 和社交代幣經濟則為創作者經濟提供了新的激勵結構。

隨著 ERC-4337 帳戶抽象標準的成熟和 ZK 技術的進步,DeSoc 系統的用戶體驗將進一步改善,成本將持續降低。我們預期在未來幾年內,DeSoc 將從加密原生用戶群體擴展到更廣泛的主流用戶。

參考資源


本文最後更新時間:2026年3月

延伸閱讀與來源

這篇文章對您有幫助嗎?

評論

發表評論

注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。

目前尚無評論,成為第一個發表評論的人吧!