以太坊代币交易中不一致行为的检测方法与流程

文档序号:19865029发布日期:2020-02-08 05:13阅读:1419来源:国知局
以太坊代币交易中不一致行为的检测方法与流程

本发明涉及计算机数据安全的检测方法,具体讲是以太坊代币交易中不一致行为的检测方法。



背景技术:

比特币的成功激励了许多加密货币的诞生,其中绝大部分的加密货币都是以智能合约的形式部署并运行于以太坊上。智能合约是在以太坊虚拟机(以太坊客户端的一个程序模块)上运行的一种表示合约性质的程序。而智能合约的应用范围很广,其具体合约内容可以涉及代币、赌博或其他用途。代币合约则是智能合约的一种具体合约形式,专门针对代币交易。为了规范代币与用户以及第三方工具(例如区块链钱包,区块链的交易所市场等)之间的交互,一些代币合约实现的规范及标准应运而生,例如以太坊代币标准包括有erc20、erc223、erc667、erc777、erc995等众多标准。在每个标准中都定义了多个标准方法(函数)和标准事件。用户可以通过给代币合约的账户地址发送一串数字,来调用该代币合约中的某个标准方法(函数)。这些代币涉及了大量的资金,与标准不一致的行为可能就会导致用户对资金真实状况的误解甚至是财产的损失。因此,对代币的分析至关重要。

在文献《detectingtokensystemsonethereum》中,等人提出了两种通过分析以太坊虚拟机(evm)的字节码来识别代币合约的方法:(1)通过标准接口的方法编码来识别;(2)使用符号执行和污点分析技术来检测代币的交易行为。这些方法有如下缺点:(1)方法编码识别的方案很容易产生误报,例如,如果智能合约代码中的某个常量等于标准接口的编码,就会产生误报。(3)两种方法都无法检测跨合约协作的代币交易行为。(4)两种方法的重心仅仅是识别某个智能合约是否是代币合约,并没有识别代币合约的实现是否符合标准。

在文献《networkanalysisoferc20tokenstradingonethereumblockchain》中,somin等人通过解析transfer事件来识别代币的交易行为进而进行交易网络分析,该方法存在如下问题:transfer事件并不一定反映真实的代币行为,不符合标准的合约代码实现,可以导致transfer事件与真实的代币交易行为截然不同,somin等人并没有关注transfer事件的实现是否与标准的定义不一致。

在文献《smartcheck:staticanalysisofethereumsmartcontracts》中,sergeitikhomirov等人将solidity编写的智能合约源代码转换为基于xml的中间表示形式,并根据xpath模式进行检查,检测了源码中的21种漏洞。它无法轻松扩展以检测以太坊虚拟机(evm)字节码中的不一致,因为(1)它需要智能合约的源代码;(2)不一致的检测需要了解程序的语义,但模式搜索不支持这种语义。



技术实现要素:

本发明提供了一种以太坊代币交易中不一致行为的检测方法,可以识别出单个或多个联动的智能合约是否为以太坊代币合约,并对已发生的以太坊代币交易进行不一致行为的检测,自动化识别以太坊代币交易的实现是否符合交易行为标准。

本发明以太坊代币交易中不一致行为的检测方法,包括:

第一阶段:提取核心数据结构和识别以太坊代币合约:

a.获取执行轨迹:当客户端在全同步时,会在客户端上重放的历史上执行过的所有交易,此时通过客户端捕获每个交易的交易信息,包括每个交易在执行时调用的操作指令和调用的智能合约的信息,将所有交易的交易信息的集合作为执行轨迹;

b.对执行轨迹中的每个交易信息,根据所检测的以太坊代币标准提取出每个交易调用的标准方法,形成标准方法集合;

例如,需要根据以太坊代币erc20标准对代币交易进行检测,在erc20标准中定义了六个标准方法与两个标准事件,其中,只有transfer和transferfrom两个标准方法是和代币交易相关的。因此在分析一笔交易的时候,就判断在这个交易中调用的方法是否是transfer或者transferfrom。假如是transfer或transferfrom方法,则判断其调用了erc20的标准方法,并将交易中的标准方法提取出来。如果这笔交易里所有调用的方法都与erc20标准里的标准方法无关,这笔交易则不是本次检测需要的交易,跳过该交易,对执行轨迹中的下个交易进行判断。

c.对执行轨迹中每个交易的操作指令与操作数进行分析,根据所检测的以太坊代币标准提取出每个交易调用的标准事件,形成标准事件集合,并记录每个交易的数据结构对以太坊数据库的修改;

d.逐一将每个交易根据其数据结构对以太坊数据库修改后的数据集合与该交易通过智能合约调用的标准方法集合或标准事件集合进行比较,如果二者完全一致,则认为该数据结构为该交易的核心数据结构,并且该交易调用的智能合约为以太坊代币合约,记录该交易的<以太坊代币合约地址-核心数据结构>映射关系。因为在智能合约中有许多种数据结构,因此需要先在步骤c中记录下来每一种数据结构对以太坊数据库的修改,然后再逐一将修改后的数据集合和该交易调用的标准方法集合或标准事件集合进行比较,当发现一致的那个数据结构,即为符合所检测的以太坊代币标准的核心数据数据结构。

核心数据结构表示的是(账户地址—余额)的映射关系,通过核心数据结构对以太坊数据库修改后的数据集合为通过交易后余额的变化量,而标准方法集合来自用户对交易发起的消息调用,表示要交易的代币数量,标准事件集合来自以太坊客户端的指令,表示以太坊客户端根据用户的交易要求进行的操作。因此,在正确的交易中,以太坊数据库修改后的数据集合(余额的变化量)、标准方法集合(用户要求交易的代币数量)和标准事件集合(以太坊客户端的指令)三者应当一致。

