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执行代码,没有异常,然后流经其余代码。让我们通过操作码来完成这个执行操作码。出现的第一个结构是我们以前见过的:
期货市场对美联储6月加息25个基点的预期升至64%:金色财经报道,美国劳工部周五公布的核心个人消费支出价格指数显示 4 月份上涨 0.4%,同比上涨 4.7%,均略高于预期。尽管通胀率较高,但随着个人收入增加,消费者支出保持良好。当月支出增长 0.8%,个人收入增长 0.4%。根据 CME Group 的数据,报告发布后,期货市场对美联储 6 月加息 25 个基点的预期升至64%。
交易员还在等待两个与通胀相关的关键数据点,5 月美国非农就业报告将于下周五公布,消费者价格指数将于 6 月 13 日公布。[2023/5/27 9:45:36]
图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是否太短,如果是这样,还原,然后稍微改进,以便我们在堆栈中有我们的函数,另外,我们差不多完成了。下一部分会很容易理解:
0x4C9f开头地址售出76枚MAYC,约206万美元:金色财经报道,据NFT Whale Alert监测,0x4C9f开头地址售出76枚MAYC系列NFT,兑换为981.49枚以太坊,约206万美元。[2023/4/14 14:03:20]
图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为智能合约的字节码提供模拟多个入口点的能力的方式,因此也就是界面。看一下解构图,这就是我们刚刚解构的:
沃顿商学院教授:美联储若延续“鹰派”政策 美经济势必陷入严重衰退:12月17日消息,宾夕法尼亚大学沃顿商学院金融学教授Jeremy Siegel周五表示,尽管近期美国通货膨胀显示出缓解的迹象,但他仍对美联储的鹰派态度感到不满,因为这将使美经济在2023年出现大幅下滑。Siegel认为,美联储继续暗示明年将只专注于通过提高、延长利率来抑制通胀,这意味着经济明年肯定会陷入“严重的衰退”。[2022/12/17 21:50:52]
图4.函数选择器和智能合约的运行时代码主入口点。总而言之,伙计们,不知不觉中你对solidity的底层代码熟悉程度超过了大部分人,坚持下去,你就能彻底把它打开。*本文由AlejandroSantander首发于medium,由猎豹区块链安全翻译并整理*猎豹区块链安全以金山霸的技术为依托,结合人工智能、nlp等技术,为区块链用户提供合约审计、情感分析等生态安全服务。Ratingtoken官网https://www.ratingtoken.net/?from=z
野村预计加密货币子公司两年内将实现盈利:金色财经报道,由于FTX加密货币交易平台的破产刺激了对数字资产领域更安全交易对手的需求,野村控股(NMR.US)计划在两年内推动其加密货币部门实现盈利。野村控股数字资产子公司Laser Digital首席执行官Jez Mohideen表示,Laser Digital将利用野村位于东京的投资银行的支持,争取机构投资者,并计划在3月前增加50名员工。他表示,现在更容易聘请到人才和以较低的估值收购资产,并补充道,该公司已经加强了风险管理。
据了解,野村于9月推出了其数字资产部门,这是作为一家全球金融公司迄今为止在该领域采取最大胆的举措之一,因为当时加密货币市场深陷崩溃,并且上个月FTX的破产加剧了这一颓势。[2022/12/8 21:30:33]
Binance创新区将于22:30上线Hooked Protocol(HOOK):12月1日消息,Binance公告宣布已经完成Hooked Protocol(HOOK)的Token分配计算,Binance创新区将于2022年12月1日22:30上线HOOK,并开通HOOK/BTC、HOOK/USDT、HOOK/BUSD、HOOK/BNB交易对。[2022/12/1 21:15:48]
标签:DATACALDATALLdata币暴涨Local TradersDefend Animals Foundationpolkawallet钱包
本篇文章的作者是Jan,文章阐述了Cell模型中支持的一种非常有趣的DApp设计模式:First-classAsset,它让加密资产变成区块链中的「一等公民」.
1900/1/1 0:00:00本文来自:DappReview,作者:DR小伙伴,星球日报经授权转发。导读:被互联网教育过的人,即使是傻子也明白一个道理:谁把握住用户谁就牛逼.
1900/1/1 0:00:00编者按:本文来自橙皮书,作者:orangefans,星球日报经授权发布。在网上观看一部电影时,我能不能随着播放进度条的进度来付费呢?比如每观看一秒钟就付一点点钱,而不是一次性买断电影单次的观看权.
1900/1/1 0:00:00文|Aesop,郝方舟编辑|郝方舟新一年的钟声刚刚敲响,属于2019的喧嚣、疯狂、奇迹、感动正在开启.
1900/1/1 0:00:00整整7个小时,华强北没有等到一个登门的顾客。那天是11月29日,矿业寒冬中,华强北最日常的景象。然而10个月前,位于深圳华强北的赛格广场还是全国最大的矿机销售市场.
1900/1/1 0:00:00本文系国内首篇通证经济学术论文,奠定了通证经济的理论基础与框架,具有重要的理论与现实意义。感谢中国航空工业集团公司原董事长,中共十八届中央委员会中央委员,中国航空学会理事长林左鸣教授对本文提供的.
1900/1/1 0:00:00