原文標題:《EIP-4337 詳細工作流程》
原文作者:Ben Law
EIP-4337 詳細工作流程
本文不會從頭介紹EIP-4337,僅介紹4337 的主要合約是如何實現的。適合對4337 有一定了解的開發者,由其是錢包開發者,以及愛好者或研究員閱讀。
主要內容位於流程圖中:
需要配合4337 源碼閱讀GitHub—eth-infinitism/account-abstraction at main。
4337 Spec 中有更多詳細細節EIP-4337: Account Abstraction using alt mempool。
請注意:
-
本流程圖只畫出了普通類型的交易,未涉及Aggregator。掌握普通流程後才方便掌握聚合型的交易。
-
流程圖中箭頭不代表程序的調用棧或輸入輸出,僅代表相關角色、函數、事件的發生的先後順序。
-
為方便讀者對宏觀架構的快速理解,流程圖中省略了一部分函數調用和邏輯。被省略的部分有可能對你研究的問題或疑惑有很大意義,具體看你想了解什麼內容,所以還是需要你必要時仔細閱讀源碼。
核心概念
研究4337 需要掌握以下核心概念:
UserOperation 的內容EntryPoint 實現Wallet 實現Paymaster 實現驗證階段、執行階段的執行流程與錯誤處理Gas 的支付流程與計算
UserOperation
一種內容類似transaction 的偽交易對象,通過新的RPC 方法eth_sendUserOperation 提交給節點。
UO 中的字段含義大部分是顯然的,僅挑選幾個容易誤解的進行分析:
sender,此處指的是要交互的wallet,而非msg.sender 或tx.origin 等其他任何概念verificationGasLimit,驗證交易時的gasLimitcallGasLimit,執行交易時的gasLimitpreVerificationGas,補償bundler 調用handleOps () 時會一部分未計算在內的gas 成本(如提交交易的calldata 成本)。
Prefund
這個並非UO 中的一個字段,而是由上面三個gas 參數計算而出。代表了該UO 在驗證階段預先支付給EntryPoint 的總成本。 Prefund 雖然是在驗證階段支付的,但包含了preVerificationGas,驗證和執行三部分的成本。之後不會再向EntryPoint 進行支付gas。
具體計算參見EntryPoint 中的_getRequiredPrefund。
EntryPoint
EntryPoint 是所有功能的核心入口。每個項目自行部署自己的EntryPoint。 Bundler,Wallet 和Paymaster 都需要圍繞EntryPoint 工作。
Bundler 在EntryPoint 內實現兩個功能
鏈下驗證UO,剔除不符合要求和有問題的UO。鏈下驗證一是防止DoS,二是避免bundler 在鏈上損失gas。
打包合規的UO,提交上鍊。
Wallet 與EntryPoint
向EntryPoint 支付gas 費
只響應來自EntryPoint 的消息
執行來自EntryPoint 的具體交易內容
注意,EntryPoint 不是Wallet 的factory。官方給出的圖片容易給人造成這種誤解,但官方實現並非如此。
Paymaster 與EntryPoint
向EntryPoint 支付gas 費
只響應來自EntryPoint 的消息
向EntryPoint 確認自己的為某UO 服務的意願
在EntryPoint 內質押才能成為paymaster
我們可以看到Wallet 與Paymaster 都有可能向EntryPoint 支付gas。 gas 餘額會存儲在deposits 這個mapping 中。
注意,雖然deposits 字面意思為充值,但並非必須一個需要預先手動完成的動作,也可以在每一筆UO 發生時,計算缺少多少gas 並自動充值。
最終,若所有操作的actualGasCost 小於prefund, EntryPoint 會將多餘額度退款至你的deposit。
注意, validationActualCost & callActualCost 僅僅是為了說明而作的標記,並非真實存在的變量。它們是由gasPrice() 累加的。
Wallet
代表用戶最終使用的錢包。需要開發者至少實現以下兩個自定義方法:
簽名驗證:你可以使用任何密碼學手段來實現簽名驗證,比如,為了配合使用蘋果的Security Enclave 而實現NIST P-256 的ECDSA。如果沒有特殊需求可直接使用以太坊的ECDSA。
處理交易:EntryPoint 通過address (sender).call (callData) 來調用wallet 中的具體的交易功能。那麼call 需要有至少一個可執行的函數,如transferEther (),callAnotherContrat () 等。
開發者還需要自行實現wallet factory,需要創建錢包時,工廠會被SenderCreator 合約調用。新建錢包應使用CREATE2 方法以保障生成地址的確定性。
Paymaster
Paymaster 可以為用戶支付gas,因此可以實現:
免費交易:用戶激勵,讓用戶免費使用錢包
gasless 交易:不直接用ether 支付gas,而使用其他token 或nft 等
等等其他類似的讚助交易功能
Paymaster 需要開發者實現:
validatePaymasterUserOp ():由於paymaster 的開放性,驗證邏輯需要開發者完全自己定義。驗證後有可能需要實現類似wallet 中payPrefund () 的功能。
postOp:必須重寫此方法,否則會被revert。此方法可以定義在paymaster 贊助完交易後需要做什麼,如在驗證時為用戶支付了ether,則此處要求用戶支付等價的ERC-20。