第二阶段:根据所述的映射关系检测以太坊代币交易行为的一致性:

e.再次扫描所述重放的所有交易的交易信息,当发现某个交易信息中交易接收方为步骤d中已识别出的以太坊代币合约,则通过该以太坊代币合约对应的映射关系,根据以太坊代币合约地址提取出对应的核心数据结构,再查找在本次交易中是否涉及到该核心数据结构对以太坊数据库的修改,如果有则记录下来;

f.对步骤e记录下的所述交易,将每个交易各自通过以太坊代币合约调用的标准方法集合、标准事件集合和根据核心数据结构对以太坊数据库修改后的数据集合的内容进行对比,如果其中任意两个不相同,则判断该交易对以太坊代币合约的实现与以太坊代币标准不一致,输出交易行为不一致的信息。

在对以太坊代币交易行为的一致性进行检测时,必须要先确定出标准的交易行为,因此需要在第一次对历史的所有交易(数量可以是成千上万)进行扫描来搜集执行轨迹,从中提取到他的核心结构,然后确定哪些交易调用的智能合约是以太坊代币合约,并记录下这些交易的<以太坊代币合约地址-核心数据结构>映射关系。然后再对历史的所有交易进行第二次扫描,根据每个交易的根据核心数据结构,判断该交易是否符合以太坊代币标准。因为在每个交易调用的代币合约里会去实现不同的方法(函数),有的方法是符合以太坊代币标准里定义的标准方法的,有方法属于自定义方法,不符合标准方法。因此需要先从所有交易中找到标准的交易行为,并提取其中核心数据结构,再对所有交易重新扫描,根据标准的交易行为对每个交易进行检测,来确定其是否是符合以太坊代币标准的。

进一步的,步骤a中,通过向客户端的源程序进行插桩,以全同步模式启动插桩后的客户端后,客户端在全同步的过程中,会从区块链的创世区块开始重放所述的所有交易记录,即从网络上的其他运行以太坊客户端的节点下载接收区块信息到本地,然后在本地重放。

进一步的,在步骤f中,根据所述的映射关系中的核心数据结构,如果发现某个交易的标准方法、标准事件或根据核心数据结构对以太坊数据库修改后的数据集合的任意一项涉及0地址、以太坊代币合约地址本身或以太坊代币的创建者地址,则删除与这些地址相关的部分后,再进行所述的比较。例如以太坊代币的创建者对所有用户进行以太坊代币增发,交易的发送方地址则为以太坊代币合约地址本身,这种交易即属于特殊交易。在检验时当发现类似的特殊交易时,认为该交易是符合以太坊代币标准的。

进一步的,在步骤如果发现中,如果发现交易中通过以太坊代币合约调用的方法不属于以太坊代币标准中定义的标准方法时,将该交易的标准方法集合设为空,只比较该交易涉及的标准事件集合和对以太坊数据库修改后的数据集合的内容是否相同。例如在交易中调用的是以太坊代币合约中自定的方法,而非以太坊代币标准中定义的标准方法。

在此基础上,步骤f中,所述交易行为不一致的信息包括不符合以太坊代币标准的以太坊代币合约地址和发生不一致行为的交易数据集。

本发明以太坊代币交易中不一致行为的检测方法的有益效果包括:

1、智能合约的覆盖率高,只要在智能合约部署之后有真实交易的执行轨迹,无需提供智能合约的源代码即可检测其不一致的交易行为。

2、可以识别跨合约的交易行为,本发明收集了每笔交易中所有的执行轨迹,多合约联动的行为将被记录下来,由此能够分析出跨合约的代币交易行为。

3、能够高效的识别出交易调用的智能合约是否为以太坊代币合约,其识别的核心在于是否真正实现了以太坊代币的交易行为,并且要有对应的标准事件通知或标准方法调用,从而避免了静态分析字节码有效信息不足的误报。

4、能够识别标准方法、标准事件以及核心数据结构三者的行为是否一致,是否符合代币的标准,填补了行业研究的空白。

以下结合实施例的具体实施方式,对本发明的上述内容再作进一步的详细说明。但不应将此理解为本发明上述主题的范围仅限于以下的实例。在不脱离本发明上述技术思想情况下,根据本领域普通技术知识和惯用手段做出的各种替换或变更,均应包括在本发明的范围内。

附图说明

图1为本发明以太坊代币交易中不一致行为的检测方法的流程图。

图2为实施例1的映射结构图。

图3为实施例2的映射结构图。

图4为实施例3的映射结构图。

图5为实施例4的映射结构图。

具体实施方式

以太坊代币标准包括有erc20、erc223、erc667、erc777、erc995等众多标准,本实施例用以太坊代币的erc20标准来进行说明。在erc20标准中定义了以太坊代币交易的6个标准方法和2个标准事件。本实施例通过对标准方法的参数、标准事件的内容,以及代表代币持有者与持有量的映射内容变化进行对比,寻找代币的交易行为是否有不一致的地方,从而判断代币合约的实现是否符合erc20标准。

如图1所示本发明以太坊代币交易中不一致行为的检测方法,包括:

第一阶段:提取核心数据结构和识别以太坊代币合约:

a.获取执行轨迹:通过向客户端的源程序进行插桩,以全同步模式启动插桩后的客户端。当客户端在进行全同步时,会从网络上的其他运行以太坊客户端的节点下载接收区块信息到本地,在客户端上重放的历史上执行过的所有交易,此时通过客户端捕获每个交易的交易信息,包括每个交易在执行时调用的操作指令和调用的智能合约的信息,将所有交易的交易信息的集合作为执行轨迹;

b.对执行轨迹中的每个交易信息,根据所检测的以太坊代币标准提取出每个交易调用的标准方法,形成标准方法集合;

