就在昨天,發生了一件令人震驚的事件:由Metamask的母公司Consensys開發以太坊 Layer 2解決方案Linea被主動關閉。給出的官方理由是減輕Velocore駭客事件的影響。這一事件不可避免地讓人想起之前的一個案例,BSC鏈(BNB鏈)也在官方協調下被關閉,以盡量減少駭客損失。這些事件經常導致人們質疑 Web3 宣導的去中心化價值觀。
上述事件背後的核心原因在於基礎設施的不完善,特別是缺乏去中心化。如果區塊鏈足夠去中心化,它不應該那麼容易關閉。由於以太坊 Layer 2的獨特結構,大多數Layer 2解決方案都依賴於集中式定序器。儘管近年來關於去中心化測序器的討論越來越多,但考慮到Layer 2的目的和結構,我們可以假設Layer 2測序器不太可能實現高水準的去中心化。事實上,它們最終可能不如BSC鏈去中心化。如果是這樣的話,我們能做些什麼呢?對於Layer 2來說,非分散式測序儀最直接的風險是缺乏抗審查性和活力。如果只有少數實體處理交易(排序器),它們對是否為您服務擁有絕對的權力:他們可以隨意拒絕您的交易,讓您沒有追索權。在Layer 2解決抗審查性問題顯然是一個重要的議題。在過去幾年中,各種以太坊 Layer 2解決方案提出了不同的方法來解決這個問題。例如,路印,Degate和StarkEx引入了強制撤退和逃生艙口功能,而Arbitrum和其他樂觀匯總已經實現了力包含功能。這些機制可以對排序器進行檢查,以防止任意拒絕使用者事務。在今天的文章中,臺北市以太坊會的NIC Lin分享了他的第一手經驗,嘗試了四大匯總的抗審查交易特徵,並對警隊包容機制進行了深入分析,重點是工作流程和操作方法。這種分析對以太坊社區和大型資產持有者特別有價值。
交易中的審查阻力對於任何區塊鏈都至關重要。如果區塊鏈可以任意審查和拒絕使用者交易,那麼它與 Web2 伺服器沒有什麼不同。以太坊的交易抗審查性目前由其眾多的驗證者來保證。如果有人想審查鮑勃的交易並阻止它被包含在區塊鏈中,他們要麼必須賄賂網路的大部分驗證者,要麼用比鮑勃更高的費用向網路發送垃圾交易,從而佔用區塊空間。這兩種方法都非常昂貴。
注意:在以太坊當前的提議者-建造者分離(PBS)架構中,審查交易的成本顯著降低。例如,您可以查看符合OFAC對Tornado Cash交易審查的區塊比例。目前的抗審查性依賴於OFAC和其他政府實體管轄範圍之外的獨立驗證者和中繼。
但是匯總呢?匯總不需要大量驗證者來確保安全性。即使匯總只有一個集中式實體(Sequencer)生成塊,它仍然與第 1 層 (L1) 一樣安全。但是,安全和抗審查性是兩個不同的問題。Rollup雖然像以太坊一樣安全,但如果它只有一個集中式排序器,它仍然可以審查任何使用者的交易。
Sequencer 可以拒絕處理使用者的交易,導致使用者的資金被鎖定,無法離開匯總。
與其要求 Rollups 擁有大量分散式排序器,不如直接利用第 1 層 (L1) 的抗審查性更有效:
由於排序器需要打包事務數據並將其發送到 L1 上的 Rollup 合約,因此我們可以在合約中添加一個功能,允許使用者自己將他們的交易插入到 Rollup 合約中。這種機制被稱為“力包含”。由於多排序器無法在 L1 級別審查使用者,因此它無法阻止使用者在 L1 強制插入事務。這樣,匯總可以繼承 L1 的抗審查性。
Sequencer 無法在不支付高成本的情況下查看使用者的 L1 事務
如果允許事務通過強制包含直接寫入匯總合約(意味著它們立即生效),則匯總的狀態將立即更改。例如,如果 Bob 使用強制包含機制插入將 1000 DAI轉移給 Carol 的交易,並且交易立即生效,則 Bob 的餘額將減少 1000 DAI,而 Carol 的餘額將在更新狀態下增加 1000 DAI。
如果強制包含允許事務直接寫入匯總協定並立即生效,則匯總的狀態將立即更改。如果排序器同時收集鏈下事務並準備將下一批發送到 Rollup 合約,則 Bob 強制插入的事務可能會中斷該事務,該事務立即生效。為避免此問題,匯總通常不允許強制包含事務立即生效。相反,使用者最初將他們的事務插入 L1 上的等待佇列中,在那裡他們進入“準備”狀態。當排序器打包要發送到匯總協定鏈下事務時,它可以選擇是否包括這些排隊的事務。如果排序器持續忽略處於「準備」狀態的事務,則在視窗期結束后,使用者可以強制將這些事務插入到 Rollup 合約中。排序器可以決定何時「偶然包含」等待佇列中的事務,但它仍然可以拒絕處理它們。如果排序器在一段時間后始終拒絕,任何人都可以使用強制包含功能將交易強行插入匯總合約。接下來,我們將在四個突出的匯總中介紹力包含機制的實現:樂觀、仲裁、StarkNet 和 zkSync。
排序器可以選擇何時從等待佇列中獲取事務。
排序器仍然可以拒絕處理等待佇列中的事務。
如果排序器始終拒絕處理事務,則在一段時間后,任何人都可以使用強制包含功能將事務強制插入到匯總合約中。接下來,我們將介紹如何在四個突出的匯總中實現力包含機制:樂觀,仲裁,StarkNet和zkSync。
首先,讓我們討論樂觀主義的存款過程。此存款過程不僅涉及將資金轉入樂觀,還涉及向L2發送“使用者消息”。當 L2 節點收到新存放的消息時,它會將消息轉換為 L2 事務並執行它,並將其傳遞給指定的收件者。
從 L1 存入 L2 的使用者訊息
L1跨域信使合約
當使用者想要將代幣充值 二餅或以太坊代幣標準到 Optimism 時,他們通過前端網頁與 L1 上的 L1StandardBridge 合約進行交互,指定要充值的金額和將接收這些資產的 L2 位址。然後,L1StandardBridge 合約將消息轉發到 L1CrossDomainMessenger 合約,該合約充當 L1 和 L2 之間的主要通信橋接。L1StandardBridge 使用此通信元件與 L2 上的 L2StandardBridge 交互,確定誰可以在 L2 上鑄造令牌或從 L1 解鎖令牌。需要創建在 L1 和 L2 之間互操作和同步狀態的合約的開發人員可以在 L1CrossDomainMessenger 合約之上構建它們。
通過 CrossDomainMessenger 合約從 L1 傳輸到 L2 的使用者訊息
注意:在本文的某些圖像中,CrossDomainMessenger被寫成CrossChainMessenger。
樂觀門戶合約
然後,L1CrossDomainMessenger合約將消息轉發到最低層,即OptimismPortal合約。處理完消息后,OptimismPortal合約會發出一個名為TransactionDeposited的事件,其中包括“發送方”、“接收方”等參數和其他相關執行細節。L2 上的樂觀節點從樂觀門戶合約偵聽此交易存款事件,並將事件的參數轉換為 L2 交易。此事務的發起方將是事件中指定的“發送方”,接收方將是事件中提到的“接收方”,其他事務詳細資訊也將從事件的參數中派生出來。
L2 節點將 OptimismPortal 發出的“交易存款”事件的參數轉換為 L2 交易。
例如,當使用者通過L1StandardBridge合約存入0.01二餅時,消息和二餅將傳輸到OptimismPortal合約(位址0xbEb5...幾分鐘后,這被轉換為 L2 事務:消息發送方是 L1CrossDomainMessenger 合約,接收方是 L2 上的 L2CrossDomainMessenger 合約,消息內容表明 L1StandardBridge 從 Bob 收到 0.01 二餅 充值。然後,這會觸發其他進程,例如 L2StandardBridge 鑄造 0.01 二餅,隨後將其傳輸給 Bob。
如何觸發它
如果您想強制將交易包含在 Optimism 的匯總合約中,您的目標是確保“從您在 L2 上的 L2 位址發起並執行”的交易可以成功執行。為此,您應該使用您的 L2 位址將消息直接提交到 OptimismPortal 合約(請注意,OptimismPortal 合約實際上位於 L1 上,但OP位址格式與 L1 位址格式匹配,因此您可以使用與 L2 帳戶位址相同的 L1 帳戶調用此合約)。從本合約發出的交易存款事件派生的 L2 交易的“發送方”將是您的 L2 帳戶,交易格式將與標準 L2 交易一致。
在從“交易存款”事件派生的 L2 事務中,Bob 本人將是贊助者;接收方將是 Uniswap 合約;它將包括指定的二餅,就像 Bob 自己發起 L2 事務一樣。
要使用 Optimism 的強制包含函數,您需要直接調用 OptimismPortal 合約的存款交易函數,並在 L2 上輸入您想要執行的交易的參數。我進行了一個簡單的力包含實驗。此交易的目標是使用我的位址在 L2 上執行自我轉帳 (0xeDc1...6909),並包含一條消息,上面寫著“強制包含”。這是我通過 OptimismPortal 合約調用存款交易函數執行的 L1 交易。從它發出的「交易存款」事件中可以看出,發送方和接收方都是我自己。
不透明數據列中的其餘值對諸如“調用 depositTransaction 函數的人附加了多少二餅”、“L2 事務發起方希望向接收方發送多少二餅”、“L2 事務 GasLimit”和“L2 接收方的數據”等資訊進行編碼。解碼此資訊后,您將獲得以下詳細資訊:「調用存款的人附加了多少二餅交易」:0,因為我沒有將二餅從 L1 存入到 L2;“L2 事務發起方想要向接收方發送多少二餅”:5566(wei);“L2 交易氣體限制”:50000;“L2 接收器的數據”:0x666f72636520696e636c7573696f6e,這是字串“強制包含”的十六進位編碼。不久之後,轉換后的 L2 事務出現了:一個 L2 事務,我將 5566 wei轉移到自己身上,Data 字段包含字串“強制包含”。此外,在“其他屬性”部分的倒數第二行中,TxnType(事務類型)顯示為系統事務 126(系統),表明此事務不是由我在 L2 上發起的,而是從 L1 事務的存款事件轉換而來的。
轉換後的 L2 事務
如果您想通過強制包含調用 L2 合約併發送不同的數據,您只需在存款交易函數中填寫參數即可。只需記住在調用存款交易函數時使用與 L2 帳戶相同的 L1 位址。這樣,當存款事件轉換為 L2 交易時,贊助者將成為您的 L2 帳戶。排序器視窗 將「交易存款」事件轉換為 L2 事務的樂觀 L2 節點實際上是排序器。由於這涉及事務排序,因此只有 Sequencer 才能決定何時將事件轉換為 L2 事務。當 Sequencer 偵聽 TransactionDeposited 事件時,它不一定會立即將事件轉換為 L2 事務;可能會有延遲。此延遲的最長持續時間稱為序列器視窗。目前,樂觀主網上的序列器視窗是24小時。這意味著,當使用者從 L1 存入資金或使用強制包含進行交易時,在最壞的情況下,它將在 24 小時後包含在 L2 交易歷史記錄中。
在樂觀中,L1 充值操作會觸發“事務存放”事件,然後只需等待 Sequencer 包含該操作即可。但是,在 Arbitrum 中,L1 上的操作(例如存入資金或向 L2 發送消息)存儲在 L1 上的佇列中,而不是簡單地發出事件。Sequencer 有一個特定的時間段將這些排隊的事務包含在 L2 事務歷史記錄中。如果排序器未能在此時間範圍內執行此操作,任何人都可以代表排序器介入以完成包含。
Arbitrum 在 L1 合約中維護一個佇列。如果 Sequencer 在一定時間內未能處理佇列中的事務,任何人都可以強制將這些事務包含在 L2 事務歷史記錄中。在Arbitrum的設計中,L1上的操作,例如存款,必須通過延遲收件匣合同,顧名思義,這些操作將在生效之前延遲。另一個合約,Sequencer 收件匣,是 Sequencer 直接將 L2 事務上傳到 L1 的地方。每次 Sequencer 上傳 L2 事務時,它還可以從延遲收件匣中獲取一些待處理事務,並將其包含在事務歷史記錄中。
當 Sequencer 寫入新事務時,它還可以包含來自 DelayedInbox 的事務。
設計複雜,缺乏參考物質
如果您參考 Arbitrum 關於 Sequencer 和 Force Inclusion 的官方文檔,您會發現 Force Inclusion 如何工作的一般說明,以及一些參數和函數名稱: 使用者首先在 DelayedInbox 合約上調用 sendUnsignedTransaction 函數。如果 Sequencer 在大約 24 小時內未包含它,用戶可以調用 SequencerInbox 合約上的 forceInclusion 函數。但是,官方文檔沒有提供這些函數的連結,因此您必須自己在合約代碼中查找它們。當您找到sendUnsignedTransaction函數時,您意識到您必須自己填寫nonce值和maxFeePerGas值。這是誰nonce?哪個網路的maxFeePerGas?你應該如何正確填寫它?沒有參考檔,甚至沒有NatSpec。您還可以在 Arbitrum 合約中找到許多類似的函數:sendL1FundedUnsignedTransaction、sendUnsignedTransactionToFork、sendContractTransaction、sendL1FundedContractTransaction。沒有文檔解釋這些函數之間的差異,如何使用它們或如何填寫參數,甚至沒有NatSpec。
您嘗試填寫參數並使用試錯方法提交交易,希望找到正確的用法。但是,您發現所有這些功能都地址別名應用於您的 L1 位址,導致 L2 上交易的發送者是一個完全不同的位址,從而使您的 L2 位址處於非活動狀態。後來,您偶然發現了Google搜尋結果,該結果顯示Arbitrum有一個教程庫,其中包含演示如何從L1發送L2事務的腳本(本質上是強制包含)。本教程列出了一個之前未提及的函數:sendL2Message。令人驚訝的是,所需的消息參數實際上是使用 L2 帳戶的已簽名 L2 事務。誰會知道「通過強制包含發送到L2的消息」實際上是「簽名的L2交易」?此外,沒有文檔或 NatSpec 解釋何時以及如何使用此功能。
結論:在仲裁上手動生成強制交易非常複雜。建議遵循官方教程並使用 Arbitrum SDK。與其他匯總不同,Arbitrum缺乏清晰的開發人員文檔和代碼註釋。許多函數缺乏對其用途和參數的解釋,導致開發人員花費比預期更多的時間來集成和使用它們。我也在仲裁不和諧中尋求説明,但沒有得到滿意的答覆。在 Discord 上詢問時,他們只指示我查看 sendL2Message,並沒有解釋其他方法的功能(包括強制包含文檔中提到的那些方法,如 sendUnsignedTransaction)、它們的目的、如何使用它們或何時使用它們。
不幸的是,StarkNet目前沒有Force Inclusion機制。官方論壇上只有兩篇文章討論審查和強制包容。無法證明失敗交易的原因是StarkNet的零知識證明系統無法證明失敗的交易,因此不能允許強制包含。如果有人惡意(或無意)強制包含失敗的、無法證明的交易,StarkNet 就會陷入困境:因為一旦交易被強行包含,證明者必須證明失敗的交易,但它不能。StarkNet預計將在v0.15.0版本中引入證明失敗事務的功能,之後應進一步實施強制包含機制。
zkSync 用於 L1->L2 消息傳輸和強制包含的機制通過郵箱合約的請求 L2Transaction 函數處理。使用者指定 L2 位址、呼叫數據、要附加的二餅量、L2GasLimit 值和其他詳細資訊。requestL2Transaction 函數將這些參數組合到 L2 事務中,並將其放入 PriorityQueue 中。當 Sequencer 打包事務並將其上傳到 L1(通過 commitBatches 函數)時,它會指示要從 PriorityQueue 中獲取多少事務以包含在 L2 事務記錄中。在強制包含方面,zkSync 類似於 Optimism,其中發起方的 L2 位址(與 L1 位址相同)用於調用相關函數並填寫必要的詳細資訊(被調用方、調用數據等),而不是像 Arbitrum 那樣需要簽名的 L2 事務。但是,在設計上,它類似於 Arbitrum,因為兩者都在 L1 上維護一個佇列,並且 Sequencer 從佇列中獲取使用者直接提交的待處理事務並將其寫入事務歷史記錄中。
如果你充值 二餅通過 zkSync 的官方橋接,就像這個交易一樣,它會調用郵箱合約的 requestL2Transaction 函數。此函數將存款二餅 L2 事務放入 PriorityQueue 中,併發出 NewPriorityRequest 事件。由於合約將 L2 交易數據編碼為位元組字串,因此不容易讀取。但是,如果您查看此 L1 事務的參數,您會發現 L2 接收者也是事務的發起者(因為它是對自己的充值)。一段時間后,當 Sequencer 將此 L2 事務從 PriorityQueue 中取出並將其包含在事務歷史記錄中時,它將轉換為 L2 事務,您可以在其中轉移給自己。轉帳金額將是贊助者在L1存款二餅交易中附加的二餅金額。
在 L1 存款交易中,發起人和收款人都0xeDc1...6909,金額為0.03二餅,沒有調用數據。
在L2上,將有一個事務,其中0xeDc1...6909 轉移到自己。事務類型 (TxnType) 為 255,表示系統事務。然後,就像我之前在 Optimism 上試驗強制事務函數一樣,我調用了 zkSync 的 requestL2Transaction 函數並發起了一個自轉移事務:沒有附加二餅,調用數據包含字串“強制包含”的十六進位編碼。然後將其轉換為L2事務,我將其轉移到自己身上,calldata包含“強制包含”的十六進位字串:0x666f72636520696e636c7573696f6e。
當
Sequencer 從 PriorityQueue 獲取事務並將其寫入事務歷史記錄時,它們將轉換為相應的 L2 事務。使用請求L2Transaction功能,用戶可以在L1上提交與其L2位址相同的L1帳戶的數據,指定L2接收者,要附加的二餅量和調用數據。如果使用者想要調用其他合約或包含不同的數據,他們只需要在 requestL2Transaction 函數中填寫參數即可。
尚無適用於使用者的強制包含功能
儘管放置在 PriorityQueue 中的 L2 事務將有一個計算的等待期以供 Sequencer 包含,但 zkSync 當前的設計沒有允許使用者強制包含它的強制包含功能。這意味著它只是部分解決方案。即使存在“包含等待期”,最終也取決於 Sequencer 是否決定包含它:Sequencer 可以在該期限到期後包含它,或者從不包含 PriorityQueue 中的任何事務。將來,zkSync 應該添加一些功能,允許使用者強制將事務包含在 L2 事務歷史記錄中,如果這些事務在等待期后仍未被 Sequencer 包含。這將是一個真正有效的部隊包容機制。
L1依靠大量的驗證者來保證網络的“安全”和“抗審查性”。但是,匯總的抗審查性較弱,因為事務由幾個甚至單個 Sequencer 寫入。因此,Rollups 需要一個強制包含機制,以允許使用者繞過 Sequencer 並將交易寫入歷史記錄,防止 Sequencer 的審查使 Rollup 無法使用並防止使用者提取資金。強制包含允許使用者強制將交易寫入歷史記錄,但設計必須選擇“交易是否可以立即插入歷史記錄並立即生效”。如果允許立即生效,則會對 Sequencer 產生負面影響,因為 L2 上的掛起事務可能會受到來自 L1 的強制包含的事務的影響。因此,匯總中的當前強制包含機制首先將從 L1 插入的事務置於等待狀態,併為 Sequencer 提供一個時間視窗來做出反應並決定是否包含這些掛起的事務。zkSync 和 Arbitrum 都在 L1 上維護一個佇列,以管理從 L1 發送到 L2 的 L2 事務或消息。Arbitrum稱之為DelayedInbox;zkSync 稱之為 PriorityQueue。但是,zkSync 發送 L2 事務的方法更類似於 Optimism,其中消息使用 L2 位址從 L1 發送,因此當轉換為 L2 事務時,發起方是 L2 位址。在樂觀情緒中發送 L2 交易的函數稱為存款交易;在 zkSync 中,它被稱為 requestL2Transaction。相反,Arbitrum 生成一個完整的 L2 事務並對其進行簽名,然後通過 sendL2Message 函數發送。在 L2 上,仲裁使用簽名將簽名者還原為 L2 事務的發起者。StarkNet目前沒有強制包含機制;zkSync 有一個半實現的強制包含機制——它有一個 PriorityQueue,佇列中的每個 L2 事務都有一個包含有效期,但這個有效期目前只是為了顯示。實際上,排序器可以選擇不包含優先順序佇列中的任何 L2 事務。
本文轉發自:[Geek Web3],原標題為“理論與實踐:如何在以太坊 Rollup中觸發抗審查交易?”,版權歸屬原作者[臺北以太坊聚會負責人NIC Lin],如果您對轉載有任何異議,請聯繫Gate Learn Team,團隊將按照相關程序儘快處理。
免責聲明:本文表達的觀點和意見僅代表作者個人觀點,不構成任何投資建議。
本文的其他語言版本由Gate Learn團隊翻譯。在未引用Gate.io 的情況下,禁止複製、分發或抄襲翻譯后的文章。
就在昨天,發生了一件令人震驚的事件:由Metamask的母公司Consensys開發以太坊 Layer 2解決方案Linea被主動關閉。給出的官方理由是減輕Velocore駭客事件的影響。這一事件不可避免地讓人想起之前的一個案例,BSC鏈(BNB鏈)也在官方協調下被關閉,以盡量減少駭客損失。這些事件經常導致人們質疑 Web3 宣導的去中心化價值觀。
上述事件背後的核心原因在於基礎設施的不完善,特別是缺乏去中心化。如果區塊鏈足夠去中心化,它不應該那麼容易關閉。由於以太坊 Layer 2的獨特結構,大多數Layer 2解決方案都依賴於集中式定序器。儘管近年來關於去中心化測序器的討論越來越多,但考慮到Layer 2的目的和結構,我們可以假設Layer 2測序器不太可能實現高水準的去中心化。事實上,它們最終可能不如BSC鏈去中心化。如果是這樣的話,我們能做些什麼呢?對於Layer 2來說,非分散式測序儀最直接的風險是缺乏抗審查性和活力。如果只有少數實體處理交易(排序器),它們對是否為您服務擁有絕對的權力:他們可以隨意拒絕您的交易,讓您沒有追索權。在Layer 2解決抗審查性問題顯然是一個重要的議題。在過去幾年中,各種以太坊 Layer 2解決方案提出了不同的方法來解決這個問題。例如,路印,Degate和StarkEx引入了強制撤退和逃生艙口功能,而Arbitrum和其他樂觀匯總已經實現了力包含功能。這些機制可以對排序器進行檢查,以防止任意拒絕使用者事務。在今天的文章中,臺北市以太坊會的NIC Lin分享了他的第一手經驗,嘗試了四大匯總的抗審查交易特徵,並對警隊包容機制進行了深入分析,重點是工作流程和操作方法。這種分析對以太坊社區和大型資產持有者特別有價值。
交易中的審查阻力對於任何區塊鏈都至關重要。如果區塊鏈可以任意審查和拒絕使用者交易,那麼它與 Web2 伺服器沒有什麼不同。以太坊的交易抗審查性目前由其眾多的驗證者來保證。如果有人想審查鮑勃的交易並阻止它被包含在區塊鏈中,他們要麼必須賄賂網路的大部分驗證者,要麼用比鮑勃更高的費用向網路發送垃圾交易,從而佔用區塊空間。這兩種方法都非常昂貴。
注意:在以太坊當前的提議者-建造者分離(PBS)架構中,審查交易的成本顯著降低。例如,您可以查看符合OFAC對Tornado Cash交易審查的區塊比例。目前的抗審查性依賴於OFAC和其他政府實體管轄範圍之外的獨立驗證者和中繼。
但是匯總呢?匯總不需要大量驗證者來確保安全性。即使匯總只有一個集中式實體(Sequencer)生成塊,它仍然與第 1 層 (L1) 一樣安全。但是,安全和抗審查性是兩個不同的問題。Rollup雖然像以太坊一樣安全,但如果它只有一個集中式排序器,它仍然可以審查任何使用者的交易。
Sequencer 可以拒絕處理使用者的交易,導致使用者的資金被鎖定,無法離開匯總。
與其要求 Rollups 擁有大量分散式排序器,不如直接利用第 1 層 (L1) 的抗審查性更有效:
由於排序器需要打包事務數據並將其發送到 L1 上的 Rollup 合約,因此我們可以在合約中添加一個功能,允許使用者自己將他們的交易插入到 Rollup 合約中。這種機制被稱為“力包含”。由於多排序器無法在 L1 級別審查使用者,因此它無法阻止使用者在 L1 強制插入事務。這樣,匯總可以繼承 L1 的抗審查性。
Sequencer 無法在不支付高成本的情況下查看使用者的 L1 事務
如果允許事務通過強制包含直接寫入匯總合約(意味著它們立即生效),則匯總的狀態將立即更改。例如,如果 Bob 使用強制包含機制插入將 1000 DAI轉移給 Carol 的交易,並且交易立即生效,則 Bob 的餘額將減少 1000 DAI,而 Carol 的餘額將在更新狀態下增加 1000 DAI。
如果強制包含允許事務直接寫入匯總協定並立即生效,則匯總的狀態將立即更改。如果排序器同時收集鏈下事務並準備將下一批發送到 Rollup 合約,則 Bob 強制插入的事務可能會中斷該事務,該事務立即生效。為避免此問題,匯總通常不允許強制包含事務立即生效。相反,使用者最初將他們的事務插入 L1 上的等待佇列中,在那裡他們進入“準備”狀態。當排序器打包要發送到匯總協定鏈下事務時,它可以選擇是否包括這些排隊的事務。如果排序器持續忽略處於「準備」狀態的事務,則在視窗期結束后,使用者可以強制將這些事務插入到 Rollup 合約中。排序器可以決定何時「偶然包含」等待佇列中的事務,但它仍然可以拒絕處理它們。如果排序器在一段時間后始終拒絕,任何人都可以使用強制包含功能將交易強行插入匯總合約。接下來,我們將在四個突出的匯總中介紹力包含機制的實現:樂觀、仲裁、StarkNet 和 zkSync。
排序器可以選擇何時從等待佇列中獲取事務。
排序器仍然可以拒絕處理等待佇列中的事務。
如果排序器始終拒絕處理事務,則在一段時間后,任何人都可以使用強制包含功能將事務強制插入到匯總合約中。接下來,我們將介紹如何在四個突出的匯總中實現力包含機制:樂觀,仲裁,StarkNet和zkSync。
首先,讓我們討論樂觀主義的存款過程。此存款過程不僅涉及將資金轉入樂觀,還涉及向L2發送“使用者消息”。當 L2 節點收到新存放的消息時,它會將消息轉換為 L2 事務並執行它,並將其傳遞給指定的收件者。
從 L1 存入 L2 的使用者訊息
L1跨域信使合約
當使用者想要將代幣充值 二餅或以太坊代幣標準到 Optimism 時,他們通過前端網頁與 L1 上的 L1StandardBridge 合約進行交互,指定要充值的金額和將接收這些資產的 L2 位址。然後,L1StandardBridge 合約將消息轉發到 L1CrossDomainMessenger 合約,該合約充當 L1 和 L2 之間的主要通信橋接。L1StandardBridge 使用此通信元件與 L2 上的 L2StandardBridge 交互,確定誰可以在 L2 上鑄造令牌或從 L1 解鎖令牌。需要創建在 L1 和 L2 之間互操作和同步狀態的合約的開發人員可以在 L1CrossDomainMessenger 合約之上構建它們。
通過 CrossDomainMessenger 合約從 L1 傳輸到 L2 的使用者訊息
注意:在本文的某些圖像中,CrossDomainMessenger被寫成CrossChainMessenger。
樂觀門戶合約
然後,L1CrossDomainMessenger合約將消息轉發到最低層,即OptimismPortal合約。處理完消息后,OptimismPortal合約會發出一個名為TransactionDeposited的事件,其中包括“發送方”、“接收方”等參數和其他相關執行細節。L2 上的樂觀節點從樂觀門戶合約偵聽此交易存款事件,並將事件的參數轉換為 L2 交易。此事務的發起方將是事件中指定的“發送方”,接收方將是事件中提到的“接收方”,其他事務詳細資訊也將從事件的參數中派生出來。
L2 節點將 OptimismPortal 發出的“交易存款”事件的參數轉換為 L2 交易。
例如,當使用者通過L1StandardBridge合約存入0.01二餅時,消息和二餅將傳輸到OptimismPortal合約(位址0xbEb5...幾分鐘后,這被轉換為 L2 事務:消息發送方是 L1CrossDomainMessenger 合約,接收方是 L2 上的 L2CrossDomainMessenger 合約,消息內容表明 L1StandardBridge 從 Bob 收到 0.01 二餅 充值。然後,這會觸發其他進程,例如 L2StandardBridge 鑄造 0.01 二餅,隨後將其傳輸給 Bob。
如何觸發它
如果您想強制將交易包含在 Optimism 的匯總合約中,您的目標是確保“從您在 L2 上的 L2 位址發起並執行”的交易可以成功執行。為此,您應該使用您的 L2 位址將消息直接提交到 OptimismPortal 合約(請注意,OptimismPortal 合約實際上位於 L1 上,但OP位址格式與 L1 位址格式匹配,因此您可以使用與 L2 帳戶位址相同的 L1 帳戶調用此合約)。從本合約發出的交易存款事件派生的 L2 交易的“發送方”將是您的 L2 帳戶,交易格式將與標準 L2 交易一致。
在從“交易存款”事件派生的 L2 事務中,Bob 本人將是贊助者;接收方將是 Uniswap 合約;它將包括指定的二餅,就像 Bob 自己發起 L2 事務一樣。
要使用 Optimism 的強制包含函數,您需要直接調用 OptimismPortal 合約的存款交易函數,並在 L2 上輸入您想要執行的交易的參數。我進行了一個簡單的力包含實驗。此交易的目標是使用我的位址在 L2 上執行自我轉帳 (0xeDc1...6909),並包含一條消息,上面寫著“強制包含”。這是我通過 OptimismPortal 合約調用存款交易函數執行的 L1 交易。從它發出的「交易存款」事件中可以看出,發送方和接收方都是我自己。
不透明數據列中的其餘值對諸如“調用 depositTransaction 函數的人附加了多少二餅”、“L2 事務發起方希望向接收方發送多少二餅”、“L2 事務 GasLimit”和“L2 接收方的數據”等資訊進行編碼。解碼此資訊后,您將獲得以下詳細資訊:「調用存款的人附加了多少二餅交易」:0,因為我沒有將二餅從 L1 存入到 L2;“L2 事務發起方想要向接收方發送多少二餅”:5566(wei);“L2 交易氣體限制”:50000;“L2 接收器的數據”:0x666f72636520696e636c7573696f6e,這是字串“強制包含”的十六進位編碼。不久之後,轉換后的 L2 事務出現了:一個 L2 事務,我將 5566 wei轉移到自己身上,Data 字段包含字串“強制包含”。此外,在“其他屬性”部分的倒數第二行中,TxnType(事務類型)顯示為系統事務 126(系統),表明此事務不是由我在 L2 上發起的,而是從 L1 事務的存款事件轉換而來的。
轉換後的 L2 事務
如果您想通過強制包含調用 L2 合約併發送不同的數據,您只需在存款交易函數中填寫參數即可。只需記住在調用存款交易函數時使用與 L2 帳戶相同的 L1 位址。這樣,當存款事件轉換為 L2 交易時,贊助者將成為您的 L2 帳戶。排序器視窗 將「交易存款」事件轉換為 L2 事務的樂觀 L2 節點實際上是排序器。由於這涉及事務排序,因此只有 Sequencer 才能決定何時將事件轉換為 L2 事務。當 Sequencer 偵聽 TransactionDeposited 事件時,它不一定會立即將事件轉換為 L2 事務;可能會有延遲。此延遲的最長持續時間稱為序列器視窗。目前,樂觀主網上的序列器視窗是24小時。這意味著,當使用者從 L1 存入資金或使用強制包含進行交易時,在最壞的情況下,它將在 24 小時後包含在 L2 交易歷史記錄中。
在樂觀中,L1 充值操作會觸發“事務存放”事件,然後只需等待 Sequencer 包含該操作即可。但是,在 Arbitrum 中,L1 上的操作(例如存入資金或向 L2 發送消息)存儲在 L1 上的佇列中,而不是簡單地發出事件。Sequencer 有一個特定的時間段將這些排隊的事務包含在 L2 事務歷史記錄中。如果排序器未能在此時間範圍內執行此操作,任何人都可以代表排序器介入以完成包含。
Arbitrum 在 L1 合約中維護一個佇列。如果 Sequencer 在一定時間內未能處理佇列中的事務,任何人都可以強制將這些事務包含在 L2 事務歷史記錄中。在Arbitrum的設計中,L1上的操作,例如存款,必須通過延遲收件匣合同,顧名思義,這些操作將在生效之前延遲。另一個合約,Sequencer 收件匣,是 Sequencer 直接將 L2 事務上傳到 L1 的地方。每次 Sequencer 上傳 L2 事務時,它還可以從延遲收件匣中獲取一些待處理事務,並將其包含在事務歷史記錄中。
當 Sequencer 寫入新事務時,它還可以包含來自 DelayedInbox 的事務。
設計複雜,缺乏參考物質
如果您參考 Arbitrum 關於 Sequencer 和 Force Inclusion 的官方文檔,您會發現 Force Inclusion 如何工作的一般說明,以及一些參數和函數名稱: 使用者首先在 DelayedInbox 合約上調用 sendUnsignedTransaction 函數。如果 Sequencer 在大約 24 小時內未包含它,用戶可以調用 SequencerInbox 合約上的 forceInclusion 函數。但是,官方文檔沒有提供這些函數的連結,因此您必須自己在合約代碼中查找它們。當您找到sendUnsignedTransaction函數時,您意識到您必須自己填寫nonce值和maxFeePerGas值。這是誰nonce?哪個網路的maxFeePerGas?你應該如何正確填寫它?沒有參考檔,甚至沒有NatSpec。您還可以在 Arbitrum 合約中找到許多類似的函數:sendL1FundedUnsignedTransaction、sendUnsignedTransactionToFork、sendContractTransaction、sendL1FundedContractTransaction。沒有文檔解釋這些函數之間的差異,如何使用它們或如何填寫參數,甚至沒有NatSpec。
您嘗試填寫參數並使用試錯方法提交交易,希望找到正確的用法。但是,您發現所有這些功能都地址別名應用於您的 L1 位址,導致 L2 上交易的發送者是一個完全不同的位址,從而使您的 L2 位址處於非活動狀態。後來,您偶然發現了Google搜尋結果,該結果顯示Arbitrum有一個教程庫,其中包含演示如何從L1發送L2事務的腳本(本質上是強制包含)。本教程列出了一個之前未提及的函數:sendL2Message。令人驚訝的是,所需的消息參數實際上是使用 L2 帳戶的已簽名 L2 事務。誰會知道「通過強制包含發送到L2的消息」實際上是「簽名的L2交易」?此外,沒有文檔或 NatSpec 解釋何時以及如何使用此功能。
結論:在仲裁上手動生成強制交易非常複雜。建議遵循官方教程並使用 Arbitrum SDK。與其他匯總不同,Arbitrum缺乏清晰的開發人員文檔和代碼註釋。許多函數缺乏對其用途和參數的解釋,導致開發人員花費比預期更多的時間來集成和使用它們。我也在仲裁不和諧中尋求説明,但沒有得到滿意的答覆。在 Discord 上詢問時,他們只指示我查看 sendL2Message,並沒有解釋其他方法的功能(包括強制包含文檔中提到的那些方法,如 sendUnsignedTransaction)、它們的目的、如何使用它們或何時使用它們。
不幸的是,StarkNet目前沒有Force Inclusion機制。官方論壇上只有兩篇文章討論審查和強制包容。無法證明失敗交易的原因是StarkNet的零知識證明系統無法證明失敗的交易,因此不能允許強制包含。如果有人惡意(或無意)強制包含失敗的、無法證明的交易,StarkNet 就會陷入困境:因為一旦交易被強行包含,證明者必須證明失敗的交易,但它不能。StarkNet預計將在v0.15.0版本中引入證明失敗事務的功能,之後應進一步實施強制包含機制。
zkSync 用於 L1->L2 消息傳輸和強制包含的機制通過郵箱合約的請求 L2Transaction 函數處理。使用者指定 L2 位址、呼叫數據、要附加的二餅量、L2GasLimit 值和其他詳細資訊。requestL2Transaction 函數將這些參數組合到 L2 事務中,並將其放入 PriorityQueue 中。當 Sequencer 打包事務並將其上傳到 L1(通過 commitBatches 函數)時,它會指示要從 PriorityQueue 中獲取多少事務以包含在 L2 事務記錄中。在強制包含方面,zkSync 類似於 Optimism,其中發起方的 L2 位址(與 L1 位址相同)用於調用相關函數並填寫必要的詳細資訊(被調用方、調用數據等),而不是像 Arbitrum 那樣需要簽名的 L2 事務。但是,在設計上,它類似於 Arbitrum,因為兩者都在 L1 上維護一個佇列,並且 Sequencer 從佇列中獲取使用者直接提交的待處理事務並將其寫入事務歷史記錄中。
如果你充值 二餅通過 zkSync 的官方橋接,就像這個交易一樣,它會調用郵箱合約的 requestL2Transaction 函數。此函數將存款二餅 L2 事務放入 PriorityQueue 中,併發出 NewPriorityRequest 事件。由於合約將 L2 交易數據編碼為位元組字串,因此不容易讀取。但是,如果您查看此 L1 事務的參數,您會發現 L2 接收者也是事務的發起者(因為它是對自己的充值)。一段時間后,當 Sequencer 將此 L2 事務從 PriorityQueue 中取出並將其包含在事務歷史記錄中時,它將轉換為 L2 事務,您可以在其中轉移給自己。轉帳金額將是贊助者在L1存款二餅交易中附加的二餅金額。
在 L1 存款交易中,發起人和收款人都0xeDc1...6909,金額為0.03二餅,沒有調用數據。
在L2上,將有一個事務,其中0xeDc1...6909 轉移到自己。事務類型 (TxnType) 為 255,表示系統事務。然後,就像我之前在 Optimism 上試驗強制事務函數一樣,我調用了 zkSync 的 requestL2Transaction 函數並發起了一個自轉移事務:沒有附加二餅,調用數據包含字串“強制包含”的十六進位編碼。然後將其轉換為L2事務,我將其轉移到自己身上,calldata包含“強制包含”的十六進位字串:0x666f72636520696e636c7573696f6e。
當
Sequencer 從 PriorityQueue 獲取事務並將其寫入事務歷史記錄時,它們將轉換為相應的 L2 事務。使用請求L2Transaction功能,用戶可以在L1上提交與其L2位址相同的L1帳戶的數據,指定L2接收者,要附加的二餅量和調用數據。如果使用者想要調用其他合約或包含不同的數據,他們只需要在 requestL2Transaction 函數中填寫參數即可。
尚無適用於使用者的強制包含功能
儘管放置在 PriorityQueue 中的 L2 事務將有一個計算的等待期以供 Sequencer 包含,但 zkSync 當前的設計沒有允許使用者強制包含它的強制包含功能。這意味著它只是部分解決方案。即使存在“包含等待期”,最終也取決於 Sequencer 是否決定包含它:Sequencer 可以在該期限到期後包含它,或者從不包含 PriorityQueue 中的任何事務。將來,zkSync 應該添加一些功能,允許使用者強制將事務包含在 L2 事務歷史記錄中,如果這些事務在等待期后仍未被 Sequencer 包含。這將是一個真正有效的部隊包容機制。
L1依靠大量的驗證者來保證網络的“安全”和“抗審查性”。但是,匯總的抗審查性較弱,因為事務由幾個甚至單個 Sequencer 寫入。因此,Rollups 需要一個強制包含機制,以允許使用者繞過 Sequencer 並將交易寫入歷史記錄,防止 Sequencer 的審查使 Rollup 無法使用並防止使用者提取資金。強制包含允許使用者強制將交易寫入歷史記錄,但設計必須選擇“交易是否可以立即插入歷史記錄並立即生效”。如果允許立即生效,則會對 Sequencer 產生負面影響,因為 L2 上的掛起事務可能會受到來自 L1 的強制包含的事務的影響。因此,匯總中的當前強制包含機制首先將從 L1 插入的事務置於等待狀態,併為 Sequencer 提供一個時間視窗來做出反應並決定是否包含這些掛起的事務。zkSync 和 Arbitrum 都在 L1 上維護一個佇列,以管理從 L1 發送到 L2 的 L2 事務或消息。Arbitrum稱之為DelayedInbox;zkSync 稱之為 PriorityQueue。但是,zkSync 發送 L2 事務的方法更類似於 Optimism,其中消息使用 L2 位址從 L1 發送,因此當轉換為 L2 事務時,發起方是 L2 位址。在樂觀情緒中發送 L2 交易的函數稱為存款交易;在 zkSync 中,它被稱為 requestL2Transaction。相反,Arbitrum 生成一個完整的 L2 事務並對其進行簽名,然後通過 sendL2Message 函數發送。在 L2 上,仲裁使用簽名將簽名者還原為 L2 事務的發起者。StarkNet目前沒有強制包含機制;zkSync 有一個半實現的強制包含機制——它有一個 PriorityQueue,佇列中的每個 L2 事務都有一個包含有效期,但這個有效期目前只是為了顯示。實際上,排序器可以選擇不包含優先順序佇列中的任何 L2 事務。
本文轉發自:[Geek Web3],原標題為“理論與實踐:如何在以太坊 Rollup中觸發抗審查交易?”,版權歸屬原作者[臺北以太坊聚會負責人NIC Lin],如果您對轉載有任何異議,請聯繫Gate Learn Team,團隊將按照相關程序儘快處理。
免責聲明:本文表達的觀點和意見僅代表作者個人觀點,不構成任何投資建議。
本文的其他語言版本由Gate Learn團隊翻譯。在未引用Gate.io 的情況下,禁止複製、分發或抄襲翻譯后的文章。