《Checking Smart Contracts with Structural Code Embedding》笔记

摘要:
在本文中提出了一种自动化的方法来学习用Solidity语言编写的智能合约的特性,这对于检测代码克隆、检测漏洞、合约有效性等有帮助。我们的新方法是基于词嵌入(word embedding)和向量空间比较(vector space comparison)。我们将智能合约解析成带有代码结构化信息的词流(word stream),将代码元素(如声明、函数)转换成可以用于编码代码语法和语义的数字向量,然后比较编码了代码的向量和已知bug代码之间的相似度,来识别潜在的问题。我们实现了这个方法的原型,称为SmartEmbed,然后使用从Ethereum blockchain收集的超过22000份智能合约进行评估。结果表明我们的工具可以有效识别许多重复的实例,克隆率在90%左右。Type3,type4语义克隆也能被精确检测到。基于我们的漏洞库,我们的工具可以有效识别超过1000个克隆相关的漏洞。我们的工具还可以用于有效评估给出的代码,将其与一系列已知的bug比较,这可以帮助提高使用者的信心和智能合约的可信度。

Approach:
《Checking Smart Contracts with Structural Code Embedding》笔记_第1张图片
整体框架如上所示
基于相似度校验和code embeding,SmartEmbed期望实现三个功能:克隆检测,bug检测,合约有效性验证。
具体来看,搜集的智能合约的源码,由我们自定构建的解析器加载和解析,生成抽象语法树(AST)。然后通过序列化AST提取token流(extract a stream of tokens by setrializing the ASTs).接着Normalize重新组装token stream来消除智能合约间的差异,将结果喂给我们的core representation。通过模型的构建和训练,每个代码段都会被嵌入固定长度的向量。所有的源代码都会被编码成code embedding matrix。同时,所有的有漏洞的源代码都会被嵌入到bug embedding matrix
下一阶段,就是通过向量空间比较,使用相似度校验的方法进行克隆检测。相似度比较只会在克隆的代码片段对上进行,并根据给出的分数与阈值比较,来判断是是否为代码克隆。

Data Collection
使用爬虫爬EtherScan

Parsing
AST是程序的结构化表示,对于每个智能合约都使用自定义的解析器去解析它,然后基于AST构建我们的code embedding,因为树结构的特性可以提供程序的结构化信息。
具体来说,ANTLR和自定义的Solidity语法被用于生成XML解析树,来作为代码表示的中间形式。然后基于这个AST构建code embedding。简单实例如下
《Checking Smart Contracts with Structural Code Embedding》笔记_第2张图片

我们根据树节点的类型,在不同层面(合约层面、函数层面、声明层面)对解析树进行序列化操作。这是为了捕获结构化信息(如我们关注点附件的分支、循环条件).进一步地,重要的token和识别符被处理并放入从树序列化得到的code element sequence中,这样明确的数据流信息(通过定义或者使用相同的名字)就被添加到序列中了。

我们搜集了52个已知漏洞的智能合约,将其分为了10类,这些都是来自现实中的漏洞例子。并且精确定位到了漏洞点,如下所示
我们来简单描述tokennize的过程
《Checking Smart Contracts with Structural Code Embedding》笔记_第3张图片
在合约层面的tokenizetion:通过倒序遍历从XML解析树中提取出所有的终端token。杜宇上图的代码,下面的token被提取出来了:
《Checking Smart Contracts with Structural Code Embedding》笔记_第4张图片
在函数层面的tokenization,在函数token后面加上合约的签名。结果如下
在这里插入图片描述
声明层面的tokenization,基于terminal tokens,我们加上了结果和细节和语义关系。比如,对于上面的代码,在AST中的祖先链和函数签名都可以从XML解析树中得到。通过添加AST中的祖先链,我们的模型可以捕获这种结构化关系;通过添加不同的邻居节点,我们的模型可以捕获关于关注点的上下文信息。
《Checking Smart Contracts with Structural Code Embedding》笔记_第5张图片

Normalization
预处理中一个重要的任务就是正则化。我们会移除一些语义无关的信息。步骤具体如下
Stop words:
对于单个单词的变量,我们会用SimpleVar来代替,如下所示
在这里插入图片描述
Punctuations:不重点的标点会被移除,重点的会被保留
在这里插入图片描述
Constants:根据变量的类型,我们将其统一为”StringLitera;”,”DecimalNumber”等
在这里插入图片描述
Camel Case Identifiers:对于驼峰记法的标记符,我们将其作为保留的token,根据其组成,将其分为独立的词
在这里插入图片描述
最终得到的tokens就是我们的训练集

Code Embedding Learning
在这一步中,基于之前的结果,我们将每一个可能的代码段,如声明、函数、合约分别映射到高维的向量。下面是我们使用的两种embedding 算法:Word2Vex,FastText
Word2Vec学习词的向量表示,对于预测同一句中周围的词很有用。然而,传统的word2vec不能捕获到词的形态结构.FastText尝试解决这个问题,它会将每个词作为他们子词的超集,字词是从词的n-gram得到的,使用FastText的词的token是它所有N-gram向量的集合。
为了训练这个模型,我们使用开源的python库gensim,它同时包含这两种算法。我们选择FastText作为我们在后续实验中主要的方法。
Token Embedding

《Checking Smart Contracts with Structural Code Embedding》笔记_第6张图片

你可能感兴趣的:(research)