c.对执行轨迹中每个交易的操作指令与操作数进行分析,根据所检测的以太坊代币标准提取出每个交易调用的标准事件,形成标准事件集合,并记录每个交易的数据结构对以太坊数据库的修改;

d.逐一将每个交易根据其数据结构对以太坊数据库修改后的数据集合与该交易通过智能合约调用的标准方法集合或标准事件集合进行比较,如果二者完全一致,则认为该数据结构为该交易的核心数据结构,并且该交易调用的智能合约为以太坊代币合约,记录该交易的<以太坊代币合约地址-核心数据结构>映射关系;

第二阶段:根据所述的映射关系检测以太坊代币交易行为的一致性:

e.再次扫描所述重放的所有交易的交易信息,当发现某个交易信息中交易接收方为步骤d中已识别出的以太坊代币合约,则通过该以太坊代币合约对应的映射关系,根据以太坊代币合约地址提取出对应的核心数据结构,再查找在本次交易中是否涉及到该核心数据结构对以太坊数据库的修改,如果有则记录下来;

f.对步骤e记录下的所述交易,将每个交易各自通过以太坊代币合约调用的标准方法集合、标准事件集合和根据核心数据结构对以太坊数据库修改后的数据集合的内容进行对比,而如果发现某个交易的标准方法、标准事件或以太坊数据库修改后的数据集合的任意一项涉及0地址、以太坊代币合约地址本身或以太坊代币的创建者地址,则删除与这些地址相关的部分。对比后如果其中任意两个不相同,则判断该交易对以太坊代币合约的实现与以太坊代币标准不一致;如果该交易通过以太坊代币合约调用的方法不属于以太坊代币标准中定义的标准方法时,将该交易的标准方法集合设为空,只比较该交易涉及的标准事件集合和对以太坊数据库修改后的数据集合的内容是否相同,如果不同,则判断该交易对以太坊代币合约的实现与以太坊代币标准不一致。

每个账户都有一个20字节的数字与字母组合(十六进制)的账户地址,0地址就是这20个字节全都是0,0地址作为特殊地址在区块链交易中非常普遍。

在对涉及0地址、以太坊代币合约地址本身或以太坊代币的创建者地址等特殊地址的交易进行判断时,例如:

标准方法集合:空集。

标准事件集合:(a,-100),(b,+100),即a地址向b地址转100个以太坊代币。

以太坊数据库修改后的数据集合:(a,-100),即表明a地址扣除了100个以太坊代币。

此交易中标准方法集合是空集,因此不参与比较。

第一步,判断比较标准事件集合与以太坊数据库修改后的数据集合是否一致,发现不一致。

第二步,识别a和b两个地址是否是创建者、以太坊代币合约地址本身或者是0地址,如果此时发现b地址是以太坊代币合约地址本身,则删掉标准事件集合与数据库修改后数据集合中和b地址有关的所有数据,则标准事件集合中删掉了(b,+100)。

第三步,比较删掉与b地址有关之后的数据,此时标准事件集合中只剩下(a,-100),与数据库修改后的数据集合的内容完全一致。那么则认为这个交易是符合以太坊代币标准的。

再例如,如果上述交易为:

标准方法集合:空集。

标准事件集合:(a,-50),(b,+50)

以太坊数据库修改后的数据集合:(a,-100)

此时,如果b是特殊地址,删掉标准事件集合中的(b,+50)标准事件,在标准事件集合中还剩下(a,-50),与数据库修改后的数据集合(a,-100)并不相同,则认为这个交易不符合以太坊代币标准,是不一致的交易行为。

最后,输出交易行为不一致的信息,包括不符合以太坊代币标准的以太坊代币合约地址和发生不一致行为的交易数据集等信息。

实施例1:

以太坊上绝大多数的erc20代币,都使用<账户地址-账户余额>映射结构,来存储代币持有者与持有余额。这种结构将一个账户的地址与其持有的代币余额建立了一对一的映射关系。如图2所示,说明了如何利用相应的映射编码,从数据库中读取一个账户地址的余额。此外还有对应的solidity源代码(即“amount=balances[addr];”)以及对应的evm指令(以太坊虚拟机指令)。此类结构首先通过evm的指令sha3,将账户地址与映射的编码进行哈希操作,得到一个新的地址值。然后通过evm的指令sload,根据得到的新的地址值,从以太坊数据库中读取该位置存储的内容,就是这个账户地址的余额。同理,如果要写入一个新的余额,就利用sha3指令对账户地址和映射编码计算得到一个新地址,然后利用sstore指令进行写入。

假设代币minttoken属于此类映射结构,地址为:

0xcccccccccccccccccccccccccccccccccccccccc;

代币交易的不一致行为检测过程如下:

第一阶段:提取核心数据结构和识别以太坊代币:

1.首先,假设当前有两个外部交易账户:

a账户地址:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;持有minttoken数量为100;

b账户地址:0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,持有的minttoken数量是0。

2.当a账户需要向b账户转账时,需要通过minttoken实现。由a账户向minttoken发送消息,触发执行minttoken的智能合约,通过minttoken的智能合约的执行完成a账户向b账户转账。

因此,a账户向b账户转账时,先在客户端上发起一笔交易,交易的接收方为minttoken,交易的携带信息为:

0xa9059cbb000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0000000000000000000000000000000000000000000000000000000000000006。

3.执行轨迹记录如下信息:

外部交易发起者地址:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

外部交易接收者地址:0xcccccccccccccccccccccccccccccccccccccccc;

外部交易携带信息:

0xa9059cbb000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0000000000000000000000000000000000000000000000000000000000000006;

以及minttoken在执行过程中产生的一系列evm(以太坊虚拟机)操作。

