以太坊协议的前史

本文详细回顾了以太坊协议的演变过程,从最初的构想到最终的发布,重点讨论了协议设计的多次重大变化和重要参与者的贡献。作者回忆了与其他关键开发者的合作以及协议各个阶段的重大决策,揭示了以太坊如何从一个简单概念发展成为一个复杂的区块链平台。

以太坊协议的前历史

以太坊协议的前历史

尽管当前以太坊协议背后的理念在过去两年中基本上保持稳定,但以太坊并不是一蹴而就,亦不是以其当前形态完全成型。在区块链启动之前,协议经历了一系列重要的演变和设计决策。本文的目的是回顾协议从起始到启动经历的各种演变;对协议实现(如 Geth、cppethereum、pyethereum 和 EthereumJ)所做的无数工作,以及以太坊生态系统中的应用和商业的历史,故意不予讨论。

另外,Casper 和分片研究的历史也不在讨论范围内。虽然我们确实可以撰写更多博客文章来讨论 Vlad、Gavin、我自己以及其他人所提出并舍弃的各种想法,包括“工作证明的工作证明”、中心-辐射链、“超立方体”、影子链(可以说是 Plasma 的前馈)、链纤维以及Casper的各种迭代,以及Vlad对共识协议中行为者激励如何推理及其属性的快速变化的思考,但这些内容还是过于复杂,不方便在一篇文章中展开,因此我们暂且不谈。

让我们首先从最终成为以太坊的最早版本开始,那时它甚至还没有被称为以太坊。当我在2013年10月访问以色列时,我花了相当多的时间与Mastercoin团队一起,甚至为他们建议了一些功能。在花了几次思考他们正在做的事情后,我向团队发送了一份提案,使他们的协议更具通用性,并支持更多类型的合约,而无需添加同样庞大且复杂的功能集:

<https://web.archive.org/web/20150627031414/http://vbuterin.com/ultimatescripting.html>

请注意,这与后来的更广泛的以太坊愿景相去甚远:它在Mastercoin试图专业化的领域,专注于双边合约,其中A和B两方都会投入资金,随后根据合约中指定的某种公式获得资金(例如,一个押注可能会说“如果X发生,则将所有资金给A,否则将所有资金给B”)。该脚本语言并非图灵完备。

Mastercoin团队对此印象深刻,但他们并不 interested 于放弃正在做的所有事情以走这条道路,而我越来越相信这是正确的选择。所以这里是版本2,大约在12月:

https://web.archive.org/web/20131219030753/http://vitalik.ca/ethereum.html

在这里,你可以看到经过重大重新架构的结果,这在很大程度上是我在11月一次长时间散步后得出的结论,当时我意识到智能合约可能会完全通用。合约不再仅仅是描述双方关系条款的一种方式,而是完全独立的账户,能够持有、发送和接收资产,甚至维护永久存储(那时,永久存储被称为“内存”,唯一临时的“内存”是256个寄存器)。该语言从基于栈的机器转变为基于寄存器的机器,完全是我自己的选择;除此之外我没有太多理由,只是认为这似乎更复杂。

此外,请注意现在有一个内置费用机制:

此时,ether实际上是Gas;在每个计算步骤后,调用交易合约的余额会减少一点,且如果合约的资金耗尽,执行会停止。请注意,这种“接收者支付”机制意味着合约本身必须要求发送者向合约支付费用,如果该费用不存在则立即退出;协议根据规则分配16个免费的执行步骤,以允许合约拒绝不支付费用的交易。


这是以太坊协议完全由我创造的时期。然而,从这里开始,新的参与者开始加入这个团队。最突出的协议方面的参与者是Gavin Wood,他在2013年12月通过about.me消息联系了我:

Go客户端的首席开发者Jeffrey Wilcke(当时称为“ethereal”)也联系了我,并在差不多同时开始编码,尽管他的贡献更多的是在客户端开发方面,而不是协议研究方面。

Gavin的初始贡献主要有两个方面。首先,你可能注意到最初设计中的合约调用模型是异步的:虽然合约A可以创建一个对合约B的“内部交易”(“内部交易”是Etherscan的术语;最初它们被称为“交易”,后来的名称是“消息调用”或“调用”),内部交易的执行不会在第一个交易的执行完全完成之前开始。这意味着交易不能将内部交易作为从其他合约获取信息的一种方式;唯一的方法是 EXTRO 操作码(有点像 SLOAD,可以用来读取其他合约的存储),这在Gavin和其他人支持后也被删除了。

在实现我初始规范时,Gavin自然是以同步的方式实现内部交易,而没有意识到其意图不同——换句话说,在Gavin的实现中,当一个合约调用另一个合约时,内部交易会立即执行,一旦该执行完成,虚拟机返回到创建内部交易的合约并继续执行下一个操作码。我们都认为这种方法更优越,因此我们决定将其作为规范的一部分。

