Origin post by Vitalik Buterin, on December 24th, 2015

咱们现已揭露持续改善以太坊协议的计划和长时间开发路线图适当长一段时间了,这个做法也是来自于从1.0版别发布之前或许过后没有能及时处理的错误中学到的经历。不管怎样,以太坊核心协议的周期性开发现已重新启动,Homestead阶段很快就要到来,咱们也现已悄然开端开发一个概念原型(PoC),方针是开发路线图中最大的里程碑: Serenity.
Serenity会有两大首要特性:深度笼统,一个我最早在这里展开评论过的特性,和Casper,根据保证金的权益证明(PoS)算法。此外,咱们也在探究滑润的部署可伸缩性(scalability)改善的办法,至少是一个脚手架,一同彻底处理这里对并行性的忧虑 - 运转在私有链环境下,多核CPU专有服务器之上的以太坊节点性能将会有马到成功的巨大提高,乃至公有链的可伸缩性也能看到2到5倍的提高。在过去的几个月中,Casper的研究和对可伸缩性与笼统改善的方式化作业(eg. EIP101)都在快速推进,参与者有我, Vlad Zamfir, Lucius Greg Meredith和其他一些人。现在我很高兴的宣告,Serenity阶段的第一个概念原型, 尽管能做的作业还十分有限仅仅能够用于测试,现已完成。
在ethereum目录下运转python test.py就能够把概念原型跑起来(别忘了先从https://github.com/ethereum/serpentSerpent下载和装置最新的 develop分支),假如看到这样的输出就对了:
vub@vub-ThinkPad-X250 15:01:03 serenity/ethereum: python test.py
REVERTING 940534 gas from account 0x0000000000000000000000000000000000000000 to account 0x98c78be58d729dcdc3de9efb3428820990e4e3bf with data 0x
Warning (file "casper.se.py", line 74, char 0): Warning: function return type inconsistent!
Running with 13 maximum nodes
Warning (file "casper.se.py", line 74, char 0): Warning: function return type inconsistent!
Warning (file "casper.se.py", line 74, char 0): Warning: function return type inconsistent!
Length of validation code: 57
Length of account code: 0
Joined with index 0
Length of validation code: 57
Length of account code: 0
Joined with index 1
Length of validation code: 57
在每5秒一个块,运用Casper+Serenity协议的条件下,这个程序模仿了的13个节点的运转;这个模仿现已很接近当时客户端能处理的上限了,不过要留意:(i) 这是python写的,C++和Go的完成很或许会有更好的体现,以及(ii) 所有这些节点都一同运转在一台电脑上,所以你有理由相信在一个更“正常”的环境中python版别的Casper能够处理大约169个节点(不过,从另一方面来说,咱们期望一致的开支远低于100%的CPU占用,因而这两点留意并不表明你能够等待Casper和上千个节点一同作业!)。假如你的电脑太慢处理不了13个节点,试试用python test.py 10来模仿10个节点(或许python test.py 7来模仿7个节点,你懂的)。当然,改善Casper功率的研究仍在持续,尽管这改善或许会以减慢终局性(finality)的收敛为代价,这些问题都会逐渐处理。network.py文件模仿了一个根本的P2P网络接口,接下来的作业会把它替换成运转在实在网络上的实在核算机。
程序代码被分割到几个首要文件中:
  • serenity_blocks.py - 描绘block类,state类,以及block和transaction等级状况搬运函数的代码(比以前的版别简略一倍)。
  • serenity_transactions.py - 描绘transaction的代码(比之前简略一倍)。
  • casper.se.py - Casper合约的serpent完成,鼓励正确的下注行为。
  • bet.py - Casper的下注逻辑和完整的客户端完成。
  • ecdsa_accounts.py - 账户相关代码,让你能够在Serenity上模仿当时的账户验证逻辑。
  • test.py - 测试脚本
  • config.py - 参数装备
  • vm.py - 虚拟机(fastvm.py供给了一个更快的完成)
  • network.py - 网络模仿
在这篇文章中,咱们只评论深度笼统的特性,因而关键文件是serenity_blocks.py, ecdsa_accounts.py和serenity_transactions.py;在下一篇评论Casper的文章中,casper.se.py和bet.py将会是焦点。
账户的笼统
现在以太坊中有两种类型的账户:外部具有的账户,由私钥控制,和合约账户,由代码控制。关于外部具有的账户,咱们指定了一种特别的数字签名算法(secp256k1椭圆曲线签名)和一个序号体系(nonce),要求每一个买卖都必须包含一个比前一个买卖序号大1的数字,意图是防止重放进犯(replay attacks)。咱们为提高笼统程度而做的首要改动是:不再有两种不同类型的账户,而是统一为一种 - 合约账户。将会存在一个特殊的“进口”账户,0x0000000000000000000000000000000000000000,任何人都能够从这个账户建议买卖。因而,协议中将不再包含签名+nonce的账户验证逻辑,用户必须用合约来维护他们自己的账户。
最简略有用的此类合约或许要属椭圆曲线数字签名验证合约了,它能够供给和现在彻底相同的功用:只要具有有用签名和序号的买卖才能经过验证,而且序号在买卖成功后添加1。这个合约的代码如下:
# We assume that data takes the following schema:
# bytes 0-31: v (ECDSA sig)
# bytes 32-63: r (ECDSA sig)
# bytes 64-95: s (ECDSA sig)
# bytes 96-127: sequence number (formerly called "nonce")
# bytes 128-159: gasprice
# bytes 172-191: to
# bytes 192-223: value
# bytes 224+: data
# Get the hash for transaction signing
~mstore(0, ~txexecgas())
~calldatacopy(32, 96, ~calldatasize() - 96)
~mstore(0, ~sha3(0, ~calldatasize() - 64))
~calldatacopy(32, 0, 96)
# Call ECRECOVER contract to get the sender
~call(5000, 1, 0, 0, 128, 0, 32)
# Check sender correctness; exception if not
if ~mload(0) != 0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1:
~invalid()
# Sequence number operations
with minusone = ~sub(0, 1):
with curseq = self.storage[minusone]:
# Check sequence number correctness, exception if not
if ~calldataload(96) != curseq:
~invalid()
# Increment sequence number
self.storage[minusone] = curseq + 1
# Make the sub-call and discard output
with x = ~msize():
~call(msg.gas - 50000, ~calldataload(160), ~calldataload(192), 160, ~calldatasize() - 224, x, 1000)
# Pay for gas
~mstore(0, ~calldataload(128))
~mstore(32, (~txexecgas() - msg.gas + 50000))
~call(12000, ETHER, 0, 0, 64, 0, 0)
~return(x, ~msize() - x)
这段代码便是用户账户的合约代码;假如用户要从自己的账户发送一个买卖,他们会先从地址0发送一个买卖到这个账户,买卖数据会像上述代码所示那样包含ECDSA签名,序号,gas价格,方针地址,数额和实在的买卖数据。合约代码会查看对买卖gas约束和数据的签名,然后查看买卖序号,假如两者都没有问题就把保存的序号加一,发送所需的音讯,然后发送另一条音讯付出gas费用作为完毕(留意,矿工能够静态分析账户的合约代码,假如买卖的账户合约最后没有付出gas能够回绝处理)。
Serenity的这个改动有一个很重要的成果,体系中的所有买卖(只需满足根本的格式)都是有用的。现阶段无效的买卖在Serenity中将仅仅是没有效果(上例中的invalid是一个没有运用的操作码,它会使程序履行立即退出)。这意味着买卖被打包进区块不再是买卖会被实在履行的保证,作为弥补,每一笔买卖都会有一条收据记录(receipt entry),经过回来码指明它是否成功履行:0表明由于gas约束买卖没有履行,1表明买卖履行了可是犯错,2表明买卖成功履行。收据记录还能够供给更多的信息,例如买卖的回来值(现在有主动日志记录)或许自己创立的日志,
这个改动最首要的好处是用户能够在账户策略这个范畴自在的立异了。或许的方向包含:
  • 比特币风格的多重签名,账户要求买卖一同具有多个私钥的签名,而不是一次接收一个签名,然后把中间成果临时存放在区块链里。
  • 其他的椭圆曲线, 包含ed25519。
  • 更好的集成先进的加密算法,例如环状签名(ring signature), 门限签名(threshold signature), 零知识证明等等。
  • 更先进的序号计划, 支撑更高程度的并行化,让用户能够一同从一个账户发出多个买卖,而且更快的把这些买卖打包。想想传统的序号和位掩码(bitmask)假如结合会怎样。咱们也能够经过各种机智的办法在有用性查看中运用时间戳或是区块的hash值。
  • 根据UTXO的代币办理, 有些用户处于隐私的元应,不喜欢以太坊运用账户而不是比特币的“未运用的买卖输出”(unspent transaction output, UTXO)模型来办理代币的所有权。现在你能够在以太坊中树立一个事实上根据UTXO的体系了,而且Serenity不再显式的特殊对待其中某一个。
  • 付出计划的立异,关于某些dapp, “由合约付出费用”或许比“由运用者付出”更有用,运用者或许没有以太币。现在dapp就能够完成这个付出模型了。假如矿工能对它的代码做静态分析并坚信他们能够得到酬劳,矿工就会承受这种买卖(本质上,咱们完成了Rookstock想要经过可选的作者付出(author-pay)想做的作业,可是是经过一种更笼统和灵敏的办法)。
  • 与“以太坊闹钟”之类的使用更好的集成,账户的查验代码不一定要查看签名,也能够查看收据的Merkle proof,或是其他账户的状况,等等。
提出这些场景是为了说明最首要的论点,经过笼统所有这些别的的机制都能够愈加简略的完成,不再需求创造一个“传递层”来把信息喂给以太坊默许的签名体系。当没有使用是特殊的时分,每个使用都特殊。
一个特别有意思的成果是:在Serenity的设计下,以太坊将具有可选的量子安全性。假如你害怕NSA秘密具有一台量子核算机,想要把自己的账户变得更安全,你随时能够个人切换运用Lamport签名。转换到PoS机制进一步稳固了安全性,即便世界上只要NSA有量子核算机他们也不能运用这一点来实施51%进犯。在以太坊的协议层仅有剩余的密码学安全假设只要SHA3的抵御磕碰(collision-resistance)的性质了。
这些改变的另一个成果是,买卖数据会变得愈加简略。买卖将会用四个字段取代现在的九个:方针地址,数据,初始gas和初始化代码。方针地址,数据和初始gas和现在相同,“初始化代码”是一个可选用于保存方针地址账户合约创立代码的字段。
需求这个机制的原因如下。现在以太坊有一个重要的性质,是允许往一个还不存在的账户转账。为了在区块链上创立一个合约承受以太币,你并不需求事前持有任何以太币。为了在Serenity中完成这个性质,咱们让账户地址能事前从它的初始化代码中推导出来,经过公式sha3(creator + initcode) % 2**160。这里creator是创立这个合约的账户(默许是地址为0的账户),而initcode便是合约的初始化代码(这段代码的运转成果会成为账户合约的代码,正如现在的CREATE相同)。因而你能够在本地先生成这段初始化代码,核算它的地址,然后让其他人往这个地址转账。然后一旦你想要从这个地址发出第一笔买卖,你能够在买卖里边包含这段初始化代码,它就会在实在的买卖履行之前,被主动履行并创立账户(这段逻辑的完成代码在这里)。
区块的笼统
Serenity中将完成的另一个洁净的分离是将区块(仅仅是一堆买卖),状况(例如合约的存储区,代码和账户余额)和一致层彻底分隔。一致鼓励在合约内部完成,而假如你期望鼓励的话,一致等级的方针(例如PoW, 赌注)应该被包含在发往“一致鼓励办理合约”的买卖中。
这应该会让你更简略用其它的一致算法 - Tendermint, HoneyBadgeBFT, subjective consensus乃至是一般的PoW - 替换掉Serenity代码中的Casper。咱们十分欢迎这个方向的研究,而且期望能做到最大的灵敏。
存储的笼统
现在,以太坊体系的“状况”数据实际上适当复杂,包含这些部分:
  • 余额,代码,nonce,和账户存储区
  • Gas上限,难度,块高度,时间戳
  • 最后256个块的hash值
  • 在履行区块内代码时,需求保存买卖索引,收据树(receipt tree, receipt是EVM中的一个概念)和当时耗费的gas。
这些数据结构存在于许多地方,包含块状况搬运函数,状况树,区块头和前一个区块头中。在Serenity里边这些将被大幅简化:尽管许多数据仍然会存在,但他们会被搬运到特殊的合约中去;因而,仅有的”“状况”将以一棵树的方式持续存在,数学上能够看作是形如https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgaddress: https://bicoin8.com/wp-content/uploads/2023/04/202304211cHpE0.jpgkey: value}}的映射。账户将是一些树,账户合约代码会被存放在主键(key)为""的地方(SSTORE不能够修改),余额会存在特别的“以太币合约”中,而序号将由每一个帐号自己决定如何保存。收据也将被搬运到合约存储区,他们会被保存在一个内容在每个区块都会被覆盖的“日志合约”中。
这样代码完成中的状况方针能够极大的简化。现在只剩余一个两级的trie了。可伸缩性方面的晋级或许要求添加为三级trie(分片ID, 地址,主键),这还没有确定,但即便是这样复杂性也远低于现在。
需求留意,把以太币搬运进一个合约办理并不是以太币笼统的全部。事实上,一个有争议的看法是相关于现状这并不是一个很大的进步,由于为了向前兼容那些和以太币相关的操作码(带value参数的CALL,BALANCE等等)仍然保留着。某种程度上说,这仅仅数据存放的一次重组。
未来的计划
在第二个概念原型中,咱们计划让笼统更进一步。现在区块和买卖等级的状况搬运函数仍然有适当的复杂性(例如更新收据,gas约束,买卖索引,区块高度,状况根节点),咱们的方针是为买卖创立一个“进口”方针来处理所有这些每一个买卖都需求的额外的“样板逻辑”,以及“块开端”和“块完毕”的进口。理论上的终极方针,是找到一个只要一个进口点的协议,这样状况搬运函数只需求从零地址发送一条包含区块内容数据的音讯给进口点即可。这样做的意图是尽或许的减少客户端完成的一致关键部分(consensus-critical client implementation)的大小,把尽或许多的逻辑推到以太坊自身上去。这样即便为了到达咱们对买卖速度和可伸缩性的方针,咱们需求采用一个承受硬分叉和一定的新复杂度的急进开发制度,也能够个确保以太坊的多重客户端形态能够持续而无需大量额外开发作业和安全审计。
长时间来看,我打算持续在python上开发概念原型,Casper团队则共同改善协议的功率,并证明它的安全性和正确性。在某个时间,这个协议将成熟到足以处理一个揭露的某种方式的测试网络,其上或许会有实在的价值,为人们找出Casper的漏洞供给鼓励,就像一条实在的链不可避免的遭受的那样。这仅仅第一步,不过是十分重要的一步,它标志着咱们关于权益证明和深度笼统的研究终于从说话,白板上的数学公式和博客文章变成了能作业的代码。
这个系列的下一篇文章将会评论Serenity的另一个旗舰特性,Casper一致算法。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注