4.对执行轨迹信息进行解析。首先提取外部交易携带信息中的前五个字节:0xa9059cbb,比较发现与erc20标准中定义的方法transfer的哈希值相同,因此记录本次标准方法调用的数据集为:

根据erc20标准中的方法transfer的定义,minttoken的发送者为外部交易的发起者,即:

0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

minttoken的接收者为携带信息中的第一个参数,即从携带信息中去掉前5个字节后,第1个32字节的数据,即:

000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

提取其中的后20个字节并加上0x就是对应接收者的地址:

0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

minttoken的交易额为方法中的第二个参数,从携带信息中去掉前5个字节后,第2个32字节的数据,即:

0000000000000000000000000000000000000000000000000000000000000006;

取不为0的有效部分并加上0x即为交易额,即0x6;

最后产生的标准方法数据集为:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

5.本次智能合约的调用会执行evm指令,所有的evm指令都会被作为执行轨迹记录下来。

6.提取执行轨迹中的关键指令。首先,本次交易中调用了log3指令,代表了事件通知,并记录了事件通知的内容为:

ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0000000000000000000000000000000000000000000000000000000000000006;

提取前32字节的数据,与erc20标准定义的事件进行比较,得出ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef与标准事件transfer相吻合,然后记录标准事件集合为:

根据标准事件transfer的定义,标准事件集合中记录的内容依次为:minttoken的发送者,minttoken的接收者,minttoken的交易额。从log3数据的第2个32字节开始,每32字节,依次代表了这些数据。即:

发送者:

000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

接收者:

000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

交易额:

0000000000000000000000000000000000000000000000000000000000000006;

其中,代表地址的数据取后20个字节,前面加0x;代表交易额的数据取不为0的部分,前面加0x;最后得到标准事件集合:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

7.然后,将根据其他evm指令,提取映射结构:

①sha3指令,可以从sha3指令中得到两部分数据:参与计算的值和计算的结果,其中参与计算的值为(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,1),计算的结果为一个哈希值,用变量名keccak_a代替;

②sstore指令,这是数据写入指令,本指令记录了写入的地址、本地址修改前的值、和写入后的新值。其中,捕捉到写入的地址为keccak_a,操作前的值为100,操作后的值为94;

③根据相同的值keccak_a,可以将上述sha3与sstore的数据关联起来,它们属于图2所示的<账户地址-账户余额>映射结构(即:核心数据结构),操作的地址为0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,映射编码为1,写入的余额从100变成为94,可见变化量为-0x6。得到编码1的映射在本次交易中的第一次修改(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6);

④sha3指令,可以从sha3指令中得到两部分数据:参与计算的值和计算的结果,其中参与计算的值为:

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,1),计算的结果为一个哈希值,用变量名keccak_b代替;

⑤sstore指令,本指令记录了操作的地址、本地址操作前的值、和操作后的值。其中,操作的地址为keccak_b,操作前的值为0,操作后的值为6;