第二,Gavin与我之间的一次讨论(在旧金山散步时进行,具体细节将永远被历史的风吹走,或许在NSA的深层档案中还会有个或两个副本)导致交易费用模型的重构,从“合约支付”方法转向“发送方支付”的方法,并转向“Gas”架构。每个单独的交易步骤不会立即占用一些ether,而是交易发送方支付并获得一些“Gas”(大致上是计算步骤的计数),计算步骤则从这个Gas配额中消耗。如果一个交易耗尽了Gas,Gas仍会被没收,但整个执行将被撤销;这似乎是最安全的做法,因为它消除了合约以前必须担心的“部分执行”攻击。当交易执行完成时,不使用的Gas费用会被退还。

Gavin还大致可以被认为是以太坊视角的微妙变化,最初把以太坊视为一个用于构建可编程货币的平台,基于区块链的合约能够持有数字资产并根据预设规则进行转移,后来转变为一个通用计算平台。这始于强调和术语的微妙变化,后来随着在“Web 3”整体上的强调越来越大,这种影响变得更加强烈,认为以太坊是一个去中心化技术套件中的一部分,其他两个部分是Whisper和Swarm。

在2014年初,还进行了其他一些由其他人提出的更改。在Andrew Miller和其他人的建议下,我们最终又回到了基于栈的架构。

Charles Hoskinson建议从比特币的SHA256切换到更新的SHA3(或更准确地说是keccak256)。尽管一度存在一些争议,但与Gavin、Andrew和其他人的讨论得出结论,栈上值的大小应限制为32字节;另一种考虑的替代方案是无限大小的整数,存在的问题是很难确定在加法、乘法和其他操作上收取多少Gas费用。


我们在2014年1月心中最初设想的挖矿算法是一种称为Dagger的装置:

<https://github.com/ethereum/wiki/blob/master/Dagger.md>

Dagger这个名字源自“有向无环图”(DAG),这是该算法使用的数学结构。其概念是,每N个区块,将从一个种子随机生成一个新的DAG,DAG的底层将是一个需要几个GB存储的节点集合。然而,生成DAG中任何单个值只需计算几千个条目。“Dagger计算”涉及获取底层数据集中随机位置的一些值,并将其哈希在一起。这意味着可以快速进行Dagger计算——已有内存中的数据,并且有一种缓慢但不耗内存的方式——从头开始重新生成你需要从DAG获取的每个值。

该算法的意图是拥有与当时流行的算法(如Scrypt)一样的“记忆硬度”特性,但仍然友好于轻客户端。矿工将使用快速的方法,因此他们的挖矿将受限于内存带宽(理论上消费者级RAM已经过非常优化,因此使用ASIC进一步优化它将非常困难),但轻客户端可以使用无内存但较慢的版本进行验证。快速方式可能会花费几微秒,而无内存的慢方式则可能需要几毫秒,因此它仍然非常适合轻客户端。

接下来,算法在以太坊开发过程中经过了几次变化。我们加进去的下一个想法是“自适应工作证明”;在这种情况下,工作证明将涉及执行随机选择的以太坊合约,还有一个巧妙的原因,表明这是预期抵抗ASIC的:如果开发出了ASIC,竞争的矿工会有动力创建和发布许多该ASIC不擅长执行的合约。没有一种算法能够解决通用计算的问题,传言说,这只是一个CPU,因此我们可以用这种对抗性的激励机制来构建基础上进行通用计算的工作证明。

这个提议因一个简单的原因破裂:长远攻击。攻击者可以从第一个区块开始填充,仅使用简单的合约,他们可以为之创建专门硬件,迅速赶超主链。所以……回到绘图板。

下一个算法称为随机电路,该算法在这个谷歌文档中进行了描述这里,由我和Vlad Zamfir提出,由Matthew Wampler-Doty分析和其他人。这里的想法也是在一个挖矿算法中模拟通用计算,这次通过执行随机生成的电路。没有硬性证据表明基于这些原则的东西将无法工作,但我们在2014年接触的计算机硬件专家往往对此持悲观态度。Matthew Wampler-Doty自己建议基于SAT求解的工作证明,但这也最终被拒绝了。

最后,我们全盘回归到一种称为“Dagger Hashimoto”的算法。“Dashimoto”,有时简称为此,借鉴了Hashimoto的许多理念,这是Thaddeus Dryja提出的一种工作证明算法,开创了“I/O绑定的工作证明”的概念,其中在挖矿速度的主要限制因素不再是每秒哈希次数,而是每秒的RAM访问量(以MB为单位)。然而,它将这一点与Dagger的轻客户端友好的DAG生成数据集的理念结合在一起。经过我、Matthew、Tim和其他人的多次调整后,这些理念最终汇聚成了我们现在称之为Ethash的算法。


到2014年夏天,协议已经相当稳定,主要的例外是工作证明算法,直到2015年初才会进入Ethash阶段,并且存在Gavin的黄皮书形式的半正式规范。

2014年8月,我开发并引入了非叔机制,以允许以太坊的区块链具有更短的区块时间和更高的容量,同时减轻中心化风险。这是作为PoC6的一部分引入的。

与Bitshares团队的讨论使我们考虑添加堆作为一种一流的数据结构,尽管由于缺乏时间,我们最终没有这么做,随后进行的安全审核和拒绝服务攻击表明,安全执行这一点实际上比我们当时想象的要困难得多。

