ERC-4337 與 EIP-7702 完整比較:帳戶抽象的兩條路徑深度分析

ERC-4337 和 EIP-7702 是帳戶抽象領域兩個最重要的標準。雖然兩者的最終目標相似——讓以太坊帳戶更加智能和靈活——但它們採取了截然不同的實現路徑。ERC-4337 作為應用層標準,無需更改以太坊共識層,已被廣泛採用;EIP-7702 作為共識層升級,提供更原生的支持和更高的效率,正在開發中。本文深入比較這兩個標準的技術架構、優劣勢、適用場景。

ERC-4337 與 EIP-7702 完整比較:帳戶抽象的兩條路徑深度分析

概述

帳戶抽象(Account Abstraction)是以太坊改進用戶體驗的關鍵技術方向。在這個領域中,ERC-4337 和 EIP-7702 是兩個最重要的標準。雖然兩者的最終目標相似——讓以太坊帳戶更加智能和靈活——但它們採取了截然不同的實現路徑。

ERC-4337 作為應用層標準,無需更改以太坊共識層,已被廣泛採用;EIP-7702 作為共識層升級,提供更原生的支持和更高的效率,正在開發中。本文深入比較這兩個標準的技術架構、優劣勢、適用場景,並分析它們如何相互補充。

背景知識:什麼是帳戶抽象?

傳統以太坊帳戶的限制

以太坊傳統上有兩種帳戶類型:

外部擁有帳戶(EOA)

合約帳戶(CA)

EOA 是以太坊最基礎的帳戶類型,但存在諸多限制:

帳戶抽象的願景

帳戶抽象的目標是:

ERC-4337 深度解析

架構設計

ERC-4337 採用「應用層優先」的策略,不修改以太坊共識層,而是通過智能合約實現帳戶抽象。

核心組件

┌─────────────────────────────────────────────────────────────┐
│                        用戶(User)                          │
│  ┌─────────────────────────────────────────────────────┐  │
│  │              UserOperation(用戶操作)                │  │
│  │  - 發送者地址                                        │  │
│  │  - nonce                                            │  │
│  │  - 初始化代碼(首次部署)                             │  │
│  │  - 調用數據                                          │  │
│  │  - Gas 限制                                          │  │
│  │  │ - 驗證 Gas                                        │  │
│  │  │ - 執行 Gas                                        │  │
│  │  │ - 預付金 Gas                                      │  │
│  │  - 受益人地址                                        │  │
│  │  - 簽名數據                                          │  │
│  └─────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                    Entry Point(入口合約)                   │
│                                                              │
│  1. 驗證 UserOperation                                      │
│  2. 扣取 Gas 費用                                          │
│  3. 調用帳戶合約                                            │
│  4. 處理錯誤和退款                                          │
│                                                              │
│  地址:0x5FF137D4b0FD9CDe4383A0a2d4E4D0f5D5a8f5F3          │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                  Account Contract(帳戶合約)               │
│                                                              │
│  ┌─────────────────────────────────────────────────────┐  │
│  │  validateUserOp()                                    │  │
│  │  - 驗證簽名                                           │  │
│  │  - 驗證 nonce                                         │  │
│  │  - 確認 Gas 支付                                      │  │
│  └─────────────────────────────────────────────────────┘  │
│  ┌─────────────────────────────────────────────────────┐  │
│  │  execute()                                            │  │
│  │  - 執行用戶請求的操作                                  │  │
│  │  - 批量處理多個調用                                    │  │
│  └─────────────────────────────────────────────────────┘  │
│  ┌─────────────────────────────────────────────────────┐  │
│  │  額外功能(可選)                                      │  │
│  │  - 社交恢復                                           │  │
│  │  - 支出限額                                           │  │
│  │  - 多重簽名                                           │  │
│  │  - 角色權限                                           │  │
│  └─────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                    Bundler(捆綁器)                        │
│                                                              │
│  - 收集多個 UserOperation                                   │
│  - 打包成單筆交易                                           │
│  - 提交到 Entry Point                                       │
│  - 承擔 Gas 費用預付                                       │
└─────────────────────────────────────────────────────────────┘

