ERC-8004 Trustless Agents 深度剖析:去中心化 AI Agent 發現與信任框架


生成提示詞

請深入分析 ERC-8004 Trustless Agents 標準:
1. 研究 EIP-8004 規範文檔
2. 分析三大註冊表架構(Identity、Reputation、Validation)
3. 解析 Agent 註冊與發現機制
4. 研究聲譽系統與驗證流程
5. 分析多種信任模型(聲譽、加密經濟、TEE)
6. 繪製 Mermaid 流程圖說明 Agent 生命週期
7. 以繁體中文撰寫工程級深度文章

執行摘要

ERC-8004 提出了一個框架,讓 AI Agent 能夠「跨組織邊界發現、選擇和互動」,無需預先建立的信任關係。本文將深入剖析其核心技術:

  • 三大註冊表:Identity(身份)、Reputation(聲譽)、Validation(驗證)
  • ERC-721 身份代幣:全局唯一的 Agent 識別符
  • 鏈上聲譽系統:可組合的回饋機制
  • 多元信任模型:聲譽、加密經濟、TEE 驗證

目錄

  1. 設計動機與核心概念
  2. 三大註冊表架構
  3. Identity Registry:身份註冊
  4. Reputation Registry:聲譽系統
  5. Validation Registry:驗證機制
  6. Agent 生命週期
  7. 信任模型分析

1. 設計動機與核心概念

1.1 解決的問題

傳統 AI Agent 協作面臨的挑戰:

flowchart TB
    subgraph Traditional["傳統模式"]
        T1[Agent A] -->|需要信任| T2[Agent B]
        T1 -->|人工審核| T3[Agent C]
        T2 -->|自定義協議| T3

        Problem1[如何發現 Agent?]
        Problem2[如何評估可信度?]
        Problem3[如何驗證工作品質?]
    end

    subgraph ERC8004["ERC-8004 模式"]
        E1[Agent A] -->|查詢 Identity Registry| Registry[(鏈上註冊表)]
        E1 -->|查詢 Reputation| Registry
        E1 -->|請求 Validation| Registry

        Registry --> E2[Agent B]
        Registry --> E3[Agent C]
    end

1.2 核心設計原則

原則說明
無信任無需預先建立信任關係
去中心化鏈上註冊,無單點故障
可組合智能合約可直接讀取聲譽
可擴展支援多種驗證協議
互操作兼容 A2A、MCP、ENS、DID

1.3 全局識別符格式

namespace:chainId:identityRegistry:agentId

範例:
eip155:1:0x1234...abcd:42
└───┘ │ └────────────┘ └─┘
  │   │        │        └── agentId (ERC-721 tokenId)
  │   │        └── Identity Registry 合約地址
  │   └── Chain ID (Ethereum Mainnet = 1)
  └── 命名空間 (EIP-155 = EVM 鏈)

2. 三大註冊表架構

2.1 架構概覽

flowchart TB
    subgraph IdentityRegistry["Identity Registry"]
        IR1[ERC-721 代幣]
        IR2[Agent 元資料]
        IR3[通訊端點]
        IR4[信任模型宣告]
    end

    subgraph ReputationRegistry["Reputation Registry"]
        RR1[回饋提交]
        RR2[分數聚合]
        RR3[標籤過濾]
        RR4[回應機制]
    end

    subgraph ValidationRegistry["Validation Registry"]
        VR1[驗證請求]
        VR2[驗證回應]
        VR3[狀態追蹤]
        VR4[摘要統計]
    end

    Agent[Agent] -->|註冊| IdentityRegistry
    Client[Client] -->|互動| Agent
    Client -->|提交回饋| ReputationRegistry
    Validator[Validator] -->|驗證| ValidationRegistry

2.2 註冊表關係

