帳戶抽象化 第4部分:聚合簽章
聚合簽章
我們目前的實作方式,是分別驗證 bundle 中的每一筆 user op。這樣理解驗證流程雖然很直觀,但可能造成浪費。因為驗證簽章需要相當多的密碼學運算,就 gas 而言可能相當昂貴。
如果能同時驗證多筆 op,只用一個簽章而不是多個,豈不是更好?
要做到這點,需要用到密碼學中的一個概念:聚合簽章(aggregate signatures)。
支援聚合的簽章方案提供了一種方法:給定多筆以不同金鑰簽署的訊息,可以產生一個組合簽章,只要驗證這個組合簽章有效,就代表其中每一個組成簽章也都有效。
支援聚合的簽章方案中,常見的例子是 BLS。
這項最佳化對於實作 rollup 特別有用,因為 rollup 的主要目標就是資料壓縮,而簽章聚合可以讓我們壓縮簽章的部分。
關於簽章聚合能節省多少空間,可參考 Vitalik 針對此主題發的推文。
介紹 aggregator
一開始就能看出,並非 bundle 中所有 user op 的簽章都能聚合在一起。別忘了,wallet 可以使用任意邏輯來驗證它拿到的簽章,因此同一個 bundle 中可能存在多種不同的簽章方案。
由於不同方案的簽章通常無法互相聚合,我們的 bundle 最終會分成好幾組 op,每組使用一種特定的聚合方案,或完全不使用聚合。
由於鏈上需要呈現多種聚合方案,每種都有自己的邏輯,我們會用一個合約來代表每種聚合方案,稱之為 aggregator。
一種聚合方案的定義,取決於它如何將多個簽章組合成一個,以及它如何驗證這個組合簽章,因此 aggregator 會以方法的形式,公開這兩個功能:

由於每個 wallet 都在定義自己的簽章方案,因此要不要相容某個 aggregator(如果有的話),由每個 wallet 自行決定。
如果一個 wallet 想要參與聚合,它會公開一個方法來選擇自己的 aggregator:
透過這個新的 getAggregator 方法,bundler 可以把使用相同 aggregator 的 op 分成一組,並使用該 aggregator 的 aggregateSignatures 方法,為它們計算出一個組合簽章。
一個分組可能長這樣:
💡 如果 bundler 對某個特定 aggregator 有鏈下的了解,它可以進行最佳化,直接寫死一份原生版本的簽章聚合演算法,而不是把 aggregateSignatures 當作 EVM 程式碼來執行。
接下來,我們需要更新 entry point 合約,讓它能使用這些新的 aggregator。
回想一下,entry point 有一個 handleOps 方法,接收一份 op 清單。
我們會給它一個新方法, handleAggregatedOps,做的事情一樣,但接收的是依 aggregator 分組後的 op:
新方法 handleAggregatedOps 的運作方式大致上和 handleOps 相同,唯一的差別在於驗證步驟。
handleOps 是透過呼叫每個 wallet 的 validateOp 方法來執行驗證,而 handleAggregatedOps 則改為針對每組的組合簽章,呼叫該組 aggregator 的 validateSignatures 方法。