關鍵合約

Entry Point 合約

Entry Point 是 ERC-4337 的核心智能合約,負責處理用戶操作的驗證和執行:

// Entry Point 合約核心接口
interface IEntryPoint {
    // 處理用戶操作
    function handleOps(
        UserOperation[] calldata ops,
        address payable beneficiary
    ) external;

    // 模擬驗證(用於錢包介面)
    function simulateValidation(
        UserOperation calldata userOp
    ) external returns (
        uint256 validationData,
        uint256 deadline
    );

    // 獲取帳戶 nonce
    function getNonce(address sender, uint192 key) external view returns (uint256);
}

// 實際 Entry Point 合約的部分實現
contract EntryPoint is IEntryPoint {
    // 用戶操作結構
    struct UserOperation {
        address sender;
        uint256 nonce;
        bytes initCode;
        bytes callData;
        uint256 callGasLimit;
        uint256 verificationGasLimit;
        uint256 preVerificationGas;
        address paymaster;
        bytes paymasterData;
        bytes signature;
    }

    // 處理用戶操作
    function handleOps(
        UserOperation[] calldata ops,
        address payable beneficiary
    ) external override {
        uint256 opsLen = ops.length;
        unchecked {
            for (uint256 i = 0; i < opsLen; i++) {
                _handleOp(ops[i], beneficiary);
            }
        }
    }

    function _handleOp(
        UserOperation calldata op,
        address payable beneficiary
    ) internal {
        // 1. 獲取帳戶合約
        address account = op.sender;

        // 2. 驗證階段
        try 
            // 調用帳戶的驗證函數
            account.call(
                abi.encodeWithSelector(
                    IAccount.validateUserOp.selector,
                    op,
                    entryPointInfo[account].nonce,
                    0  // missing funds
                )
            )
        returns (uint256 validationData) {
            // 驗證成功
            // 檢查驗證結果
            if (validationData != 0) {
                // 處理不同的驗證結果
                _validateSignature(op, account);
            }
        }

        // 3. 執行階段
        // ... 執行用戶的調用數據
    }
}

帳戶合約接口

每個 ERC-4337 帳戶需要實現以下接口:

interface IAccount {
    // 驗證用戶操作
    function validateUserOp(
        UserOperation calldata userOp,
        uint256 requiredPrefund
    ) external returns (uint256 validationData);

    // 執行用戶操作
    function execute(
        bytes calldata dest,
        uint256 value,
        bytes calldata func
    ) external;

    // 執行批量操作
    function executeBatch(
        bytes[] calldata calls
    ) external;
}

完整錢包合約示例

以下是一個完整的 ERC-4337 錢包合約實現:

// ERC-4337 智能合約錢包
contract ERC4337Wallet is IAccount, IERC165 {
    using ECDSA for bytes32;
    using SafeERC20 for IERC20;

    // 帳戶所有者
    address public owner;

    // Nonce 管理
    mapping(uint256 => uint256) public nonceMap;
    uint256 public nonce;

    // 入口點地址
    IEntryPoint public immutable entryPoint;

    // 事件
    event Executed(
        address indexed target,
        uint256 value,
        bytes data,
        bytes result
    );

    // 修飾符:僅入口點
    modifier onlyEntryPoint() {
        require(msg.sender == address(entryPoint), "Only EntryPoint");
        _;
    }

    constructor(IEntryPoint _entryPoint, address _owner) {
        owner = _owner;
        entryPoint = _entryPoint;
    }

    // 實現 IERC165
    function supportsInterface(bytes4 interfaceId) 
        external 
        pure 
        returns (bool) 
    {
        return interfaceId == type(IAccount).interfaceId ||
               interfaceId == type(IERC4337Wallet).interfaceId;
    }

    // 驗證用戶操作(入口點調用)
    function validateUserOp(
        UserOperation calldata userOp,
        uint256 requiredPrefund
    ) external onlyEntryPoint returns (uint256) {
        // 解析簽名
        bytes32 hash = userOp.hash();
        bytes32 signedHash = hash.toEthSignedMessageHash();

        // 驗證簽名
        address signer = signedHash.recover(userOp.signature);
        require(signer == owner, "Invalid signature");

        // 驗證 nonce
        // (這裡可以添加更複雜的 nonce 管理邏輯)

        // 如果需要預付費用,檢查餘額
        if (requiredPrefund > 0) {
            require(address(this).balance >= requiredPrefund, "Insufficient balance");
        }

        // 返回驗證成功的 marker
        return 0;
    }

    // 執行單個調用
    function execute(
        address dest,
        uint256 value,
        bytes calldata func
    ) external onlyEntryPoint {
        _call(dest, value, func);
    }

    // 執行批量調用
    function executeBatch(
        Call[] calldata calls
    ) external onlyEntryPoint {
        for (uint256 i = 0; i < calls.length; i++) {
            _call(calls[i].to, calls[i].value, calls[i].data);
        }
    }

    // 內部調用函數
    function _call(
        address target,
        uint256 value,
        bytes memory data
    ) internal {
        (bool success, bytes memory result) = target.call{value: value}(data);
        if (!success) {
            assembly {
                revert(add(result, 32), mload(result))
            }
        }
        emit Executed(target, value, data, result);
    }

    // 社交恢復功能
    mapping(address => address[]) public guardians;
    mapping(address => uint256) public guardianCount;

    function addGuardian(address guardian) external {
        require(msg.sender == owner, "Not owner");
        guardians[owner].push(guardian);
        guardianCount[owner]++;
    }

    function recover(
        address newOwner,
        GuardianSignature[] calldata signatures
    ) external {
        // 驗證足夠的監護人簽名
        uint256 validSigs = 0;
        for (uint256 i = 0; i < signatures.length; i++) {
            if (verifyGuardianSignature(
                msg.sender, 
                signatures[i].signer, 
                signatures[i].signature
            )) {
                validSigs++;
            }
        }

        require(validSigs > guardianCount[msg.sender] / 2, "Not enough signatures");
        owner = newOwner;
    }

    // 接收 ETH
    receive() external payable {}
}

優勢

  1. 無需共識層更改:ERC-4337 完全在應用層實現,不需要以太坊升級
  2. 向後兼容:現有 EOA 可以繼續使用
  3. 完全靈活:可以實現任何自定義邏輯
  4. 快速部署:已經在多條鏈上可用
  5. 成熟的生態:有錢包、工具、SDK 支持

劣勢

  1. Gas 效率較低:每次操作都需要通過 Entry Point
  2. 額外成本:需要部署智能合約錢包
  3. 依賴 Bundler:需要依賴第三方的 Bundler 服務
  4. 複雜度:比傳統 EOA 交易更複雜

代表項目

EIP-7702 深度解析

設計理念

EIP-7702 採用「共識層優先」的策略,通過修改以太坊共識層來實現帳戶抽象。其核心思想是讓 EOA 臨時獲得合約帳戶的功能。

核心機制

基本原理

  1. 用戶簽名授權一個合約
  2. 合約成為該 EOA 的「代理」
  3. 在特定交易中,合約可以代表用戶執行
  4. 交易結束後,代理關係清除

技術實現

新的交易類型

EIP-7702 引入新的交易類型:

// EIP-7702 交易類型
struct Transaction {
    uint256 chain_id;
    uint256 nonce;
    uint256 max_priority_fee_per_gas;
    uint256 max_fee_per_gas;
    uint256 gas_limit;
    address to;
    uint256 value;
    bytes data;