erDiagram
    IDENTITY_REGISTRY ||--o{ AGENT : "registers"
    AGENT ||--o{ REPUTATION_REGISTRY : "receives feedback"
    AGENT ||--o{ VALIDATION_REGISTRY : "requests validation"
    CLIENT ||--o{ REPUTATION_REGISTRY : "gives feedback"
    VALIDATOR ||--o{ VALIDATION_REGISTRY : "provides validation"

    AGENT {
        uint256 agentId PK
        string tokenURI
        bytes metadata
    }

    REPUTATION_REGISTRY {
        uint256 agentId FK
        address client
        uint8 score
        bytes32 tag1
        bytes32 tag2
    }

    VALIDATION_REGISTRY {
        bytes32 requestHash PK
        uint256 agentId FK
        address validator
        uint8 response
    }

3. Identity Registry:身份註冊

3.1 基於 ERC-721 的身份代幣

Identity Registry 繼承自 ERC-721 URIStorage,為每個 Agent 鑄造唯一的 NFT 代幣:

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

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";

contract IdentityRegistry is ERC721URIStorage {
    struct MetadataEntry {
        bytes32 key;
        bytes value;
    }

    mapping(uint256 => mapping(bytes32 => bytes)) private _metadata;

    /// @notice 註冊新 Agent
    /// @param tokenURI 指向 Agent 註冊檔案的 URI (IPFS 或 HTTPS)
    /// @param metadata 可選的鏈上元資料
    /// @return agentId 新分配的 Agent ID
    function register(
        string calldata tokenURI,
        MetadataEntry[] calldata metadata
    ) external returns (uint256 agentId) {
        agentId = _nextTokenId++;
        _safeMint(msg.sender, agentId);
        _setTokenURI(agentId, tokenURI);

        for (uint256 i = 0; i < metadata.length; i++) {
            _metadata[agentId][metadata[i].key] = metadata[i].value;
        }

        emit AgentRegistered(agentId, msg.sender, tokenURI);
    }

    /// @notice 簡化註冊(僅 tokenURI)
    function register(string calldata tokenURI)
        external returns (uint256 agentId)
    {
        agentId = _nextTokenId++;
        _safeMint(msg.sender, agentId);
        _setTokenURI(agentId, tokenURI);
    }

    /// @notice 最簡註冊(無 URI)
    function register() external returns (uint256 agentId) {
        agentId = _nextTokenId++;
        _safeMint(msg.sender, agentId);
    }

    /// @notice 獲取鏈上元資料
    function getMetadata(uint256 agentId, bytes32 key)
        external view returns (bytes memory)
    {
        return _metadata[agentId][key];
    }

    /// @notice 設定鏈上元資料
    function setMetadata(uint256 agentId, bytes32 key, bytes calldata value)
        external
    {
        require(ownerOf(agentId) == msg.sender, "Not owner");
        _metadata[agentId][key] = value;
    }
}

3.2 Agent 註冊檔案格式

tokenURI 指向的 JSON 文件結構:

{
  "name": "Travel Booking Agent",
  "description": "AI agent for booking flights and hotels",
  "image": "ipfs://Qm.../agent-icon.png",

  "endpoints": {
    "a2a": "https://api.example.com/a2a",
    "mcp": "https://api.example.com/mcp",
    "ens": "travel-agent.eth",
    "did": "did:ethr:0x1234...",
    "wallet": "0x5678..."
  },

  "trustModels": {
    "reputation": {
      "enabled": true,
      "reputationRegistry": "0xabcd..."
    },
    "cryptoEconomic": {
      "enabled": true,
      "stakeContract": "0xefgh...",
      "minimumStake": "1000000000000000000"
    },
    "teeAttestation": {
      "enabled": false
    }
  },

  "capabilities": [
    {
      "name": "flight-search",
      "description": "Search for flights",
      "inputSchema": {...},
      "outputSchema": {...}
    },
    {
      "name": "hotel-booking",
      "description": "Book hotels",
      "inputSchema": {...},
      "outputSchema": {...}
    }
  ],

  "pricing": {
    "model": "per-request",
    "currency": "USDC",
    "amount": "0.01"
  }
}

3.3 身份發現流程

sequenceDiagram
    participant Crawler as 爬蟲服務
    participant IR as Identity Registry
    participant IPFS as IPFS/HTTPS
    participant Directory as Agent 目錄

    Crawler->>IR: 監聽 AgentRegistered 事件
    IR-->>Crawler: 新 Agent (agentId, tokenURI)

    Crawler->>IPFS: 獲取註冊檔案
    IPFS-->>Crawler: JSON 元資料

    Crawler->>Directory: 索引 Agent
    Note over Directory: 按能力、評分、價格分類

    Client[客戶端]->>Directory: 搜尋 "flight booking"
    Directory-->>Client: Agent 列表

4. Reputation Registry:聲譽系統

4.1 回饋提交機制

回饋需要 Agent 預先授權,使用 EIP-191 或 ERC-1271 簽名:

contract ReputationRegistry {
    struct Feedback {
        address client;
        uint8 score;           // 0-100
        bytes32 tag1;          // 分類標籤
        bytes32 tag2;          // 次要標籤
        string fileUri;        // 可選的鏈下詳情
        bytes32 fileHash;      // 檔案完整性雜湊
        uint256 timestamp;
        bool revoked;
    }

    mapping(uint256 => Feedback[]) private _feedbacks;

    event NewFeedback(
        uint256 indexed agentId,
        address indexed client,
        uint8 score,
        bytes32 tag1,
        bytes32 tag2
    );
    event FeedbackRevoked(uint256 indexed agentId, uint256 feedbackIndex);
    event ResponseAppended(uint256 indexed agentId, uint256 feedbackIndex);

    /// @notice 提交回饋
    /// @param agentId Agent ID
    /// @param score 評分 (0-100)
    /// @param tag1 主要分類標籤
    /// @param tag2 次要分類標籤
    /// @param fileUri 可選的鏈下詳情 URI
    /// @param fileHash 檔案完整性雜湊
    /// @param feedbackAuth Agent 預授權簽名
    function giveFeedback(
        uint256 agentId,
        uint8 score,
        bytes32 tag1,
        bytes32 tag2,
        string calldata fileUri,
        bytes32 fileHash,
        bytes memory feedbackAuth
    ) external {
        require(score <= 100, "Score must be 0-100");

        // 驗證 Agent 授權
        bytes32 messageHash = keccak256(abi.encodePacked(
            agentId, msg.sender, "feedback"
        ));
        require(
            _verifySignature(agentId, messageHash, feedbackAuth),
            "Invalid authorization"
        );

        _feedbacks[agentId].push(Feedback({
            client: msg.sender,
            score: score,
            tag1: tag1,
            tag2: tag2,
            fileUri: fileUri,
            fileHash: fileHash,
            timestamp: block.timestamp,
            revoked: false
        }));

        emit NewFeedback(agentId, msg.sender, score, tag1, tag2);
    }

    /// @notice 撤銷回饋
    function revokeFeedback(uint256 agentId, uint256 feedbackIndex) external {
        Feedback storage fb = _feedbacks[agentId][feedbackIndex];
        require(fb.client == msg.sender, "Not feedback owner");
        require(!fb.revoked, "Already revoked");

        fb.revoked = true;
        emit FeedbackRevoked(agentId, feedbackIndex);
    }

    /// @notice 追加回應(退款、標記垃圾等)
    function appendResponse(
        uint256 agentId,
        uint256 feedbackIndex,
        string calldata responseUri
    ) external {
        // 任何人都可以追加回應
        emit ResponseAppended(agentId, feedbackIndex);
    }
}

4.2 聲譽聚合

struct Summary {
    uint256 totalFeedbacks;
    uint256 averageScore;
    uint256 positiveFeedbacks;  // score >= 70
    uint256 negativeFeedbacks;  // score < 30
}

/// @notice 獲取聲譽摘要
/// @param agentId Agent ID
/// @param tag1 可選的標籤過濾
/// @param includeRevoked 是否包含已撤銷的回饋
function getSummary(
    uint256 agentId,
    bytes32 tag1,
    bool includeRevoked
) external view returns (Summary memory) {
    Feedback[] storage feedbacks = _feedbacks[agentId];

    uint256 count;
    uint256 totalScore;
    uint256 positive;
    uint256 negative;

    for (uint256 i = 0; i < feedbacks.length; i++) {
        Feedback storage fb = feedbacks[i];

        if (!includeRevoked && fb.revoked) continue;
        if (tag1 != bytes32(0) && fb.tag1 != tag1) continue;

        count++;
        totalScore += fb.score;

        if (fb.score >= 70) positive++;
        else if (fb.score < 30) negative++;
    }

    return Summary({
        totalFeedbacks: count,
        averageScore: count > 0 ? totalScore / count : 0,
        positiveFeedbacks: positive,
        negativeFeedbacks: negative
    });
}

4.3 回饋流程

sequenceDiagram
    participant Client as 客戶端
    participant Agent as Agent
    participant RR as Reputation Registry

    Client->>Agent: 請求服務
    Agent-->>Client: 提供服務 + feedbackAuth 簽名

    Client->>RR: giveFeedback(agentId, score, tags, feedbackAuth)
    RR->>RR: 驗證簽名
    RR-->>Client: 回饋已記錄

    Note over RR: 事件: NewFeedback

    alt 客戶端後悔
        Client->>RR: revokeFeedback(agentId, feedbackIndex)
        RR-->>Client: 回饋已撤銷
    end

    alt 有人追加回應
        Anyone->>RR: appendResponse(agentId, feedbackIndex, responseUri)
        Note over RR: 如:Agent 提供了退款證明
    end

5. Validation Registry:驗證機制

5.1 驗證請求與回應

contract ValidationRegistry {
    struct ValidationRequest {
        uint256 agentId;
        address requester;
        string requestUri;     // 輸入/輸出資料的 URI
        bytes32 requestHash;   // 資料完整性雜湊
        uint256 timestamp;
    }

    struct ValidationResponse {
        address validator;
        uint8 response;        // 0-100
        string responseUri;    // 驗證詳情 URI
        bytes32 responseHash;
        bytes32 tag;
        uint256 timestamp;
    }

    mapping(bytes32 => ValidationRequest) private _requests;
    mapping(bytes32 => ValidationResponse[]) private _responses;

    event ValidationRequest(
        bytes32 indexed requestHash,
        uint256 indexed agentId,
        address indexed requester
    );
    event ValidationResponse(
        bytes32 indexed requestHash,
        address indexed validator,
        uint8 response
    );

    /// @notice 請求驗證
    /// @param validatorAddress 指定的驗證者地址
    /// @param agentId Agent ID
    /// @param requestUri 包含輸入/輸出的 URI
    /// @param requestHash 資料雜湊
    function validationRequest(
        address validatorAddress,
        uint256 agentId,
        string calldata requestUri,
        bytes32 requestHash
    ) external {
        require(
            _isOwnerOrOperator(agentId, msg.sender),
            "Not authorized"
        );

        _requests[requestHash] = ValidationRequest({
            agentId: agentId,
            requester: msg.sender,
            requestUri: requestUri,
            requestHash: requestHash,
            timestamp: block.timestamp
        });

        emit ValidationRequest(requestHash, agentId, msg.sender);
    }

    /// @notice 提交驗證回應
    /// @param requestHash 請求雜湊
    /// @param response 驗證結果 (0-100)
    /// @param responseUri 驗證詳情 URI
    /// @param responseHash 回應資料雜湊
    /// @param tag 分類標籤
    function validationResponse(
        bytes32 requestHash,
        uint8 response,
        string calldata responseUri,
        bytes32 responseHash,
        bytes32 tag
    ) external {
        require(
            _requests[requestHash].agentId != 0,
            "Request not found"
        );

        _responses[requestHash].push(ValidationResponse({
            validator: msg.sender,
            response: response,
            responseUri: responseUri,
            responseHash: responseHash,
            tag: tag,
            timestamp: block.timestamp
        }));

        emit ValidationResponse(requestHash, msg.sender, response);
    }

    /// @notice 獲取驗證狀態
    function getValidationStatus(bytes32 requestHash)
        external view
        returns (ValidationRequest memory, ValidationResponse[] memory)
    {
        return (_requests[requestHash], _responses[requestHash]);
    }
}

5.2 驗證流程

sequenceDiagram
    participant Owner as Agent Owner
    participant VR as Validation Registry
    participant Validator as 驗證者
    participant Storage as 鏈下存儲

    Owner->>Storage: 上傳驗證資料 (輸入/輸出)
    Storage-->>Owner: requestUri

    Owner->>VR: validationRequest(validator, agentId, requestUri, hash)
    VR-->>Validator: 事件: ValidationRequest

    Validator->>Storage: 獲取驗證資料
    Validator->>Validator: 執行驗證協議

    alt 質押重新執行
        Validator->>Validator: 重新執行 Agent 邏輯
        Validator->>Validator: 比對輸出
    else zkML 驗證
        Validator->>Validator: 驗證零知識證明
    else TEE 驗證
        Validator->>Validator: 驗證 TEE 證明
    end

    Validator->>VR: validationResponse(requestHash, score, responseUri, hash, tag)
    VR-->>Owner: 事件: ValidationResponse

    Note over VR: 可能有多個 Validator 回應

5.3 驗證摘要

struct ValidationSummary {
    uint256 totalValidations;
    uint256 passedValidations;    // response >= 70
    uint256 failedValidations;    // response < 30
    uint256 averageResponse;
}

function getSummary(uint256 agentId)
    external view
    returns (ValidationSummary memory)
{
    // 聚合所有該 Agent 的驗證結果
    // ...
}

6. Agent 生命週期

6.1 完整生命週期

flowchart TB
    subgraph Registration["1. 註冊"]
        R1[準備元資料]
        R2[上傳註冊檔案]
        R3[調用 register()]
        R4[獲得 agentId]

        R1 --> R2 --> R3 --> R4
    end

    subgraph Discovery["2. 發現"]
        D1[爬蟲索引]
        D2[目錄搜尋]
        D3[客戶端選擇]

        D1 --> D2 --> D3
    end

    subgraph Interaction["3. 互動"]
        I1[客戶端請求]
        I2[Agent 處理]
        I3[返回結果]

        I1 --> I2 --> I3
    end

    subgraph Feedback["4. 回饋"]
        F1[簽發授權]
        F2[提交回饋]
        F3[聲譽更新]

        F1 --> F2 --> F3
    end

    subgraph Validation["5. 驗證 (可選)"]
        V1[請求驗證]
        V2[Validator 執行]
        V3[提交結果]

        V1 --> V2 --> V3
    end

    Registration --> Discovery
    Discovery --> Interaction
    Interaction --> Feedback
    Feedback --> Validation
    Validation --> Discovery

6.2 關鍵事件

// Identity Registry
event AgentRegistered(uint256 indexed agentId, address owner, string tokenURI);
event AgentTransferred(uint256 indexed agentId, address from, address to);
event MetadataUpdated(uint256 indexed agentId, bytes32 key);

// Reputation Registry
event NewFeedback(uint256 indexed agentId, address client, uint8 score, bytes32 tag1, bytes32 tag2);
event FeedbackRevoked(uint256 indexed agentId, uint256 feedbackIndex);
event ResponseAppended(uint256 indexed agentId, uint256 feedbackIndex);

// Validation Registry
event ValidationRequest(bytes32 indexed requestHash, uint256 indexed agentId, address requester);
event ValidationResponse(bytes32 indexed requestHash, address validator, uint8 response);

7. 信任模型分析

7.1 三種信任模型

flowchart TB
    subgraph Reputation["聲譽模型"]
        Rep1[客戶端回饋]
        Rep2[鏈上聚合]
        Rep3[評分排名]

        Rep1 --> Rep2 --> Rep3
    end

    subgraph CryptoEconomic["加密經濟模型"]
        CE1[Validator 質押]
        CE2[重新執行]
        CE3[結果比對]
        CE4[獎勵/懲罰]

        CE1 --> CE2 --> CE3 --> CE4
    end

    subgraph TEE["TEE 驗證模型"]
        TEE1[TEE 執行]
        TEE2[生成證明]
        TEE3[鏈上驗證]

        TEE1 --> TEE2 --> TEE3
    end

7.2 模型對比

模型優點缺點適用場景
聲譽簡單、低成本可能被操控一般服務
加密經濟經濟激勵對齊成本較高高價值任務
TEE硬體級保證硬體依賴隱私敏感任務

7.3 組合使用

Agent 可以同時啟用多種信任模型:

{
  "trustModels": {
    "reputation": {
      "enabled": true,
      "minimumScore": 70,
      "minimumFeedbacks": 10
    },
    "cryptoEconomic": {
      "enabled": true,
      "stakeContract": "0xabcd...",
      "minimumStake": "1 ETH"
    },
    "teeAttestation": {
      "enabled": true,
      "enclaveType": "SGX",
      "mrenclave": "0x1234..."
    }
  }
}

7.4 安全考量

威脅緩解措施
Sybil 攻擊回饋者聲譽系統
惡意回饋預授權簽名 + 撤銷機制
虛假驗證多 Validator + 質押懲罰
資料篡改內容定址(IPFS)+ 雜湊驗證

總結

ERC-8004 的創新

  1. 統一身份層

    • 基於 ERC-721 的全局識別符
    • 可擴展的鏈上元資料
  2. 可組合聲譽

    • 智能合約可直接讀取
    • 支援標籤過濾與聚合
  3. 靈活驗證

    • 支援多種驗證協議
    • 漸進式驗證狀態
  4. 模型可插拔

    • 聲譽、加密經濟、TEE 可組合
    • 適應不同信任需求

適用場景

場景說明
Agent 市場發現與選擇 Agent
跨組織協作無需預建信任
品質保證驗證 Agent 工作
聲譽建立累積可信度

關鍵介面

// Identity Registry
function register(string tokenURI) returns (uint256 agentId);
function getMetadata(uint256 agentId, bytes32 key) returns (bytes);

// Reputation Registry
function giveFeedback(uint256 agentId, uint8 score, ...) external;
function getSummary(uint256 agentId, ...) returns (Summary);

// Validation Registry
function validationRequest(address validator, uint256 agentId, ...) external;
function validationResponse(bytes32 requestHash, uint8 response, ...) external;

ERC-8004 為去中心化 AI Agent 生態系統提供了急需的發現與信任基礎設施,其模組化設計和多種信任模型支援使其能夠適應從簡單服務到高價值任務的各種場景。