在9月,Gavin和我规划了对协议设计的接下来的两个主要更改。首先,除了状态树和交易树之外,每个区块还将包含一个“收据树”。该收据树将包括由交易生成的日志的哈希,以及中间状态根。日志将允许交易创建在区块链上保存的“输出”,并可供轻客户端访问,但未来的状态计算中无法访问未来的状态数据。这可以用于让去中心化应用能够轻松查询事件,比如代币转移、购买、创建及填补交易订单、启动拍卖等。

还考虑了其他一些想法,例如为整个交易执行跟踪生成Merkle树以允许任何内容的证明;选择日志是因为它们在简单性和完整性之间达成了妥协。

第二个想法是“预编译”,解决了在EVM中允许复杂的加密计算可用而无需处理EVM开销的问题。我们还考虑了更多雄心勃勃的想法,例如“本地合约”,如果矿工对某些合约有优化的实现,他们可以选择“投票”将这些合约的Gas价格降低,因此,在大多数矿工能够执行得更快的合约将自然有更低的Gas价格;然而,所有这些想法都被拒绝,因为我们无法想出一个在密码经济上安全的实现方式。攻击者始终可以创建一个执行某个陷门加密操作的合约,将陷门分发给自己和他们的朋友,使得他们能够更快地执行该合约,然后降低Gas价格,利用这一点对网络实施拒绝服务攻击。相反,我们选择了减少数量、简单指定于协议中的预编译版适用于常见操作如哈希和签名方案。

Gavin还是发展“协议抽象”想法的关键最初的声音之一——将尽可能多的协议部分(如以太币余额、交易签名算法、随机数等)转移到协议本身作为合约,理论上的最终目标是达到一种情况,其中整个以太坊协议可以描述为调用某个具有预初始化状态的虚拟机中的函数。由于时间不足,这些想法未能在初始的Frontier版本中实现,但预计将在某些君士坦丁堡的变更、Casper合约和分片规范中逐步集成这些原则。

这一切都在PoC7中实现;在PoC7之后,协议实际上没有发生太大变化,尽管还是有些细节相对较小,但有些情况下则是非常重要的,这些是在安全审核中曝光的...


2015年初,Jutta Steiner及其他人组织了预发布阶段的安全审核,包括软件代码审计和学术审计。软件审计主要集中在C++和Go实现上,由Gavin Wood和Jeffrey Wilcke分别主导,尽管我的pyethereum实现也进行了小规模审核。在两次学术审计中,一次是由Ittay Eyal(“自私挖矿”之名)进行的,另一只是由Andrew Miller和Least Authority的其他人进行的。Eyal审核导致了一个小的协议更改:链的总难度将不包括叔块。Least Authority审核更多关注智能合约和Gas经济,以及Patricia树。这项审核导致了一些协议更改。一项小的更改是以sha3(addr)和sha3(key)作为默克尔树键,而不是直接使用地址和键;这将使对树进行最坏情况下攻击变得更加困难。

我们讨论的另一个重要事项是Gas限制投票机制。那时,我们已经对比特币区块大小辩论中感知到的缺乏进展感到担忧,希望在以太坊中有一个更灵活的设计,可以根据需要随着时间的推移进行调整。但挑战是:最佳限制是什么?我最初的想法是做一个动态限制,定位于实际Gas使用量的1.5倍的长期指数移动平均线,这样从长远来看,平均区块将是83%的满块。然而,Andrew指出这在某些方面是可利用的——具体地说,想要提高限制的矿工会简单地在自己的区块中包含消耗大量Gas,但处理时间极少的交易,因此,总能以无成本创建完整块。因此,安全模型至少在向上方向上等同于简单让矿工投票确定Gas限制。

我们没有设法想出一个不太容易出问题的Gas限制策略,因此Andrew建议的解决方案是让矿工明确投票决定Gas限制,并将默认投票策略设置为1.5倍EMA规则。理由是我们仍然离知道正确的最大Gas限制设置方法非常遥远,而任何具体方法失效的风险似乎大于矿工滥用其投票权的风险。因此,我们不妨直接让矿工投票Gas限制,并接受这一限制过高或过低的风险,以换取灵活性的好处,并使矿工能够迅速合作根据需要上调或下调限制。


在Gavin、Jeff和我之间的一个迷你黑客马拉松之后,PoC9在3月推出,旨在成为最终的概念证明版本。一个名为Olympic的测试网运行了四个月,使用了计划在主网中使用的协议,而以太坊的长期规划得以建立。Vinay Gupta撰写了一篇博客文章,"以太坊发布流程",描述了以太坊主网开发的四个预期阶段,并为它们赋予了当前的名称:Frontier、Homestead、Metropolis和Serenity。

Olympic持续了四个月。在前两个月,发现了许多实现中的错误,发生了共识失败,等等问题,但到6月网络明显稳定。在7月作出冻结代码的决定,随后进行发布,并在7月30日发布成功。

  • 原文链接: vitalik.eth.limo/general...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Vitalik Buterin
Vitalik Buterin
https://vitalik.ca/