如何缩减合约以规避合约大小限制

你能做些什么来防止合约变得太大?

> * 原文:https://soliditydeveloper.com/max-contract-size > * 译文出自:[登链翻译计划](https://github.com/lbc-team/Pioneer) > * 译者:[翻译小组](https://learnblockchain.cn/people/412) > * 校对:[Tiny 熊](https://learnblockchain.cn/people/15) > * 本文永久链接:[learnblockchain.cn/article…](https://learnblockchain.cn/article/2773) ## 为什么合约有一个大小限制? ![为什么](https://img.learnblockchain.cn/pics/20210725140955.png) 在[2016年11月22日](https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/),Spurious Dragon硬分叉引入了[EIP-170](https://eips.ethereum.org/EIPS/eip-170),增加了智能合约的大小限制为24.576kb。对于作为Solidity开发者的你来说,这意味着当你向你的合约添加越来越多的功能时,在某些时候你会达到限制,当部署时你会看到错误: *Warning: Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries.* 警告:合约代码大小超过24576字节(Spurious Dragon分叉中引入的限制),这个合约可能无法在主网上部署。考虑启用优化器,关闭revert字符串,或使用库。 引入这一限制是为了防止拒绝服务(DOS)攻击。任何对合约的调用从Gas上来说都是相对便宜的。然而,由于调用的合约代码的大小(从磁盘读取代码,预处理代码,添加数据到Merkle证明)的原因,合约调用对以太坊节点的影响并不是成比例地增加。每当你出现这样的情况,攻击者只需要很少的资源就能给别人造成大量的工作,这会增加DOS攻击的可能性。 最初,这不是一个问题,因为一个合约大小限制是区块块Gas限制。很明显,一个合约需要被部署在一个交易中,这个交易持有合约的所有字节码。如果你把大合约的部署交易纳入一个区块,你可以用完所有的Gas。但这种情况下的问题是,区块Gas限制随时间变化,理论上是无限制的。在EIP-170的时候,区块Gas的限制只有470万。现在,区块Gas限制是1500万。 ## 那就战斗吧 不幸的是,没有简单的方法来获得你的合约的字节码大小,如果你使用Truffle,一个很好的工具可以帮助你,那就是[truffle-contract-size](https://github.com/IoBuilders/truffle-contract-size)插件。 1. `npm install truffle-contract-size`。 2. 在*truffle-config.js*中添加该插件:`插件。[`truffle-contract-size`]`。 3. 运行`truffle run contract-size`。 这将帮助你弄清楚怎么的变化及如何影响总的合约打下规模。 在下文中,我们将根据其潜在的影响来研究一些方法。从缩减角度来考虑。对于一个人来说,要达到他们的目标体重(在我们的例子中是24kb),最好的策略是首先关注影响大的方法。在大多数情况下,仅仅固定你的饮食就能达到目标,但有时你需要更多一点。如可能会增加一些运动(中等影响)或甚至补充剂(小影响)。 ![体重减轻](https://img.learnblockchain.cn/pics/20210725140945.jpg) ### 需要重点关注(较大影响) #### 把你的合约分开 这应该永远是你的首要方法。如何把合约分成多个小合约?一般来说,这迫使你为你的合约想出一个好的架...

  • 原文:https://soliditydeveloper.com/max-contract-size
  • 译文出自:登链翻译计划
  • 译者:翻译小组
  • 校对:Tiny 熊
  • 本文永久链接:learnblockchain.cn/article…

为什么合约有一个大小限制?

在2016年11月22日,Spurious Dragon硬分叉引入了EIP-170,增加了智能合约的大小限制为24.576kb。对于作为Solidity开发者的你来说,这意味着当你向你的合约添加越来越多的功能时,在某些时候你会达到限制,当部署时你会看到错误:

Warning: Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). This contract may not be deployable on mainnet. Consider enabling the optimizer (with a low "runs" value!), turning off revert strings, or using libraries.

警告:合约代码大小超过24576字节(Spurious Dragon分叉中引入的限制),这个合约可能无法在主网上部署。考虑启用优化器,关闭revert字符串,或使用库。

引入这一限制是为了防止拒绝服务(DOS)攻击。任何对合约的调用从Gas上来说都是相对便宜的。然而,由于调用的合约代码的大小(从磁盘读取代码,预处理代码,添加数据到Merkle证明)的原因,合约调用对以太坊节点的影响并不是成比例地增加。每当你出现这样的情况,攻击者只需要很少的资源就能给别人造成大量的工作,这会增加DOS攻击的可能性。

最初,这不是一个问题,因为一个合约大小限制是区块块Gas限制。很明显,一个合约需要被部署在一个交易中,这个交易持有合约的所有字节码。如果你把大合约的部署交易纳入一个区块,你可以用完所有的Gas。但这种情况下的问题是,区块Gas限制随时间变化,理论上是无限制的。在EIP-170的时候,区块Gas的限制只有470万。现在,区块Gas限制是1500万。

那就战斗吧

不幸的是,没有简单的方法来获得你的合约的字节码大小,如果你使用Truffle,一个很好的工具可以帮助你,那就是truffle-contract-size插件。

  1. npm install truffle-contract-size
  2. truffle-config.js中添加该插件:插件。[truffle-contract-size]
  3. 运行truffle run contract-size

这将帮助你弄清楚怎么的变化及如何影响总的合约打下规模。

在下文中,我们将根据其潜在的影响来研究一些方法。从缩减角度来考虑。对于一个人来说,要达到他们的目标体重(在我们的例子中是24kb),最好的策略是首先关注影响大的方法。在大多数情况下,仅仅固定你的饮食就能达到目标,但有时你需要更多一点。如可能会增加一些运动(中等影响)或甚至补充剂(小影响)。

需要重点关注(较大影响)

把你的合约分开

这应该永远是你的首要方法。如何把合约分成多个小合约?一般来说,这迫使你为你的合约想出一个好的架...

剩余50%的内容订阅专栏后可查看

  • 单篇购买 10学分
  • 永久订阅专栏 (90学分)
  • 发表于 2021-07-25 15:56
  • 阅读 ( 1059 )
  • 学分 ( 0 )
  • 分类:Solidity
  • 专栏:全面掌握Solidity智能合约开发

评论