⑥根据相同的值keccak_b,可以将上述sha3与sstore的数据关联起来,它们属于图2所示的<账户地址-账户余额>映射结构(即:核心数据结构),操作的地址为0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,映射编码为1,写入的值从0变成为6,可见变化量为0x6。得到编码1的映射第二次修改内容(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

8.最终,编码为1的映射对以太坊数据库的修改数据集合为:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

9.将根据编码为1的映射对以太坊数据库修改后的数据集合与所述的标准事件集合进行比较,发现完全一致,因此则认为合约minttoken是一个以太坊代币,其中代表了持有者和持有额度的关系的特殊数据结构为编码为1的映射(即:核心数据结构),将此信息作为该客户端在以太坊交易时的代币合约实现标准。

第二阶段:根据所述的映射关系检测以太坊代币交易行为的一致性:

10.账户a通过该客户端再次发起一笔交易,交易的接收者为minttoken,携带的数据为:

0xa0712d680000000000000000000000000000000000000000000000000000000000000005。

11.执行轨迹记录如下信息:

外部交易发起者地址:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

外部交易接收者地址:0xcccccccccccccccccccccccccccccccccccccccc;

外部交易携带信息:

0xa0712d680000000000000000000000000000000000000000000000000000000000000005;

以及minttoken执行过程中产生的一系列evm操作。

12.对执行轨迹信息解析。首先提取外部交易携带信息中的前五个字节:0xa0712d68,不属于erc20标准中定义的标准方法的哈希值,因此不做特殊记录,标准方法集合为空。

13.寻找evm中的日志指令,发现本次交易并无日志指令,设置为空集。

14.根据其他evm指令,捕捉是否有代币交易行为:

①sha3指令,可以从sha3指令中得到两部分数据:参与计算的值和计算的结果,其中参与计算的值为(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,1),计算的结果为一个哈希值,用变量名keccak_a代替;

②上述sha3指令的映射编码为1,说明是在进行代币的交易,交易账户为0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,账户余额的新地址编码为keccak_a;

③sstore指令,本指令记录了操作的地址、本地址操作前的值、和操作后的值。其中,操作的地址为keccak_a,操作前的值为94,操作后的值为99。

根据keccak_a可知,对应操作的真实交易账户是0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,账户的余额改变量为0x5。

15.由于没有其他操作,输出本次映射的数据集合(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,0x5)。

16.对标准方法集合、标准事件集合与根据映射的数据集合对太坊数据库修改后的数据集合进行比较,由于本次方法调用是非标准的,因此忽略掉标准方法集合(标准方法集合为空),仅比较后两者。可以看到,因标准事件集合为空集,映射集合不为空,此时代币的交易行为出现了不一致现象,不符合erc20的标准,不符合原因是:当代币交易行为发生时,没有用标准事件进行通知,标准事件集合为空。

17.最后,输出本次不一致代币的地址,以及标准方法集合、标准事件集合与映射集合的数据内容。

实施例2:

以太坊上的部分erc20代币,使用<账户地址-结构体>映射结构,来存储代币持有者与持有余额。这个映射结构把账户地址与一个结构体建立了一一对应关系,这个结构体中包含了该账户的代币持有量以及一些其他的信息。图3展示了如何利用这类映射编码,从数据库中读取一个账户地址的余额,及其对应的solidity源代码(即“amount=balances[addr].amount;”)以及对应的evm指令。首先将账户地址和映射编码进行哈希操作,得到一个新地址的值,对应的evm指令为sha3。然后再根据代表代币余额的变量在结构体中的相对位置,得到一个偏移量,再通过evm的指令add将所述的新地址与这个偏移量相加,就得到了余额所在的地址值。最后,根据计算得到的余额所在的地址,从数据库中读出余额的值,对应evm指令为sload。同理,假如要写入新的余额,就计算出余额所在地址后,利用sstore指令进行写入。

假设代币minttoken2属于此类映射结构,地址为:

0xcccccccccccccccccccccccccccccccccccccccc;

代币交易的不一致行为检测过程如下:

第一阶段:提取核心数据结构和识别以太坊代币:

1.假设当前有两个外部交易账户

a账户地址:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;持有minttoken2数量为100;

b账户地址:0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,持有的minttoken2数量是0。

2.a账户在以太坊上发起一笔交易,交易的接收方为minttoken2,交易的携带信息为:

0xa9059cbb000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0000000000000000000000000000000000000000000000000000000000000006。

3.执行轨迹记录如下信息:

外部交易发起者地址:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

外部交易接收者地址:0xcccccccccccccccccccccccccccccccccccccccc;

外部交易携带信息:

0xa9059cbb000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0000000000000000000000000000000000000000000000000000000000000006;

以及minttoken2执行过程中产生的一系列evm操作。

4.解析执行轨迹信息。首先提取外部交易携带信息中的前五个字节:0xa9059cbb,比较发现与erc20标准中定义的方法transfer的哈希值相同,因此记录本次标准方法调用的数据集为:

根据erc20标准中的方法transfer的定义,minttoken2的发送者为外部交易的发起者,即:

0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

minttoken2的接收者为携带信息中的第一个参数,即从携带信息中去掉前5个字节后,第1个32字节的数据,即:

000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

提取其中的后20个字节并加上0x就是对应接收者的地址:

0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

minttoken2的交易额为方法中的第二个参数,从携带信息中去掉前5个字节后,第2个32字节的数据,即:

0000000000000000000000000000000000000000000000000000000000000006;

取不为0的有效部分并加上0x即为交易额,即0x6;

最后产生的标准方法数据集为:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

5.本次合约的调用会执行evm指令,所有的evm指令都会被记录下来。

6.提取关键指令。首先,本次交易调用,捕捉到log3指令,代表了事件通知,并记录了事件通知的内容为:

ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0000000000000000000000000000000000000000000000000000000000000006。

提取第一个32字节数据,与erc20标准定义的事件比较,得出ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef与标准事件transfer相吻合,记录标准事件集合为:

根据标准事件transfer的定义,依次记录的内容为:minttoken2的发送者,minttoken2的接收者,minttoken2的交易额。从log3数据的第2个32字节开始,每32字节,依次代表了这些数据。即:

发送者:

000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

接收者:

000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

交易额:

0000000000000000000000000000000000000000000000000000000000000006;

其中,代表地址的数据取后20个字节,前面加0x;代表交易额的数据取不为0的部分,前面加0x;最后得到标准事件集合:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

7.根据其他evm指令,提取映射结构:

①sha3指令,可以从sha3指令中得到两部分数据:参与计算的值和计算的结果,其中参与计算的值为(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,1),计算的结果为一个哈希值,用变量名keccak_a代替;

②sstore指令,本指令记录了操作的地址,本地址操作前的值,和操作后的值。其中,操作的地址为(keccak_a+5),操作前的值为100,操作后的值为94;

③由于sstore与sha3的哈希值仅仅有个位数的差距,可以将上述sha3与sstore的数据关联起来,操作的地址为:

0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

写入的值从100变成为94,可见变化量为-0x6;得到编码1的映射在偏移量为5的位置,数据修改为(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6);

④sha3指令,可以从sha3指令中得到两部分数据:参与计算的值和计算的结果,其中参与计算的值为:

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,1),计算的结果为一个哈希值,用变量名keccak_b代替;

⑤sstore指令,本指令记录了操作的地址,本地址操作前的值,和操作后的值。其中,操作的地址为(keccak_b+5),操作前的值为0,操作后的值为6;

⑥由于sstore与sha3的哈希值仅仅有个位数的差距,可以将上述sha3与sstore的数据关联起来,操作的地址为:

0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

写入的值从0变成为6,可见变化量为6;得到编码1的映射在偏移量为5的位置,第二份数据为(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

8.最终,编码为1的映射在偏移量为5的位置对以太坊数据库的修改集合为:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

9.将编码为1的映射在偏移量为5的位置的数据集合与标准事件集合进行比较,发现完全一致,此时,认为合约minttoken2是一个以太坊代币,其中代表了持有者和持有额度关系的特殊数据结构为:编码为1的映射中偏移量为5的位置(即:核心数据结构)。

第二阶段:根据所述的映射关系检测以太坊代币交易行为的一致性:

10.账户a通过该客户端再次发起一笔交易,交易的接收者为代币minttoken2,携带的数据为:

0xa0712d680000000000000000000000000000000000000000000000000000000000000005。

11.执行轨迹记录如下信息:

外部交易发起者地址:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

外部交易接收者地址:0xcccccccccccccccccccccccccccccccccccccccc;

外部交易携带信息:

0xa0712d680000000000000000000000000000000000000000000000000000000000000005;

以及minttoken2执行过程中产生的一系列evm操作。

12.解析执行轨迹信息。首先,提取外部交易携带信息中的前五个字节:0xa0712d68,不属于erc20标准中定义的标准方法的哈希值,因此不做特殊记录,标准方法集合为空。

13.通过evm中的日志指令,发现本次交易触发了标准transfer日志,数据集为:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,0x5),