    // EIP-7702 新增欄位
    address auth_contract_address;  // 授權合約地址
    bytes auth_data;                 // 授權數據
    bytes signature;                 // 用戶簽名
}

授權合約示例

// EIP-7702 授權合約示例
contract EIP7702Auth {
    // 授權映射
    mapping(address => Authorization) public authorizations;

    // 授權結構
    struct Authorization {
        address contractAddress;
        uint256 nonce;
        uint64 validAfter;
        uint64 validBefore;
        bool isAuthorized;
    }

    // 設置授權
    function setAuthorization(
        address user,
        address _contractAddress,
        uint256 _nonce,
        uint64 _validAfter,
        uint64 _validBefore,
        bytes calldata signature
    ) external {
        // 驗證用戶簽名
        bytes32 hash = keccak256(abi.encodePacked(
            user,
            _contractAddress,
            _nonce,
            _validAfter,
            _validBefore,
            block.chainid
        ));

        // 驗證簽名來自用戶
        require(
            ecrecover(hash, signature.v, signature.r, signature.s) == user,
            "Invalid signature"
        );

        // 設置授權
        authorizations[user] = Authorization({
            contractAddress: _contractAddress,
            nonce: _nonce,
            validAfter: _validAfter,
            validBefore: _validBefore,
            isAuthorized: true
        });
    }

    // 執行授權操作
    function executeAsUser(
        address user,
        address to,
        uint256 value,
        bytes calldata data,
        bytes calldata signature
    ) external {
        Authorization storage auth = authorizations[user];
        
        // 驗證授權
        require(auth.isAuthorized, "Not authorized");
        require(block.timestamp >= auth.validAfter, "Not valid yet");
        require(block.timestamp < auth.validBefore, "Expired");

        // 驗證簽名
        bytes32 hash = keccak256(abi.encodePacked(
            user,
            to,
            value,
            data,
            auth.nonce,
            block.chainid
        ));

        require(
            ecrecover(hash, signature.v, signature.r, signature.s) == msg.sender,
            "Invalid signature"
        );

        // 增加 nonce
        auth.nonce++;

        // 執行調用
        (bool success, ) = to.call{value: value}(data);
        require(success);
    }
}

優勢

  1. 原生支持:作為共識層升級,獲得更好的原生支持
  2. Gas 效率更高:不需要通過 Entry Point
  3. 無需預部署:用戶不需要預先部署錢包合約
  4. 更安全的設計:臨時授權,攻擊面更小

劣勢

  1. 需要共識層升級:需要等待以太坊升級
  2. 生態系統需要適配:錢包和 DApp 需要升級支持
  3. 兼容性問題:舊合約可能不完全兼容
  4. 時間不確定:升級時間取決於開發進度

詳細比較

技術架構比較

特性ERC-4337EIP-7702
實現層應用層(智能合約)共識層(協議升級)
部署成本需要部署智能合約臨時設定合約代碼
交易驗證Entry Point 合約原生 AUTH 操作碼
Gas 效率較低(多一次調用)較高(原生支持)
隱私需要 Bundler直接提交交易

功能特性比較

特性ERC-4337EIP-7702
社交恢復原生支持需要自定義合約
批量交易原生支持需要自定義合約
權限管理靈活自定義需要自定義合約
簽名驗證可自定義固定格式
多重簽名可實現可實現
支出限額可實現可實現

用戶體驗比較

ERC-4337 用戶體驗

首次使用:
1. 部署智能合約錢包
2. 支付部署 Gas
3. 存款到錢包

後續使用:
1. 創建 UserOperation
2. Bundler 收集操作
3. 提交到 Entry Point
4. 等待確認

EIP-7702 用戶體驗

首次使用:
1. 選擇授權合約
2. 設定授權
3. 開始使用

後續使用:
1. 選擇授權合約(可緩存)
2. 提交交易
3. 等待確認

