热门标签

Kiếm tiền từ cờ bạc online:以太坊高度数据(www.326681.com)_EVM 深入探讨 Part 2

时间:2个月前   阅读:1

以太坊开奖网www.326681.com)采用以太坊区块链高度哈希值作为统计数据,以太坊开奖网(联博统计)数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入

点击阅读:EVM 深入探讨 Part 1

导语

在第 1 部门中,我们探讨了 EVM 若何通过被挪用的合约函数知道需要运行哪个字节码,其中我们领会了挪用栈、calldata、函数署名和 EVM 操作码指令。

在第 2 部门中,我们将开启内存之旅,周全领会合约的内存以及它在 EVM 上的事情方式。

此系列我们将引介翻译 noxx 的文章(https://noxx.substack.com/)深入探讨 EVM 的基础知识。

内存之旅

我们依然使用第 1 部门中在 remix 上为人人演示的示例代码。

第 1 部门中我们凭证合约编译后天生的字节码研究了与功效选择相关的部门。在本文中,我们将注重力放在字节码的前 5 个字节。

这 5 个字节示意初始化 “空闲内存指针” 操作。要完全明白这些字节码的作用,首先需要明白治理支配合约内存的数据结构。

1、内存数据结构

合约内存是一个简朴的字节数组,其中数据存储可以使用 32 字节(256 位)或 1 字节(8 位)的数据块存储数据,然则读取时每次只能读取牢靠巨细的 32 字节(256 位)的数据块。下面的图片说明晰此结构以及合约内存的读/写功效。

这个功效是由操作内存的 3 个操作码决议的。

你可以将内存位置简朴地看作是最先写入/读取数据的数组索引。若是想写入/读取跨越 1 个字节的数据,只需继续从下一个数组索引写入或读取。

2、EVM Playground

EVM Playground 有助于牢固我们这 3 个操作码的运行原理、作用以及内存位置的明白。单击 Run 和右上角的箭头举行调试来查看客栈和内存是若何更改的。(操作码上方有注释来形貌每个部门的作用)

可能会注重到一些新鲜的征象,我只添加了 1 个字节,为什么多了这么多零呢?

3、内存扩展

当合约写入内存时,需要为写入的字节数支付 Gas,也就是扩大内存的开销。若是我们正在写入一个以前没有写入过的内存区域,那么第一次使用它会发生分外的内存扩睁开销。

写入之前未触及的内存空间时,内存以 32 字节(256 位)为增量扩展。前 724 个字节,内存扩展呈线性增进,之后呈二次方增进。(由以太坊黄皮书公式 326 扩大内存的 Gas 开销得出,公式为:

,扩展内存时为每个分外的字的开销。其中 a 是合约挪用中写入的最大内存位置,以 32 字节字为单元。用 1024 字节内存为例,那么 a = 32 。)

在位置 32 处写入 1 个字节之前,我们的内存是 32 个字节。此时我们最先往未触及的内存空间写入内容,效果,内存增添了 32 个字节,增添到 64 个字节。内存中所有位置的都初始被界说为 0,这也是为什么我们会看到 2200000000000000000000000000000000000000000000000000000000000000 被添加到内存中的缘故原由。

4、内存是一个字节数组

调试历程中,我们可能注重到的第二件事发生在我们从内存位置 33 (0x21) 运行 MLOAD 时。我们将以下值返回到挪用栈。

3300000000000000000000000000000000000000000000000000000000000000

内存读取可以从一个非 32 字节元素最先。

内存是一个字节数组,这意味着可以从任何内存位置最先读取(和写入)。我们不限于 32 的倍数。内存是线性的,可以在字节级别举行寻址。内存只能在函数中新建。它可以是新实例化的庞大类型,如数组/结构(例如,通过 新建一个 int[...])或从存储引用的变量中复制。

现在我们对数据结构已有了一定的领会了,接下来让我们来看空闲内存指针。

5、空闲内存指针

空闲内存指针只是一个指向空闲内存最先位置的指针。它确保智能合约可以跟踪到哪些内存位置已写入,哪些未写入。这可以防止合约笼罩已分配给另一个变量的某些内存。当一个变量被写入内存时,合约将首先引用空闲内存指针来确定数据应该存储在那里。然后,它通过纪录要写入新位置的数据量来更新空闲内存指针。这两个值的简朴相加将发生新的空闲内存最先的位置。

空闲内存指针的位置 + 数据的字节巨细 = 新空闲内存指针的位置

6、字节码

就像我们之前所提到的,空闲内存指针是通过这 5 个操作码在运行时字节码的界说的。

这些操作码声明空闲内存指针位于内存中字节 0x40(十进制中的 64)处,值为 0x80(十进制中的 128)。

Solidity 的内存结构保留了 4 个 32 字节的插槽:

  • 0x40 - 0x5f (32 bytes):空闲内存指针,当前分配的内存巨细,空闲内存的起始位置,初始化为 0x80。

  • 0x60 - 0x7f (32 bytes):插槽 0,用作动态内存数组的初始值,永远不应写入。

我们可以看到,0x40 是空闲内存指针的预界说位置。而值 0x80 只是在 4 个 32 字节保留值插槽之后可写入的第一个内存字节。

7、合约中的内存

为了牢固我们到现在为止所学到的知识,接下来将看看内存和空闲内存指针是若何在 Solidity 代码中更新的。

我们确立 MemoryLane 合约来举行演示。合约的 memoryLane() 界说了两个长度划分为 5 和 2 的数组,并将 uint256 类型的 1 赋值给 b[0]。

要查看合约代码在 EVM 中执行的详细信息可以将其复制到 Remix IDE 中编译并部署合约。挪用  memoryLane() 后进入 DeBug 模式来逐步执行操作码(以上操作可以参考:

https://remix-ide.readthedocs.io/en/latest/tutorial_debug.html)。

,

以太坊高度

,

Kiếm tiền từ cờ bạc online(www.vng.app):Kiếm tiền từ cờ bạc online(www.vng.app) cổng Chơi tài xỉu uy tín nhất việt nam。Kiếm tiền từ cờ bạc online(www.vng.app)game tài Xỉu đánh bạc online công bằng nhất,Kiếm tiền từ cờ bạc online(www.vng.app)cổng game không thể dự đoán can thiệp,mở thưởng bằng blockchain ,đảm bảo kết quả công bằng.

,

www.326681.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。

,

将简化版操作码提取到 EVM Playground 中,可通过这个链接查看详细的操作码及注释信息(https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy-d6b#:~:text=version%20into%20an-,EVM%20Playground,-and%20will%20run)。

这里将操作码分成 6 个差其余部门依次解读,删除了 JUMP 以及与内存操作无关的操作码同时将注释添加了进去利便查看当前在执行什么操作。

1)空闲内存指针初始化(EVM Playground 操作码代码 1-15 行)

首先,0x80(十进制为 128)先入栈,这是由 Solidity 内存结构划定的值,当前内存中没有任何器械。

最后,我们挪用 MSTORE,它将第一项从栈 0x40 弹出以确定在内存中写入的位置,并将第二个值 0x80 作为写入的内容。这样留下了一个空栈,但已经填充了一部门到内存中。内存由十六进制字符示意,其中每个字符代表 4 位。例如:在内存中有 192 个十六进制字符,这意味着我们有 96 个字节(1 字节 = 8 位 = 2 个十六进制字符)。若是我们回首 Solidity 的内存结构会发现,前 64 个字节将被分配为暂存空间,接下来的 32 个字节将用于空闲内存指针。

2)内存分配变量 “a” 和空闲内存指针更新(EVM Playground 第 16-34 行)

接下来的部门,我们将跳到每个部门的竣事状态,并精练概述。

首先,为变量 “a”(bytes32[5])分配下一个内存,并更新空闲内存指针。编译器将通过数组巨细和默认数组元素巨细确定需要若干空间。Solidity 中内存数组中的元素都是占有 32 字节的倍数(这同样适用于 bytes1[],但 bytes 和 string 不适用)。当前需要分配的内存为 5 * 32 字节,示意为 160 或 0xa0(16 进制的 160)。我们可以看到它被压入栈中并添加到当前空闲内存指针 0x80(十进制中的 128)来获取新的空闲内存指针值。这将返回 0x120(十进制的 288 = 128 + 160),我们可以看到它已被写入空闲内存指针位置。挪用栈将变量 “a” 的内存位置保留在栈 0x80 上,以便以后可以在需要时引用它。0xffff 代表一个 JUMP(无条件跳转) 位置,可以忽略,由于它与内存操作无关。

3)内存初始化变量 “a”(EVM Playground 第 35-95 行)