我們幾乎完成了!
但到這裡有一個大家已經很熟悉的問題。
bundler 想要在把一組 op 放進 bundle 之前,先模擬驗證流程,確認該 aggregator 會驗證通過這組 op,因為如果驗證失敗,bundler 就得自己付 gas。但一個邏輯任意的 aggregator,很容易在模擬時成功、卻在實際執行時失敗。
我們會用和 paymaster 與 factory 完全相同的方式來解決這個問題:限制 aggregator 能存取的儲存空間以及能使用的 opcode,並且除非它不存取儲存空間,否則要求它在 entry point 中質押 ETH。
聚合簽章的部分到此結束!
總結
到目前為止我們建立的,大致上就是 ERC-4337 的完整架構!雖然細節上有些差異,例如部分方法的名稱與參數,但已經沒有任何我會稱之為「架構上的差異」的東西了。如果我做得夠好,你現在應該能夠閱讀真正的 ERC-4337,並理解裡面在講什麼。
如果你讀到這裡,非常謝謝你讀完我的說明!希望這篇文章對你的幫助,就像寫作過程對我的幫助一樣大。
附錄:與 ERC-4337 的差異
雖然我們已經掌握了帳戶抽象化的整體架構,但 ERC-4337 背後那些聰明人,想出了一些和上面描述略有不同的做法。
我們來看看其中幾個!
1. 驗證的時間範圍
前面提到 wallet 的 validateOp 以及 paymaster 的 validatePaymasterOp 的回傳型別時,說得相當含糊。ERC-4337 找到了一個很好的方式來運用這一點。
wallet 很希望能做到的一件事,是只讓某個 user op 在一段特定時間內有效。否則,惡意的 bundler 可能會把這個 operation 壓著很久,然後在對自己有利的時間點,晚點才把它放進 bundle。
wallet 可能想在驗證時檢查 TIMESTAMP,確保時間不會太過未來,但它做不到,因為我們已經禁止在驗證期間使用 TIMESTAMP,以避免模擬結果失真。這代表 wallet 需要另一種方式,來表示這個 operation 在什麼時間範圍內有效。
因此,ERC-4337 讓 validateOp 有一個回傳值,讓 wallet 可以用來選擇一個時間範圍:
這個回傳值以兩個相連的 8 位元組整數,來表示該 operation 有效的時間範圍。
另外還有一點來自 ERC-4337:在驗證失敗的情況下,wallet 應該從 validateOp 回傳一個哨兵值(sentinel value),而不是直接 revert,這有助於 gas 估算,因為 eth_estimateGas 無法告訴你一筆 revert 的交易實際用了多少 gas。
2. wallet 與 factory 的任意呼叫資料
我們前面說過,wallet 的介面是:
在 ERC-4337 中,wallet 實際上並沒有一個叫做 executeOp 的方法。
取而代之的是,user operation 有一個 callData 欄位:
這會以呼叫資料的形式傳給 wallet。
對於一般的智慧合約來說,這份資料的前四個位元組會被解讀為函式選擇器(function selector),其餘部分則是函式參數。
這代表除了必要的 validateOp 方法之外,wallet 可以自行定義自己的介面,而 user operation 可以用來呼叫 wallet 上任意的方法。
同樣地,在 ERC-4337 中,factory 合約實際上也沒有 deployContract 方法。它們同樣接收任意的呼叫資料,這裡是來自 op 的 initCode 欄位。
3. paymaster 與 factory 的精簡資料
前面我們提到,user operation 包含用來指定 paymaster 的欄位,以及要傳給它的資料欄位:
在 ERC-4337 中,這兩者被合併成一個欄位,作為一種最佳化:該欄位的前 20 個位元組是 paymaster 位址,其餘部分則是資料:
factory 以及傳給它的資料也是同樣的情況:雖然我們用了 factory 和 factoryData 這兩個欄位,但 ERC-4337 把它們合併成單一欄位 initCode。
好,你做到了!
希望你對帳戶抽象化學到了很多東西。
你也可能發明帳戶抽象化
錯過這系列共四篇文章的開頭了嗎?回去從頭讀起吧!
相關總覽
錢包2026年9月2日
代理錢包:AI 代理的工作階段與權限模型
AI 代理如何在不持有私鑰的情況下,取得範圍受限、可撤銷的錢包存取權限:工作階段、委派簽署與即時撤銷。
錢包2026年7月29日
別再把私鑰貼進 Cursor:如何為你的 coding agent 建立錢包
為你的 coding agent 建立錢包,但不用把私鑰交給它。了解 Alchemy CLI agent wallets 如何透過限定範圍的 session,讓 agent 在 .env 中沒有私鑰的情況下完成交易。
錢包2026年6月24日
什麼是加密貨幣 Bundler?
加密貨幣 Bundler 會將多筆交易或操作合併為一次鏈上提交,涵蓋批次處理、MEV、rollups、代幣發行與帳戶抽象化等場景。

打造區塊鏈魔法
Alchemy 結合最強大的 Web3 開發者產品與工具,並提供資源、社群與卓越的支援。