一种在区块链数据库上针对关键字key的索引方法与流程

文档序号:16536915发布日期:2019-01-08 19:59阅读:652来源:国知局
一种在区块链数据库上针对关键字key的索引方法与流程
本发明涉及区块链数据查询
技术领域
,尤其涉及一种在区块链数据库上针对关键字key的索引方法。
背景技术
:随着比特币,以太币等一系列加密货币的兴起,其底层的区块链技术也受到了越来越广泛的关注。比特币最核心的意图是为了实现去中心化,即在没有第三方信任机构参与的情况下实现两个对等实体的数字货币交易。然而,现实世界中不可避免的存在很多自然中心,比如提供贷款的银行,提供电信服务的电信运营商等。虽然可以把这些中心机构当作是对等实体,将其与用户的交易记录到区块链上,比如用比特币去交话费,但是这种做法是不切实际的,因为这不利于机构管理用户数据(包括用户的信用等级等)。实际上,现有的中心机构都是由自己管理其存储用户相关信息的数据库,但是这种模式存在很多缺陷:1)不同的数据库可能存储着相同的用户基本身份信息,导致数据冗余度高;2)不同的中心机构各自管理自己的数据,不利于机构之间的数据共享;3)每个数据库大都由单一机构中心化管理,使得用户必须无条件信任该机构,存在中心化问题;4)用户不能够独立验证数据的正确性,如果数据被恶意篡改,用户与机构都无法察觉。而区块链技术具有去中心化、防篡改以及公开透明的特性,为解决上述这些问题提供了可能。为此,希望有高效的共识算法来提高系统的吞吐率,并有高效的查询算法实现在区块链上检索数据。当前,在共识算法上已经有很多研究,例如pow、pos、pbft。然而针对区块链查询的研究相对较少,大都是利用同步技术将交易数据同步到传统数据库,根据各数据项建立索引,从而实现快速查询,但是这种做法并不能保证索引的不可篡改,所以损失了区块链不可篡改的特性。技术实现要素:本发明要解决的技术问题是针对上述现有技术的不足,提供一种在区块链数据库上针对关键字key的索引方法,解决区块链的查询问题,实现一种不可篡改的索引。为解决上述技术问题,本发明所采取的技术方案是:一种在区块链数据库上针对关键字key的索引方法,包括以下步骤:步骤1:普通节点根据用户输入的带关键字key的原始数据生成交易记录,具体包括:步骤1-1:生成交易默认信息,包括区块链版本号信息以及数据创建时刻的时间戳信息;步骤1-2:指定该交易的前驱prehash,若该关键字key是第一次出现,则前驱prehash置为null,否则前驱为该关键字key所对应的最新交易的哈希值;步骤1-3:生成数据权限信息以及数据签名;将scriptpubk赋值为下一个可对该关键字key数据进行修改的公钥,利用ecdsa算法,根据自己的私钥对交易数据进行签名;步骤2:存储节点将交易打包到区块中,具体包括:步骤2-1:验证交易格式是否符合规范,过滤无法识别的交易;步骤2-2:验证交易签名是否有效;根据prehash值到k-v数据库中检索其交易索引txindex,根据txindex检索到前驱交易pretx,取其指定的下一任公钥信息pretx.scriptpubk;根据ecdsa算法的verify()函数进行签名验证,若verify(pretx.scriptpubk,tx.scriptsig,tx)=true,则签名有效,否则签名无效,丢弃该交易;步骤2-3:检测双花;读取交易的prehash字段,若其不为空,则根据prehash值到k-v数据库中检索前驱交易索引txindex,如果该索引指明前驱交易的后继交易不为空,则表明待验证交易为双花交易,判定其无效;如果其后继交易为空,则将后继交易赋值为待验证交易的哈希值,待验证交易有效;如果交易的prehash字段为空,即交易的创建者认为之前不存在与此交易关键字key相同的交易,此时查找系统中是否能够检索到关键字为key的交易,如果检索到则该交易无效,如果未检索到则该交易有效;步骤2-4:当交易被验证有效之后,将交易插入到区块体中key有序的交易数组vtx[]中,更新merklerbtree索引;更新merklerbtree的规则如下:初始化当前节点为merkleroot,比较待插入节点关键字key和当前节点关键字nodekey,如果key<=nodekey,则插入到当前节点的左子树,然后更新当前节点为当前节点的左孩子,否则插入到右子树,然后更新当前节点为其右孩子,依次递归,直到最后一层分支节点;插入交易之后,对该树进行旋转使其保证黑色平衡,并递归向上更新分支节点哈希值为hash(lefthash,rigthhash,key);在最后一层分支节点根据如下4种情况插入该节点:情况1:如果该分支节点为空,该情况只在merkleroot为空时出现,则对交易进行sha256双哈希操作,得到其哈希值hash(tx),然后新建一个分支节点,并定义其关键值为key,左哈希为叶子结点哈希值,右哈希为0,形如(hash(tx),0,key);情况2:如果待插入数据key值小于该节点nodekey值,应将该数据插入到该节点左侧;首先对交易进行sha256双哈希操作,得到其哈希值hash(tx),然后新建一个红色的分支节点,其关键字为待插入节点key,左哈希为hash(tx),右哈希为原来分支节点的左哈希,即(hash(tx),oldlefthash,key);记hash=hash(hash(tx),oldlefthash,key),则更新父节点为(hash,oldrighthash,oldkey);情况3:如果待插入数据key值大于该节点nodekey值,而且该节点右哈希为0,则对交易进行sha256双哈希操作,得到其哈希值hash(tx),然后更新该分支节点为(oldlefthash,hash(tx),oldkey);情况4:如果待插入数据key值大于该节点nodekey值而且该节点右哈希不为0,则先对交易进行sha256双哈希操作,得到其哈希值hash(tx),然后新建红色分支节点,分支节点关键值为待插入数据key值与原分支节点右孩子key值中的较小者,左孩子为待插入数据与原分支节点右孩子中key值较小者,右孩子为较大者;最后更新其父节点右哈希为新建分支节点哈希;步骤3:将区块数据追加写入磁盘文件,具体包括:步骤3-1:将区块头以及区块体中保存交易原始数据的交易数组vtx[]序列化,顺序写入到磁盘文件blk000x中,并返回区块在磁盘中的位置nfile,blockpos;步骤3-2:生成每个交易的元数据txindex(nfile,blockpos,n),其中nfile指定第几个文件,blockpos指定该区块在文件中的偏移量,n指定交易对应在有序数组中的下标,并将每个交易的元数据信息存储到k-v数据库中,格式为k=hash(tx),v=(txindex);步骤3-3:将merklerbtree索引项存储在k-v数据库中,其中k=hash(lefthash,righthash,key),v=(lefthash,righthash,key);步骤4:根据关键字key查询交易,返回查询结果;从最新的区块开始查找交易,如果该区块没有查找到则查询其前一区块;在单个区块的查找方法为:从区块头的merkleroot进入到merklerbtree中,从merkleroot开始比较目标关键字key与当前节点关键字ckey,若key小于等于ckey,则查找其左孩子,并将右孩子和节点关键字压入到验证路径栈中,否则查找其右孩子,并将左孩子和节点关键字压入到验证路径栈中,依次执行直到叶子节点;如果叶子节点关键值key等于查询关键字key,则查询命中;根据最后在叶子节点查询到的交易哈希值hash(tx),以hash(tx)为k,在k-v数据库中查询到该交易对应在磁盘上的索引信息txindex,最后根据txindex在磁盘文件中读取到交易信息tx;最后将验证路径栈和交易原信息返回给普通用户;步骤5:普通用户对查询结果进行可信性验证;普通用户收到验证路径栈和交易信息之后,首先对交易进行sha256双哈希操作得到交易哈希值hash(tx),然后与验证路径栈中弹出的值做sha256双哈希操作,得到的哈希值继续与栈中弹出的下一个值做哈希,直到栈为空;比较得到的哈希值与本地区块头中的merkleroot值是否相等,如果相等则数据可信,否则不可信。采用上述技术方案所产生的有益效果在于:本发明提供的一种在区块链数据库上针对关键字key的索引方法,可以直接根据数据关键字进行索引,而不是现有区块链中根据哈希值进行索引,实现了数据的可查询性;将传统区块链中的交易结构扩展到可以存储类似于传统数据库的模式结构,提高了适用性;根据数字签名技术管理数据权限,提高了数据安全性;可以根据merklerbtree自我感知索引是否被篡改,根据交易哈希感知交易是否被篡改,从而保证了数据的不可篡改性;同时实现了轻量级节点的数据验证功能,使得查询端能够有效检测数据可信性。附图说明图1为本发明实施例提供的交易结构图;图2为本发明实施例提供的区块结构图;图3为本发明实施例提供的merklerbtree结构图;图4为本发明实施例提供的数据插入规则示例图,其中,(a)为情况1的空节点插入结果,(b)为情况2的左侧插入结果,(c)为情况3的右孩子为空时的右侧插入结果,(d)为情况4的右孩子不为空时的右侧插入结果。具体实施方式下面结合附图和实施例,对本发明的具体实施方式作进一步详细描述。以下实施例用于说明本发明,但不用来限制本发明的范围。本发明设计的区块链技术术语的解释如下:哈希指针:一个数据项的哈希指针指的是将该数据项的内容做哈希操作后得到固定长度的哈希值,同时以该哈希值为key,该数据项的内容为value,将此k-v对存储于k-v数据库,则该key即为该数据项的哈希指针;交易:如图1所示,为交易结构图,交易分为交易头(transaction)和模式(schema)两部分,交易头包含:版本号(version)、父交易哈希(prehash)、交易时间(ntime)、交易下一拥有者公钥(scriptpubk)、证明本交易有效的签名(scriptsig);模式部分类似于传统数据库中的表结构,包含关键字key,以及各个字段(field);区块链:区块链就是一个个的区块根据哈希指针首尾相连,每一个区块一旦形成便不可改变;如图2所示,为区块结构图,区块分为区块头和区块体两部分,区块头包括:版本号、前一区块哈希指针(由前一区块头数据哈希得到)、区块形成时的时间戳、区块体中交易自下而上哈希得到的merkle根以及用于工作量证明的随机数和目标哈希;区块体中保存着区块中的所有交易记录;区块链数据库:数据库中有多条区块链,每一条区块链相当于传统数据库中的一张表,所有的中心机构充当数据的存储节点,所有的存储节点根据共识算法生成区块链,所有节点(包括用户)存储区块头信息,可以由区块头信息检索到记录并验证记录正确性;merklerbtree:将merkle树与红黑树进行结合,用于索引区块体中的交易数据;如图3所示,为merklerbtree结构图,每个节点都存有关键字信息,从根节点开始,关键值小于等于该节点关键字的数据存储于左子树,大于该节点关键字的数据存储于右子树;叶子节点存储交易数据的哈希指针,非叶子结点值由其左右孩子节点两两哈希得到。针对已有区块链数据库中只能对交易哈希值查询、无法存储一般数据结构的不足,本发明提供一种在区块链数据库上针对关键字key的索引方法,具体步骤如下所述。步骤1、生成交易记录。用户输入数据是类似于传统sql数据库中的schema数据,本步骤的目的是生成区块链机制运行所需要的额外信息。步骤1-1、生成默认信息。生成区块链版本号信息,以及数据创建时刻的时间戳信息。步骤1-2、生成前驱信息。在本发明中,对于拥有相同关键字key的数据,始终认为只有最新的数据是有效的,而旧的数据被认为是新数据的前驱,所以对于相同关键字的数据在逻辑上首尾相连生成一个链式结构。当写入关键字为key的数据时,要指定该数据对象的前驱,如果没有前驱,则前驱置为null。步骤1-3、生成数据权限信息以及数据签名。在本发明中,写入数据库中的数据不可删除,数据修改是通过重新写入一条相同关键字的数据项来实现。数据的权限信息指的是,本交易数据的创建者可以指定对该数据进行修改所需要满足的条件。在这里引入了ecdsa算法,指定可以对该数据项进行修改的下一公钥,并将其赋值给scriptpubk。最后本数据创建者利用其私钥对该交易进行签名,用于后续证明本数据创建者拥有对该数据进行修改的权限。步骤2、将交易打包到区块中。步骤2-1、验证交易正确性。交易的正确性验证主要验证交易的格式以及数据权限信息。格式验证去除无法识别的交易,保证系统安全。交易的权限验证引入了ecdsa算法,交易中的sicrippubk为下一权限拥有者公钥,scriptsig为本交易创建者生成的数字签名信息。权限验证是通过verify()函数验证本交易的scriptsig是否与其前驱交易的scriptpubk相匹配,如果匹配则证明本交易的创建者拥有其前驱交易所要求的私钥,可以对本交易的前驱进行修改,如果不匹配则没有相关的权限,本交易无效。步骤2-2、检测双花。数据权限验证保证只有拥有对应的私钥,才能进行对交易前驱的修改,但是当交易的拥有者将权限转移给下一后继之后,其仍然可以将本交易的权限转移给其他后继者,并且对本交易进行修改,从而造成了数据不一致性,称这一现象为双花。存储节点收到交易记录之后,读取交易的prehash字段,根据prehash值到k-v数据库中检索前驱交易索引txindex,如果该索引指明前驱交易的后继交易不为空,则表明待验证交易为双花交易,判定其无效。如果其后继交易为空,则将后继交易赋值为待验证交易的哈希值,待验证交易有效。如果交易的prehash字段为空,即交易的创建者认为之前不存在与此交易关键字key相同的交易,此时的双花验证则是查找系统中是否能够检索到关键字为key的交易,如果检索到则待验证交易无效,如果未检索到则该交易有效。步骤2-3、更新区块索引。当交易被验证有效之后,将其原始数据tx存储到key有序的数组vtx[]中,对tx进行双sha256哈希操作,得到交易的存储关键字key=hash(tx),将该存储关键字插入到merklerbtree中。merklrrbtree为红黑树与merkle树的结合,每一个节点都是一个k-v对,其中k=hash(val),v=(hashleft,hashright,key)。从根节点开始插入数据,比较待插入节点关键字key和merkleroot节点关键字nodekey,如果key<=nodekey则插入到其左子树,否则插入到其右子树,直到最后一层分支节点。插入交易之后,对该树进行旋转使其保证黑色平衡,并递归向上更新分支节点哈希值为hash(1efthash,rigthhash,key)。在最后一层分支节点根据如下4种情况插入该节点:情况1:如果该分支节点为空(只在merkleroot为空时出现),对交易进行sha256双哈希操作,得到其哈希值hash(tx),然后新建一个分支节点,并定义其关键值为key,左哈希为叶子结点哈希值,右哈希为0,形如(hash(tx),0,key),插入结果如图4(a)所示。这也说明了一棵树只要不为空,则其分支节点一定不为空,而且最后一层分支节点的key值一定与其左孩子key值相同。情况2:如果待插入数据key值小于该节点nodekey值,我们应该将该数据插入到该节点左侧,但是由情况1可知,该节点左孩子一定不为空,而且是叶子结点。首先对交易进行sha256双哈希操作,得到其哈希值hash(tx),然后新建一个红色的分支节点,其关键字为待插入节点key,左哈希为hash(tx),右哈希为原来分支节点的左哈希,即(hash(tx),oldlefthash,key)。记hash=hash(hash(tx),oldlefthash,key),则更新父节点为(hash,oldrighthash,oldkey),插入结果如图4(b)所示。情况3:如果待插入数据key值大于该节点nodekey值,而且该节点右哈希为0,则对交易进行sha256双哈希操作,得到其哈希值hash(tx),然后更新该分支节点为(oldlefthash,hash(tx),oldkey),插入结果如图4(c)所示。情况4:如果待插入数据key值大于该节点nodekey值而且该节点右哈希不为0。则先对交易进行sha256双哈希操作,得到其哈希值hash(tx),然后新建红色分支节点,分支节点关键值为待插入数据key值与原分支节点右孩子key值中的较小者,左孩子为待插入数据与原分支节点右孩子中key值较小者,右孩子为较大者;最后更新其父节点右哈希为新建分支节点哈希,插入结果如图4(d)所示。步骤3、将区块数据追加写入磁盘文件。数据写入是以区块为单位进行的,当区块中交易数量达到固定阈值,则将区块中的数据写入到磁盘上。首先将区块头以及区块体中保存交易原始数据的交易数组vtx[]顺序写入到磁盘文件blk000x中。区块体中建立的merklerbtree则存储到k-v数据库中。同时生成blockindex存储区块的元数据,用来检索区块;生成txindex保存交易的存储位置。步骤4、数据查找。根据数据关键字key来查询交易,所有的区块首尾相连,从最新的区块开始根据key查找。在单个区块内,从区块头的merkleroot进入到merklerbtree中,从merkleroot开始比较目标关键字key与当前节点关键字ckey,若key小于等于ckey,则查找其左孩子,否则查找其右孩子,依次执行直到叶子节点,对于n个节点的区块中查询时间复杂度为o(lgn)。如果交易在本区块中,则最后在叶子节点会查询到交易哈希值hash(tx),以hash(tx)为k,可以在k-v数据库中查询到该交易对应在磁盘上的索引信息txindex,最后根据txindex在磁盘文件中读取到交易信息tx。如果交易不在本区块中,则按照同一方法在其前驱区块中查找。本发明中数据的不可篡改性体现在以下几个方面:(1)从key获得hash(tx)的过程中,根据merklerbtree从根节点向下检索,因为该树在生成时是由叶子节点哈希得来,所以一定能够最终检索到叶子节点,如果在途中查询不到某一分支节点,则说明是上一分支节点数据被篡改或者下一节点数据丢失;(2)从hash(tx)获得tx的过程中,因为hash(tx)是tx经由hash运算得来,所以可以根据hash(tx)检测交易tx是否被篡改。步骤5、数据验证。轻量级节点只存储区块头信息,存储节点存储区块头和区块体。当轻量级节点查询数据时,存储节点返回查询结果以及验证路径。轻量级节点收到数据时,从查询结果开始往上两两哈希,最终生成验证merkleroot,通过比对该merkleroot是否与本地保存的区块头中的merkleroot一致来验证查询结果是否有效。下面根据具体实施例进一步说明本发明提供的区块链数据索引方法。表1为用户想要存储到区块链数据库中的数据。表1要存储到区块链数据库中的数据keynamesexaccount1600005bobmale70001600004alicefemale60001600007tommale50001600006jackmale8000本实施例主要演示数据在merklerbtree中的索引过程,故省略了交易prehash、pubkey和scriptsig等控制信息。假设当前区块为空,上述表1中的四条交易先后到来,存储节点依次将交易打包到区块中。当节点接收到第1条交易,此时merkleroot为空,按照本实施例步骤2-3中情况1所述,首先将该交易进行双sha256哈希操作,得到交易的哈希值为747d51d1007b4fb1be01aeb633e78f66cbdeae393aaa200e73627498b2551df(为便于书写后续只显示其前8位),然后生成分支节点,以交易哈希值为其左哈希,右哈希为0,结点关键字key为1600005,生成merklerbtree索引项如表2所示,其中k=hash(v)。表2第1条交易时生成merklerbtree索引项当节点再插入第2条交易时,此时merkleroot节点关键字为1600005,待插入交易关键字为1600004,小于根节点关键字,此时应该插入到左子树,又因为merkleroot为左侧最后一层分支节点(索引项表中不存在k=747d51d1的表项),此时情况与步骤2-3中情况2相符,则操作步骤为:先将交易2进行sha256双哈希操作,得到交易哈希值为dcaa0e32,新生成分支节点,其左哈希为dcaa0e32,右哈希为父节点左哈希747d51d1,关键字为1600004;之后向上更新父节点,父节点左哈希为新生成分支节点哈希,父节点k也相应改变,更新之后merklerbtree索引项如表3所示。表3插入第2条交易后merklerbtree索引项当节点插入第3条交易时,merkleroot关键字为1600005,待插入节点关键字为1600007,大于merkleroot关键字,则应该插入到其右子树,又因为此时merkleroot本身为右侧最后一层分支节点,此时情况与步骤2-3中情况3相符,则后续步骤为:将交易进行sha256双哈希操作,得到交易哈希值为b178577f,更新merkleroot右哈希为b178577f,继而merkleroot的k相应改变,最后merklerbtree索引项如表4所示。表4插入第3条交易后merklerbtree索引项虽然在插入关键字为1600007的交易之后,索引表中没有key=1600007的记录,但是在查询时,1600007>1600005,所以查找其右哈希b178577f,而b178577f正是key=1600007所对应的交易哈希,即1600005的右哈希记录了key>1600005的记录(1600007)。当节点插入第4条交易时,merkleroot关键字为1600005,待插入节点关键字为1600006,大于merkleroot关键字,应当插入右子树,又merkleroot为右侧最后一层分支节点,与步骤2-3情况4相符,之后操作为:将交易进行哈希操作,得到交易哈希值为228de82e,新生成分支节点,节点左哈希为228de82e,右哈希为b178577f,节点关键字为1600006,之后向上更新父节点右哈希为该分支节点哈希,最后更新merkleroot的k值。更新之后的merklerbtree索引项如表5所示。表5插入第4条交易后merklerbtree索引项假设此时区块大小达到阈值(实际上每个区块有上千个交易),开始准备存入磁盘。此时区块头中的merkleroot值对应为d90f7e2e,区块体中的交易数组为表1中的交易原始数据,merklerbtree索引项直接写入k-v数据库。首先将区块头和区块体中的交易数组数据序列化,顺序追加到磁盘文件blk0001.dat中,返回区块在磁盘偏移量为nfile=1,blockpos=8,随后生成每个交易的元数据txindex(nfile,blockpos,n,nexthash),其中nfile指定第几个文件,blockpos指定该区块在文件中的偏移量,n指定交易对应在有序数组中的下标,nexthash指定交易后继(用于检测双花在此省略)最后将每个交易的元数据信息存储到k-v数据库中,元数据如表6所示。表6每个交易的元数据信息txhashnfileblockposndcaa0e32180eaf1e7ec181228de82e182b178577f183为方便说明问题,将各个交易的哈希值罗列如下:表7各个交易的哈希值txhashkeynamesexaccountdcaa0e321600004alicefemale6000eaf1e7ec1600005bobmale7000228de82e1600006jackmale8000b178577f1600007tommale5000当查询关键字为160006的交易时,首先根据区块头的merkleroot值d90f7e2e,到k-v数据库中检索到merkleroot值为(baa9d30a,be149016,1600005),1600006>1600005,故在k-v数据库中检索k=be149016,得到merklerbtree索引值为(228de82e,b178577f,1600006),1600006=1600006,故在k-v数据库中检索k=228de82e,得到交易元数据为(1,8,3),最后在磁盘文件中反序列化得到该交易原始数据为(1600006,jack,male,8000),同时验证路径为在查询时未命中的那侧的哈希值,在本实施例中即为((baa9d30a,1600005),(b178577f,1600006)),最后返回给轻量级节点的结果为((baa9d30a,1600005),(b178577f,1600006),(1600006,jack,male,8000)),轻量级节点通过验证hash(baa9d30a,hash(hash(1600006,jack,male,8000),b178577f,1600006),1600005)的值是否与本地的merkleroot值相等来验证查询结果的可信性。最后应说明的是:以上实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述实施例所记载的技术方案进行修改,或者对其中部分或者全部技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明权利要求所限定的范围。当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1