[]通过 EVM 代码默克尔化缩减见证数据大小


[]通过 EVM 代码默克尔化缩减见证数据大小
本文插图

免责声明:本文旨在传递更多市场信息 , 不构成任何投资建议 。 文章仅代表作者观点 , 不代表火星财经官方立场 。
小编:记得关注哦
来源:以太坊爱好者
作者: Sina Mahmoodi
翻译&校对: IAN LIU & 阿剑
来源:以太坊爱好者
摘要:区块中每发生一次合约调用 , 无状态客户端都需要完整的合约代码作为区块见证(witnesss)的一部分 , 而传输合约代码占用无状态客户端带宽的比例 , 高居其带宽开销的第二位 。
人们认为 , 代码默克尔化方法(Merklization)能够优化带宽开销 。 本文解释了如何将代码拆分为 “块( chunk ) ” , 默克尔化这些 chunk , 并只在交易需要的情况下传递这些 chunk。 实验证明 , 基于目前的主网情况 , 我们能看到合约代码传输的开销节省了 40%~60%。
巨大的无状态区块
代码默克尔化的概念已经被提出好一阵子了 , 一开始主要用于代码去重 , 但其他用途还未被很好地探索 。 现在它重新进入大众视线 , 却是因为另一个目的 —— 用于降低无状态客户端所需要的带宽开销(e.g. 详见此处) 。 如果你想知道无状态客户端为什么出现 , 我推荐这篇总结 , 或是 Alexey Akhunov 的推文(编者注:中译本见文末《以太坊无状态客户端初探》) , 里面还附上了他的实验数据 。 为求简短扼要 , 我不会深入整个无状态客户端模型的细节 , 仅提供相关细节的简要总结(如果你早已了解相关的背景 , 可以跳过下一段的内容) 。
在无状态模式下 , (至少有部分)节点可以依赖其他节点(例如矿工节点)来取得区块内容(包含合约代码)并使用相关默克尔证明加以验证 , 而不必自己存储所有区块状态 —— 这会给网络带宽带来巨大的性能提升 。 Alexey Akhunov 和 turbo-geth 团队一直在研究 , 希望能确定已经产出的主网区块的区块见证大小 。 下图是对最近 50000 个区块的测量结果:红线追踪每个无状态区块需要发送的合约代码量(合约代码目前占见证大小的第二大头) 。 如果以太坊从当前的 hexary 字典树结构转为二进制 trie , 则见证数据所包含的哈希值数据大小约能减小 3 倍(编者注:中译本见文末《二进制状态树实验》) , 这时候合约代码量就成为构成见证大小的第一大头了 。
[]通过 EVM 代码默克尔化缩减见证数据大小
本文插图

- 图表显示最近 50000 个主网区块的无状态区块见证大小变化 , 经过窗口 = 128个区块的移动平均计算 (数据来自 https://github.com/mandrigin/ethereum-mainnet-bin-tries-data)-
不要发送整段代码
我们假设 , 其实每笔交易只会调用部分的合约代码(例如只调用 4 个函数中的 2 个) , 所以我们的目标就是拆分这些代码块(chunk) , 每次交易只发送需要的 chunk(以及相应的有效性证明)的区块见证 。 如果这种假设合理 , 而且每笔交易真的只用到一小部分字节码(剧透:历史数据表示的确这样) , 那么区块见证的合约代码部分就能大大的减小 。
为了更好地理解 , 想象我们正在部署一份新的合约 , 我们需要传递代码和并确定 basic block (详见此处算法) 。 请注意 , 为了进行 JUMPDEST 分析 , 客户端已经传递过一次代码 , 因此这次传递不会增加开销 。 这些 basic block(译者注:指只有一个入口且只有一个出口的代码块 , 没有跳转进入 , 也没有跳转退出)有两种特性:
[]通过 EVM 代码默克尔化缩减见证数据大小
本文插图

- 字节码的 basic blocks(假想的)-