CNN+LSTM:智能合约漏洞检测
今天记录一下最近将深度学习方法用于智能合约漏洞检测的第一次实验,顺便给研究这方向的同行们提供一点借鉴意义。这个方法跟NLP有点相似,但又不太一样,因为操作码序列虽然具备一定语义信息,但偏向底层机器语言,所以刚开始我并不确定最终能不能达到很好的训练效果。这个实验的完整过程如下:首先通过插桩在本地链上同步当前以太坊的部分区块交易数据,借此拿到每笔交易的操作码序列、合约地址等等原始数据;接着通过word2vec或one-hot编码将每个操作码转成词向量;最后搭建CNN+LSTM的深度学习模型完成多分类训练。

0. 导包
1. 从数据库获取数据
我使用的是MongoDB数据库,因此可以使用可视化软件MongoDB Compass或Navicat for MongoDB直接查询获取,同样也可以通过python连接数据库获取,本质上都是编写MongoDB的查询语句,导出格式一般是csv或txt,csv因为携带了标签比较容易处理。
2. 训练词向量
对于文本的向量化其实有很多方式,包括独热(one-hot),词袋模型(bag of words),逆文本特征频率(tf-idf)和word2vec等,在本实验中我使用现成的word2vec预训练模型直接训练得到词向量,同样也可以用自己搭建的模型训练。word2vec是使用深度学习的方式将词映射为一个多维向量,维度可以自行选择。
3. 数据预处理
读取csv或txt格式的原始数据并处理成嵌套列表的形式。
4. 根据词向量创建词语字典
加载上面生成的word2vec模型创建出对应的词向量字典(操作码向量字典)。
5. 将序列文本转成字典索引数字
将输入操作码序列中出现在词向量字典中的操作码转换为索引数字,未出现的转换为0即可。
6. 统一序列长度
定义必要参数,加载词向量数据并填充词向量矩阵。
将原始数据集分为训练集和测试集,把序列操作码转成对应索引并统一长度。
7. 搭建模型并训练
本来我只用了LSTM,但因为序列长度太大,所以只能加上CNN层来对矩阵进行降维,这样训练速度会更快,结果发现效果也还行。
8. 输出可视化训练图表
可以通过show_train_history函数打印的训练集曲线来判断模型是否过拟合。
借鉴项目:https://github.com/sph116/lstm_emotion(大家自行搜索)
部分结果截图(仅供参考):