已经分配好了内存而且更新了空闲内存指针,接下来需要为变量 “a” 初始化内存空间。由于该变量只是被声明并没有被赋值,它将被初始化为零值。

EVM 通过使用了 CALLDATACOPY(复制新闻数据)操作码来举行操作,其中存在 3 个变量。

  • memoryOffset/destOffset(将数据复制到的内存位置) 

  • calldataOffset/offset(需要复制的 calldata 中的字节偏移量)

  • size/length(要复制的字节巨细)

  • 表达式:

    memory[destOffset:destOffset+length] = msg.data[offset:offset+length]

在这个例子中,memoryOffset(destOffset) 是变量 “a”(0x80)的内存位置。calldataOffset(offset) 是现实 calldata 的巨细,由于并不需要复制任何 calldata,以是初始化内存为零。最后,传入的变量为 0xa0(十进制的 160)。

这是可以看到我们的内存已经扩展到 288 字节(这包罗插槽 0),而且挪用栈再次保留了变量的内存位置和以及栈上的 JUMP 地址。

这与变量 “a” 的内存分配和空闲内存指针更新相同,只是这次是针对 “bytes32[2] memory b”。内存指针更新为 0x160(十进制为 352),即是先前的空闲内存指针 288 加上新变量的巨细 64(以 bytes 64 为单元)。空闲内存指针已在内存中更新为 0x160,那么现在在栈上就拥有变量 “b”(0x120)的内存位置。

