DATA:解构智能合约(3):功能选择器

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执行代码,没有异常,然后流经其余代码。让我们通过操作码来完成这个执行操作码。出现的第一个结构是我们以前见过的:

Patrick McHenry:稳定币有望成为21世纪支付系统的支柱:8月7日消息,在PayPal宣布推出稳定币PYUSD之后,美国众议院金融服务委员会主席Patrick McHenry发表声明称,“这一公告是一个明确的信号,即稳定币(如果在明确的监管框架下发行)有望成为我们21世纪支付系统的支柱。明确的法规和强大的消费者保护对于稳定币充分发挥其潜力至关重要。这就是为什么国会通过立法提供全面的数字资产监管比以往任何时候都更重要,特别是针对稳定币。两党的《支付稳定币透明度法案》承认了各州在监管数字资产公司方面发挥的重要作用,并以纽约州等成功的州制度为基础进行了完善。我们正处于一个十字路口,要让美国保持数字资产创新的领先地位,国会两党正在立法方面取得重大进展,确保美国引领未来的金融体系。我们必须完成这项工作。”

此前,众议院金融服务委员会已通过《支付稳定币透明度法案》(Clarity for Payment Stablecoins Act of 2023)。该法案确定批准和监管稳定币发行者的监管途径,同时通过为支付稳定币创建统一的联邦最低标准,确保为消费者提供强有力的保护。[2023/8/7 21:30:16]

图1.空闲内存指针这是Solidity生成的EVM代码将始终在调用之前执行的任何操作:将一个点保存在内存中以便稍后使用。让我们看看接下来会发生什么:

CFTC前主席:SEC起诉Terraform Labs和Do Kwon的做法“绝对正确”:金色财经报道,美国商品期货交易委员会(CFTC)前主席Timothy Massad表示,美国证券交易委员会(SEC)追查稳定币发行人Terraform Labs和创始人Do Kwon的做法是绝对正确的。Massad称,“当你邀请人们投资一种承诺回报率为19%到20%的代币时,这就是一种证券。”

此外,Massad还表示,美国银行监管机构现在有能力创建一个框架,为稳定币发行人颁发许可证。[2023/2/18 12:14:26]

图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是否太短,如果是这样,还原,然后稍微改进,以便我们在堆栈中有我们的函数,另外,我们差不多完成了。下一部分会很容易理解:

外媒:SBF在巴哈马监狱中获得“优待”:12月22日消息,据外媒报道,前FTX首席执行官Sam Bankman-Fried(SBF)在巴哈马福克斯山监狱中一直被关押在医务室,与其他囚犯不同,他可以获得自来水,甚至还有厕所,以及其他福利。据不愿透露姓名的监狱官员说,SBF整天都在看电视新闻和阅读有关自己的文章。

在福克斯山监狱,SBF与其他四名男子共用一间病房。他们都有帆布床,这在监狱里是一种奢侈,囚犯们抱怨说他们被迫睡在光秃秃的地面上,或者睡在老鼠出没的牢房里的临时纸板床上。按照标准程序,那些被限制在医疗单位的人不允许出去锻炼,SBF大部分时间都在帆布床上度过。尽管他最初表示他会反对引渡,但SBF上周晚些时候开始表示他准备返回美国。据一位直接了解此事的人士透露,SBF态度的转变部分与他能够在美国获得保释的预期有关。

此前今日早些时候消息,SBF已抵达巴哈马机场接受美国引渡。(彭博社)[2022/12/22 22:00:42]

图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为智能合约的字节码提供模拟多个入口点的能力的方式,因此也就是界面。看一下解构图,这就是我们刚刚解构的:

a16z合伙人:加密市场低迷给风投公司更多投资机会,希望创造一个更好的互联网:8月23日消息,a16z合伙人Chris Dixon在接受《金融时报》采访时表示,目前的加密市场低迷给风险投资公司更多的投资机会。目前互联网上的权力由一小部分公司掌握。我们可以做的是创造一个更好的互联网,创造新的系统,让网络效应累积到社区而不是公司。(CoinDesk)[2022/8/23 12:43:10]

图4.函数选择器和智能合约的运行时代码主入口点。总而言之,伙计们,不知不觉中你对solidity的底层代码熟悉程度超过了大部分人,坚持下去,你就能彻底把它打开。*本文由AlejandroSantander首发于medium,由猎豹区块链安全翻译并整理*猎豹区块链安全以金山霸的技术为依托,结合人工智能、nlp等技术,为区块链用户提供合约审计、情感分析等生态安全服务。Ratingtoken官网https://www.ratingtoken.net/?from=z

分析师:资金短缺依然是限制BTC和ETH价格上涨的主要原因:8月4日消息,链上分析师Phyrex发推表示,从Glassnode的数据统计来看,目前尚未有明显的数据表明有大量的资金从外部转移进币圈,所以按照目前的局面来看,资金的短缺依然是限制BTC和ETH价格上涨的主要原因。[2022/8/4 12:01:53]

郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。

金星链

[0:62ms0-0:839ms