作者:Nic @ imToken Labs
校對:Members at imToken Labs
封面說明:Mushroom for EOAs! by Geeky Shots on Unsplash
目標讀者:區塊鏈開發者
先備知識:
知道 EOA 與合約的不同
了解 EVM 與合約的執行過程
EIP-3074 讓 EOA 能將控制權交給指定的合約,藉此獲得和合約一樣豐富的執行能力。在 EIP-3074 以前,EOA 每次送出交易就只能做一個操作,例如去 approve ERC20 或是去 Uniswap 兌換;在 EIP-3074 以後,EOA 可以一次完成多個操作,或甚至出現以前無法想像的用途。簡而言之,EIP-3074 讓使用體驗大幅提升,目前熟悉的代幣授權方式也將被重塑,在維持使用體驗不變的前提下提升安全性。
而且透過 EIP-3074,EOA 可以不必再自己送交易上鏈,也就不需要煩惱要先籌出 ETH 來支付交易手續費的問題。
能夠獲得 EOA 控制權的合約稱為 Invoker 合約。當然不是任意的合約都能獲得 EOA 的控制權:EOA 要用私鑰簽名,簽名內容會明確指定是哪個 Invoker 合約,以及允許 Invoker 執行的操作。
實際執行流程大概會長這樣:
Alice 用她的 EOA 私鑰簽名,然後將簽名內容及簽章交給 Relayer
Relayer 帶上鏈到 Invoker 合約執行
Invoker 驗證簽章,驗證通過後就能以 EOA 的身份去執行操作,例如去 approve USDC,然後去 Uniswap 兌換,最後再轉一些 USDC 給 Relayer 作為手續費
註 1:Relayer 為非必要,Alice 也可以自己帶簽名內容和簽章上鏈。
不過要注意,執行完並不會增加該 EOA 的 nonce 值,所以同一個簽名有可能可以重複使用(只要 EOA nonce 不變),因此 Invoker 需要自己實作一套 nonce 機制來避免重放。
關於 EIP-3074 實際的運作機制介紹可以參考:EIP3074 簡介
讓使用者把原本該分為好幾筆交易的執行合併為一筆,省下多次授權簽名的過程以及一些 Gas 成本。
註:這會需要 dApp 也支援 Batchcall 的功能,像是目前社群正在推的 EIP-5792,否則 dApp 把使用者當普通 EOA 的話一樣只會每個操作都 prompt 一次交易給使用者簽名。
使用者也可以讓第三方在有條件限制下替他代為操作,如下圖中的 delegate key
就是被授權的第三方;access policy
則是執行的限制條件,例如限制只能去操作 Uniswap、每天最多轉走 1 ETH、授權有效期限等等。這些條件都是在 Invoker 合約內設計並檢查,只要檢查能通過,第三方就能以使用者 EOA 身份去執行操作。
只要條件滿足(也就是 Permit 簽章合法),就能以授權人 EOA 身份去執行 ETH 轉帳,達成原生 ETH Permit 的效果。
使用者填好限價單條件,等到條件滿足就能以使用者 EOA 身份去執行,包含 approve 代幣給 DEX、去 DEX 兌換等等操作。和 DEX 本身提供的 Limit Order 相比,使用者不需事先送交易去 approve 給 DEX。
把條件設計得更通用的話,就會變成像是一個 Intent 合約:只要使用者指定的條件被滿足,任何人都能以他的 EOA 身份去執行完成意圖。
讓使用者遺失 EOA 私鑰時,能藉由當初她(Alice)簽好的 EIP-3074 授權,搭配她授權的人(Husband 及 Trust Agent)的簽名來將該 EOA 的資產全部轉走。實際上 Recover 的是(可轉移的)資產,不是賬戶控制權。EOA 私鑰遺失後該 EOA 就無法再使用了。
dApp 目前都是以使用者是 EOA 的假設去設計的:使用者必須「事先 approve」且要「approve 足夠大的金額」給 dApp 合約,如此使用者才不需要隨時保持在線、等待 dApp 執行,以及不需要不斷重複 approve,這對使用體驗有很大的提升。例如條件觸發的應用像是限價單或是 DCA,使用者不一定會在條件符合時在線上,所以要事前先 approve 夠大的金額讓 dApp 合約去執行,而且可能是重複執行。
或是後來出現的 permit 模式,例如 代幣原生的 EIP-2612 或是 非原生的 Permit2,都是為了改善 approve 模式的使用體驗及安全性:使用者不需再 approve 很大的金額給各個 dApp 合約(而且每個代幣都要 approve 一次),而是只需「簽一個名」就可以授權 dApp 合約在「指定時間」內「提取指定金額」,如此不僅大大限縮了攻擊面,也大大提升了使用體驗。
但事實上,不只是 approve,permit 模式被利用作為詐騙攻擊手段的事件仍然層出不窮(1、2、3):受害者誤簽了以為是要給 dApp 用的 permit 但實際上是給了攻擊者。
註:另外目前的 permit 設計並不兼容重複性操作的 dApp,例如 DCA 或其他定期支付應用。這是因為 permit 有防重放機制,所以轉帳完一次之後就無法再用同一個 permit,等於是使用者要先為未來每一次重複性操作都預先簽好 permit。
不過 EIP-3074 帶來了改變的契機:當 dApp 開發者知道 EOA 可以透過 Invoker 做到各種複雜的操作之後,dApp 交互上的設計便不再需要為了提升使用體驗而犧牲安全性,例如「使用者事前 approve 大筆金額」、「使用者簽個 permit 訊息授權提款」。取而代之的是使用者將 dApp 操作與 approve 綁在一起,透過 Invoker 去進行原子化(Atomic)的執行:要不 approve 和 dApp 操作一起成功執行,要不一起失敗,沒有 approve 單獨成功的可能,所以使用者可以很確信這一次 approve 就是給這次的操作。而且使用者是使用鏈下簽名的授權方式,所以使用體驗和 permit 是一樣的!這表示 dApp 將不再需要 permit 模式!未來錢包可以直接對 permit 簽名請求進行封禁或更嚴格的審查,不必再擔心是否會造成使用者用不了某些 dApp(但反而因此被詐騙利用)。
註:這不表示可以完全阻絕詐騙!使用者一樣有可能被騙進詐騙網站,詐騙網站一樣可以組 approve 或轉帳操作讓使用者簽名,但此時使用者至少可以看到這次簽名是要做什麼操作,錢包甚至可以透過模擬顯示執行結果並呈現給使用者,讓使用者可以明確知道誰會少了多少錢、誰會多了多少錢。相比於沒辦法知道做什麼操作或甚至執行結果的 permit, 使用者有了更多資訊去決定要不要授權。雖然不是完美的防治,但仍將是對現狀大幅的改善。
目前的 EIP-3074 設計會把 EOA nonce 值包含在簽名內容中,所以只要 EOA 送了一筆交易上鏈執行,改變了 nonce 值,原本的 EIP-3074 授權就會直接全部失效。
如果使用者是去授權其他人來代為操作 EOA,例如上面提到的 Session Key 或是 Social Recovery 方式,那 EOA 的 nonce 就要避免被改變,否則就要再重新簽一次所有授權並交給受託人,這對使用體驗及機制的穩健程度都有不小影響。
如果使用者是由自己授權操作的話,那就不用特別避免 EOA nonce 被改變,因為 EIP-3074 簽名還是和交易一樣預期要在某個期限之前去執行。只是錢包要多管理該 EOA 的 EIP-3074 交易:如果有 EIP-3074 簽名正在等待上鏈,那 EOA 自己上鏈的交易就要等待。
註:Invoker 合約自己會(也應該要)維護一套 nonce 機制,所以簽名用過之後一樣得再簽一次,不管 EOA nonce 是否改變。
Session Key 和 Social Recovery 非常可能要等到 EIP-3074 修改規則把 EOA nonce 從簽名內容移除,才有可能被大模規採用。因此錢包只需專注在「使用者自己授權操作」的使用情境下,並把 EIP-3074 簽名也當作交易一樣來處理,就不需要擔心要避免 EOA 送交易、改變 EOA nonce。
不過要注意,如果是使用者自己要帶自己的 EIP-3074 簽名內容上鏈的話會有兩個缺點:
使用者要簽兩次名:一次是 EIP-3074 簽名,一次是上鏈交易的簽名
因為上鏈交易會在交易開始執行前就先將 EOA nonce +1,所以使用者的 EIP-3074 簽名的 EOA nonce 要是預先 +1 才能對得上因為自己上鏈而造成的 EOA nonce +1
EIP-3074 讓 EOA 獲得和合約一樣豐富的執行能力,開啟了很多新的應用場景
這不僅讓使用體驗大幅提升,也將會改變現行的代幣授權方式,讓它在使用體驗不變的前提下變得更為安全
而且 EIP-3074 是單純簽名,使用者不一定要自己將簽名帶上鏈執行,也就不需要煩惱要先湊到 ETH 來支付手續費
EIP-3074 的用途包含 Batch Call、Session Key、Native ETH Permit、Limit Order、Social Recovery。這些許多原本都是 EOA 不可能做到的,有些像是 Limit Order 則是需要預授權等較不安全的方式才能使用
EIP-3074 也將改變現行的代幣授權方式。approve 直接授權指定地址有無限期提領代幣的權力,而且需要使用者 EOA 先送出一筆交易執行 approve,因此使用體驗及安全性都不佳;permit 只需要使用者簽名,且每次簽名都會指定金額及有效期,在使用體驗及安全性上都比 approve 提昇不少
但 permit 依然被頻繁利用於詐騙,簽名時使用者只能知道要授權給哪個地址、多少金額及有效期,但不會知道這個授權是要「用來做什麼」的。「用來做什麼」會是另一筆簽名(或交易),正常 dApp 會讓使用者簽 permit 及「用來做什麼」,但它們仍然會是兩筆不同簽名,因此被請求 permit 簽名時,使用者及錢包都沒辦法知道這筆 permit 會被「用來做什麼」
有了 EIP-3074,使用者 (1) 不需要事先 approve 很大的金額給 dApp,而是有操作時才 approve,效果和 permit 一樣;(2) 只是單純簽名且不需煩惱湊 ETH 付手續費,和 permit 一樣;(3)每次 approve 都是和指定的操作所綁定、一起簽名,使用者可以清楚知道這次 approve 是「用來做什麼」,這會比 permit 更為安全!
期望 EIP-3074 能成功取代現行的 approve 及 permit 模式,提供給使用者一個更安全的授權方式