成本比較

Gas 成本估算(2026 年數據):

操作ERC-4337EIP-7702
部署錢包~150,000 Gas不需要
簡單轉帳~50,000 Gas~21,000 Gas
批量轉帳(5筆)~80,000 Gas~40,000 Gas
社交恢復~100,000 Gas~80,000 Gas

安全性比較

特性ERC-4337EIP-7702
攻擊面智能合約漏洞授權合約漏洞
重放保護Nonce + Entry PointNonce + Chain ID
盜竊風險智能合約被攻擊授權被濫用
恢復機制社交恢復取決於合約設計

實際應用場景

場景 1:簡單的日常支付

使用 ERC-4337

使用 EIP-7702

建議:對於日常支付,EIP-7702 更具成本優勢

場景 2:高安全性資產管理

使用 ERC-4337

使用 EIP-7702

建議:對於高安全性場景,ERC-4337 有更成熟的解決方案

場景 3:社交恢復錢包

使用 ERC-4337

使用 EIP-7702

建議:ERC-4337 有更多現成的社交恢復錢包選擇

場景 4:DeFi 交易

使用 ERC-4337

使用 EIP-7702

建議:ERC-4337 目前在 DeFi 中應用更廣泛

共存與互補

技術互補

兩種標準可以共存並相互補充:

錢包可以同時支持兩種標準:

contract UnifiedWallet {
    // ERC-4337 接口
    function validateUserOp(UserOperation calldata op) external {
        // ERC-4337 驗證邏輯
    }

    // EIP-7702 處理
    function execute() internal {
        if (isEIP7702Mode()) {
            // EIP-7702 執行邏輯
        } else {
            // 標準執行邏輯
        }
    }
}

生態演進

短期(2025-2026)

中期(2026-2027)

長期(2027+)

選擇指南

選擇 ERC-4337 的情況

選擇 EIP-7702 的情況

混合策略

最佳策略可能是同時支持兩種標準:

// 混合錢包合約
contract HybridWallet {
    // ERC-4337 模式
    function validateUserOp(UserOperation calldata op) external returns (uint256) {
        // ERC-4337 驗證
    }

    // EIP-7702 模式
    function executeWithAuth(
        bytes calldata authData,
        bytes calldata signature
    ) external {
        // EIP-7702 執行
    }

    // 自動檢測使用哪種模式
    function execute(bytes calldata data) external {
        if (msg.sender == address(entryPoint)) {
            // ERC-4337 模式
        } else {
            // EIP-7702 模式
        }
    }
}

結論

ERC-4337 和 EIP-7702 代表了帳戶抽象的兩條不同路徑,各有其優勢和適用場景。

ERC-4337 已經成熟並被廣泛採用,提供了完整的錢包解決方案。其應用層實現使其可以快速部署,並且已經建立了完善的生態系統。對於需要立即使用社交恢復、批量交易等功能的用戶,ERC-4337 是更好的選擇。

EIP-7702 提供了更原生的支持、更低的 Gas 成本和更安全的設計。雖然需要等待共識層升級,但其長期潛力巨大。對於對成本敏感、需要最高效解決方案的應用,EIP-7702 可能是更好的選擇。

最終,這兩個標準可能會趨向融合,形成一個更加統一和強大的帳戶抽象解決方案。在這個過渡期間,錢包和 DApp 應該考慮支持兩種標準,為用戶提供最大的靈活性。


參考資源

  1. ERC-4337: https://eips.ethereum.org/EIPS/eip-4337
  2. EIP-7702: https://eips.ethereum.org/EIPS/eip-7702
  3. Ethereum Foundation. "Account Abstraction." ethereum.org
  4. https://www.erc4337.io/
  5. https://github.com/ethereum/ERCs/blob/master/ERCS/erc-4337.md

延伸閱讀與來源

這篇文章對您有幫助嗎?

評論

發表評論

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

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