Solidity合约内调用new()实例化其他合约为何新增20K部署体积?
现象原因
- Solidity 中使用
new关键字在合约内部署另一合约时,编译器会将被部署合约的完整运行时字节码+创建时字节码完整嵌入到调用方合约的字节码中,这是体积上涨的核心原因。你观测到的约20KB增量=BKopyLite本身17KB字节码 +new操作对应的参数编码、合约创建逻辑、异常校验等附加开销,完全符合该机制的表现。 - 当你把
new逻辑替换为返回address(0)时,编译器会判定BKopyLite的字节码完全未被使用,自动在编译阶段剔除所有相关代码,所以合约体积直接回落到4.68KB的基础大小。
可行规避方案
- 使用EIP-1167最小代理模式(首推)
提前部署一份BKopyLite的实现合约,后续创建实例时仅部署几十字节大小的最小代理合约指向该实现即可。调用方合约不需要嵌入BKopyLite的完整字节码,仅需要包含代理合约的创建逻辑,整体增量可以控制在1KB以内。注意需要将BKopyLite的构造函数逻辑替换为公开的initialize初始化函数,配合代理调用完成参数初始化。 - 拆分独立工厂合约
将BKopyLite的创建逻辑抽离到单独的工厂合约中,主合约仅通过调用工厂合约的创建接口完成新实例部署,主合约完全不需要引入BKopyLite的任何字节码,体积不会出现额外上涨。 - 开启编译器优化
在hardhat.config中开启Solidity编译器优化,设置合适的runs值(通常设置为200~1000即可),可以剔除大量冗余字节码,若体积仅超出限制几KB,该方案可以直接解决问题。 - 裁剪被实例化合约逻辑
拆分BKopyLite的冗余功能,移除未使用的函数、库依赖,缩小BKopyLite本身的字节码体积,也能减少嵌入到主合约的字节码大小。
内容的提问来源于stack exchange,提问作者GGizmos
相关产品推荐
相关产品推荐

