区块链研究实验室-深入了解Solidity如何在以太坊上运行-第七节

01

数组绑定检查

我们已经看到固定长度数组与结构和状态变量具有相同的存储布局,但生成的汇编代码是不同的。 原因是Solidity生成数组访问的边界检查。

让我们再次编译数组合约,这次关闭优化:

$ solc --bin --asm c-static-array.sol

下面对组件进行了评论,在每条指令后输出相应状态:

tag_2:

0xc0fefe

[0xc0fefe]

0x5

[0x50xc0fefe]

dup1

/* array bound checking code */

// 5

0x6

[0x60x50xc0fefe]

dup2

[0x50x60x50xc0fefe]

lt

[0x10x50xc0fefe]

// bound_check_ok = 1 (TRUE)

// if(bound_check_ok) { goto tag5 } else { invalid }

tag_5

[tag_50x10x50xc0fefe]

jumpi

// Test condition is true. Will goto tag_5.

// And `jumpi` consumes two items from stack.

[0x50xc0fefe]

invalid

// Array access is valid. Do it.

// stack: [0x5 0xc0fefe]

tag_5:

sstore

[]

storage: {0x5=>0xc0fefe }

我们现在看到绑定检查代码, 我们已经看到编译器能够优化其中的一些东西,但并不是很完美。

在本文的后面,我们将看到数组绑定检查如何干扰编译器优化,使得固定长度数组的效率远低于存储变量或结构。

02

数组压缩

存储是昂贵的, 一个关键的优化是将尽可能多的数据打包到一个32字节的插槽中。

考虑一个包含四个存储变量的合约,每个变量64位,总共加起来为256位(32字节):

pragma solidity ^0.4.11;

contract C {

uint64a;

uint64b;

uint64c;

uint64d;

function C() {

a =0xaaaa;

b =0xbbbb;

c =0xcccc;

d =0xdddd;

}

}

我们希望(希望)编译器使用一个sstore将它们放在同一个存储槽中。

编译:

$ solc --bin --asm --optimize c-many-variables--packing.sol

组合:

tag_2:

/* "c-many-variables--packing.sol":121:122 a */

0x0

/* "c-many-variables--packing.sol":121:131 a = 0xaaaa */

dup1

sload

/* "c-many-variables--packing.sol":125:131 0xaaaa */

0xaaaa

not(0xffffffffffffffff)

/* "c-many-variables--packing.sol":121:131 a = 0xaaaa */

swap1

swap2

and

or

not(sub(exp(0x2,0x80), exp(0x2,0x40)))

/* "c-many-variables--packing.sol":139:149 b = 0xbbbb */

and

0xbbbb0000000000000000

or

not(sub(exp(0x2,0xc0), exp(0x2,0x80)))

/* "c-many-variables--packing.sol":157:167 c = 0xcccc */

and

0xcccc00000000000000000000000000000000

or

sub(exp(0x2,0xc0),0x1)

/* "c-many-variables--packing.sol":175:185 d = 0xdddd */

and

0xdddd000000000000000000000000000000000000000000000000

or

swap1

sstore

需要注意的关键是目前只有一个sstore。证实我们优化成功!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180811A0DY5000?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券