合約錢包如今備受 Dapper Labs、Gnosis 和 Argent 等明星團隊的關注與開發,但也可能威脅鏈上隱私,因而以太坊元交易通用標準引發了不少討論,本文則介紹了 EIP-712 和批量交易方案。

原文標題:《引介 | 探索以太坊元交易的通用標準》(Ethereum Meta Transactions : Our Take)
撰文:Kiran Fernando
翻譯 & 校對:曾汨 & 阿劍

本文是 Bloxis 對 Metamask 在 Gitcoin 上舉辦的普遍化元交易競賽的迴應。由於我們計劃將這項功能整合進我們即將面世的產品中,因而在該領域投入了大量時間與精力,也正因如此,我們由衷地希望能夠參與到該領域的討論中來。如果您對我的觀點有任何異議,歡迎指出,我非常樂於與您討論。

引介 | 探索以太坊元交易的通用標準圖源:Gitcoin

引言

只要你願意花錢,你可以在一筆以太坊交易內執行任何(不超出 Gas 限制的)操作 —— 在一個幾乎是完全去中心化的無國界區塊鏈網絡上。聽起來非常酷不是麼?事實也確實如此。但是!問題就在於,執行交易需要耗費 Gas,而 Gas 是用以太幣來支付的,可是新用戶誰有以太幣啊親?(什麼?你說賽博朋克、囤幣黨、傳銷組織都有?拜託那都不是正常人)

引介 | 探索以太坊元交易的通用標準圖源:這個表情包是我自己 P 的 : )

DeFi、區塊鏈遊戲和 dApp 生態的未來依賴於入場玩家的規模。這意味着我們需要解決新玩家的上手問題,並降低安全操作的知識門檻。當下最主要的兩個問題是:玩家上手時需要擁有一個數字錢包以及一些以太幣 —— 這也是行業內許多人正在努力攻克的方向。

所謂元交易(Meta transaction),就是讓用戶用自己的密鑰來簽名發起交易,但不需要用戶來支付交易手續費(即 Gas 費用),而由 「中繼者(relay)」 來爲 TA 支付 Gas 費。中繼者作爲發送方,將交易提交至網絡,並支付 Gas 費用。交易的目標合約可以確定原始用戶及其意圖,並相應地處理合約的調用。

在元交易出現之前,完成上述服務需要預存資金,即先將以太幣存入終端用戶的賬戶中以促進交易。Uport 推出的 Lambda Sensui 是這方面的一個典型應用。

如果你想更加深入地瞭解元交易,可以閱讀下面這篇文章,其作者是社區中的標杆人物 —— Austin Griffith。

以太坊元交易:降低以太坊普及的門檻。

實現

在鏈上,實現元交易需要一種編碼標準來編碼原始發送者發出的交易數據 —— 以使目標合約能復原他們的簽名和數據,而不被 msg.sender (即中繼者)影響。然而,在鏈下,必須通過 API 或者通信協議才能將終端用戶連接到中繼者。且中繼者本身還必須擁有一些以太幣和基礎設施來獲取並轉發元交易。

很適合所在具體場景的解決方案,比如在 Dai 的 ERC-20 代幣合約中使用的 permit() 方法,就很優雅地解決了鏈上部分的難題 —— 這是一種需要終端用戶直接提交的 approve 方法。此外,這一方法還實現了 EIP-712,該標準用於表示和簽名供鏈上使用的消息數據。可以說, Dai 只需要支持這一種元交易就足夠了,因爲所有其它的用例(例如發送 Dai 和協調 DeFi 的操作)都可以利用這一解決方案來實現。

Gas Station Network 在此基礎上更進了一步,它創建了一個基於智能合約的網絡來協調中繼者,並創建了合約方法,使得任何智能合約只要經過很小的改動就可以連接到該網絡。所有的中繼者都通過一箇中繼集合站(relay hub)來跟合約進行交互,而中繼集合站本身也是一個合約,維護着中繼者的註冊表。其它合約向中繼集合站支付以太幣以激勵中繼者幫用戶支付 Gas 費,而且中繼者只有成功轉發一筆交易之後才能獲得該費用。

合約錢包

諸如 Dapper Labs、Gnosis 和 Argent 在內的許多組織正在推出合約錢包,旨在兼得用戶體驗和安全性。合約錢包將用戶的資金託管於智能合約之中,而合約內發送交易和保護賬戶安全的功能可以遠超以太坊協議本身的水平。

在用戶使用合約錢包時,得益於集成在錢包內的聯合簽名功能,終端用戶能夠僅憑其設備上的密鑰來簽名交易、表明自己想要進行交易的意圖,並將該交易發送給共同簽名者或者轉發方(通常是錢包服務的提供商),後者會轉發該交易並承擔 Gas 費用。比如,在 Dapper Labs 的產品 CoreWallet 上調用 invokeN…() 方法,實際發生的事情就像我們這裏說的一樣。

合約錢包挺火但還不完美,繼續探索以太坊元交易標準圖源:Dapper Labs