与变量 “a” 的内存初始化相同。现在内存已增添到 352 字节,栈内仍然保留 2 个变量的内存位置。

最后,我们最先为数组 “b” 索引 0 赋值。代码指出 b[0] 的值应该为 1。该值被压入栈 0x01。接下来发生向左移位,然则移位的输入为 0,这意味着我们的值不会改变。接下来,要写入 0x00 的数组索引位置被压入客栈,并检查该值是否小于数组 0x02 的长度。若是不是,则执行跳转四处置此错误状态的字节码的差异部门。MUL(乘法)和 ADD(加法) 操作码用于确定需要将值写入内存中的哪个位置以使其对应于准确的数组索引。

0x20 (10 进制为 32) * 0x00 (10 进制为 0) = 0x00

需要记着,内存数组是 32 字节的元素,因此该值示意数组索引的起始位置。鉴于我们正在写入索引 0,没有偏移量,也就是从 0x00 最先写入。

0x00 + 0x120 = 0x120 (10 进制为 288)

ADD 用于将此偏移值添加到变量 “b” 的内存位置。偏移量为 0,直接将数据写入分配的内存位置。最后, MSTORE 将值 0x01 存储到这个内存位置 0x120。

下图显示了函数执行竣事时的系统状态。所有栈项都已弹出。请注重,现实上在 remix 中另有一些项目留在客栈上,一个 JUMP 位置和函数署名,然则它们与内存操作无关,因此在 EVM playground 中被省略了。

内存已更新为包罗 b[0] = 1 赋值,在我们内存的倒数第三行,0 值酿成了 1。可以验证该值位于准确的内存位置,b[0] 应占用位置 0x120 - 0x13f(bytes 289 - 320)。

我们现在对合约内存的事情原理有了一定水平的领会。在后续需要编写代码时,将为我们提供很好明白与辅助。当你跳过一些条约操作码,看到某些内存位置不停弹出 (0x40) ,现在就知道他们简直切寄义了。

在本系列下一篇文章中,我们将在 EVM 深入探讨系列第 3 部门深入探讨合约存储的事情原理,领会存储插槽包装(slot packing),揭开存储插槽的神秘面纱。

查看更多,

chơi game kiếm tiền ios(www.84vng.com):chơi game kiếm tiền ios(www.84vng.com) cổng Chơi tài xỉu uy tín nhất việt nam。chơi game kiếm tiền ios(www.84vng.com)game tài Xỉu đánh bạc online công bằng nhất,chơi game kiếm tiền ios(www.84vng.com)cổng game không thể dự đoán can thiệp,mở thưởng bằng blockchain ,đảm bảo kết quả công bằng.

上一篇:三公大吃计算公式(www.eth108.vip)

下一篇:欧博注册官网:SP SETIA INTERNATIONAL MARKETS BOUNCE BACK STRONG

网友评论