Gas 上限
礦池決定著區塊的Gas 上限。我們先來快速回顧下礦工和礦池的運營模式:幾乎所有礦工都會選擇將自己的算力起源與其他人的匯集在一起。他們會將資源集中到一起,然後獲得穩定的收益流,而不是冒著長期沒有收益的風險、單打獨斗地挖礦。因此,礦池應運而生,負責驗證每位礦工的貢獻,並分配下一個區塊的挖礦任務。大多數區塊都是由大礦池挖出的。下圖顯示了以太坊誕生以來,礦池的出塊佔比情況:
由上圖可見,星火礦池、Ethermine 和魚池的出塊佔比遙遙領先。
除了參與硬分叉之外,礦池運營者還承擔一項重要的治理職責:設置以太坊的Gas 上限。不同於出塊時間和Gas 價格等特性,每個區塊的Gas 上限都需要主動設置。新區塊的Gas 上限與上一個區塊之間的差距必須在0.1% 以內,因此每個區塊的大小只能輕微上下浮動(參見黃皮書:公式47)。如果礦池運營者達成共識,可以大幅調整Gas 上限:在2.5 個小時內,Gas 上限可以加倍或減半。如果沒有達成共識,Gas 上限就是礦池規模的加權中位數。
目前,由於缺乏關於礦工真實行為的詳細信息,我們採取了一種比較簡單的方法:投票系統。希望我們將來能通過軟分叉將這一方法轉變成更精確的算法。 —— 以太坊的基本設計原理 (2015 年3 月)
從以太坊發展初期開始,由礦工設置Gas 上限就是一個權宜之計。由於其它方案都不夠好,這個權宜之計就一直延續了下來。 EIP 1559 提出了一個不同的機制,目前社區正在討論是否將其加入柏林硬分叉。在那之前,礦池運營者可以像OPEC(石油輸出國組織)管理石油開採那樣管理Gas 供應。
- Ethermine 礦池運營者-
最近,全球最大的兩個以太坊礦池做出了一個有爭議的決定,將每日Gas 產量提高25% 。此舉的目的是通過增加Gas 供應量來抑製過高的交易費。到目前為止,我們發現,再怎麼提高Gas 上限,也跟不上用戶對交易需求的增長速度。這就意味著,Gas 價格在經歷短暫下降後,最終還是會再度回升。
提高Gas 上限會給以太坊帶來很高的隱形安全成本。正如我們所見,提高Gas 上限會提高叔塊率和空塊率。在交易負載量正常的情況下,這一影響不大。但是出於安全性考慮,我們只對極端情況感興趣,並不關心正常情況。根據Perez 和Livshits(2019)的研究,在最糟糕的情況下,如果生成一批處理效率極低的交易(在Gas 成本相同的情況下,處理這類交易的速度比普通交易慢100 倍),並將其打包到區塊內,節點需要花90 秒的時間來處理這個區塊,從而導致節點落後,礦池挖出大量空塊和叔塊。自這項研究發布以來,已經出現了一些緩解措施,但是問題並未得到徹底解決。因此,兩位主要的節點開發者Péter Szilágyi 和Alexey Akhunov 批評了關於提高Gas 上限的決定。
因此,達到Gas 上限時,Gas 價格就會上漲,而且我們似乎不應該進一步提高Gas 上限。那麼我們還能採取什麼措施?我們能夠降低交易所需的Gas 成本嗎?
Gas 耗用量
交易的Gas 消耗量基本上就是其EVM 操作的消耗量。一筆交易是由許多EVM 基本操作組成的,而每一個操作的Gas 耗用量都通過EIP 和硬分叉來治理的。在過去的硬分叉中,主要操作的Gas 消耗量有升(EIPs 150、160、1884)有降(EIPs 1108、2028、2200)。計劃中的 “柏林” 硬分叉也在考慮引入幾個Gas 消耗量變更(EIPs 1380、1559、2046、2565、2537)。
所有這些變更的目的都是為了讓手續費能更精確地反映操作的真實成本。因為計算操作的成本會隨著計算機性能和算法效率的提升而變得更低。但存儲操作的成本則完全不同。存儲和查找操作的成本會跟隨區塊鏈狀態規模的變動而變動,而以太坊的狀態規模是一直在變大的。這種增長不會因為存儲設備的升級或者數據庫技術的改變而改變。
這就意味著存儲仍然會是DeFi 成本中的一大塊。創建一個新的餘額需要2 萬Gas,而修改一個已有的餘額要耗費5 千。一筆轉賬至少要改變兩個月,一次交換則要改變至少4 個,更複雜的DeFi 交易會包含更多昂貴的狀態操作。看起來實在不容易降低相關存儲的數量和成本,這個趨勢九頭牛都拉不回來。但好消息是,Layer-2 擴展方案會嘗試做成存儲粗放且計算密集的,看起來會更討喜一些。
最後,提高區塊的Gas Limit 也同樣有安全性方面的隱憂:提高Gas Limit 是有效果的辦法中最差的。單純根據當前真實操作的平均成本來改變Gas 消耗量也是非常危險的(Naively optimizing the Gas cost for the current true average cost of operations is very dangerous.)。
到此為止,為什麼擴展以太坊是一個棘手的問題,已經很顯然了。在我們討論大家提出的解決方案以前,我們希望再探討一個當前以太坊可能傷害DeFi 用戶的缺點。
礦工可抽取價值
區塊生產者雖然受到共識規則的限制,但共識規則也為他們提供了一些重要的自由(freedom),比如交易選擇和排序。對於一般的代幣轉賬來說,生產者的自由並不會造成很大影響,但對於DeFi 交易比如交易所交易來說,搶跑(front-running,指發送Gas Price 更高的交易來搶先使交易上鍊)可能收穫巨大的經濟價值。更複雜的問題是,一筆目標交易被夾在兩筆交易中間,像夾三明治一樣。 Daian et al. (2019) 將能夠從搶跑交易中獲得的價值稱為 礦工可抽取價值(miner extractable value)。
沒有證據表明現在的礦池在惡意利用他們的交易排序自由,但如果他們做過,也必然是有獲利的。礦池一般都使用Geth 客戶端,該客戶端會根據Gas Price 來排序交易(見1,2)。這導致了Gas 的價格競拍,對Gas 出價最高的交易能最先打包上鍊。這一機制的負面效果是,任何人都能通過提高出價來搶跑一筆交易。相互競爭的交易者會持續提高出價,直至交易的利潤被Gas 費完全耗盡。到了這個時候,交易可獲得的所有價值都會變成Gas 費,進到礦工的口袋(譯者註:這是一個理論上的結果,也是“礦工可抽取價值” 概念的由來;實際上,高Gas費的交易可能很快就會打包上鍊,而不會存在相互競爭的交易者像拍賣那樣安逸地相互出價;所以礦工可抽取價值也沒有想像中那麼高,畢竟礦池之間有競爭)。
另一方面,讓自己的交易緊跟在另一筆交易之後上鍊,可能也是有價值的,比如在價格信息傳輸機制更新信息後第一個清算倉位(liquidate a position)。這個叫做back-running,最後也會變成礦工的收益。
礦工可抽取價值最終是從普通的DeFi 用戶處得來的,表現是更大的價差、更差的價格、更高的手續費,以及更多失敗的交易。要想獲得更好的DeFi 體驗,就應該解決這個問題。解決辦法之一是限制交易排序自由,比如要求一個區塊裡的交易按Gas Price 由低到高排序。
現在我們已經對以太坊的局限性及其對DeFi 的影響有了全面的了解。當然,所有天王級的團隊都在開發解決方案,對吧?
一個Layer-1,兩種願景
現在有很多厲害的團隊在開發不同的可擴展性解決方案。解決方案主要有兩個方向,“Layer-1” 和“Layer-2”。 Layer-1 的方案致力於打造一個更可擴展的區塊鏈來取代當前的以太坊,Layer-2 方案則是嘗試在當前以太坊的基礎上接入更可擴展的基礎設施。我們這裡就談Layer-1,Layer-2 方案留給下一篇文章。
我們從最明顯的一個方案開始:提高當前以太坊區塊鏈的性能。也就是“Eth1.x” 同仁在做的事。單論以太坊客戶端的性能提升,就有很多工作可以做。不過,Eth1.x 還沒有得到他們應得的支持力度,所以進展緩慢。想要對這個方向的性能提升可達到的程度有個基本概念,只需了解一下Solana 就好,Solana 實現了以太坊的1000 倍吞吐量,而且還有空間可以提高;缺點在於需要很高級的硬件才能運行全節點。
大部分其他解決方案都有三點共同之處:(1)使用WebAssembly 作為虛擬機;(2)最小化狀態的架構;以及最重要的,(3)分片。當前的以太坊是串行執行所有交易的。事實上,讓交易能排成一個隊列可以說是區塊鏈的全部意義所在。但這種模式的缺點就在於,難以並行執行交易,所以我們無法通過投入直接更多資源來解決擴展問題。那麼把區塊鏈分割成多個鬆散互聯的領域,一個線程就叫一個“分片”,就能實現並行化處理。在一個分片內部,事務仍然是串行發生的,但不同分片的事務是移步發生的。這就使得所有分片能並行運行,以分片數量為倍數擴大網絡的吞吐量。我們用來分割網絡的領域也不需要與分片一一對應,可以把多個領域分配給同一個分片(線程),甚至可以移動它們做負載均衡。看Near Protocol 的“夜影” 協議白皮書可更深入地了解分片的大體。
具體如何將區塊鏈分割成多個領域,下一代的區塊鏈各有想法。可以認為,這是一條從細粒度(許多細小領域)到粗粒度(少數幾個大型領域)的光譜。
fine parallelization <-------------------> coarse parallelization DFinity Eth 2.0 Polkadot actors (TBD. Contracts?) chains兩個項目分別代表這條光譜的兩端。 DFinity 在細粒度這一端,每一個“actor” 都有自己的細小領域,而且每個actor 之間的交互都是異步的。粒度稍大的的Near Protocol,其中每個合約都有自己的領域。粗粒度一端的是PolkaDot,一個領域就是一整個分片,更具體一點應該叫做一條“平行鏈”。從一個dApp 開發者的視角來看,斷言Ethereum 2.0 位於哪個位置還為時尚早。 ETH1 EE(執行環境)應該是粗粒度型的,其邊界恰好與一個分片的邊界一致,就是當前的以太坊所化成的一個分片(也就是Eth1 在Eth2 實現後的未來)。一個專門的Eth2EE 可能會選擇一個更細粒度的方案。細粒度方案的長處在於它們是透明的;可以將所有的跨合約調用一視同仁,無論這些調用是否跨越了分片邊界。這就能反過來允許我們通過在分片間移動合約來實現負載均衡。
缺點在於,跨越領域的事務就不再是原子化的了,它們會變成 並行的,甚至是部分 不可逆 的。在DFinity 和Near 中,這一點表現為跨合約的交易變成async狀態,並返回一個承諾:你需要await (等待)。在一場await期間,所有到時已經發生的交易都會被提交到鏈上。然後其他人的交易可以堆積在上面。到這時你就無法回滾已經發生的事情了。當await最終解決的時候,它會從合約調用中返回“成功” 或者“失敗”。有許多提案嘗試避免這一點、找回某種形式的跨分片原子性,但都有自己的缺點。看起來,擁抱非原子性會是自然結果。但對DeFi 應用來說,一個異步的transferFrom調用會帶來相當大的挑戰。設想一個兩方之間的簡單交換,Alice 和Bob 希望交換Eth 和Dai。基本合約看起來會像這樣:
但現在我們需要能處理錯誤。如果第一筆交易失敗,我們可以簡單地終止交易。但如果第一步交易成功而第二筆交易失敗,我們要能返還給Alice 一個ETH。問題在於,Bob 可能已經在我們處理錯誤之前就花掉了這筆錢。解決這個問題的一個辦法是使用一個escrow:
很好,現在就不會有人丟幣了。但現在Bob 就對Alice 的出價有了一個免費的排他性期權(free exclusive option)。雖然現在Alice 的錢保管在託管方手裡,但這些錢既不能接受其他人的交易請求,也不能保證跟Bob 的交易一定會成功。你可以用懲罰惡意行為來解決這個問題,但是你很難確定合理的懲罰力度,因為不同DeFi 交易的價值差別非常大。你也可以要求所有市場參與者從一開始就把錢都放在同一個儲蓄合約(託管方)裡,但這樣就重新使得狀態集中化、取消了分片的意義。
另一個需要注意的事情是,這些並發問題可能非常棘手。在現實的交易所中,訂單的填充狀態(fill-state)需要不斷更新,這就使得寫一遍的更加複雜。如果說困擾以太坊1.0 的可重入漏洞(reentrancy bug)是蝴蝶,可能引起巨大的後果,那並發問題就是床上的臭蟲(bug),無孔不入。並發漏洞是不確定的,而且在測試中可能根本看不出來。就像我們在上面的簡單的交換的例子中看到的,開發者需要從頭重新思考整個架構,就像床上的臭蟲,清除它們的唯一辦法就是把一切都推倒,從頭重建。
交易所是DeFi 世界其餘部分的基石,而且顯然是個川流不息的連續過程。我們已經看過了訂單簿類型的交易所面臨怎樣的挑戰。自動化做市商(Automated market maker)交易所還簡單點,因為參與者已經將資金都存儲在託管方(合約)處,但在這種情境下,儲備起來的餘額本身就阻礙了並行化處理。即使在更快的傳統交易所裡,結算活動最終也是在一個撮合引擎裡面按順序處理的,不會用到並發,(但比較好的是傳統交易所還可以有冗餘)。想深入了解傳統交易所是如何運作的,可觀看Brian Nigito 的演講。
上面說的不代表這些問題是不可能解決的。最簡單的解決方案就是要求所有這些協議在每一個分片上都部署一個獨立的實例,然後讓套利者來保證不同實例之間沒有價差。又或者,我們可以讓一個同步的分片擁有足夠強大的性能,強大到可以包含所有的DeFi 交易,然後就不用煩惱並發問題了。
在本文中,我們歷數了以太坊在擴展DeFi 容量時的局限性。如你所見,這是一個複雜的問題,沒有顯而易見的解決辦法。在後續的文章中,我們會深入了解具體的一類解決方案,“Layer-2 方案”,並闡述0x 自己的想法。
參考文獻
Daniel Perez & Benjamin Livshits (2019). “Broken Metre: Attacking Resource Metering in EVM.”Daian et al. (2019). “Flash Boys 2.0: Frontrunning, Transaction Reordering, and Consensus Instability in Decentralized Exchanges.”Brian Nigito (2017 ). “How to Build an Exchange.”Danny Ryan (2020). “The State of Eth2, June 2020.”Scott Shapiro & William Villanueva (2020). “ETH 2 Phase 2 WIKI.”Near Protocol sharding design
原文鏈接:
https://blog.0xproject.com/scaling-defi-layer-one-7eeb24aca4f0
作者: Remco Bloemen
翻譯&校對: 閔敏 &阿劍