你最近要是用了 DeFi 产品,一定会因高额交易费望而却步。现在为以太坊交易支付几十到上百美元交易费再正常不过。以当前的费率,只有「巨鲸」交易才能获利。就忘了那些所谓的「让没有银行账户的人享受金融服务」 (banking-the-unbanked) 或「构建普惠大众的无需许可金融基础设施」这些高尚的目标吧。以太坊变成了富人的乐园。
小额交易手续费有时会高达 10%
高额交易费的背后是区块链可扩展性问题。这个问题众所周知,甚至还有一个专门维基百科页面。可扩展性是目前区块链发展的最大限制,除此之外还有确定性时间长、易出现抢先交易、跨链互操作性等问题。
我们想要创造一个所有价值可自由流动的代币化世界,区块链的局限却正在阻碍我们实现这一使命。这就是为什么 0x Labs 专门成立工程师团队,力图解决这些局限性的问题。通过我们的研究,我们希望通过本文来探讨以太坊的局限性,及其如何影响 DeFi 用户。此外,本文也会简单论及下一代区块链。在未来,我们还将撰写文章,探讨不同的解决方案 Layer 2,并演示我们满足 DeFi 需求的策略。
首先要说明,以太坊交易的大小以 gas 计算。区块中收集交易,大约每 13 秒一个区块。每个区块所容纳的交易数量空间有限,也就是「gas 上限」。目前每个区块大约有 1,200 万 gas 交易空间。纯 ERC-20 代币转账大约需要五万 gas。也就是每个区块可容纳最多 240 笔代币转账,约每秒 18 笔转账。DeFi 转账通常涉及多笔代币转账和簿记,造成交易成本翻倍,进而限制区块吞吐量。「gas 上限」和区块时间意味着需要持续提供交易所需的 gas。
首先,我们来看以太坊历史上 gas 供应及其使用如何增长。
每天以太坊上约有六千区块挖出,有几十亿价值 gas 交易空间。主要由于「gas 上限」增加,gas 交易数量也随着时间改变、增加。同时,交易消耗总 gas 费也会随着以太坊上的交易增多、变大而增长。
回顾以太坊整个历史的 gas 供应(灰色)和消费(黑色),如下图:
从上图可以看出,以太坊是企业级应用,因为办公时间应用最高
拜占庭 (Byzantium)、君士坦丁堡 (Constantinople) 和缪尔冰川 (Muir Glacier) 硬分叉之前,以太坊 gas 供应有几次断续下跌。这都是以太坊「难度炸弹」(也称为 「冰川时代」)的影响。
在「冰河时代」,出块时间大幅增加,造成单日出块量减少,gas 供应降低。当然这种情况非常不受欢迎,迫使网络硬分叉来调整。这样做的目的就是:迫使硬分叉带来升级改进,防止陷入创新停滞。伊斯坦布尔 (Istanbul) 硬分叉没有重设「难度炸弹」,所以很快进行了缪尔冰川硬分叉。即将进行的柏林(Berlin) 硬分叉考虑更改这一机制 (EIP 2515)。
看用量情况(黑色),以太坊自从 2017 年 ICO 热潮以来,gas 用量始终占 60% 以上。之后「gas 上限」几次增长到四倍,每次上限增长后 gas 用量也成比例增长。过去几个月,以太坊用量一直卡在 95%。
要理解以太坊 gas 用量为何不会超过 95%,需要先了解「空块」 (empty block) 和「叔块」 (ommer block) 的概念。
以太坊历史上,即使需求再高,gas 用量也从未超过上限 95%。让人惊讶的是,剩余 5% 浪费在完全空的区块。这些空块定期出现,大约每二十个块有一个。有交易要付款进入打包入块,为什么还会有人要挖空块?先看以下数据:
空块率随着时间稳定增长,目前是 5%。所有矿池的空块率相等,所以挖空块的不会是恶意矿工。相反,真实原因可能是出块过快。如果挖块时间低于六秒,那获得空块的概率便会几何增长。
一个解释就是,矿工一获得新区块头,在完整个区块没打包完成前便开始挖下一个区块。这种操作在比特币里称为 SPV 挖矿,让矿工可以没完成一个区块验证可即刻开始找下一个区块,但只能加入空区块。新区块完全打包完成后,就可以添加下一个完整区块,并切换去挖。
这种解释的进一步证据就是,如果同一矿工快速连续挖到两个区块,空块率就会降低 25%。
挖空块的另一种方法就是,在挖上一个区块的同时,处理新区块。这就造成同时挖出多个区块。如果出现此类情况,以太坊会选出一个主干区块,把其他区块标记为「叔块」 (ommer)。挖到「叔块」的矿工仍旧可以得到小额奖励。这种情况出现的比率稳定:
2018 年 gas 用量达到峰值期间,「叔块」率也到新高,但之后占比降到所有挖出区块的 5%。这与矿工可能此时更改挖矿策略造成空块率升高相吻合。
空块率对以太坊可扩展性的伤害没有立即表现出来,但确实有影响。自从拜占庭升级的 EIP-100 提案,难度调整维持一定主干链区块和「叔块」比率。所以「叔块」率高就表示浪费的「叔块」增多,主链增加的块减少。这就表现为每日出块时间延长,每日总 gas 量减少。(造成出块时间延长的另一个原因是「难度炸弹」)
「叔块」或空块都是以太坊网络的重要健康指标。任何一个指标增长,都意味着每日用于交易的总 gas 减少。「叔块」率分析是支持 EIP 2028 和 1559 研究(参见 1、2、3)的主要部分。意外的是,这两个 EIP 都没提到空块率,而且研究存在方法缺陷。用逻辑回归等恰当的统计学方法分析「叔块」率和空块率,这样更严谨的分析会更好。
有方法可以降低空块率和「叔块」率。推定根本原因就是,由于网络和处理延迟,矿池没有最新的状态可用。一个简单但不太让人满意的解决方案就是,让矿池更中心化,最近的状态就会集中在一起。
更去中心化一点的解决方案就是 bloXroute 那样,创建矿池间专用连接。受「间谍挖矿」 (spy mining) 启发,可以让矿池预先分享目前在挖的区块。其他矿池会准备可能会挖的后续区块。矿池成功挖完自己的块后,就已经知道后续可以挖哪些块,立即切换。在堆栈上方,改进节点通讯协议和处理算法也有效,这些地方仍有改进空间。最终,降低空块率和「叔块」率才能单日提升最多 5% gas 供应量。
所以似乎有 95% gas 上限,但如果有人想要使用超过 95% 的量怎么办?
以太坊 gas 上限到顶会怎样?矿工可以自由选择打包交易(后续详述),但实际上矿工按「高 gas 费优先原则」打包交易,因为这样利润最高。这样就产生对可用 gas 的第一价格拍卖现象。
Gas 价格已成为「完美非弹性供应量」的教科书范本。随着网络使用率超过 80%,涨到 95% 位置,gas 价格明显增加。任何潜在需求增加只会增加价格,直到价格赶退需求,降回相同水平。
让价格下降的唯一方式就是增加 gas 供应,或降低需求,而最近 gas 上限增加不足以有效降低 gas 价格。
乍一看,对以太坊都兴趣增加,只会推升价格,不会造成用量增长。实际上,高价值使用会驱逐低价值使用,便宜的游戏类非同质化代币 (NFT) 交易减少,大额 DeFi 交易更多。
提案 EIP 1559 意在使短期内 gas 供应更加弹性。在需求高峰期,可以加大区块容量(高达 2,000 万 gas)。这就有助于保持高峰 gas 价格平稳,可以更快打包交易。但这样无法改变长期供应量不具弹性的问题。
根据提案 EIP-1559,长期仍有固定 gas 发行率,意味着 gas 价格会持续上升,直到需求足够小。EIP-1559 仍旧鼓励同一区块内支付溢价的优先打包处理(假设矿池继续按原先顺序挖区块)。这就意味着抢先交易、gas 竞价和矿工牟利的情况仍旧存在。
图中的数字代表下个区块内可打包交易的最低价格。你愿意等得越久,gas 价格会越低。历史数据表明,若你愿意等两分钟或更久,那价格便会很低。EIP-1559 有助于降低溢价,便于更快处理交易。
因此,gas 上限促使 gas 价格上升,那我们该如何提高上限?
矿池确定 gas 上限。下面简要概述矿工和矿池工作原理:几乎所有矿工都会把算力资源聚集一起。矿工们不会冒着长期没有收获的风险单独去到下一个区块,而是将资源聚集而获得稳定收入。矿池来验证每个矿工贡献的算力,再继续挖下个区块,这种方式推动了矿池发展。大型矿池最终会挖得较大份额区块。
下面来看以太坊上矿池份额的发展情况:
星火、Ethermine 和鱼池三家获得主要区块。
除了进行硬分叉外,矿池运营者有重要治理责任:他们可以设置以太坊 gas 上限。与出块时间和 gas 价格(新特性)不同,gas 上限由每个区块各自确定。新 gas 上限限于上一区块的 0.1%,所以每个区块仅能做出微小浮动(《黄皮书》公式 47)。要是三家矿池一致同意快速复利滚动单边浮动,两个半小时 gas 上限就能翻倍或减半。要是意见不一致,gas 上限就是矿池规模的加权平均数。
目前由于缺少矿工实际操作的详细信息,我们会用简单的方法:投票系统。[…] 希望未来我们可以软分叉,变为更精确的算法。
以太坊设计原理 (2015 年 3 月首次加入)
以太坊早期矿工设定 gas 上限的方式是「补缺解决方案」。很多「补缺解决方案」足够好,就变成了备用参数。EIP 1559 建议采用不同机制,目前正在讨论在柏林分叉时应用。这之前,矿池运营者可像 OPEC 控制石油产量一样控制 gas 供应量。
Ethermine 矿池运营者
最近两大矿池一致决定提升 gas 产量 25%,颇有争议。目的本是通过增加 gas 供应来缓解高交易费压力。目前我们所看到的,交易需求增长快过 gas 上限增长速度。这就造成价格暂时趋缓,最终还是会上升。
提高 gas 上限会对以太坊安全带来巨大隐患。如上所述,gas 上限会增加「叔块」率和空块率。正常交易负载下,这一增长很小。但对于安全问题,我们不关心正常行为,只关心糟糕情况下的不利行为。Perez 和 Livshits (2019 年) 研究了这种糟糕情况,结果就是同等 gas 成本下,糟糕时的交易要比正常交易慢百倍。需要九十秒区块才能填满交易。这就造成节点同步滞后,矿池挖「叔块」和空块。至本稿发布,问题已有缓解,但不足以避免。这就引致两位节点主开发者 Péter Szilágyi 和 Alexey Akhunov 批评提高 gas 上限的决定。
所以,gas 上限促使 gas 价格上升。似乎我们不该一味增加 gas 上限。那该怎么做?或许可以降低交易所需的 gas 成本?
交易的 gas 成本主要由 EVM 运行成本组成。交易是由众多 EVM 操作组成,每次运行成本由 EIP 和硬分叉决定。过去几次硬分叉中,有些操作的 gas 成本已经增加 (EIPs 150、160、1884),有些降低 (EIPs 1108、2028、2200)。计划中的柏林硬分叉也在在考虑变更一些特定操作的 gas 成本。
所有变更的目标是要让费用更准确反应操作的真实成本。这就意味着,随着计算机和算法变快,计算运行成本会降低。
而存储操作成本有所不同。存储与检索成本视链上状态大小而定,而以太坊状态大小在持续增加。改善存储设备或数据库不会抵消状态规模的增加。
这就意味着,存储仍旧是 DeFi 应用的大额成本。创建新的余额要两万 gas,修改现有余额要五千 gas。转账至少要修改两次余额,汇兑至少要修改四次,DeFi 交易所需的状态费用更高。似乎没有简单方法能降低相关存储量,有需求,存储费就会上升。好的一面,Layer 2 扩展解决方案偏向轻量存储和高计算量,似乎更有优势。
最后,随着 gas 上限提高,也会出现相同的安全担忧:糟糕情况影响大。本地优化 gas 成本达到当前操作的平均成本很危险。
这样就很清楚为何以太坊扩展性的问题这么棘手。在给出解决方案前,还需提及目前以太坊伤害 DeFi 用户的另一局限之处。
区块打包者遵守共识规则。共识规则保证交易选择和排序等重要自由。对于普通代币转账,问题不大。但对交易所等 DeFi 交易,抢先交易就有很高经济价值。目标交易两面受攻击,便会出现更复杂的牟利行为。Daian 等人 (2019) 称之为「矿工牟利」 (miner extractable value)。
矿池似乎不会恶意使用自己的交易排序自由,但仍可以用其牟利。矿池有可能使用 Geth 按 gas 价格排序交易(参见 1、2)。这就会产生 gas 价格拍卖,最高竞价交易优先。这会造成不良影响,任何人都可以通过高竞价抢先交易。竞争交易者持续竞价让 gas 价格升高,直到交易利润完全抵消 gas 费。目前,所有牟利都会变为交易费落入矿工口袋。
其他情况下,恰好接着一笔交易会有价值,例如价格预言机更新后第一个清算仓位。这称为「back-running」,结果也是矿工获益。
大价差、价格偏离、高手续费及更多失败交易,最终会让 DeFi 用户受损,矿工牟利。要有更好的 DeFi 体验,这个问题就得解决。解决这个问题就要限制交易排序自由,例如要求一个区块内最低 gas 价格的交易优先。
现在已完全了解以太坊的局限,及其如何影响 DeFi。当然所有致力于扩展性的明星团队终将解决这个问题,对吧。
有很多出众的团队致力于不同可扩展性解决方案。解决方案有两种:Layer 1 和 Layer 2。Layer 1 解决方案的目标是构建扩展性更好的以太坊,Layer 2 解决方案是要在以太坊的基础上构建更具可扩展性的基础设施。
从最明显的问题开始:提升现有以太坊的性能——这是 Eth1x 要做的事情。改进以太坊客户端性能,仍旧可以有很多提高。糟糕的是,Eth1x 几乎没有得到任何应有的支持,所有进展很慢。
要了解 Eth1x 可以达到何种性能,可以先来看看 Solana。Solona 吞吐量可达到以太坊千倍以上,还有提升空间。这种方法的主要劣势是,运行全节点的硬件要求很高。
多数其他解决方案都有三个共同点:
使用 WebAssembly 作为虚拟机,极简状态架构,和最重要的分片。目前以太坊上的所有交易都按序列执行。交易排序毫无疑问是区块链的关键。这种模式的缺点是,很难并行处理,所以投入更多资源也无法轻松解决可扩展性问题。这就是下一代区块链 Eth2.0 要解决的。
通过更改交易执行方式,让交易平行处理。将区块链分为多个松散连接的域,也就是称作「分片」的处理程序,来实现这一方案。一个分片内的交易仍旧按顺序排列,但分片之间是异步进行。这就允许所有分片平行运行,依分片数量扩展网络。
用以分离的域不一定与分片相匹配,同一个分片可以有多个域,甚至可以迁移域,达到负载平衡。如需深入了解分片技术,读者请浏览 Near 协议的「夜影」论文。
下一代区块链主链从哪里分为域何时分为域,视情况而定。第二代区块链可看作是从细粒化(众多微小域)到粗粒化(少量大域)光谱。
两个项目各占粒度光谱两边:Dfinity 在细粒度一端,每个代理人有自己的域,每次代理人交互都是异步。Near 协议细粒度化稍小,每个合约都有自己的域。粗粒度一端是波卡,其域是就是整个分片,这种情况称为「平行链」更准确。从 DApp 开发者角度判断以太坊 2.0 为时尚早。Eth1EE (Eth2 上的 Eth1 执行环境)将为粗粒度,有与分片一致的界限,目前的以太坊会成为一个分片。细粒度解决方案的优势是透明;合约间调用无论是否跨分片边界,都能看上去一样。这就进而允许在分片间移动合约来轻松平衡负载。
缺点是跨域交易不再是原子化,而是变成并行,其中部分不可撤销。Dfinity 和 Near 中显示合约间调用为 async,返回约定等待 await 。await 期间所有发生的交易都会写入链上。之后其他人的交易可以叠加之上。这时候之前的所有交易就不能撤销。await 最终确认后,可返回合约调用成功或失败指令。有多个提案避免这一情况,让跨分片获得一定原子化,但这样也有劣势。拥抱非原子化似乎是自然结果。
对于 DeFi,异步 transferFrom 调用构成很大挑战。设想双方进行简单交易,Alice 和 Bob 想要用 ETH 和 DAI 交易。基本合约应该是:
但现在我需要处理错误。如果第一次交易失败,我们可停止交易。如果第二次交易失败,就需要将 1 个 ETH 退给 Alice。问题是,这时 Bob 可能已经把那 1 个 ETH 花了。解决这个问题的一个方式就是托管。
这样就行了,没人会损失。但现在 Bob 就对 Alice 的交易有了专属自由选择权。Alice 的代币被托管,不会再进行其他交易,也尚未保证与 Bob 的交易一定会成功。解决这个问题可以对违规者惩罚。而 DeFi 交易会很贵,就难以确定多少惩罚额度合适。解决这个问题可以要求市场各方最开始都在一个存款合约存入资金托管。而这样又变成中心化状态,根本上就不需要分片了。
另一个需要注意的是,这些并发问题到底能多复杂。真实交易中,也有需要更新的序列填充状态 (fill-state of the order),这就让协议更加复杂。相比并发漏洞,困扰以太坊 1.0 的重入攻击漏洞便不足为奇。并发漏洞为不确定性,测试中也不会发生。从上述简单交易可知,要解决这个问题就需要重新思考基础架构,唯一可靠的方式就是打翻重来。
交易是 DeFi 构建的基础,是一系列处理程序。我们已知道交易所交易簿如何构成挑战。自动做市商交易所就较为简单,因为有托管储备金在,但储备金余额形成妨碍并行的瓶颈。即使最快的传统交易所,结算也没有并行(尽管会有冗余),在单一匹配引擎排序完成。如需详细了解传统交易所工作原理,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
撰文:Remco Bloemen,0x 技术专家
编译:Leo Young