(0x0000000000000000000000000000000000000000,-0x5)。

14.然后根据其他evm指令,捕捉是否有代币交易行为:

①sha3指令,可以从sha3指令中得到两部分数据:参与计算的值和计算的结果,其中参与计算的值为(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,1),计算的结果为一个哈希值,用变量名keccak_a2代替;

②上述sha3指令的映射编码为1,说明是在进行代币的交易,交易账户为0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,账户余额的新地址编码为keccak_a2。

③sstore指令,本指令记录了操作的地址、本地址操作前的值、和操作后的值。其中,操作的地址为keccak_a3,操作前的值为94,操作后的值为99。

根据(keccak_a3=keccak_a2+5)可知本sstore指令与编码为1的映射相关联,偏移量为5说明是在进行代币交易操作,对应操作的真实交易账户是0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,账户的余额改变量为0x5。

15.由于没有其他操作,最终输出本次映射数据集合(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,0x5)。

16.对标准方法集合、标准事件集合与根据映射数据集合对以太坊数据库修改后的数据集合进行比较,由于本次方法调用是非标准的,因此标准方法集合为空,忽略掉标准方法集合,仅仅比较后两者。可以看到,标准事件比映射集合多出来一条:

(0x0000000000000000000000000000000000000000,-0x5)

因为0地址属于特殊地址,并且除此之外其他数据都相同,于是就排除掉0地址的干扰,认为这是一次普通的代币增发行为,是符合erc20标准的。

17.最后,因本次交易未检测到异常,检测结束后不做任何输出。

实施例3:

以太坊上的部分erc20代币,使用<账户地址-结构体数组>的映射结构,来存储代币持有者与持有余额。这个结构把账户地址与一个结构体数组建立了对应关系,结构体数组记录了该账户所有的历史余额,数组的每一项元素都包含某个时间节点下账户的余额,数组的最后一项记录包含了该账户当前最新的代币持有量。图4展示了如何利用这类映射编码,从数据库中读取一个账户地址的余额的方案,及其对应的solidity源代码(即“amount=balances[addr][balances[addr].length-1].amount;”)以及对应的evm指令。首先将账户地址和映射编码进行哈希操作,得到结构体数组的地址编码,对应的evm指令为sha3。第二步使用sload指令从结构体数组的地址编码标识的位置中,读取出来结构体数组当前的长度,然后利用sub指令,将长度值减一,把这个值乘以单个结构体的大小,对应mul指令,得到一个偏移量。第三步,将结构体数组的地址编码再次进行sha3操作,然后与第二步得到的偏移量相加,就得到了结构体数组最后一项的地址编码,对应add指令。第三步,将代表代币余额的变量在结构体中的偏移量,与结构体数组最后一项的地址编码相加,就得到了这个账户当前余额所在地址的编码,利用sload即可读出。同理,利用sstore指令可以写入。

假设代币minttoken3属于此类,地址为:

0xcccccccccccccccccccccccccccccccccccccccc;

代币交易的不一致行为检测过程如下:

第一阶段:提取核心数据结构和识别以太坊代币:

1.假设当前有两个外部交易账户

a账户地址:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;持有minttoken3数量为100;

b账户地址:0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,持有的minttoken3数量是0。

2.a账户在客户端上发起一笔交易,交易的接收方为minttoken3,交易的携带信息为:

0xa9059cbb000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0000000000000000000000000000000000000000000000000000000000000006

3.执行轨迹记录如下信息:

外部交易发起者地址:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

外部交易接收者地址:0xcccccccccccccccccccccccccccccccccccccccc;

外部交易携带信息:

0xa9059cbb000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0000000000000000000000000000000000000000000000000000000000000006。

以及minttoken3执行过程中产生的一系列evm操作。

4.解析执行轨迹信息。提取外部交易携带信息中的前五个字节:0xa9059cbb,比较发现与erc20标准中定义的方法transfer的哈希值相同,因此记录本次标准方法调用的数据集:

根据erc20标准中的方法transfer的定义,minttoken3的发送者为外部交易的发起者,即:

0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

minttoken3的接收者为携带信息中的第一个参数,即从携带信息中去掉前5个字节后,第1个32字节的数据,即:

000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

提取其中的后20个字节并加上0x就是对应接收者的地址:

0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

minttoken3的交易额为方法中的第二个参数,从携带信息中去掉前5个字节后,第2个32字节的数据,即:

0000000000000000000000000000000000000000000000000000000000000006;

取不为0的有效部分并加上0x即为交易额,即0x6;

最后产生的标准方法数据集为:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)

5.本次合约调用会执行evm指令,所有的evm指令都会被记录下来。

6.提取关键指令。首先,本次交易调用,捕捉到log3指令,代表了事件通知,并记录了事件通知的内容为:

ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0000000000000000000000000000000000000000000000000000000000000006。

提取第一个32字节数据,与erc20标准定义的事件比较,得出ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef与标准事件transfer相吻合,记录标准事件数据集为:

根据标准事件transfer的定义,依次记录的内容为:minttoken3的发送者、minttoken3的接收者、minttoken3的交易额。从log3数据的第2个32字节开始,每32字节,依次代表了这些数据。即:

发送者:

000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

接收者:

000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

交易额:

0000000000000000000000000000000000000000000000000000000000000006;

其中,代表地址的数据取后20个字节,前面加0x;代表交易额的数据取不为0的部分,前面加0x;最后得到标准事件集合:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

