作者:VitalikButerin
以太坊创始人VitalikButerin近日针对与Proto-danksharding有关的疑问近了解答。Danksharding为以太坊提出的新分片设计,这种技术究竟能带来什么?
什么是Danksharding?
Danksharding是为以太坊提出的新分片设计,与之前的设计相比,它引入了一些显着的简化。
自2020年以来的所有最近的以太坊分片提案与大多数非以太坊分片提案的主要区别在于以太坊以汇总为中心的路线图:以太坊分片没有为交易提供更多空间,而是为数据提供,以太坊协议本身不会尝试解释。验证blob只需检查blob是否可用,即是否可以从网络下载。这些blob中的数据空间预计将由支持高吞吐量事务的第2层Rollup协议使用。
Danksharding引入的主要创新是合并费用市场:不再有固定数量的分片,每个分片都有不同的区块和不同的区块提议者,在Danksharding中,只有一个提议者选择进入该槽的所有交易和所有数据.
为避免这种设计对验证者提出高系统要求,我们引入了提议者/构建者分离(PBS):称为区块构建者的一类特殊参与者竞标选择slot的权利,提议者只需要选择出价最高的有效header即可。只有区块构建者需要处理整个区块;所有其他验证者和用户都可以通过数据可用性采样非常有效地验证区块。
什么是proto-danksharding?
Proto-danksharding是一个以太坊改进提议,用于实现构成完整Danksharding规范的大部分逻辑和“脚手架”,但尚未实际实现任何分片。在proto-danksharding实现中,所有验证者和用户仍然必须直接验证完整数据的可用性。
proto-danksharding引入的主要特征是新的交易类型,我们称之为一种带有blob的交易。带有blob的交易与常规交易类似,不同之处在于它还携带称为blob的额外数据。Blob非常大,并且比类似数量的calldata便宜得多。但是,EVM执行无法访问blob数据;EVM只能查看对blob的承诺。
因为验证者和客户端仍然需要下载完整的blob内容,所以proto-danksharding中的数据带宽目标为每个插槽1MB,而不是完整的16MB。然而,由于这些数据没有与现有以太坊交易的gas使用量竞争,因此仍然有很大的可扩展性好处。
为什么向每个人都必须下载的块添加1MB数据是可以的,而不是让calldata便宜10倍?
这与平均负载和最坏情况负载之间的差异有关。今天,我们已经遇到了平均块大小约为90kB的情况,但理论上可能的最大块大小约为1.8MB。以太坊网络过去处理的区块接近最大值。但是,如果我们简单地将calldatagas成本降低10倍,那么尽管平均区块大小会增加到仍然可以接受的水平,但最坏的情况会变成18MB,这对于以太坊网络来说实在是太多了。
当前的gas定价方案无法将这两个因素分开:平均负载与最坏情况负载之间的比率取决于用户在calldata与其他资源上花费多少gas的选择,这意味着gas价格必须是根据最坏情况的可能性设置,导致平均负载不必要地低于系统可以处理的负载。但是,如果我们改变gas定价以更明确地创建一个多维费用市场,我们可以避免平均情况/最坏情况负载不匹配,并在每个区块中包含接近我们可以安全处理的最大数据量的数据。Proto-danksharding和EIP-4488就是这样做的两个提议。
proto-danksharding与EIP-4488相比如何?
EIP-4488是解决相同平均情况/最坏情况负载不匹配问题的较早且更简单的尝试。EIP-4488使用两个简单的规则来做到这一点:
Calldatagas成本从每字节16gas降低到每字节3gas每个块1MB的限制加上每个事务额外的300字节硬限制是确保平均情况负载的较大增加不会导致最坏情况负载增加的最简单方法。天然气成本的降低将大大增加汇总的使用,可能会将平均块大小增加到数百KB,但硬限制将直接阻止包含10MB的单个块的最坏情况可能性。事实上,最坏情况下的块大小会比现在小。
Proto-danksharding而是创建了一种单独的事务类型,可以在大型固定大小的blob中保存更便宜的数据,并限制每个块可以包含多少blob。这些blob无法从EVM访问,并且blob由共识层而不是执行层存储。
EIP-4488和proto-danksharding之间的主要实际区别在于EIP-4488试图最小化今天所需的更改,而proto-danksharding今天进行了大量更改,因此将来升级到完全分片需要很少的更改。尽管实现全分片是一项复杂的任务,并且在proto-danksharding之后仍然是一项复杂的任务,但这种复杂性包含在共识层中。一旦proto-danksharding推出,执行层客户端团队、rollup开发人员和用户不需要做进一步的工作来完成向全分片的过渡。
请注意,两者之间的选择不是非此即彼的:我们可以尽快实施EIP-4488,然后在半年后使用proto-danksharding跟进它。
proto-danksharding实现了完整danksharding的哪些部分,还有哪些需要实现?
引用EIP-4844:
此EIP中已经完成的工作包括:·一种新的交易类型,其格式与“全分片”中需要存在的完全相同。·全分片所需的所有执行层逻辑。·全分片所需的所有执行/共识交叉验证逻辑。·BeaconBlock验证和数据可用性采样blob之间的层分离。·完全分片所需的大部分BeaconBlock逻辑。·blob的自调整独立gasprice。实现完全分片尚需完成的工作包括:·共识层中blob_kzgs的低度扩展以允许2D采样。·数据可用性采样的实际实现,·PBS,以避免要求单个验证者在一个插槽中处理32MB的数据。·每个验证者的托管证明或类似的协议内要求,以验证每个区块中分片数据的特定部分。请注意,所有剩余工作都是共识层更改,不需要执行客户端团队、用户或Rollup开发人员的任何额外工作。
所有这些非常大的区块都会增加磁盘空间需求怎么办?
EIP-4488和proto-danksharding都导致每个插槽的长期最大使用量约为1MB。这相当于每年大约2.5TB,远高于以太坊今天所需的增长率。
在EIP-4488的情况下,解决此问题需要历史记录到期方案(EIP-4444?),其中不再需要客户端存储超过某个时间段的历史记录。
在proto-danksharding的情况下,无论是否实施EIP-4444,共识层都可以实施单独的逻辑以在一段时间后自动删除blob数据。但是,无论采用何种短期数据扩展解决方案,都强烈建议尽快实施EIP-4444。
这两种策略都将共识客户端的额外磁盘负载限制在最多几百GB。从长远来看,采用一些历史过期机制本质上是强制性的:完整分片每年会增加大约40TB的历史blob数据,因此用户实际上只能将其中的一小部分存储一段时间。因此,值得尽早设定对此的期望。
如果数据在30天后被删除,用户将如何访问旧Blob?
以太坊共识协议的目的不是保证所有历史数据的永久存储。相反,目的是提供一个高度安全的实时公告板,并为其他去中心化协议留出空间进行更长期的存储。公告板的存在是为了确保在公告板上发布的数据可用时间足够长,以便任何想要该数据的用户或任何备份数据的长期协议都有足够的时间来获取数据并将其导入到他们的其他应用程序或协议中。
一般来说,长期历史存储很容易。虽然每年2.5TB对常规节点的要求太大,但对于专用用户来说非常易于管理:您可以以每TB约20美元的价格购买非常大的硬盘驱动器,这完全可以满足业余爱好者的需求。与具有N/2-of-N信任模型的共识不同,历史存储具有1-of-N信任模型:您只需要其中一个数据存储者是诚实的。因此,每条历史数据只需要存储数百次,而不是完整的数千个正在做实时共识验证的节点。
存储完整历史记录并使其易于访问的一些实用方法包括:
特定于应用程序的协议可能要求其节点存储与其应用程序相关的历史记录部分。丢失的历史数据对协议没有风险,只会对单个应用程序造成风险,因此应用程序承担存储与自己相关的数据的负担是有意义的。在BitTorrent中存储历史数据,例如。每天自动生成和分发一个7GB的文件,其中包含来自区块的blob数据。以太坊门户网络可以很容易地扩展到存储历史。区块浏览器、API提供商和其他数据服务可能会存储完整的历史记录。个人爱好者和从事数据分析的学者可能会存储完整的历史记录。在后一种情况下,将历史存储在本地为它们提供了重要的价值,因为它使直接对其进行计算变得更加容易。TheGraph等第三方索引协议可能会存储完整的历史记录。在更高级别的历史存储下,一些数据被遗忘的风险会变得更高。这可能是分片区块链可扩展性的真正极限。然而,目前所有提出的参数都距离这一点非常远。
blob数据的格式是什么,它是如何提交的?
一个blob是一个包含4096个字段元素的向量,范围内的数字:
0<=x<52435875175126190479447740508185965837690552500527637822603658699938581184513
blob在数学上被视为表示具有上述模数的有限域上的次数<4096多项式,其中blob中位置i处的场元素是对该多项式在wi处的评估。w是满足w=1的常数。
对blob的承诺是KZG承诺对该多项式的一个哈希。然而,从实现的角度来看,关注多项式的数学细节并不重要。相反,只会有一个椭圆曲线点的向量,而KZG对blob的承诺将只是一个线性组合。引用EIP-4844的代码:
defblob_to_kzg(blob:Vector)->KZGCommitment:computed_kzg=bls.Z1forvalue,point_kzginzip(tx.blob,KZG_SETUP_LAGRANGE):assertvalue<BLS_MODULUScomputed_kzg=bls.add(computed_kzg,bls.multiply(point_kzg,value))returncomputed_kzg
BLS_MODULUS是上述模数,而KZG_SETUP_LAGRANGE是椭圆曲线点的向量,它是基于拉格朗日的可信设置。对于实现者来说,现在将其简单地视为一个黑盒专用哈希函数是合理的。
为什么使用KZG的哈希而不是直接使用KZG?
EIP-4844没有使用KZG直接表示blob,而是使用版本化哈希:单个0x01字节后跟KZG的SHA256哈希的最后31个字节。
这样做是为了EVM兼容性和未来兼容性:KZG承诺是48字节,而EVM更自然地使用32字节值,如果我们从KZG切换到其他东西,KZG承诺可以继续为32字节。
proto-danksharding中引入的两个预编译是什么?
Proto-danksharding引入了两种预编译:blob验证预编译和点评估预编译。
Blob验证预编译是不言自明的:它将版本化哈希和Blob作为输入,并验证提供的版本化散列实际上是Blob的有效版本化哈希。此预编译旨在供OptimisticRollup使用。引用EIP-4844:
OptimisticRollup只需要在提交欺诈证明时实际提供基础数据。欺诈证明提交功能将要求欺诈blob的全部内容作为calldata的一部分提交。它将使用blob验证功能根据之前提交的版本化哈希验证数据,然后像今天一样对该数据执行欺诈证明验证。点评估预编译将版本化哈希、x坐标、y坐标和证明作为输入。它验证证明以检查P(x)=y,其中P是由具有给定版本化哈希的blob表示的多项式。此预编译旨在供ZKRollup使用。引用EIP-4844:
ZKrollup将为其交易或状态增量数据提供两个承诺:blob中的KZG和使用ZKrollup内部使用的任何证明系统的一些承诺。他们将使用等价协议的承诺证明,使用点评估预编译,来证明kzg和ZKrollup自己的承诺引用相同的数据。请注意,大多数主要的OptimisticRollup设计都使用多轮防欺诈方案,其中最后一轮只需要少量数据。因此,可以想象,OptimisticRollup也可以使用点评估预编译而不是blob验证预编译,而且这样做会更便宜。
KZG可信设置是什么样的?
看:
https://vitalik.ca/general/2022/03/14/trustedsetup.html对powers-of-tau可信设置如何工作的一般描述
https://github.com/ethereum/research/blob/master/trusted_setup/trusted_setup.py所有重要的可信设置相关计算的示例实现
特别是在我们的例子中,当前的计划是并行运行四个大小,,和的仪式。理论上,只需要第一个,但是运行更多的更大的尺寸,通过允许我们增加blob来提高未来的适用性尺寸。我们不能只是有一个更大的设置,因为我们希望能够对可以有效提交的多项式次数有一个硬限制,这个限制等于blob大小。
可能的实用方法是从Filecoin设置开始,然后运行一个仪式来扩展它。包括浏览器实现在内的多种实现将允许许多人参与。
我们不能在没有可信设置的情况下使用其他一些承诺方案吗?
不幸的是,使用KZG以外的任何东西会使分片路线图变得更加困难。这有几个原因:
非算术承诺与数据可用性采样不兼容,因此如果我们使用这样的方案,当我们转向完整分片时,无论如何我们都必须更改为KZG。IPA可能与数据可用性采样兼容,但它会导致更复杂的方案具有更弱的属性哈希和IPA都不兼容点评估预编译的廉价实现。因此,基于哈希或IPA的实现将无法有效地使ZKRollup或支持多轮OptimisticRollup中的廉价欺诈证明。因此,不幸的是,使用除KZG之外的任何东西的功能损失和复杂性增加远大于KZG本身的风险。此外,任何与KZG相关的风险都包含在内:一个KZG故障只会影响Rollup和其他依赖于blob数据的应用程序,而不会影响系统的其余部分。
KZG有多“复杂”和“新”?
KZG承诺是在2010年的一篇论文?中介绍的,并且自2019年以来已广泛用于PLONK类型的ZK-SNARK协议中。然而,KZG承诺的基础数学是椭圆曲线运算和配对的基础数学之上的一个相对简单的算术。
使用的特定曲线是BLS12-381?,它是由Barreto-Lynn-Scott在2002年发明的。椭圆曲线配对是验证KZG承诺所必需的,是非常复杂的数学,但它们是在1940年代发明并自1990年代以来应用于密码学。到2001年,提出了许多使用配对的加密算法。
从实现复杂性的角度来看,KZG并不比IPA更难实现:计算承诺的函数与IPA的情况完全相同,只是使用了一组不同的椭圆曲线点常数。点验证预编译更复杂,因为它涉及配对评估,但数学与EIP-2537实现中已经完成的部分相同,并且非常类似于bn128配对预编译。因此,实现KZG验证不需要复杂的“新工作”
proto-danksharding实现的不同软件部分是什么?
有四个主要组成部分:
1.执行层共识发生更改:
包含blob的新交易类型输出当前交易中第i个blob版本化哈希的操作码Blob验证预编译点评估预编译2.共识层共识更改:
BeaconBlockBody中的blobKZG列表“sidecar”机制,其中完整的blob内容与来自BeaconBlock的单独对象一起传递执行层中的blob版本化哈希与共识层中的blobKZG之间的交叉检查3.内存池
BlobTransactionNetworkWrapper更强大的反DoS保护以补偿大的blob大小4.区块构建逻辑
接受来自内存池的交易封装器,将交易放入ExecutionPayload,将KZG放入信标区块和sidecar中的主体应对二次元手续费市场请注意,对于最小的实现,我们根本不需要内存池,我们只需要一个客户端来实现区块构建逻辑。只有执行层和共识层的共识变更需要进行广泛的共识测试,相对轻量级。在这样的最小实现和所有客户端都支持区块生产和内存池的“完整”部署之间的任何事情都是可能的。
proto-danksharding多维费用市场是什么样的?
Proto-danksharding引入了一个多维的EIP-1559费用市场,其中有两种资源,gas和blob,具有单独的浮动gas价格和单独的限制。
也就是说,有两个变量和四个常量:
blob费用以gas收取,但它是可变数量的gas,它会进行调整,以便从长远来看,每个区块的平均blob数量实际上等于目标数量。
二维性质意味着区块构建者将面临一个更难的问题:与其简单地接受具有最高优先级费用的交易,直到它们用完交易或达到区块gas限制,他们将不得不同时避免达到两个不同的限制。
这是一个例子。假设gas限制为70,blob限制为40。mempool有很多交易,足以填满区块,有两种类型:
优先费5pergas,4blobs,4totalgas优先费3pergas,1blob,2totalgas遵循幼稚的“降低优先费用”算法的矿工将用第一种类型的10笔交易填充整个区块,并获得5*40=200gas的收入。因为这10笔交易填满了blob完全限制,他们将无法包含更多交易。但最优策略是采取第一种类型的3笔交易和第二种类型的28笔交易。这为您提供了一个包含40blob和68gas的块,以及5*12+3*56=228的收入。
执行客户端现在是否必须实施复杂的多维背包问题算法来优化他们的区块生产?不,有几个原因:
EIP-1559确保大多数区块不会达到任何一个限制,因此实际上只有少数区块面临多维优化问题。在内存池没有足够交易达到任一限制的通常情况下,任何矿工都可以通过包含他们看到的每笔交易来获得最佳收入。在实践中,相当简单的启发式方法可以接近最优。在类似的情况下,请参阅Ansgar的EIP-4488分析?以获取有关此的一些数据。多维定价甚至不是专业化带来的最大收入来源——MEV是。通过专用算法从链上DEX套利、清算、抢先NFT销售等中提取的专用MEV收入占“可提取收入”总额的很大一部分:专用MEV收入似乎平均约为0.025ETH每个区块,总优先权费用通常在每个区块0.1ETH左右。提议者/建造者分离?是围绕高度专业化的区块生产而设计的。PBS将区块构建过程转变为拍卖,专业参与者可以竞标创建区块的特权。常规验证者只需要接受最高出价。这是为了防止MEV驱动的规模经济蔓延到验证者中心化,但它处理了所有可能使优化区块构建变得更加困难的问题。由于这些原因,更复杂的费用市场动态不会大大增加中心化或风险;事实上,更广泛应用的原则?实际上可以降低DoS攻击的风险!
指数型EIP-1559blob费用调整机制如何运作?
今天的EIP-1559调整基础费用b以达到特定的目标gas使用水平t,如下所示:
其中b(n)是当前区块的基本费用,b(n+1)是下一个区块的基本费用,t是目标,u是使用的gas。
这种机制的一个大问题是它实际上并不针对t。假设我们得到两个区块,第一个u=0,下一个u=2t。我们得到:
尽管平均使用量等于t,但基本费用下降了63/64。所以basefee只有在使用率略高于t时才会稳定;在实践中显然高出约3%,尽管确切的数字取决于方差。
一个更好的公式是指数调整:
exp(x)是指数函数e^x,其中e≈2.71828。在x值较小时,exp(x)≈1+x。但是,它具有与交易置换无关的便利特性:多步调整
仅取决于总和u1+...+u/n,而不取决于分布。要了解原因,我们可以进行数学运算:
因此,包含的相同交易将导致相同的最终基础费用,无论它们如何在不同区块之间分配。
上面的最后一个公式也有一个自然的数学解释:术语(u1+u2+...+u/n-nt)可以看作是多余的:实际使用的总gas与打算使用的总gas之间的差异。
当前基本费等于
的事实清楚地表明,超出部分不能超出一个非常窄的范围:如果超过8t?60,那么basefee变为e^60,高得离谱,没有人可以支付它,如果它低于0,则资源基本上是免费的,并且链将被垃圾邮件发送,直到超出部分回到零以上。
调整机制完全按照这些术语工作:它跟踪实际总计(u1+u2+...+u/n)并计算目标总计(nt),并将价格计算为差异的指数。为了使计算更简单,我们不使用e^x,而是使用2^x;事实上,我们使用了2^x的近似值:EIP中的fake_exponential函数。假指数几乎总是在实际值的0.3%以内。
为了防止长时间的未充分使用导致长时间的2倍完整区块,我们添加了一个额外的功能:我们不会让多余的区块低于零。如果actual_total低于targeted_total,我们只需将actual_total设置为等于targeted_total。在极端情况下,这确实破坏了交易顺序的不变性,但增加的安全性使得这是一个可接受的折衷方案。还要注意这个多维市场的一个有趣的结果:当最初引入proto-danksharding时,最初可能只有很少的用户,因此在一段时间内,一个blob的成本几乎肯定会非常便宜,即使是“常规的”以太坊区块链活动仍然很昂贵。
作者认为这种费用调整机制比目前的方法更好,因此最终EIP-1559费用市场的所有部分都应该转向使用它。
有关更长更详细的解释,请参阅Dankrad的帖子?。
fake_exponential是如何工作的?
为方便起见,这里是fake_exponential的代码:
deffake_exponential(numerator:int,denominator:int)->int:cofactor=2**(numerator//denominator)fractional=numerator%denominatorreturncofactor+(fractional*cofactor*2+(fractional**2*cofactor)//denominator)//(denominator*3)
这里是用数学重新表达的核心机制,去掉了四舍五入:
目标是将(QX)的许多实例拼接在一起,其中一个为每个范围适当地移动和放大。Q(x)本身是0≤x≤1的2^x的近似值,选择用于以下属性:
简单性左边缘的正确性(Q(0)=2^0=1)右边缘的正确性(Q(1)=2^1=2)平滑斜率最后三个要求给出三个未知系数的三个线性方程,上面给出的Q(x)给出了唯一的解。
近似值出奇地好;对于除最小输入之外的所有输入,fake_exponential给出的答案在2^x实际值的0.3%范围内:
proto-danksharding中有哪些问题仍在争论中?
注意:此部分很容易过时。不要相信它会就任何特定问题给出最新的想法。
所有主要的OptimisticRollup都使用多轮证明,因此它们可以使用点评估预编译而不是blob验证预编译。任何真正需要blob验证的人都可以自己实现它:将blobD和版本化哈希h作为输入,选择x=hash(D,h),使用重心评估?计算y=D(x)并使用点评估预编译验证h(x)=y。因此,我们真的需要blob验证预编译,还是可以直接删除它并只使用点评估?该链在处理持久的长期1MB+块方面的能力如何?如果风险太大,是否应该在一开始就减少目标blob数?blob应该以gas还是ETH计价?是否应该对费用市场进行其他调整?应该将新的交易类型视为blob还是SSZ对象,在后一种情况下将ExecutionPayload更改为联合类型?可信设置实现的确切细节。
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。