欧易下载

欧易交易所
欧易交易所APP官网下载

欧易交易所(Huobi Global)是最老牌的比特、莱特、以太交易所,欧易交易平台支持OTC法币交易,支持微信、支付宝和银行卡转账,安全方便快捷,欧易下载官方APP链接。

深入理解 EVM 存储机制及安全问题

EVM 是一个轻量级的虚拟机,其设计初衷就是提供一种可以忽略硬件、操作系统等兼容性的虚拟的执行环境供以太坊网络运行智能合约。

简单来说 EVM 是一个完全独立的沙盒,在 EVM 中运行的代码是无法访问网络、文件系统和其他进程的,以此来避免错误的代码能让智能合约毁灭或者影响外部环境。

在此基础上,知道创宇区块链安全实验室带大家一起深入理解 EVM 的存储机制和安全问题。

可以看到 EVM 存储数据分为两类:

存储在 code 和 storage 里的数据是 non-volatile (不容易丢失的)

存储在 stack,args,memory 里数据是volatile(容易丢失的)

Code

code 部署合约时储存 data 字段也就是合约内容的空间,即专门存储智能合约的二进制源码的空间

Storage

Storage 是一个可以读写修改的持久存储的空间,也是每个合约持久化存储数据的地方。Storage 是一个巨大的 map,一共 2^256 个插槽 (slot),每个插糟有 32byte,合约中的“状态变量”会根据其具体类型分别保存到这些插槽中。

Stack

stack 即所谓的“运行栈",用来保存 EVM 指令的输入和输出数据。可以免费使用,没有 gas 消耗,用来保存函数的局部变量,数量被限制在 16 个。stack 的最大深度为 1024 ,其中每个单元是 32 byte。

Args

args 也叫 calldata,是一段只读的可寻址的保存函数调用参数的空间,与栈不同的地方的是,如果要使用 calldata 里面的数据,必须手动指定偏移量和读取的字节数。

Memory

Memory 一个简单的字节数组,主要是在运行期间存储数据,将参数传递给内部函数。基于 32byte 进行寻址和扩展。

前面已经说过 Storage 是每个合约持久化存储数据的地方其储存数据的方式是通过插槽来实现的,现在就具体介绍它是怎么实现的:

天桥资本创始人:更多公司应在资产负债表上持有比特币:金色财经报道,对冲基金天桥资本(Skybridge Capital)创始人、前美国白宫通讯联络主任Anthony Scaramucci表示,由于美国货币供应量的爆炸性增长,更多的公司应该在其资产负债表上持有比特币。他认为比特币有潜力“再次开始使钱标准化,这将对在低报酬职务工作的人和中产阶级产生更好的影响”。因此,除非美元被数字化并且“不再受政界人士和决策者的影响”,否则有一天比特币很有可能成为世界货币。当被问及是否有一天将看到天桥资本拥有基于以太坊的产品时,Scaramucci说:“是的,这会发生。”当被问及他是否正在研究去中心化金融时,Scaramucci说:“是的,所以请继续关注。”此前消息,天桥资本已向美国证券交易委员会(SEC)申请了比特币交易所交易基金(ETF)。[2021/3/22 19:05:39]

1.对于大小在 32 字节以内的变量(常量),以其定义的顺序作为它的索引值来存储。即第一个变量的索引为 key(0),第二个变量的索引为 key(1)...

2.对于连续较小的值,可能被优化存储在同一个位置,比如:合约中前四个状态变量都是 uint64 类型的,则四个状态变量的值会被打包成一个 32 字节的值存储在 0 位置。

未优化:

pragma solidity ^0.4.11;contract C {   uint256 a = 12;   uint256 c = 12;   uint256 b = 12;   uint256 d = 12;   function m() view public returns(uint256,uint256,uint256,uint256){       return (a,b,c,d);   }}

优化后:

pragma solidity ^0.4.11;contract C {   uint64 a = 12;   uint64 c = 12;   uint64 b = 12;   uint64 d = 12;   function m() view public returns(uint64,uint64,uint64,uint64){       return (a,b,c,d);   }}

FTX首席执行官:FTX估值已达到35亿美元:根据首席执行官Sam Bankman-Fried的说法,去年推出的总部位于香港的加密货币交易所FTX目前的估值已达到35亿美元。(The Block)[2020/12/5 14:03:51]

对于大小在 32 字节以内的结构体同样也是顺序存储,例如结构体变量索引定义在位置 0,结构体内部有两个成员,则这两个成员的依序为 0 和 1。

pragma solidity ^0.4.11;contract C {struct Info {   uint256 a ;   uint256 b ;}   function m()  external returns(uint256,uint256){       Info storage info;       info.a = 12 ;       info.b = 24 ;       return(info.a,info.b);   }}

map 存储位置是通过 keccak256 (bytes32(key) + bytes32(position) ) 计算得到的,position 表示 key 对应 storage 类型变量存储的位置。

pragma solidity ^0.4.11;contract Test { mapping(uint256 => uint256) knownsec; function go() public {     knownsec[0x60] = 0x40; }}

同上,只要在 32 字节以内也是顺序存储,不过在编译时编译器会进行边界检查防止越界。

