您当前的位置: > 山寨币 >
引介 | 值得思量删除的 EVM 功效
发布时间:2024-04-30 17:20
出格感激 Micah Zoltu 提出的一些发起
媒介:为什么 “归并” 是我们删掉一些工具的最后时机,以及为什么我们应该这样做
到 2020 年,我们对如何设计智能合约和区块链协议的理解已经遥超 2013-15 年。因此,假如我们在 2021 年重新开始搭建以太坊,我们就不会引进许多早期添加的功效了。然而从一条正在运行的、拥有活跃生态的区块链中移除功效,遥比在一个新系统中不添加它们要可贵多。
有些 “缺陷功效” 是无害的。有些可以宁静而缓慢地移除或改良。另有些已经深深地嵌进到了太多的应用中,以至于底子改不动(比方 EVM 的 256 位字长)。另一方面,也有一些功效要么已经被移除,要么已经被改良,要么即将被移除(比方对状态树格局的改良、用 SSZ 编码法则取代 RLP 等)。
可是另有一些中间环境:有些功效过于庞大,对生态的成长造成了中等水平的伤害,我们可以移除它们,可是需要冒一点风险。假如我们移除这些功效,可能会有少量的应用被粉碎。可是不移除的话,它们会继续拖累生态。
就跟此外 “长痛短痛” 抉择景象一样,人们很收留易低估短痛带来的持久收益。出格是在我们的环境中,因为解决庞大环境的代码已经写好了,所以感受保留它们不需要支付任何成本。但实际上有两个重要的成本要思量:
为协议开辟新实现的成本若要改变功效 B,但 B 会跟没须要存在的庞大功效 A 交互,可能会发生 “交互 bug”以从头设计状态树为例:若以太坊的状态越是遵循一些简朴的恒常性质(invariants),那么替代更高效的双层十六入制 Patricia 树就会越收留易。然而在现实环境中,由于SELFDESTRUCT操作码可以在单笔事务中不受限制地删除大量存储插槽,这给改进状态树带来了很大的坚苦。另一个例子是 2300 gas 津贴机制(见下文)使 gas 从头订价变得更庞大。\"归并\"(抛却 eth1 的 PoW 链,并将其状态导进 eth2 的 PoS 信标链的事件)可能是我们扯掉一些疾苦绷带的最后时机,这篇文章就是解释这样做的来由。归并是举行最后一轮不兼收留更新的一个很是天然的时间节点,有以下几个来由:归并后构建的客户端很可能不处置惩罚 PoW 链,而是专门验证 PoS 信标链。因此,假如在归并时或归并前往除不须要的庞大功效,客户端最收留易从中受益,由于它们底子不需要实现这些功效。(从技能上讲,纵然是在归并前成立的客户端也可以设计成只处置惩罚最近 1-2 个硬分叉之后的数据,可是 “PoS 信标链作为一条独立的链而不需要处置惩罚 PoW 链上过于长远的数据” 的说法更收留易让人接管)以太坊已经产生了很大的改变,社区对这将是 “以太坊的一次重大进级” 告竣了共鸣。出格是 “在分片和归并完成之前会呈现快速的入化,但归并之后就会趋于不变” 的概念也获得了社区的一致承认。须要的向后不兼收留的改变(比方,BLOCKHASH 操作码不再是一个好的随机性来历)已经产生了。这篇文章将先容一些可以思量删除的功效的例子。功效列表
2300 gas 津贴
这是什么?当一个合约挪用另一个合约时,被挪用的合约会获得 2300 gas 用于执行很是有限的操作(足够做一点计较和天生一条日志,但不敷写满一个存储槽)为何引进?最初是为了让智能合约钱包在收钱时能自动天生一条日志。厥后还被用于实现 “保卫” 功效以防止合约收到 ETH。有何问题?因为它配置的是固定的 gas 数目,因此只要 gas 代价可以调解,人们就没有措施确定这些 gas 到底能支持什么类型的计较。它并没有很好地满意设计意图,有两个原因。首先,许多用户仍旧在使用外部账户,而外部账户并不会天生日志。其次,SELFDESTRUCT操作码绕过了津贴机制。从久远来望,通过账户抽象化,外部账户的感化将被弱化,而且SELFDESTRUCT操作码可能将被移除,可是在这两件事完成之前,它都只是一个不充实的解决方式。如何移除?有两种可能 —— 要么将 2300 改成 0(不支持子执行(child execution))要么不限制数目(子执行可以从父执行中得到全部的 gas 可用额度)移除有何副感化?假如我们移除子执行,那么这将需要在合约挪用中添加一个鸠拙的二分处置(two-clause mechanic),即 0 gas 解释为 0,任何其他数字解释为 “发送所有的 gas”。它还会粉碎反吸收保卫功效和日志记载。假如我们在执行中允许子执行得到全部的 gas,那么通过挪用发送 ETH 会酿成一个需要信任的操作,恶意合约可能会借此扰乱一些应用。不外,Solidity 文档已经发起各人用 withdrawal 模式取代transfer,这样就不会有任何风险了。如何消除挂念?让所有的 ETH 转账,无论是来自挪用照旧SELFDESTRUCT(假如保留的话),都天生一条日志,这样钱包就不需要天生日志了增加一条法则,对于提供 0 gas 的挪用,可望做是一个 “可以天生日志的STATICCALL”。这样就复制了在 gas 津贴的执行情况里实际做到的功效。剩余 Gas 额度可见性
这是什么?GAS操作码允许合约检察当前的执行情况中还剩几多 gas 可用。CALL允许挪用者为子上下文提供固定命量的 gas。为何引进?阻挡让CALL将父情况中剩余的全部 gas 都交给子情况的最主要原因是制止 “不行信任的挪用”:即发送者不信任接管者的挪用。一个简朴的例子是发送 ETH 给介入方的金融机制。另一个例子是 M-of-N 外部代价信息的输进机制(oracle),通过挪用一些合约,在得到所有合约答复后取中位数作为输出。有何问题?实在尽大大都不行信任挪用的用例都可以通过其他方式绕已往。对于转账,Solidity 文档已经发起各人用 withdrawal 模式取代transfer。M-of-N 外部代价信息的输进机制可以很收留易地通过为每一个外部输进单独创建一笔生意业务实现。这会让 gas 重订价变得很难做,当操作码的gas耗损量产生变化,固定 gas 数目的挪用可能会不敷用。如何移除?让CALL可以自动将父情况的所有可用 gas 额度都交给子情况。GAS操作码只需简朴地返归生意业务的初始 gas 数目。移除有何副感化?我们知道的 “不行信任挪用的正当用例” 主要是第三方赞助挪用(译者注:即元生意业务)。第三方公布一笔事务,事务中包罗你但愿的挪用,当挪用产生后,可以自动地向你扣费(你会发布授权他们这样做的签名)。这对用户没有任何 ETH 的智能合约钱包、混币者的隐私掩护以及其他一些用例都很有用。我们需要一个有限 gas 数目的挪用以确保终极的付出语句真正被挪用,而不会由于 gas 不足而被归退。如何消除挂念?矿工可以直接充傍边介,假如生意业务终极没有付钱给他们,他们就可以直接抛弃事务。拜见 Phil Daian 的事情,他创建了一个由第三方呆板人组成的生态,矿工可以自动发生 “宁静” 的批量生意业务。在协议内增加一个明确的 “第三方付款人” 的生意业务类型。拜见 EIP 2711 的例子。还请注意,假如我们想要走得更遥,我们还需要调解 63/64 法则使得假如子挪用失败,父挪用也彻底失败(所以连 1/64 都不剩)。这可能会粉碎更多的用例(“假如子挪用失败就仅执行一个简朴的操作”),但它将确保当 gas耗损量产生变化时只会引起一种类型的行为变化(原本乐成的生意业务此刻会失败)。SELFDESTRUCT
请望这篇文章。Gas 退款
这是什么?挪用SELFDESTRUCT销毁一个合约,或者将一个存储槽配置为零,会退归 15000-25000 gas。退款会在事务执行的最后触发,并抵扣发送者需要付出的用度。为何引进?激励应用开辟者践行 “杰出的状态卫生”,清除不再需要的存储插槽和合约。有何问题?在实践中,险些没有人真正践行杰出的状态卫生。这是由于激励不敷高,不值得为此增加代码的庞大度甚至带来宁静风险。退费机制使得 GasToken 鼓起。GasToken 有利于将低费率时期的 gas 调配到高费率时期使用,可是它倒霉于网络,出格是加重了状态范围的膨胀,并使低效的 gas 使用要领梗阻了区块链。它加剧了区块巨细的颠簸,使一个区块实际上的理论最大 gas 耗损量险些是字面意义上区块 Gas 上限的两倍。这并不致命,但仍旧不行取,出格是思量到,在 EIP-1559 实施后,退款机制可以使网络的实际 Gas 使用量持久维持高程度,阻碍 1559 机制的运行。如何移除?只要把退款功效从协议中完全删除。移除有何副感化?我们可以相称确信,没有任何应用会因此无法使用,由于退款只在执行竣事后触发,所以取消退款并不会改变任何执行的可用 gas 数目。GasToken 将变得毫无用处在 gas 代价反常时,应用失往了降低用度的能力。幸亏这个功效今朝最主要的用户是 defi 的套利呆板人,而套利呆板人之间的 gas 代价竞争是一种零和勾当,不外还不清晰移除这个它们用于竞争的兵器会造成什么全局性的倒霉影响。如何消除挂念?Gastoken 在他们的网站上已经警告过,将来的协议变动可能会使 GasToken 无效,所以用户不会以为惊讶我们可以提前发布变动时间其他候选功效(猜测)
比拟上面枚举的,我对移除以下功效会带来几多价值缺乏决心信念,不外照旧值得列出一个清单。RIPEMD160 预编译:这是一个非尺度的哈希函数,很少有项目使用(除了与比特币交互的应用)。我们可以用链上布置的合约举行替代,对于真正需要高效验证的项目,可以直接使用 ZK-SNARK。动态跳转:使用变量作为跳转方针会使代码的阐明和操作变得越发坚苦(比方,无法简朴地替代操作码序列,或者预置一些代码)。往掉动态跳转,只允许相对偏移的静态跳转,而且为子法式提供一些专用的指针方案(指针不作为整型袒露)可以解决这个问题。然而,这将是一个底层的改变,可能会粉碎很多自界说的合约,所以其收益/成本比似乎不如这个列表中的其他项目。MODEXP 预编译:对于大整数计较来说,这显然是一个错误的 “根基元件”,而且其 gas 耗损的计较方案也相称庞大。更好的选择是:(i) 用预编译的 ADD、MUL 和 MOD 作为替换的根基原语,并用这些预编译的指令编写用于替换 MODEXP 的实现,或者 (ii) 将 EVM384 扩铺到更多的长度(256,384,512,768,1024 ... 8192)原文链接:
https://hackmd.io/@HWeNw8hNRimM****GH56Cw/evm_feature_removing
作者:Vitalik
翻译&校对:戡乱 &阿剑