HI,欢迎我一起继续解构智能合约。本文是系列文章的第三部分,如果您还没有阅读之前的文章,请先看一下:前言:基础代码与操作方式;创造与运行时间代码解析;我们正在解构一个简单的Solidity智能合约的EVM字节码。在上一篇文章中,我们确定了将智能合约的字节码分为创建和运行两部分,并且知道了为什么这么做,深入了解了创建部分后,现在是时候开始我们对运行时部分的探索了。如果你看一下解构图,我们可以首先看一下名为BasicToken.evm的第二个大拆分块。这可能看起来有点可怕,因为运行的代码长度至少是创建代码大小的四倍!但不要担心,我们在之前的文章中为了解EVM代码而开发的技能,加上我们使用绝对可靠的“分而治之”的策略,将使这一挑战更加系统化,甚至可能更容易。这只是开始,我们将继续识别独立结构,继续拆分直到分解为一个个可解决的问题为止。首先,让我们回到Remix在线编辑器,并使用运行时字节码启动调试会话。我们怎么做?上次,我们部署了智能合约并调试了部署事务。这一次,我们将使用其中一个函数与已部署的智能合约接口进行交互,并调试该事务。首先,一起回想一下我们的智能合约:我们启用了优化的编译器的JavascriptVM,v0.4.24版本,并将10000作为初始供应。部署智能合约后,你应该看到它在Remix上的“run”面板“DeployedContracts”的部分中列出。单击它可以展开看到智能合约的界面。这个界面是什么?它是智能合约中所有公共或外部方法的列表-即任何以太坊帐户或智能合约都可以与之交互。私人和内部方法不会在这里显示,如何与智能合约运行时代码的特定部分进行交互,将是本文解构的重点。我们可以尝试一下,单击Remix的“run”面板中的totalSupply按钮。您应该立即在按钮下方看到响应,这是我们所期望的,因为我们将智能合约作为初始token供应部署。现在,在Console面板中,单击Debug按钮以使用此特定事务启动调试会话。请注意,Console面板中将有多个Debug按钮;确保你使用的是最新版本。在这种情况下,我们没有调试到该0x0地址的事务,正如我们在上一篇文章中看到的那样,创建了一个智能合约。相反,我们正在调试对智能合约本身的事务-即它的运行时代码。如果弹出“指令”面板,则应该能够验证Remix列出的指令与解构图中BasicToken.evm部分中的指令相同。如果它们不匹配,则出现问题。尝试重新开始并确保您使用上述正确的设置。您可能会注意到的第一件事是调试器将您置于指令246并且事务滑块位于字节码的大约60%处。为什么?因为Remix是一个非常慷慨的程序,它直接带你到EVM即将执行totalSupply函数体的部分。然而,在此之前发生了很多事情,这些都是我们在这里要注意的。实际上,我们甚至不会在本文中研究函数体的执行情况。我们唯一关注的是Solidity生成的EVM代码如何路由传入的事务,这是我们作为合约的“功能选择器”将要理解的工作。因此,抓住滑块并将其一直拖到左边,这样我们就从指令零开始。正如我们之前看到的,EVM总是从指令0执行代码,没有异常,然后流经其余代码。让我们通过操作码来完成这个执行操作码。出现的第一个结构是我们以前见过的:
美联储5月加息25个基点概率为83.9%:金色财经报道,据CME美联储观察:美联储 5 月维持利率不变的概率为 16.1%,加息 25 个基点至 5.00%-5.25% 区间的概率为 83.9%。[2023/4/30 14:35:58]
图1.空闲内存指针这是Solidity生成的EVM代码将始终在调用之前执行的任何操作:将一个点保存在内存中以便稍后使用。让我们看看接下来会发生什么:
图2.Calldata长度检查。如果在Debug选项卡中打开Remix的Stack面板并跳过指令5到7,您将看到堆栈现在包含两次数字。如果您在阅读这些超长数字时遇到问题,请注意您调整Remix调试面板的宽度,以便数字很好地适合单行。第一个来自常规推送,但第二个是执行操作码的结果,正如黄皮书所述,没有参数并返回“当前环境中的输入数据”的大小,或者我们经常称为calldata:4CALLDATASIZE什么是calldata?正如Solidity的文档ABI规范中所解释的,calldata是一个十六进制数字的编码块,其中包含有关我们要调用的智能合约函数的信息,以及它的参数或数据。简单地说,它由一个“函数id”组成,它是通过散列函数的签名然后是压缩参数数据生成的。如果需要,您可以详细研究文档链接,但不要担心这个包装如何工作到最精细的细节。它在文档中有解释,但有点难以一次掌握。用实际例子来理解它会容易得多。让我们看看这个calldata是什么。在Remix的调试器中打开“调用数据”面板,查看:0x18160ddd。这是通过将keccak256函数签名上的算法应用为字符串来精确生成的四个字节"totalSupply()"?并执行所述截断。由于此特定函数不带参数,因此它只是:一个四字节的函数id。当CALLDATASIZE被调用时,它只是将第二个推4入堆栈。然后,指令8LT用于验证calldata大小是否小于4。如果是,则以下两条指令执行JUMPI指令86。这不到四个字节,因此在这种情况下不会有跳转,执行流将继续执行指令13.但在我们这样做之前,让我们假设我们用空的calldata调用我们的智能合约-也就是说,0x0而不是0x18160ddd。你不能用Remixbtw做到这一点,但你可以手动构建交易。在这种情况下,我们最终会进入指令86,它基本上将几个零推送到堆栈并将它们提供给REVERT操作码。为什么?好吧,因为这个智能合约没有后备功能。如果字节码没有识别传入数据,它会将流转移到回退函数,如果该结构没有“捕获”调用,则此恢复结构将终止执行,绝对没有回滚。如果没有什么可以回归,那么就没有任何事可做,而且呼叫完全恢复了。现在,让我们做一些更有趣的事情。返回Remix的Run选项卡,复制Account地址,并将其用作参数来调用balanceOf而不是totalSupply调试该事务。这是一个全新的调试会话;让我们暂时忘记吧totalSupply。导航到指令8,CALLDATASIZE现在将36推入堆栈。如果你看看calldata,那就是现在0x70a08231000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c。这个新的calldata实际上非常容易分解:前四个字节70a08231是签名的散列,后面"balanceOf(address)"的32个字节包含我们作为参数传递的地址。为什么32个字节,如果以太坊地址只有20个字节长,好奇的读者可能会问?ABI总是使用32字节“字”或“槽”来保存函数调用中使用的参数。继续在我们的balanceOf调用环境中,让我们在指令13处离开我们离开的地方,此时堆栈中没有任何内容。指令13然后推0xffffffff送到堆栈,并且下一条指令将29字节长的0x000000001000…000数字推送到堆栈。我们马上就会明白为什么。现在,只需要注意一个包含四个字节,另一个包含四个字节的0's'。接下来CALLDATALOAD取一个参数并从该位置的calldata读取一个32字节的块,在这种情况下,在Yul中将是:calldataload基本上将我的整个calldata推到堆栈。现在来了有趣的部分。DIV从堆栈中消耗两个参数,获取calldata并将其除以奇怪的0x000000001000…000数字,有效地过滤除了calldata中的函数签名之外的所有内容,并将其留在堆栈中:0x000…000070a08231。下一条指令使用AND,它也消耗堆栈中的两个元素:我们的函数id和带有四个字节的数字f。这是为了确保签名哈希正好是八个字节长,如果存在任何其他内容,则屏蔽其他任何内容。我认为,Solidity使用的安全措施。简而言之,我们只是检查calldata是否太短,如果是这样,还原,然后稍微改进,以便我们在堆栈中有我们的函数,另外,我们差不多完成了。下一部分会很容易理解:
Cosmos Hub第四个公开激励测试网Interchain NFTs开放注册:金色财经报道,Cosmos Hub的第四个公开激励测试网Interchain NFTs开放注册,奖金池为2万枚ATOM(约合27万美元)。本次测试旨在验证ICS-721的应用,共分为两个阶段,第一阶段已开放测试网,第二阶段将包含一场黑客马拉松,验证者和开发者拟在多个IBC兼容链测试Interchain NFTs,包括IRISnet、Stargaze、Juno、OmniFlix和Uptick。(cryptoslate)[2023/2/16 12:09:22]
图3.函数选择器在指令53处,代码将18160ddd推送到堆栈,然后使用aDUP2来复制70a08231当前存在于堆栈中第二位置的传入calldata值。为什么要复制?因为EQ指令59处的操作码将消耗堆栈中的两个值,并且我们希望保持70a08231值,因为我们经历了从calldata中提取它的麻烦。代码现在将尝试将calldata中的函数id与已知函数id之一进行匹配。由于70a08231进入,它将不匹配18160ddd,跳过JUMPIat指令63.但它将在下一次检查中匹配并在指令74跳转到JUMPI。让我们花点时间观察一下这些平等检查对智能合约的每个公共或外部功能。这是函数选择器的核心:充当某种switch语句,只是简单地将执行路由到代码的正确部分。这是我们的“中心”。因此,由于最后一个案例是匹配,执行流程将我们带到JUMPDESTat位置130,正如我们将在本系列的下一部分中看到的那样,该balanceOf函数的ABI“包装器”。正如我们将看到的,这个包装器将负责解包事务的数据以供函数体消耗。继续尝试transfer这次调试功能。功能选择器真的没有神秘感。这是一个简单而有效的结构,位于每个合约的门口并将执行重定向到代码中的适当位置。这就是Solidity为智能合约的字节码提供模拟多个入口点的能力的方式,因此也就是界面。看一下解构图,这就是我们刚刚解构的:
希尔顿酒店集团继承人将在The Sandbox上推出Parisland:金色财经报道,希尔顿酒店集团继承人Paris Hilton将于2月13日在The Sandbox上推出Parisland,Parisland被定义为元宇宙中的虚拟真人秀,其中的活动包括购买服装、挑选结婚戒指等。Sandbox首席运营官兼联合创始人Sebastien Borget表示,Parisland旨在培养玩家之间真正的关系和联系。(Decrypt)[2023/2/10 11:58:25]
图4.函数选择器和智能合约的运行时代码主入口点。总而言之,伙计们,不知不觉中你对solidity的底层代码熟悉程度超过了大部分人,坚持下去,你就能彻底把它打开。*本文由AlejandroSantander首发于medium,由猎豹区块链安全翻译并整理*猎豹区块链安全以金山霸的技术为依托,结合人工智能、nlp等技术,为区块链用户提供合约审计、情感分析等生态安全服务。Ratingtoken官网https://www.ratingtoken.net/?from=z
全链抗MEV DEX聚合器Cashmere Labs将在Aptos部署合约:10月23日消息,基于LayerZero的全链抗MEV DEX聚合器Cashmere Labs发推称,Cashmere合约将部署至Aptos。目前Cashmere Labs产品暂未推出。
Aptos Bridge用户可以将USDC、USDT和ETH从Etheruem、Arbitrum、Arbitrum、Optimism、Avalanche、Polygon、BNB Chain跨链至Aptos。[2022/10/23 16:36:05]
美股三大指数集体低开,Coinbase跌超24%:5月11日消息,美股三大指数集体低开,道指跌0.04%,标普500指数跌0.21%,纳指跌0.78%,区块链概念股大跌,Coinbase跌超24%,股价最低触及52.8美元 创历史新低,公司Q1营收同比下降近30%至11.66亿美元,不及预期。MicroStrategy跌近12%,嘉楠科技、Marathon Digital跌逾6%,Riot Blockchain跌近6%。(财联社)[2022/5/11 3:08:26]
前言:提到中国企业出海上市,离不开VIE架构,红筹模式,10号文、新浪模式这些熟悉又陌生的名词,而境外上市也造就了新浪、搜狐、网易、中华网、华晨汽车、UT斯达康这些上世纪的资本传奇.
1900/1/1 0:00:00图片来源:nulltx.com目前,狗狗币正进行的Doge4Amazon请愿书活动中,已有22839人签署了请愿书,该请愿书的签名目标是25000.
1900/1/1 0:00:00北京时间10月16日,自02:16块高度556767起,以比特大陆和蚂蚁矿池为首的BCHABC阵营和以CoinGeek及nChain为首的BCHSV阵营(代表人物CraigSteveWright,即澳本聪)正式宣告分家.
1900/1/1 0:00:00OK区块链资本联合中科院大学数字经济与区块链研究中心撰写的《区块链金融产业全景及趋势报告》于近日正式对外发布。本报告基于对传统金融业务发展现状、趋势及痛点的研究,深入剖析了能以区块链技术实现改造的业务领域以及具体模式.
1900/1/1 0:00:00文|秦晓峰、吴盐、黄雪姣出品|Odaily星球日报编者按:新一年的钟声刚刚敲响,属于2019的喧嚣、疯狂、奇迹、感动正在开启.
1900/1/1 0:00:00如何在成人广告中找到人贩子?比特币也许是一个不错的办法。最近,来自伯克利大学的RebeccaPortnoff发明了一种算法,这种算法可以在比特币的帮助下追踪性贩卖者.
1900/1/1 0:00:00