在OOP语言中,重写继承是一种众所周知的最佳实践。坚固性也是一种OOP语言,但是也存在气体效率问题。
在Solidity中,问题是,考虑到各自的燃气成本,组成和继承之间如何比较?
答案 0 :(得分:2)
在1-1比较中,Composition的部署和执行成本更高。也就是说,如果您需要部署许多实例,则可以使用Library pattern并以这种方式使用组合。
如果您要部署相同代码的许多副本,则库可以降低部署成本。如果您设想部署100个相同代码的副本,则可能只需要部署一个库,然后可以将更多的代码推送到库中,则每个依赖合同部署的成本就会降低。但是调用该库会增加执行成本。
库需要考虑的另一件事:共享库存在重大的安全问题。锁定资金的奇偶校验黑客为due to usage of composition。
继承是一个简单得多的模型,并且执行起来总是更便宜。
但是,您将不得不致电适合自己的用例。该合同会有很多版本吗?如果是这样,每个实例是否会经常执行以弥补部署成本?
答案 1 :(得分:0)
调整合同不是一门精确的科学,而是在安全性,良好的编码习惯和成本之间取得平衡。
在以太坊中,交易消耗了汽油,因此消耗了以太。在两种情况下,减少合同消耗的气体很重要
诸如继承和组合之类的OOP原理可促进代码重用,并因此自动减小合同的字节大小。但是,开发人员仍然有责任编写高效的代码以优化气体使用量。
为避免在部署合同时花费巨大的成本,对于开发人员而言,编写有效的代码非常重要。尤其是当一个合同继承自另一个合同或一个合同由另一个合同组成时。
如果Contract B
继承自Contract A
,则在编译期间,Solidity编译器会将A
的字节码注入B
中。这增加了B
的部署成本。 (实际上,B
的大小= B
的大小+ A
的大小)。同样,如果Contract C
由Contract D
组成,则D
的字节码将被编译为C
的字节码。但是,如果您作为开发人员认为与通过重复使用代码来减少transaction cost
相比,此初始成本是合理的,那么您就需要做出行政决定!
但是,当您进行这样的合成时:
// Foo bytecode will be loaded into memory from an existing Foo deployment
Foo public foo2 = Foo(0xF00BAA...); //THIS is more efficient compared to new Foo().
在某些情况下,您可以考虑继承的替代方法。例如,在主合同(例如,注册表或主存储/逻辑)中调用外部功能的子合同往往比继承了复杂合同的子合同小。这样不仅可以降低部署成本,而且可以减少总计transactions
的耗油量。
另一种减少无用代码的方法,。例如:
function p1 ( uint x ){
if ( x > 5)
if ( x*x < 20)
XXX }
在上面的代码中,第3行和第4行将永远不会执行,可以避免仔细地通过合同逻辑避免这些无用的代码,这将减小智能合同的大小。
总体而言,仅选择“成分与继承”并不能提高气体效率。其实用的编码方式可以节省气体!
有关更多详细信息,此article有助于您对气体效率高的固体代码进行编码。
希望有帮助。