有了這一方法,賬戶內即使沒有以太幣也可以發出交易,而且不需要整個行業都接受同一個標準 —— 合約錢包可以像外部所有者賬戶(即由標準密鑰對控制的普通用戶地址,EOA)一樣調用其它合約。此外,它還帶來了一系列安全功能,諸如 Authereum 的交易防火牆 。

引介 | 探索以太坊元交易的通用標準圖源:Authereum

合約錢包帶來的困擾

對於合約錢包和諸如以太坊域名服務(ENS)等創舉,以太坊社區內的呼聲很高。然而,隨着許多用戶在其所有的鏈上活動中都使用 ENS 域名作爲身份(並且域名可讀部分使用了真實姓名),巨大的隱私和安全問題開始顯現。

此外,大家一邊關注保護隱私的協議(比如 AZTEC,可用於隱蔽發送 token)(這些協議都依賴於私鑰的所有和保管),另一邊又忽略了私鑰管理的難度和傳統方案的隱私方面。

以太坊的錢包地址本身是 「僞匿名的」(因此具有一定的隱私性),但現在許多錢包軟件提供商都在鼓勵其用戶獲取 ENS 地址,卻不告知他們這樣做的後果。簡言之,以太坊賬戶的交易記錄(包括其投資組合及與 dApp 之間的互動記錄)在鏈上是公開的,一個地址註冊 ENS 域名之後,這些交易活動就跟這個 ENS 域名關聯起來了。而用戶所註冊的 ENS 名字很可能是用戶在其它服務或是現實生活中已經使用過的名字。這就是我對(供個人使用的)合約錢包地址綁定 ENS 持懷疑態度的主要原因。

然而,對於將 ENS 用於識別智能合約以防止詐騙,以及可以從透明操作中獲益的組織使用 合約錢包 / 多重簽名錢包,我舉雙手支持🙌。

通過分層確定性錢包規則(Hierarchical Deterministic Wallet,簡稱 HD 錢包),用戶可以用單個私鑰來生成許多 EOA 地址,以保管不同的資產;使用多個地址分別操作,即便用戶會使用 dApp、DeFi 協議併發起大量交易,仍然可以保持一定程度的匿名性。使用這套規則,用戶甚至可以只持有一把私鑰,然後爲每一個要用到的 dApp 和 token 專門創建一個 EOA 地址用於交互。合約錢包雖然也能做到這一點,但因爲 Gas 費用的存在,爲用戶使用的每一個 dApp/ 代幣 創建一個合約錢包顯得十分昂貴而不切實際。就算不考慮 Gas 費用,這樣做也會造成網絡擁堵。

引介 | 探索以太坊元交易的通用標準分層確定性錢包本身便是一種隱私解決方案,也適用於以太坊錢包。圖源:Casa

假設以太坊生態內所有的用戶對於與其交互的每一個 dApp 都有一個對應的合約錢包,從而既能利用元交易功能,又能保護自己的隱私 —— 屆時智能合約採用一個通用的標準會更加合理。

邁向普遍化標準

無論你對基於合約及合約錢包的解決方案持有何種立場,目前都還沒有一個確定的標準 —— 方法調用因合約而異,用於中繼交易的系統也各不相同。Gas Station Network 已經做了許多基礎性的工作,但依舊不夠靈活。收款方合約可能不會支付 Gas 費。那麼用戶又如何使用其資產來爲中繼者支付報酬呢?我們該如何讓另一方來爲這筆交易支付 Gas 費呢?這些都是我們希望在普遍化元交易競賽中解決的問題 —— 真正有價值的提案就是要面對這些問題。

基於我們提出的想法,我們的總法律顧問 Vincent 提出了一個想法:讓 dApp 的開發者預先爲用戶存入資金用於支付 gas 費,用戶用法幣來交換;爲避免 dApp 項目被認定爲交易所,這些以太幣只能在 dApp 內部使用。這就是我們希望未來的普遍化元交易標準能夠支持的機制(這是我們一年前在研究另一件事情的時候想到的)。通過 acceptRelayedCall() 方法的一個自定義實現,Gas Station Network 爲這一想法提供了技術支持。

此外,讓中繼者能夠批處理交易,是不是也能降低 Gas 費用?

無論提議來源於何處,我們都希望在其中看到如下內容:

  • 有機制可支持替代性的中繼者 報銷 / 支付方式
  • 適合在資產 dApp 和 DeFi 的智能合約(而非合約錢包標準)中運行的方法
  • 支持在目標合約或用於中繼交易的合約內進行交易批處理的機制

我們的提議概述

如你所見,我們強烈支持 Gas Station Network 提出的想法。由 RelayRecipient 提供的 getSender()getMessageData() 方法實現了一個統一的接口,使所有合約的元交易可以相互兼容。然而,這些方法在其當前的形式下還存在兩個短板 —— 無法防止釣魚網絡和重放攻擊。詳情:

  • ethereum/EIP-1613:Gas Station Network
  • ethereum/EIP-712

