解构智能合约:手把手教你拆解深入Solidity神秘世界

当前位置:首页 > 币圈百科 > 解构智能合约:手把手教你拆解深入Solidity神秘世界

解构智能合约:手把手教你拆解深入Solidity神秘世界

2022-12-08币圈百科188

第一部分前言

想象一下,1969年你正驾驶着野马马赫行驶在美国西部的一条高速公路上。阳光照耀在华丽的镀金轮圈上,整条路只有你和沙漠。一望无际的地平线见证了你对落日的追求.

突然,一声巨响。你的335马力

你要去看看是什么问题。当你打开前引擎盖,你发现你根本看不懂。你根本不知道这个该死的机器是怎么工作的,于是你拿起手机求助,结果发现附近没有信号.

解构智能合约:手把手教你拆解深入Solidity神秘世界

上面描述的情况与您正在进行的DApp开发相似吗?在开发Dapp的过程中,打个比方,一辆豪车就是你的智能合约,轮圈和改装的地方就是那些经过深思熟虑的小细节。一旦出现问题,您需要在智能合约EVM字节码中寻找答案。大多数情况下,你不知道发生了什么。

如果你是Dapp的开发者,遇到了以上尴尬的情况,那么以后就不用担心了!

因为,这一系列文章的目的是解构一个简单的Solidity契约,看看它的字节码,把它分解成可识别的结构,直到最底层。我们将打开跑车Solidity的引擎盖。在本系列的最后,您应该可以轻松查看或调试EVM字节码了。本系列的重点是揭开由Solidity编译器生成的EVM字节码的奥秘,它真的比看起来简单得多。

下面是我们解构时要用到的智能合约代码:

pragma solidity 0 . 4 . 24;合同基础肯{ uint 256 total supply _;映射(地址=uint256)余额;构造函数(uint 256 _ initial supply)public { total supply _=_ initial supply;balances[msg . sender]=_ initial supply;}函数total supply()public view returns(uint 256){ return total supply _;}函数传递(address _to,uint256 _value)公共返回(bool) {require(_to!=地址(0));require(_ value=balances[msg . sender]);balances[消息发送者]=balances[消息发送者]-_ value;余额[_至]=余额[_至]_值;返回true} function balance of(address _ owner)public view returns(uint 256){ return balances[_ owner];}}

注意:这个契约容易受到溢出攻击。我们尽量简洁,只是为了说明问题。

编合同

编合同,我们会用Remix(地址:https://remix.ethereum.org)。

打开Remix编译器,点击文件浏览器区域上方左上角的按钮,新建一个智能合约。将文件名设置为BasicToken.sol.创建之后,将上面的代码粘贴到编辑器中。

在右侧,转到“设置”选项,并确保选中“启用个人模式”。另外注意,选择的Solidity编译器版本是

"?版本:0 . 4 . 24 commit . e67f 0147 . EMS cripten . clang?”。

这两个细节非常重要,否则你将无法检查文章中讨论的字节码。

接下来可以进入编译选项,点击细节按钮。您将看到一个弹出窗口,包含Solidity编译器生成的所有内容,其中一个是名为BYTECODE的JSON对象,它具有“object”属性。这是已编译的合同代码。它的代码是这样的:

608060405234801561001057600080 FD 5b 506040516020806102178339810160409081529051600081815338152600160205291909120556101d 1800。首先,确保您使用的是Javascript VM。这基本上是一个嵌入式Javascript EVM网络,也是以太坊的理想培训场所。确保在ComboBox中选择了BasicToken,并在Deploy输入框中输入数字10000。接下来,单击“部署”按钮进行部署。这是我们创建的已部署的Basictoken智能合约实例。最初提供的10,000个令牌归ComboBox帐户顶部当前选择的帐户所有,蓑衣网小编2022该帐户将保留我们设置的所有令牌供应。

在“Run”选项卡的“Deployed Contracts”中,您可以看到已部署的智能合同,它包含三个与合同交互的字段:transfer、balanceOf和totalSupply。在这里,我们可以与新部署的智能合约实例进行交互。

但在此之前,我们先来看看契约的“部署”到底是什么意思:

在页面底部的控制台区域,可以看到一个日志“创建basic token pending……”,后面是一个事务条目,包含各种字段:from、to、value、data、logs和hash。单击这个条目展开事务信息,您应该会看到日期、输入和我们上面提到的字节码。因此,创建一个智能契约实例,它将包含自己的地址和代码。

我们将在下一篇文章中详细研究这个交易过程。

反汇编字节码

在控制台的中央,事务框的右侧,有一个“调试”按钮。点击这个按钮,你将在Remix的右边区域激活调试器选项。我们可以一起看看说明部分。如果我们向下滚动,应该会出现以下内容:

000 push 1 80

002 push 1 40

004 store

005 call value

006 dup1

007 is zero

012 push 1 00

014 DUP1

015 REVERT

016 jump dest

017 POP

018 push 1 40

020 MLOAD

021 push 1 20

023 DUP1

024 push 2 0217

027 DUP4

028 code copy

这其实就是契约的反汇编字节码。 如果您逐字节扫描原始字节码(一次两个字符),EVM将识别蓑衣网小编2022与特定操作相关的特定操作码。例如:

060=push

001=add

002=mul

000=stop

Opcode

在解构智能合约代码之前,您将需要一个基本的工具集来了解单个Opcode的操作码,如PUSH、ADD、SWAP、DUP等。最后,每个操作只能从堆栈、内存或存储中推送或消耗一个属于EVM契约的项目吗?

要查看EVM可以处理的所有可用操作码,您可以查看Pyethereum,它显示操作码列表。要了解每个操作码的工作原理,Solidity的官方汇编文档也是很好的参考。尽管它与原始操作码不是一一对应的,但它非常接近(它实际上是Yul,一种介于Solidity和EVM字节码之间的中间语言)。如果能看懂技术文档,可以看以太坊黄皮书。其实说到底都是上面的内容。

虽然给大家推荐了这么多文档,但是现在从头到尾看完这些资源也没什么意义。你只要记住有这样一种材料,需要的时候我们会用到它们。

指令

上面反汇编代码中的每一行都是EVM执行的一条操作指令,每条指令都包含一个操作码。例如,让我们取其中一条指令,指令88,并将数字4压入堆栈。这个特殊的反汇编程序解释如下:

88 push 1004

| |

| hex value for push。

|操作码

指令编号

尽管有反汇编,我们还是需要一个可以解构所有问题的方法。

策略

任何一开始看似不可能的任务,其实都可以通过不断的拆解,分解成可解的任务,我们遇到的问题也不例外。面对这个问题,我采取的策略是“分而治之”。

我们可以尝试找到反汇编代码的分叉点,逐步分解,直到分解成非常小的块,我们会在Remix的调试器中逐步完成。

下图可以看到我们第一蓑衣网小编2022次拆分反汇编代码(下一篇文章我会全面分析)。

如果你不懂图表,不用担心。你不必一开始就什么都知道。我们的系列文章将逐步介绍。现在跟着我们的节奏,深入你的豪车内部结构。

*本文由亚历杭德罗桑坦德(Alejandro Santander)首次发表于medium,由猎豹区块链安全翻译整理*

解构智能合约:手把手教你拆解深入Solidity神秘世界 | 分享给朋友: