一.前言
![cb5b599ab00c22a3990fcd06dab8e9ad.gif](https://img-blog.csdnimg.cn/img_convert/cb5b599ab00c22a3990fcd06dab8e9ad.gif)
这周由于兴(lao)趣(shi)趋(yao)势(qiu),阅读了几篇以太坊智能合约安全综述,对其中的几个代码层漏洞进行整理归纳,并结合安全事件与相关案例进行分析,如有不正确的地方,还望各位大佬多多指正。
二.以太坊智能合约程序编程模型
![cb5b599ab00c22a3990fcd06dab8e9ad.gif](https://img-blog.csdnimg.cn/img_convert/cb5b599ab00c22a3990fcd06dab8e9ad.gif)
1.程序结构
以太坊上的智能合约主要是通过Solidity进行编写,Solidity是一种具有面向对象性质的弱类型语言。在以太坊上部署智能合约时,开发人员需要先将使用Solidity编写的智能合约代码编译为以太坊虚拟机可执行的二进制代码。而在编译过程中,智能合约代码的入口会插入一小段称为函数选择器(Function Selector)的代码,用以在调用函数时快速跳转到相应函数并加以执行。在编译完成后,可以通过客户端发送合约创建交易(Contract Creation Transaction),或通过其他合约执行特殊的EVM指令CREATE来部署该编译后的智能合约。
2.调用方式
在以太坊成功部署的智能合约,可以通过如下的三种方式调用合约中的公共函数(External/Public):
1) 通过客户端发送消息调用交易(Message Call Transaction),其中包含了数据参数以及目标函数签名的哈希值。
这种函数调用方式必须在交易得到确认后才能生效。并且,矿工会对该交易收取Gas来作为执行函数时所需要的代价,因此,该方式是一种写操作,即会对消息调用者的账户余额以及合约的状态进行更改
2) 通过另一个合约来间接的调用。
这种函数调用方式最终可以被追溯成另一笔消息调用交易。
3) 通过客户端调用view(或pure)函数。
这种函数调用方式并不会改变合约的状态,也不需要耗费Gas。
3.存储结构
以太坊虚拟机(Ethereum Virtual Machine,EVM)的存储方式可以分为四种:栈(Stack)、状态存储(Storage)、虚拟机内存(Memory)和只读内存。EVM是基于栈的虚拟机,栈中的每一个元素的长度是256位,基本的算数运算和逻辑运算都是使用栈完成。虚拟机内存实际上是一个连续的数组空间,用于存放如字符串等较复杂的数据结构。状态存储时key-value的存储结构,用于持久化数据。与栈和虚拟机内存不同,状态存储的值会被记录到以太坊的状态树当中。只读内存是EVM最特殊的一种存储结构,主要用于存放参数和返回值。
三.代码层漏洞
![cb5b599ab00c22a3990fcd06dab8e9ad.gif](https://img-blog.csdnimg.cn/img_convert/cb5b599ab00c22a3990fcd06dab8e9ad.gif)
1.可重入漏洞
该漏洞主要是因为智能合约调用一个未知的合约地址