7.根据其他evm指令,提取映射结构:

①sha3指令,计算的值是(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,1),得到的结果为keccak_a;

②sstore指令,在位置keccak_a的地方存储了一个值,标记为len;

③sha3指令,参与计算的值为keccak_a,得到的结果为keccak_a2;

④sstore指令,在位置(keeccak_a2+len-1)存储了数值:

0000000000000000000000000000011700000000000000000000000000000064;

这个数值的长度是32字节,结构体长度为1,但是结构体中元素个数至少2个,因此将本32字节从中拆分成两个数值:

0x00000000000000000000000000000117,

0x00000000000000000000000000000064;

⑤因是结构体数组类型,在识别过程中将维护一个键值对,键由minttoken3的地址、映射的编码1、以及地址0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa共同组成;值是一个数组,不断在数组末尾添加新的元素,这个元素是最终sstore在位置(keeccak_a2+len-1)存储的数值。通过这样的方法,每次取数组的最后一个元素,就可以得到上一笔交易的数据。此处根据键值对,取出了上一次映射的内容为:

000000000000000000000000000001060000000000000000000000000000005e;

同样拆分成两个数值:0x00000000000000000000000000000116和0x0000000000000000000000000000005e;与当前交易的差值分别为0x1与-0x6;

最后可以得到编码为1的映射,针对地址:

0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa有两个数据集,前16个字节的数据为(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,0x1),后16字节数据为(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6)。

⑥同理,当再次出现相同的指令结构时,捕捉到编码为1的映射,针对地址0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb有两个数据集,前16个字节的数据为(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x1),后16字节数据为(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

8.最终,编码为1的映射对以太坊数据库的修改的有两套数据:

前16字节:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,0x1),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x1);

后16字节:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

9.将根据编码为1的映射对以太坊数据库修改后的数据集合与标准事件集合进行比较,发现映射1的后16字节与标准事件内容完全一致,此时,认为合约minttoken3是一个代币,代币中代表了持有者和持有额度的特殊数据结构为:编码为1的映射中,存储的数据里后16字节位置(即:核心数据结构)。

第二阶段:根据所述的映射关系检测以太坊代币交易行为的一致性:

10.账户a通过该以太网客户端再次发起一笔交易,交易的接收者为minttoken3,携带的数据为:

0xa0712d680000000000000000000000000000000000000000000000000000000000000005。

11.执行轨迹记录如下信息:

外部交易发起者地址:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

外部交易接收者地址:0xcccccccccccccccccccccccccccccccccccccccc;

外部交易携带信息:

0xa0712d680000000000000000000000000000000000000000000000000000000000000005;

以及minttoken3执行过程中产生的一系列evm操作。

12.解析执行轨迹信息。首先提取外部交易携带信息中的前五个字节:0xa0712d68,不属于erc20标准中定义的标准方法的哈希值,因此不做特殊记录,标准方法集合为空。

13.通过寻找evm中的日志指令,发现本次交易触发了标准transfer日志,数据集为:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,0x0),

(0x0000000000000000000000000000000000000000,0x0)。

14.根据其他evm指令,捕捉是否有代币交易行为:

①sha3指令,计算的值是(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,1),得到的结果为keccak_a;

②sstore指令,在位置keccak_a的地方存储了一个值len;

③sha3指令,计算的值为keccak_a,得到的结果为keccak_a2;

④sstore指令,在位置(keeccak_a2+len-1)存储了数值:

0000000000000000000000000000011800000000000000000000000000000000;

取出上一笔交易中存储的值的后16字节是0x5e,本次直接置0,可见修改值为(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x5e)。

15.对标准方法集合、标准事件集合与映射数据集合对以太坊数据库修改后的数据集合进行比较,由于本次方法调用是非标准的,标准方法集合为空,因此忽略掉标准方法集合,仅仅比较后两者。可以看到,标准方法与标准事件的内容无法匹配,即使去掉特殊地址0地址的相关数据,对于地址0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,其余额变化量依旧不同。因此代币的实现与标准不一致。

16.最后,输出本次不一致代币的地址、以及标准方法集合、标准事件集合与映射集合的数据内容。

实施例4:

以太坊上的部分erc20代币,使用双映射结构,来存储代币持有者与持有余额。有的代币合约中拥有非常复杂的映射关系,需要用到不止一个映射的编码。图5展示了这种映射关系下,如何利用映射编码来读取某个代币的账户余额,以及这种结构对应的solidity源代码(“amount=asset.wallets[holderindex[addr]].amount;”)和evm指令。第一步,利用sha3指令将账户余额与映射一编码进行哈希计算,得到一个地址编码,利用sload指令从这个地址编码中读出账户余额对应的一个特殊编码,称为索引值。第二步,利用sha3指令把索引值和映射二编码进行哈希计算,得到结构体地址的编码,计算代币余额变量在结构体中的偏移量,与结构体地址相加,就可以用sload指令读出当前账户的余额。

假设代币minttoken4属于此类,地址为:

0xcccccccccccccccccccccccccccccccccccccccc;

代币交易的不一致行为检测过程如下:

第一阶段:提取核心数据结构和识别以太坊代币:

1.假设当前有两个外部交易账户:

a账户地址:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;持有minttoken4数量为100;

b账户地址:0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,持有的minttoken4数量是0。

2.a账户在客户端上发起一笔交易,交易的接收方为minttoken4,交易的携带信息为:

0xa9059cbb000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0000000000000000000000000000000000000000000000000000000000000006。

3.执行轨迹记录如下信息:

外部交易发起者地址:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

外部交易接收者地址:0xcccccccccccccccccccccccccccccccccccccccc;

外部交易携带信息:

0xa9059cbb000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0000000000000000000000000000000000000000000000000000000000000006;

