首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何编写优化的(天然气成本)智能合同?

如何编写优化的(天然气成本)智能合同?
EN

Ethereum用户
提问于 2017-10-19 15:03:00
回答 2查看 21.7K关注 0票数 44

众所周知,有许多因素决定了一个好的明智的合同,例如:

  • 安全性:它具有最小/零的漏洞,因此它们不能被对手利用。对攻击免疫。
  • 费用:a (a)智能合同部署费用、(b)运行/调用信息技术每项功能的费用总额。
  • 正确性:它按计划执行。

在这个问题上,我想把重点放在智能合同的成本上。

问题1:如何制定符合成本效益的智能合同?

问题2:如何避免使用一些昂贵的功能?换句话说,有什么功能是众所周知的比其他操作更昂贵,我们能用更好的吗?

问题3:一般来说,以最低的成本写一份聪明的合同有什么好的做法?

简而言之:我们怎样才能节省汽油:以太:钱?

EN

回答 2

Ethereum用户

回答已采纳

发布于 2017-10-19 22:51:39

在以太,交易成本的天然气,因此乙醚。事务的气体消耗取决于EVM必须执行的操作码。每个Opcode的气体成本可以在这个问题中找到。很少有普通的操作码和气体,

代码语言:javascript
复制
Operation         Gas           Description

ADD/SUB           3             Arithmetic operation
MUL/DIV           5             Arithmetic operation
ADDMOD/MULMOD     8             Arithmetic operation
AND/OR/XOR        3             Bitwise logic operation
LT/GT/SLT/SGT/EQ  3             Comparison operation
POP               2             Stack operation 
PUSH/DUP/SWAP     3             Stack operation
MLOAD/MSTORE      3             Memory operation
JUMP              8             Unconditional jump
JUMPI             10            Conditional jump
SLOAD             200           Storage operation
SSTORE            5,000/20,000  Storage operation
BALANCE           400           Get balance of an account
CREATE            32,000        Create a new account using CREATE
CALL              25,000        Create a new account using CALL

当涉及到智能合同时,这是一个值得关注的问题,因为交易也涉及到,在设计合同时必须考虑天然气的成本。

减少合同消耗的气体在两种情况下都很重要,

  1. 部署合同的费用
  2. 调用合同函数的成本

部署合同

的成本

为此,大多数优化都是在编译时完成的,如文件-常见问题中所述,

在已部署的合同中是否包括了评论,是否增加了部署气体?不,在编译过程中,不需要执行的所有内容都会被删除。其中包括注释、变量名和类型名称。

优化器的详细信息可以找到这里

另一种缩小大小的方法是删除无用的代码。例如:

代码语言:javascript
复制
1 function p1 ( uint x ){ 
2    if ( x > 5)
3     if ( x*x < 20)
4        XXX }

在上面的代码中,第3行和第4行将永远不会被执行,这些类型的无用代码可以通过仔细地遍历契约逻辑来避免,这将减少智能契约的大小。

调用合同函数的

成本

当合同的函数被调用时,为了执行功能,它要花费天然气。因此,优化函数以减少气体的使用是非常重要的。当考虑到个人合同时,可以有许多不同的方法。在执行过程中可以节省汽油的有几个,

  1. 减少昂贵的操作

昂贵的操作是具有更多气体值(如SSTORE )的操作码。下面是一些降低昂贵操作的方法。

( A) 短路规则的使用

操作符\和&&应用常见的短路规则。这意味着,在表达式f(x)中,如果f(x)计算为true,则即使有副作用,g(y)也不会被计算。

因此,如果逻辑操作包括昂贵的操作和低成本的操作,以一种使昂贵的操作可以短路的方式安排,将减少一些执行时的气体。

如果f(x)低成本,g(y)昂贵,则安排逻辑操作

  • 或:f(x) || g(y)
  • 和:f(x) && g(y)

如果短路,会节省更多的汽油。

如果f(x)g(y)相比返回false的概率要高得多,那么像f(x) && g(y)那样安排和操作可能会通过短路来节省执行过程中的更多气体。

如果f(x)返回true的概率比g(y)高得多,那么将OR操作安排为f(x) || g(y)可能会通过短路来节省执行过程中的更多气体。

( B)循环中昂贵的操作

例:

代码语言:javascript
复制
 uint sum = 0;
 function p3 ( uint x ){
     for ( uint i = 0 ; i < x ; i++)
         sum += i; }

在上面的代码中,由于每次在循环中读取和写入sum存储变量,所以每次迭代时都会执行代价高昂的存储操作。可以通过引入如下的局部变量来避免这种情况,以节省气体。

代码语言:javascript
复制
 uint sum = 0;
 function p3 ( uint x ){
     uint temp = 0;
     for ( uint i = 0 ; i < x ; i++)
         temp += i; }
     sum += temp;
  1. 其他循环相关模式

环路组合

代码语言:javascript
复制
function p5 ( uint x ){
    uint m = 0;
    uint v = 0;
    for ( uint i = 0 ; i < x ; i++) //loop-1
        m += i;
    for ( uint j = 0 ; j < x ; j++) //loop-2
        v -= j; }

环路-1和循环-2可以结合起来,节省气体,

代码语言:javascript
复制
 function p5 ( uint x ){
    uint m = 0;
    uint v = 0;
    for ( uint i = 0 ; i < x ; i++) //loop-1
       m += i;
       v -= j; }

还可以找到一些更多的循环模式,这里

  1. 使用固定大小的字节数组

来自文档

可以使用一个字节数组作为byte[],但是当传入调用时,它浪费了大量的空间,每个元素都浪费了31个字节。最好使用字节。

根据经验,对任意长度的原始字节数据使用字节,对任意长度的字符串(UTF-8)使用字符串。如果可以将长度限制为一定数量的字节,请始终使用bytes1中的一个到bytes32,因为它们要便宜得多。

固定长度总能节省汽油。也可以参考这个问题

  1. 如前面在合同部署下解释的那样,删除无用的代码即使在执行函数时也会节省气体,如果可以在函数内部完成的话。
  2. 在实现功能时不使用库对于简单的使用来说成本更低。

为了简单的使用调用库可能会花费很大。如果该功能简单可行,可以在契约内部实现,因为它避免了调用库的步骤。对于这两种功能,仅执行成本仍然是相同的。

  1. 对于外部访问的函数,使用可见性external只能强制使用calldata作为参数位置,这在函数执行时节省了一些气体。
  2. 在可能的情况下,在函数中使用memory变量可以节省访问storage的气体。

这是一些节省气体的方法,而且可能有许多其他的方法,取决于需求。

票数 63
EN

Ethereum用户

发布于 2018-09-01 14:44:46

我相信使用内联组装函数在智能合同中编写函数可以比您试图在合同中进行的任何更改更具有成本效益。一个简单的循环函数,在固体取x的魏氏。在同一功能中写入的实体的内嵌装配所占的比例低到0.7(x) %。

票数 2
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/28813

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档