爲了防止釣魚,EIP-712 提出了一個巧妙的解決方案 —— 域名分隔符。該對象包含了(用戶簽名交易要轉發給的)合約的詳細信息 —— 也就是地址,以及 dApp 的名稱和版本。這些數據都包含在簽名中,並和所有其它的交易數據一併以一種非常友好的方式呈現給終端用戶。這樣就限制了用戶簽名交易的方式,防止他們發起預期以外類型的交易(比如有意把交易發到錯誤的合約)。

引介 | 探索以太坊元交易的通用標準使用 signTypedData_v4 方法對數據簽名的 Metamask 界面。圖源:Metamask

支持 EIP-712 的合約需要驗證域名分隔符與合約自身是否匹配,如果不匹配則回絕該交易。從下面列出的 Dai 合約的代碼中,你可以看到這一點。我們希望將 EIP-712 整合進 getSender() 和 getMessageData() 中,以便能在每一次方法調用時執行這項檢查 —— 一旦簽名不匹配,就回絕該交易。你可以點擊下面的鏈接查看該函數的代碼。(很抱歉,文章內嵌代碼的格式無法正常顯示)

Makerdao/dss:https://github.com/makerdao/dss/blob/b1fdcfc9b2ab7961bf2ce7ab4008bfcec1c73a88/hide/dai.sol#L114-L138

此外,在上面的代碼中,你還可以看到 MakerDAO 自己用 nonce 屬性實現了重放保護 —— 如果沒有該屬性,得到授權的參與方可以通過重放交易來耗盡用戶的資金。

一筆元交易經常屬於一組操作的一部分,而這些操作可能依賴於前面的交易。舉個例子,在我們構建的概念驗證案例中,用戶可以將 xDai 存入 Compound 協議。而在主網上,這意味着我們要批准 cDai 合約訪問用戶資金,然後調用 mint() 方法將該資金存入貸款協議。

如果用戶的賬戶並非合約錢包,完成這一過程就需要一系列操作:首先得通過交易調用 approve()/permit() 方法,然後等待該交易被打包之後再調用 mint() 方法。而有了合約錢包之後,就可以一步到位,通過調用一個特殊的合約方法來批處理這些交易。

如果有一種人人可用的普遍化元交易批處理方法,那肯定是一個重大的創新。這會大大簡化鏈上的活動,就像上文舉過的種種例子。此外,該方法還要允許用戶可以同時簽名和轉發多筆互不相關的交易。

不僅如此,該方法還應該學學 MakerDAO 是如何使用 permit() 方法處理 nonce 和重放保護的。這樣,用戶就可以爲互不相關的合約轉發多條消息,同時不用操心網絡中交易的提交順序 —— 例如,當用戶爲某些現實生活服務支付多筆資產的時候。

然而,在某些情況下,用戶可能希望往某一個合約發送多筆元交易。例如,某一個只持有一種資產的 EOA 想要批量發薪水的時候。一個批處理元交易的系統在設計的時候必須考慮到這一點,並確保保持了交易發送的順序。

此外,批處理交易也讓中繼者可以通過用戶簽名的交易集中地收取手續費,也就是在一批交易中加入一筆轉賬給中繼者的交易,方法也是可以定製化的。可以是將 ERC-20 代幣轉給中繼者,或者讓用戶的目標合約來支付該費用。

中繼集合器應當支持交易批處理,並通過 sendRawTransactionSet() 方法來補充 sendRawTransaction() ,以便同一用戶發送多筆交易。sendRawTransactionSetPlural() 方法也應該加以利用,以方便中繼對來自多個用戶的交易進行批處理,從而最小化 Gas 費用。

引介 | 探索以太坊元交易的通用標準圖源:Tabookey

如果可以通過交易集中的一筆交易來爲其提供資金,那麼只需要對中繼集合器現在的工作流程做很小的改動就可以實現上述操作,中繼者可以將 gasPrice 和費用參數 acceptRelayCall() 都設置爲 0。中繼者可以從交易集中不斷提取出交易並按標準來處理,直至完成。

我們面臨的真正挑戰是如何創建一種標準將交易打包進交易集,以及解包並執行交易(同時確保交易的原子性)。如果交易的原子性無法得到保證,中繼者就可以通過只轉發付費的交易來矇混過關,而無視集合中的其它交易。這纔是工作的重頭!對於如何實現這一點,我目前還毫無頭緒,但請繼續關注我的下一篇文章!希望我可以將這一切變成可行的方案來參加競賽。

總結

在我們看來,合約錢包有用不假,但有點名過其實了,而且因爲合約錢包常常鼓勵用戶做那些便利日常使用的措施,還可能會危害到鏈上的隱私。這會極大地影響我們希望在以太坊生態內實現普遍化元交易的方式。

我們希望在 Gas Station Network 的基礎上更進一步,以支持 EIP-712 和批量交易。這也意味着對 RelayHub 和 RelayRecipient 進行修改,並創建一個新標準,支持簽名交易集合並保證交易的原子性。請保持關注,並留下您的反饋 —— 這是我在 Medium 上發表的第一篇文章!

來源鏈接:medium.com