以及minttoken4执行过程中产生的一系列evm操作。

4.解析执行轨迹信息。首先提取外部交易携带信息中的前五个字节:0xa9059cbb,比较发现与erc20标准中定义的方法transfer的哈希值相同,因此记录本次标准方法调用的数据集:

根据erc20标准中的方法transfer的定义,minttoken4的发送者为外部交易的发起者,即:

0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

minttoken4的接收者为携带信息中的第一个参数,即从携带信息中去掉前5个字节后,第1个32字节的数据,即:

000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

提取其中的后20个字节并加上0x就是对应接收者的地址:

0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

minttoken4的交易额为方法中的第二个参数,从携带信息中去掉前5个字节后,第2个32字节的数据,即:

0000000000000000000000000000000000000000000000000000000000000006;

取不为0的有效部分并加上0x即为交易额,即0x6;

最后产生的标准方法数据集为:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)

5.本次合约的调用会执行evm指令,所有的evm指令都会被记录下来。

6.提取关键指令。首先,本次交易调用,捕捉到log3指令,代表了事件通知,并记录了事件通知的内容为:

ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb0000000000000000000000000000000000000000000000000000000000000006;

提取第一个32字节数据,与erc20标准定义的事件比较,得出ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef与标准事件transfer相吻合,记录标准事件数据集:

根据标准事件transfer的定义,依次记录的内容为:minttoken4的发送者、minttoken4的接收者、minttoken4的交易额。从log3数据的第2个32字节开始,每32字节,依次代表了这些数据。即:

发送者:

000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

接收者:

000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;

交易额:

0000000000000000000000000000000000000000000000000000000000000006;

其中,代表地址的数据取后20个字节,前面加0x;代表交易额的数据取不为0的部分,前面加0x;最后得到标准事件集合:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

7.根据其他evm指令,提取映射结构:

①sha3指令,操作数为:(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,1),得到的值为keccak_id;

②sload指令,从地址为keccak_id取出一个值,用符号addressid表示;

③sha3指令,操作数为:

(0x000000000000000000000000000000000000000c,2),得到值为keccak_assets;

④sha3指令,操作数为(addressid,keccak_assets+1),得到的值为keccak_assets_balance;

⑤sstore指令,在位置keccak_assets_balance存入数据,写入的值从100变成为94,可见变化量为-0x6。由于keccak_assets_balance来自于addressid,与映射1有关,还来自于keccak_assets,与映射2有关。最终得到编码1的映射,以及编码为2的映射在偏移量为1的位置,共同构成了minttoken4的一个复杂映射结构,交易数据集为(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6)。

⑥sha3指令,操作数为:

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,1),得到的值为keccak_id2;

⑦sload指令,从地址为keccak_id2取出一个值addressid2;

⑧sha3指令,操作数为:

(0x000000000000000000000000000000000000000c,2),得到值为keccak_assets;

⑨sha3指令,操作数为(addressid2,keccak_assets+1),得到的值为keccak_assets_balance2;

⑩sstore指令,在位置keccak_assets_balance2存入数据,写入的值从0变成为6,可见变化量为0x6。得到编码1的映射,以及编码为2的映射在偏移量为1的位置,共同构成了minttoken4的一个复杂映射结构(即:核心数据结构),交易数据集为(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)。

8.最终,双映射结构对以太坊数据库的修改集合为:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,-0x6),

(0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,0x6)

9.将根据编码为1的映射对以太坊数据库修改后的数据集合与标准事件集合进行比较,发现完全一致,此时,认为合约minttoken4是一个代币,代币中代表了持有者和持有额度的特殊数据结构为:编码为1的映射,以及编码为2的映射在偏移量为1的位置(即:核心数据结构)。

第二阶段:根据所述的映射关系检测以太坊代币交易行为的一致性:

10.账户a通过该客户端再次发起一笔交易,交易的接收者为代币minttoken4,携带的数据为:

0xa0712d680000000000000000000000000000000000000000000000000000000000000005。

11.执行轨迹记录如下信息:

外部交易发起者地址:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;

外部交易接收者地址:0xcccccccccccccccccccccccccccccccccccccccc;

外部交易携带信息:

0xa0712d680000000000000000000000000000000000000000000000000000000000000005;

以及minttoken4执行过程中产生的一系列evm操作。

12.解析执行轨迹信息。首先,提取外部交易携带信息中的前五个字节:0xa0712d68,不属于erc20标准中定义的标准方法的哈希值,因此不做特殊记录,标准方法集合为空。

13.寻找evm中的日志指令,发现本次交易没有事件通知。

14.根据其他evm指令,捕捉是否有代币交易行为:

①sha3指令,操作数为:

(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,1),得到的值为keccak_id;

②sload指令,从地址为keccak_id取出一个值addressid;

③sha3指令,操作数为:

(0x000000000000000000000000000000000000000c,2),得到值为keccak_assets;

④sha3指令,操作数为(addressid,keccak_assets+1),得到的值为keccak_assets_balance;

⑤sstore指令,在位置keccak_assets_balance存入数据,写入的值从94变成为99,交易数据集为(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,0x5)。

15.由于没有其他操作,最终输出本次映射数据集合(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,0x5)。

16.对标准方法集合、标准事件集合与映射数据集合对以太坊数据库修改后的数据集合进行比较,由于本次方法调用是非标准的,标准方法集合为空,因此忽略掉标准方法集合,仅仅比较后两者。可以看到,因标准事件集合为空集,映射集合不为空,此时代币的交易行为出现了不一致现象,不符合erc20的标准,不符合原因是:当代币交易行为发生时,没有用标准事件进行通知,标准事件集合为空。

17.最后,输出本次不一致代币的地址,以及标准方法集合、标准事件集合与映射集合的数据内容。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1