前言
EVM是一个轻量级的虚拟机,其设计初衷就是提供一种可以忽略硬件、操作系统等兼容性的虚拟的执行环境供以太坊网络运行智能合约。
简单来说EVM是一个完全独立的沙盒,在EVM中运行的代码是无法访问网络、文件系统和其他进程的,以此来避免错误的代码能让智能合约毁灭或者影响外部环境。
在此基础上,知道创宇区块链安全实验室带大家一起深入理解EVM的存储机制和安全问题。
EVM存储结构
可以看到EVM存储数据分为两类:
存储在code和storage里的数据是non-volatile(不容易丢失的)
Yuga Labs:因接收地址有其他比特币资产而保留的剩余铭文现已发送:金色财经报道,Yuga Labs发推更新比特币NFT系列 TwelveFold 的发送情况,表示由于接收地址拥有其他比特币资产而保留的剩余铭文现已发送。
此前报道,Yuga Labs发推称有21个地址不是空的,但仍坚持向这些地址发送作品;如果用户将铭文与其他比特币资产一起保留,可能会在正常使用比特币的过程中意外转移铭文聪。[2023/3/21 13:17:06]
存储在stack,args,memory里数据是volatile(容易丢失的)
各个存储位置的含义
Web3 PoS节点部署平台MarsProtocol完成1000万美元融资:金色财经报道,纽交所上市公司 Mega Matrix(NYSE:MTMT)旗下 PoS 节点部署平台 MarsProtocol 宣布完成 1000 万美元融资,参投方来自多名业内知名人士。融资将用于平台的持续开发和优化,该平台已经于 2023 年 1 月上线,第一阶段推出的产品支持以太坊去中心化非托管节点部署服务。
MarsProtocol 是由纽交所上市公司 Mega Matrix 开发,该平台为机构客户及巨鲸个人用户提供一站式的 PoS 节点部署及运行服务,采用非托管机制,集成 MEV 收益,支持单个及批量快速质押托管,提供可视化资产看板等服务。[2023/1/21 11:24:56]
Code
数字资产公司BlockFills与Isla Verde Capital合作为加密矿工提供碳排放抵消额度:9月14日消息,全球数字资产金融服务、技术和交易公司BlockFills与专门从事可再生能源的Isla Verde Capital达成合作,将为加密矿工提供碳排放抵消额度,向其出售碳排放抵消和可再生能源信用额度(REC)以及其他碳核算工具。[2022/9/14 13:28:34]
code部署合约时储存data字段也就是合约内容的空间,即专门存储智能合约的二进制源码的空间
Storage
Storage是一个可以读写修改的持久存储的空间,也是每个合约持久化存储数据的地方。Storage是一个巨大的map,一共2^256个插槽(slot),每个插糟有32byte,合约中的“状态变量”会根据其具体类型分别保存到这些插槽中。
Halborn 发现 Flow 编程语言 Cadence 中的高危漏洞,目前已修复:7月11日消息,区块链安全机构 Halborn 在 Twitter 上表示,在审计 Cadence 语言期间发现 Flow 编程语言 Cadence 中的高危漏洞,该漏洞使得 Cadence 可以允许访问被销毁的资源。该漏洞产生的原因是由于当资源被销毁时,解释器不会使对资源的引用无效,从而使得可以调用被销毁资源上的函数。目前 Cadence 解释器已更新,以便在创建对可选项的引用时检查内部值的类型。[2022/7/11 2:06:06]
Stack
stack即所谓的“运行栈",用来保存EVM指令的输入和输出数据。可以免费使用,没有gas消耗,用来保存函数的局部变量,数量被限制在16个。stack的最大深度为1024,其中每个单元是32byte。
Args
args也叫calldata,是一段只读的可寻址的保存函数调用参数的空间,与栈不同的地方的是,如果要使用calldata里面的数据,必须手动指定偏移量和读取的字节数。
Memory
Memory一个简单的字节数组,主要是在运行期间存储数据,将参数传递给内部函数。基于32byte进行寻址和扩展。
EVM数据存储概述
前面已经说过Storage是每个合约持久化存储数据的地方其储存数据的方式是通过插槽来实现的,现在就具体介绍它是怎么实现的:
状态变量
1.对于大小在32字节以内的变量(常量),以其定义的顺序作为它的索引值来存储。即第一个变量的索引为key(0),第二个变量的索引为key(1)...
2.对于连续较小的值,可能被优化存储在同一个位置,比如:合约中前四个状态变量都是uint64类型的,则四个状态变量的值会被打包成一个32字节的值存储在0位置。
未优化:
pragmasolidity^0
??functionm()?externalreturns(uint256,uint256){????Infostorageinfo;????info
??functiontest(bytes32_name,address?_mappedAddress)public{????Personperson;????person.name=_name;????person.mappedAddress=_mappedAddress;????require(unlocked);?}}
漏洞合约分析:
可以看到该合约在函数部分创建新的结构体时没有进行初始化,由此我们可以利用该函数进行对owner的修改。不过使用该函数我们还要通过require验证,不过这也不难因为状态变量unlocked也同样在我们可控的范围内。
具体操作:
调用test函数分别传入向_name传入:0x0000000000000000000000000000000000000000000000000000000000000001(真值)
_mappedAddress传入:0xfB89eCb0188cb83c220aADDa1468C1635208e821(个人地址)
传参前:
传参后:
可以看到已经成功更改了地址。
总结
可以看到EVM的存储器就是一个key=>value的健值数据库,存储的数据可以通过校验和来确保一致。但是其也是和智能合约语言进行交互的,当其中一些规则发生冲突很可能就被别有用心的人用来作恶,所以规范的使用智能合约语言是避开漏洞的必要条件。
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。