pragma solidity ^0.4.11;contract C {   uint256 a = [12,24,48] ;      function m() public view returns(uint256,uint256,uint256){       return (a,a,a);   }   }

由于可变长度数组长度不定,一般在编译可变长度数组时会提前预留存储空间,所以就会使用状态变量的位置存储可变长度数组的长度。

而具体的数据地址会通过计算 keccak256 (bytes32(position)) 算得数组首地址,再加数组长度偏移量获得具体的元素。

pragma solidity ^0.4.11;contract C {   uint256[] a = [12,24,48] ;      function m() public view returns(uint256,uint256,uint256){       return (a,a,a);   }   }

如果长度小于等于31字节 :

1.对于定长字节数组则是同定长数组一样;

2.对于可变字节数组和字符串,会在存储值位置补0一直到32字节,并用补0的最后一个字节存储字符串的编码长度。

pragma solidity ^0.4.4;contract A{   string public name0 = "knownsec";    bytes8 public name=0x6b6e6f776e736563;   bytes public g ;      function test() public {       g.push(0xAA);       g.push(0xBB);       g.push(0xCC);   }   function go() public view returns(bytes){       return g;   }}

当节数组和字符串长度大于31字节时

1.变量位置存储编码长度,并且编码长度公式更换为编码长度 = 字符数 * 2 + 1

2.真实存储值第一个位置通过公式 keccak256(bytes32(position)) 获取,剩余值在获取到的位置顺序存储,同样在最后存储位置补0到32字节。

string public name = "knownsecooooooooooooooooooooooooo";

前面已经讲到EVM的存储结构及存储机制,现在我们再来探讨其安全问题。

漏洞原理:

在官方手册中提到结构体,数组和映射的局部变量默认是放在 storage 中的,而 solidity 语言中函数中设置的局部变量的默认类型取决于它们本身的类型。

因此如果在函数内部设置以上 storage 类型变量却没有进行初始化,他们就相当于存储指针指向合约中的其他变量,当我们对其进行改变时改变的就是其指向的变量。漏洞合约,目的修改 owner 为自己地址:

pragma solidity ^0.4.0;contract testContract{   bool public unlocked = false;   address public owner = 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c;struct Person {   bytes32 name;   address mappedAddress;}   function test(bytes32 _name , address  _mappedAddress) public{       Person person;       person.name = _name;       person.mappedAddress = _mappedAddress;       require(unlocked);  }}

漏洞合约分析:

可以看到该合约在函数部分创建新的结构体时没有进行初始化,由此我们可以利用该函数进行对owner的修改。不过使用该函数我们还要通过require验证,不过这也不难因为状态变量unlocked也同样在我们可控的范围内。

具体操作:

调用test函数分别传入向_name 传入:0x0000000000000000000000000000000000000000000000000000000000000001(真值)

_mappedAddress 传入:0xfB89eCb0188cb83c220aADDa1468C1635208e821(个人地址)

传参前:

传参后:

可以看到已经成功更改了地址。

可以看到 EVM 的存储器就是一个 key=>value 的健值数据库,存储的数据可以通过校验和来确保一致。但是其也是和智能合约语言进行交互的,当其中一些规则发生冲突很可能就被别有用心的人用来作恶,所以规范的使用智能合约语言是避开漏洞的必要条件。

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

欧易交易所

火币下载9月最具平台影响力作者榜 20位作者荣誉登榜

2021年5月,金色财经面向优秀专栏作者,开放了平台推荐通道;通过推荐关注、首页推荐位、月度榜单等形式将专栏作者触达给更多的金色用户,给予优秀专栏作者更多的推荐曝光和频道展示机会,帮助专栏作者积累粉丝的同时平台也在进行数据沉淀,期望未来可以更好的服务专栏作者,为作者带来实在的收益。

MANA美SEC主席:稳定币就像是桌上的筹码 希望将加密货币纳入公共政策框架

周二,美国证券交易委员会(SEC)主席Gary Gensler接受《华盛顿邮报》专栏作家David Ignatius的采访,谈到了加密货币领域、区块链技术以及他对该领域进行监管的方法。 在采访开始时,Gensler对近期市场崩盘发表了评论,称加密货币是一种“高度投机性的资产类别”。 “稳定币现在几乎就像里的扑克筹码,”Gensler 说。

Ethereum虚实中的元宇宙 未到颠覆世界之时

在概念炒作之后,市场将审视相关技术革新、硬件设备和上游产业的进展速度,并开始对元宇宙蓝图具象化的漫长等待。 资本追逐新而又玄的概念时永不眠。2021年上半年,在NFT、量子计算、太空旅行等占据舆论风口时,元宇宙(Metaverse)也结束了潜伏,引燃属于它的第一批爆点。

DOT区块链、NFT进入电影IP衍生业 化解“高成本”难题指日可待?

“我们正在筹备一只专投区块链版权市场这类的基金,可能至少10亿规模以上。”9月21日,凯诺资本创始人、总裁韩田新在第五届国际电影IP授权与衍生产业开发论坛上介绍道。 韩田新表示,当前文化产业的侵权无处不在,所以必须在创作过程中把所发生的各项版权价值进行明确,实现对创作市场合法权益的保护。

[0:15ms0-3:765ms