在区块链系统中退出跨片事务的方法及装置与流程

文档序号:26278049发布日期:2021-08-13 19:34阅读:117来源:国知局
在区块链系统中退出跨片事务的方法及装置与流程
本说明书一个或多个实施例涉及区块链
技术领域
,尤其涉及在区块链系统中退出跨片事务的方法及装置。
背景技术
:区块链(blockchain)是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。区块链是按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构,并以密码学方式保证的不可篡改和不可伪造的分布式账本。由于区块链具有去中心化、信息不可篡改、自治性等特性,区块链也受到人们越来越多的重视和应用区块链分片技术是一种用于对区块链进行扩容的方案。区块链分片的基本思路是将区块链网络中的节点分成若干个相对独立的子网络,每个子网络构成一个区块链,一个子网络也就是一个分片(shard)。通过多个分片的并行处理,可提升整个网络的吞吐量。在申请公布号为cn112579261a的专利“退出跨片事务的方法和系统、主链节点和目标分片节点”中,公开了一种包含分片的区块链系统中退出跨片事务的方法,该区块链系统中至少包括两个分片,不同分片中的节点存储不同的状态集合;所述区块链系统还包括主链;所述方法包括,目标分片在本地提交跨片事务相关的操作发生异常,或者等待跨片事务相关的消息发生超时:目标分片在本地撤回发生异常/超时的跨片事务操作,并针对所述跨片事务产生需要由对应源分片执行的退出指令,并将所述跨片事务退出指令发送至主链;主链生成主链区块的过程中,将接收到的需要由源分片执行的跨片事务退出指令填入主链区块的区块体中;所述主链将所述需要源分片执行的跨片事务退出指令按照源分片的标识发送至对应的源分片中;所述源分片生成源分片区块的过程中,将接收到所述主链发来的跨片事务填入所述源分片区块的区块体中,并执行所述跨片事务退出指令。然而,该专利中所限定的退出跨片事务的技术方案中,需要消耗较长的时间来完成退出跨片事务。技术实现要素:本说明书一个或多个实施例中提供了一种在区块链系统中退出跨片事务的方法及装置,可减少分片间的交互操作,节省退出跨片事务的时间。第一方面,提供了一种在区块链系统中退出跨片事务的方法,所述方法包括:根据跨片事务对应的退出时间信息确定是否退出所述跨片事务;在确定退出所述跨片事务的情况下,指示所述跨片事务对应的源分片和目标分片退出所述跨片事务。第二方面,提供了了一种在区块链系统中退出跨片事务的装置,所述装置包括:确定单元,配置为根据跨片事务对应的退出时间信息确定是否退出所述跨片事务;指示单元,配置为在确定退出所述跨片事务的情况下,指示所述跨片事务对应的源分片和目标分片退出所述跨片事务。第三方面,提供了一种计算机可读存储介质,其上存储有计算机程序/指令,当所述计算机程序/指令在计算设备中执行时,计算设备执行如第一方面中所述的方法。第四方面,提供了一种计算设备,包括存储器和处理器,所述存储器中存储有计算机程序/指令,所述处理器执行所述可计算机程序/指令,实现如第一方面中所述的方法。通过本说明书一个或多个实施例中提供的方法及装置,根据跨片事务对应的退出时间信息确定退出所述跨片事务时,直接指示跨片事务对应的源分片和目标分片退出跨片事务,可减少了分片间的交互操作,节省退出跨片事务的时间。附图说明为了更清楚地说明本说明书实施例的技术方案,下面将对实施例描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其它的附图。图1为本说明书实施例中提供的一种区块链系统架构示意图;图2为本说明书实施例中提供的一种区块链系统分片架构的示意图;图3为本说明书实施例中提供的一种区块链数据存储的结构示意图;图4为本说明书实施例中提供的一个简化版的状态树示意图;图5为本说明书实施例中提供的一种区块链状态树的存储结构;图6为本说明书实施例中提供的一致性哈希的原理示意图;图7为本说明书实施例中提供的一种基于主链的区块链分片系统示意图;图8为本说明书实施例中提供的一种在包含分片的区块链系统中执行跨片事务的方法的流程图;图9为本说明书实施例中提供的一种在区块链系统中退出跨片事务的方法的流程图;图10为本说明书实施例中提供的一种退出跨片事务的过程示意图;图11为本说明书实施例中提供的一种在区块链系统中退出跨片事务的装置的示意图。具体实施方式为了使本
技术领域
的人员更好地理解本说明书中的技术方案,下面将结合本说明书实施例中的附图,对本说明书实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本说明书的一部分实施例,而不是全部的实施例。基于本说明书中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都应当属于本说明书保护的范围。目前限制区块链技术大规模落地应用的一个很重要因素是性能,即吞吐量,这个吞吐量一般可以通过每秒交易笔数(transactionpersecond,tps)来度量。开发者们提出了各种各样的方案来尝试提升区块的吞吐量,这一过程称为“扩容”。从扩容采用技术的方向上来说,可以分为链上扩容和链下扩容两个方向。链上扩容通常包括扩块、隔离见证、分片、共识层改进这些方案。链下扩容通常包括状态通道、侧链、链下计算这些方案。分片技术是属于链上扩容的一种方案。分片概念源于数据库领域,本意是指数据库中数据的水平分区(将表的不同行分到不同的分区),每个分片都保存在一个单独的数据库服务器实例上,以分散负载。区块链分片的基本思路是将区块链网络中的节点分成若干个相对独立的子网络,每个子网络中包含一部分节点,一个子网络也就是一个分片(shard)。单个分片处理规模较小的事务,甚至只存储部分网络状态,多个分片并行处理事务,理论上整个网络的吞吐量将会提升。分片技术根据不同的分片机制可以划分为三种:网络分片(networksharding),交易分片(transactionsharding),状态分片(statesharding)。网络分片是最基础的一种分片方式,包括将整个区块链网络划分成多个子网络,也就是多个分片。这样,区块链网络中的多个分片可以并行处理网络中不同的交易。交易分片是将交易按某种规则分配到不同分片,其思路为按一定规则将交易分配到同一个分片处理,这样既能够达到并行处理的目的又能避免双花问题。交易分片的前提是先进行网络分片。在所有的分片机制当中,状态分片是最具挑战的分片方式。状态分片的关键是将整个存储区分开,让不同的分片存储不同的部分,每个节点只负责存储自己的分片数据,而不是存储完整的区块链状态。状态分片能够解决存储能力瓶颈问题。一些区块链系统架构如图1所示。如图1中,一个区块链系统例如包含a、b、c、d、e、f、g、h、i、j、k、l、m、n、o、p共16个全量节点。节点之间的连线示意性的表示p2p(peertopeer,点对点)连接。这些节点上都存储全量的账本,即承担着存储全部交易、智能合约和各种状态。随着区块链业务的增长,单个节点存储的数据量也会越来越大,有的达到t数量级(1tb=1024gb),甚至到达p或e的数量级(1pb=1024tb,1eb=1024pb)。为了支撑区块链系统的运行和应对业务的持续,对于每一个节点都需要寻求扩容(获得更大的存储空间)而进行巨大的花费。基于此,本说明书实施例中提供了如图2所示的一种区块链系统。该区块链系统包括主链25、分片1、分片2、分片3和分片4。区块链系统中的节点进行分片后比如图2所示,分为4个分片。每个分片包括4个节点。每个分片内的节点之间的连线表示p2p连接,各个分片通过主链25相互连接,即主链25为区块链系统中的所有分片提供服务。本实施例是为了便于举例而示意性的列举4个分片,每个分片包括4个节点。实际上,每个分片中节点的数量可以不同。为了说明本申请中的状态分片方法,先介绍本申请涉及的区块链状态存储结构。鉴于很多区块链平台和应用是基于以太坊(ethereum)的底层技术而构建的,这里先介绍以太坊的状态存储结构。当然,基于其他区块链技术构建的区块链系统,也可能适用于本申请的核心内容,例如基于fabric的超级账本(hyperledger)和企业操作系统(enterpriseoperatingsystem,eos)、quorum、corda等,不再赘述。以太坊相比于比特币网络进行了拓展,采用账户系统和世界状态,可以直接用账户来显示的记录账户的余额和状态。以太坊的账户可以分为两种类型:外部账户(externallyownedaccount):用户的账户,例如以太币拥有者账户。合约账户(contractaccount):存储执行的智能合约代码以及智能合约代码中状态的值,通常只能通过外部账户调用激活。外部账户和合约账户的设计,实际上是账户地址到账户状态的映射。账户的状态通常包括nonce、balance、storage_root、codehash等字段。nonce、balance在外部账户和合约账户中都存在。codehash和storage_root属性一般仅在合约账户上有效。nonce:计数器。对于外部账户,这个数字代表从账户地址发送的交易数量;对于合约账户,是账户创建的合约数量。balance:这个地址拥有的以太币的数量。storage_root:一个mpt树根节点的哈希,这个mpt树对合约账户的状态变量的存储进行组织。codehash:智能合约代码的哈希值。对于合约账户,这是智能合约被哈希计算并存储的代码;对于外部账户,由于不包括智能合约,因此codehash字段一般可以是空字符串/全0字符串。mpt全称为merklepatriciatree,是结合了merkletree(默克尔树)和patriciatree(压缩前缀树,一种更节省空间的trie树,字典树)的一种树形结构。merkletree,默克尔树算法对每个交易都计算一个hash值,然后两两连接再次计算hash,一直到最顶层的merkle根。以太坊中采用改进的mpt树,例如是16叉树的结构,通常也简称为mpt树。以太坊mpt树的数据结构包括状态树(statetrie)。状态树中包含以太坊网络中每个账户所对应的存储内容的键值对(keyandvaluepair)。状态树中的“键”可以是一个的160bits标识符(以太坊账户的地址),这个账户地址分布于从状态树的根节点开始到叶子节点的存储中。状态树中的“值”是通过对以太坊账户的信息进行编码(使用递归长度字典编码(recursive-lengthprefixencoding,rlp)方法)生成的。如前所述,对于外部账户来说,值包括nonce和balance;对于合约账户来说,值包括nonce、balance、codehash和storage_root。合约账户用于存储智能合约相关的状态。智能合约在区块链上完成部署后,会产生一个对应的合约账户。这个合约账户一般会具有一些状态,这些状态由智能合约中状态变量所定义并在智能合约创建、执行时产生新的值。所述的智能合约通常是指在区块链环境中以数字形式定义的能够自动执行条款的合约。一旦某个事件触发合约中的条款(满足执行条件),代码即可以自动执行。在区块链中,合约的相关状态保存在存储树(storagetrie)中,存储树根节点的hash值即存储于上述storage_root中,从而将该合约的所有状态通过hash锁定到该合约账户下。存储树也是一个mpt树形结构,存储了状态地址到状态值的key-value映射。从存储树的根节点到叶子节点存储有一个状态的地址,一个叶子节点中存储一个状态的值。图3是一个区块链数据存储的结构示意图。由图3所示的一些的区块链数据存储中,每一区块的区块头包括若干字段,例如上一区块哈希previous_hash(图中的prevhash,或称为父hash),随机数nonce(在一些区块链系统中这个nonce不是随机数,或者在一些区块链系统中不启用区块头中的nonce),时间戳timestamp,区块号blocknum,状态根哈希state_root,交易根哈希transaction_root,收据根哈希receipt_root等。其中,下一区块(如区块n+1)的区块头中的prevhash指向上一区块(如区块n),即为上一区块的hash值。通过这种方式,区块链上通过区块头实现了下一区块对上一区块的锁定。特别的,如前所述,state_root是当前区块中所有账户的状态组成的mpt树的根的哈希值,即指向state_root的为一棵mpt形式的状态树。这个mpt树的根节点可以为一个扩展节点(extensionnode)或一个分支节点(branchnode),state_root中存储的一般为这个根节点的hash值。从这个mpt的根节点到叶子节点中每个节点的一部分值按照顺序串联起来可以构成账户地址并作为key,叶子节点中存储的账户信息为这个账户地址对应的value,这样,构成了key-value键值对。具体的,这个key可以是sha3(address),即账户地址的hash值(hash算法例如采用sha3算法),其存储的值value可以为rlp(account),即账户信息的rlp编码。其中账户信息是[nonce,balance,storage_root,codehash]构成的四元组。如前所述,对于外部账户来说,一般只有nonce和balance两项,而storage_root、codehash字段默认存储空字符串/全0字符串。也就是说,外部账户不存储合约,也不存储合约执行后的产生的状态变量。合约账户一般包括nonce,balance,storage_root,codehash。其中nonce是同一账户的交易计数器;balance是账户余额;storage_root对应另外一个mpt,通过storage_root能链接到合约相关的状态的信息;codehash是合约代码的hash值。不论是外部账户还是合约账户,其账户信息一般都位于一个单独的叶子节点(leafnode)中。从根节点的扩展节点/分支节点到每个账户的叶子节点,可能中间会经过若干个分支节点以及扩展节点。状态树可以是mpt形式的树,一般是16叉树,每一层最多可以有16个孩子节点,而最多可以有64层的深度。对于扩展节点,用于存储共同前缀,其一般有1个孩子节点,这个孩子节点可以是分支节点。对于分支节点,其最多可以有16个孩子节点,其中可能包括扩展节点和/或叶子节点。这样的mpt树最多可以有64层的深度。当区块链中的账户数量达到一定数量时,这棵mpt树可能接近或达到64层的深度。其中,对于状态树中的一个合约账户来说,其storage_root指向另一棵同为mpt形式的树,其中存储了合约执行涉及的状态变量(statevariable)的数据。这个storage_root指向的mpt形式的树为存储树,即存储树的根节点的hash值。一般的,这个存储树存储的也是key-value键值对。从根节点到叶子节点的路径上存储的一部分数据连起来构成key,叶子节点中存储value。前面提到,这个存储树也可以是mpt形式的树,一般也是16叉树,即对于分支节点,其最多可以有16个孩子节点,其中可能包括扩展节点和/或叶子节点。而对于扩展节点,其一般可以有1个孩子节点,其可以是分支节点。这棵存储树最多可以有64层的深度。智能合约中,例如通过以太坊提供的solidity高级开发语言中,可以定义的状态变量包括两种类型,一种是基本数据类型的状态变量,另一种是映射(map或mapping)类型的状态变量。以下是一个用solidity编写的智能合约的代码的片段:contractdemo{inta;intx;mapping(address=>int)publicbalancea;functionmyfunc()public{a=8;x=9;balancea[123]=100;}}其中,整形变量a、x都属于基本数据类型,在myfunc函数中,a赋值为8,x赋值为9。map类型数据结构中,上面代码中定义了外部账户地址到一种资产类型的余额(balancea,不同于外部账户中的balance和合约账户中的balance)的映射,即地址address→balancea的映射。在myfunc函数中,例如为外部账户的地址123初始化对应的balancea为100。以太坊和其它区块链系统中,例如可以在智能合约中按照erc20标准创建新的数字资产,当然也可以是按照其他方式自定义的数字资产。例如上述的balancea即可以为按照erc20标准创建的一种数字资产。当然,在一个智能合约中,可以定义多个资产类型,例如balancea、balanceb、balancec、…。这个合约中的map可以为每个外部账户赋予持有和交易这种新创建的数字资产的能力。如上述代码的例子,一般的,每个外部账户都可以对应一个balancea类型的资产。那么,如果区块链的状态树中存在10000个外部账户,则通过智能合约,每个外部账户可以对应持有/交易balancea类型的资产,即存在10000个“外部账户→balancea”的映射。需要说明的是,这里的资产是广义的,还可以是余额外的其它内容。例如在区块链电子发票的场景中,资产可以定义为发票的代码集合,这个集合例如为balancep。这样,在“外部账户→balancep”的映射中,balancep中可以包括一组发票的代码集合。这个发票代码集合中可能会增加新的发票代码。上述的基本数据类型和map类型的状态变量,在存储树中都可以是以key-value键值对的形式存储。对于基本数据类型,key是合约中的状态变量声明的位置(从0开始计数)。对于map类型,key=sha3(map中的关键字,变量声明位置),也就是把map中的关键字和状态变量声明位置拼在一起成为一定长度(例如64字节)的字符串后计算hash值。value可以存储状态变量的实际值。在另一种实施方式中,两种类型的状态变量的key都可以取为变量名称的哈希值,通过这样设置,各个状态变量的key的长度相同,便于以树的形式存储。前面提到,如果区块链的状态树中存在10000个外部账户,则通过智能合约,每个外部账户可以对应持有/交易balancea类型的资产,即存在10000个外部账户→balancea的映射。具体的,该合约账户下,存储树中可以存储这些map的值。如上所述,具体是通过key-value的方式存储在存储树中。类似的,这个存储树也可以是mpt形式的树,一般也是16叉树,每一层最多可以有16个孩子节点,最多可以有64层的深度。从这个mpt的根节点到叶子节点中存储的一部分数据连起来可以作为key,叶子节点中存储的信息为这个key对应的value。这样,就构成了key-value键值对。当区块链中的外部账户的数量达到一定量时,状态树的深度可能接近或达到64层的深度。类似的,合约中map类型的状态变量的数量也可能达到相同的量,这时存储树也接近或达到64层的深度。此外,对于一个智能合约来说,合约中基本数据类型的变量不会太多,一般不会超过32个。这样,当外部账户的数量较大时,加上合约中基本数据类型的变量,合约中的状态变量的总数与外部账户基本是差不多的。图4是一个简化版的状态树示意图。区块链系统中存在若干外部账户,例如图4中分别编号的外部账户1、外部账户2,…。此外,区块链系统中存在若干合约账户,例如图4中的分别编号的合约账户1,合约账户2,…。这些外部账户和合约账户及其信息内容例如通过mpt树的形式组织,构成状态树。区块头中的state_root存储这个mpt树的根节点的hash值。图4中以节点1、节点2、节点3共三个节点来示意性的表示mpt树的形式,具体的,可以表示mpt树中的扩展节点、分支节点。外部账户可以通过创建合约的交易在区块链上部署智能合约。此外,智能合约也可以是原生合约,即融合在区块链平台的代码中,与区块链平台代码一同编译后完成部署。不论是哪种形式部署的智能合约,在合约创建后,区块链上出现一个与该智能合约对应的合约账户,并拥有一个特定的地址,合约代码和账户存储将保存在该合约账户中。智能合约的账户存储保存了这个合约的状态。合约创建之后,外部账户可以调用创建的智能合约,也可以是外部账户通过智能合约来调用智能合约(也可以通过1个或多个智能合约来调用智能合约)。被调用的智能合约,将产生的状态变量以key-value的形式写入该智能合约的账户存储中,如图4所示。这些key-value,可以组织成mpt树的形式,构成存储树。存储树中,key-value除了包括基本数据类型的状态变量外,还可以包括map类型的状态变量。一般的,一个合约中不超过32个基本类型的状态变量,即一般一个存储树中包括不超过32个key-value来对应基本类型的状态变量的存储。一个合约中,map类型的状态变量一般与外部账户对应。存在n个外部账户的情况下,一个合约中一般存在对应的n个key-value来对应map类型的状态变量的存储。合约账户中的map类型的状态变量的数量一般与外部账户对应,此外,合约账户中还包括基本类型的状态变量。当外部账户的数量比较多时,合约账户中的map类型的状态变量的数量也很多。状态树实际上包括了两层mpt结构,每一层最大深度是64层。对于区块链系统中大量的合约操作,都要涉及合约的状态变量。这样,在现有的账户体系结构中,虽然建立了外部账户和合约账户,但是操作的热点将集中于合约账户中的状态变量,而关于外部账户的操作却很少。这就形成了单账户热点。单账户热点导致合约账户存储的负载压力比较大,将限制和影响区块链系统的性能。本说明书实施例提供一种区块链状态树的存储结构。以图5为例加以说明。区块头中的state_root存储整个状态树的根节点的hash值。第一层树形结构的叶子节点可以用来存储外部账户存储和合约账户存储的根hash值。外部账户和合约账户可以分别有若干个。如图5中的外部账户(例如外部账户1或外部账户2)所示,第二层为合约存储树(schematicstoragetrie)。具体的,第二层树形结构的根节点为外部账户涉及的智能合约的存储的hash值。类似的,第二层可以通过一个以节点1、节点2、节点3共三个节点来示意性的表示mpt树的形式,具体的,可以表示mpt树中的扩展节点、分支节点。第二层的存储可以包括一个或多个智能合约,即可以有多个叶子节点。第二层的每个叶子节点可以用来存储该外部账户下涉及的一个智能合约的存储的根hash值,可以基于包括该外部账户涉及的合约id(contractid)、storage_root计算得到。第三层为存储树。具体的,第三层树形结构的根节点为外部账户涉及的智能合约中的状态变量的根hash值。类似的,第三层可以通过一个以节点1、节点2、节点3共三个节点来示意性的表示mpt树的形式,具体的,可以表示mpt树中的扩展节点、分支节点。第三层的每个叶子节点可以用来存储合约中的一个状态变量的value值。上述的三层树的结构,每棵树的根节点到叶子节点的路径上存储的一部分数据连起来可以构成key,叶子节点中可以存储value。这样,通过这样的存储模型,可以在每个外部账户下存储该外部账户涉及的每个智能合约中的状态变量的key-value。通过图5所示的外部账户的上述存储结构,实际上将原有的合约账户存储中涉及的该合约中所有状态变量按照关联的外部账户,分解到了对应的外部账户的存储中。例如,原有的合约账户存储中包括了该合约涉及的所有map类型的状态变量1、2、3、…10000,其中1-1000与外部账户1相关,1001-2000与外部账户2相关,以此类推。这样,将与外部账户1相关的map类型的状态变量1-1000,分解到了外部账户1的存储中;将与外部账户2相关的map类型的状态变量1001-2000,分解到了外部账户2的存储中,以此类推。除了map数据结构,还可以通过其它数据结构定义外部账户地址到一种资产类型的映射,这里并不限制。上述map类型的状态变量,与每个外部账户有关。这样,对于每个外部账户来说,这个map类型的状态变量是局部类型的状态变量。此外,智能合约中定义的基本数据类型,可能与每个外部账户都相关,而不仅仅是与一个外部账户相关。这样,基本数据类型的状态变量,属于全局类型的状态变量。以下说明全局类型状态变量的存储。如图5中的合约账户(合约账户1或合约账户2)所示,第一层叶子节点中每个合约账户的账户信息的根hash,可以基于包括该合约账户的nonce、balance、codehash以及该合约账户涉及的智能合约的存储的根hash值计算得到。所述智能合约的存储的根hash值如图5中合约账户2的storage_root。类似的,第二层可以通过一个以节点1、节点2、节点3共三个节点来示意性的表示mpt树的形式。第二层的每个叶子节点可以用来存储该合约账户下涉及的一个全局类型的状态变量。如前所述,这个合约账户涉及的状态变量,可以是基本数据类型,也可以是合约账户中的状态变量。具体的,该层树形结构的根节点为所述合约账户涉及的智能合约中全局类型的状态变量的根hash值。类似的,该层可以通过一个以节点1、节点2、节点3共三个节点来示意性的表示mpt树的形式,具体的,可以表示mpt树中的扩展节点、分支节点。第三层的每个叶子节点可以用来存储合约中的一个状态变量的value值。上述树的结构,每棵树的根节点到叶子节点的路径上存储的一部分数据连起来可以构成key,叶子节点中可以存储value。这样,通过这样的存储模型,可以存储该合约账户涉及的全局类型的状态变量的key-value。这样,对于区块链节点执行调用合约的交易,产生待存储的与所述区块链合约账户相关的状态,例如产生所述合约中基本数据类型的状态变量以及合约账户的状态变量的情况,可以将所述待存储的与所述区块链合约账户相关的状态存储到对应的区块链合约账户的状态存储中,即将所述待存储的合约中基本数据类型的状态变量以及合约账户的状态变量存储到对应的区块链合约账户的状态存储中。区块链合约账户的状态存储中通过树形结构存储所述区块链合约账户涉及的全局类型的状态变量的key-value的映射关系,具体与前述类似,不再赘述。在另一种方式中,在合约账户中,可以不再设置合约状态相关的存储(storage),而是设置一个独立于所述外部账户存储以及所述合约账户存储的全局状态存储。这样,可以将所述待存储的与所述区块链合约账户相关的状态存储到独立于所述外部账户存储以及所述合约账户存储的全局状态存储中,即将所述待存储的合约中基本数据类型的状态变量以及合约账户的状态变量存储到独立于所述外部账户存储以及所述合约账户存储的全局状态存储中。具体的,所述全局状态存储中,可以通过树形结构存储所述区块链合约账户相关的状态的key-value的映射关系,即将所述待存储的合约中基本数据类型的状态变量以及合约账户的状态变量通过树形结构存储到独立于所述外部账户存储以及所述合约账户存储的全局状态存储中。此外,还可以有第三种方式,即将所述待存储的合约账户的状态变量存储到对应的区块链合约账户的状态存储中,而将所述基本数据类型的状态变量存储到独立于所述外部账户存储以及所述合约账户存储的全局状态存储中。具体的,可以是在所述合约账户的状态存储中通过树形结构存储所述区块链合约账户的状态变量的key-value的映射关系,在所述全局状态存储中通过树形结构存储所述基本数据类型的状态变量的key-value的映射关系。上述的树形结构,可以采用16叉树。一般的,一个智能合约中的全局状态不超过32个状态变量。采用16叉树,可以采用两层树结构。则第二层树结构中,可以包括16*16=256个叶子节点,远大于32,因此可以满足一般的一个智能合约中可能包括的全局状态的数量。需要说明的是,本说明书提到的区块链节点,侧重逻辑节点的概念。也就是说,一个物理节点也可以从逻辑上划分为多个逻辑的节点。当然,本说明书中的区块链节点也可以适用于物理节点的情形。不同分片中的节点可以存储不同的外部账户集合的状态。例如,在区块链系统中创建账户时,可通过对账户的编号或标识对4取模确定该账户对应的分片。从而,对于分片1中的节点a、b、c、d,每个节点的状态存储外部账户1、5、9、13...,对于分片2中的节点e、f、g、h,每个节点的状态存储外部账户2、6、10、14...的状态;对于分片3中的节点i、j、k、l,每个节点的状态存储外部账户3、7、11、15...的状态;对于分片4中的节点m、n、o、p,每个节点的状态存储外部账户4、8、12、16...的状态。需要说明的是,不同分片对应的不同外部账户集合,这些集合之间可以有一定的交集。例如,分片2和分片3分别对应的两个外部账户集合{外部账户集合}分片2和{外部账户集合}分片3,两个集合之间可以没有交集的外部账户,也可以有一定交集的外部账户。除了上述取模的方式外,还可以采用分段的方式。例如,区块链系统中的外部账户包括id为1-4000的共4000个账户。可以分配分片1中的节点存储外部账户1-1000的状态,分片2中的节点存储外部账户1001-2000的状态,分片3中的节点存储外部账户2001-3000的状态,分片4中的节点存储外部账户3001-4000的状态。上述的取模或者分段,可以是针对外部账户的id划分,也可以是针对外部账户的地址划分,或者针对id或地址的hash值划分,等等,整体上根据账户的某个唯一标识划分即可,这里并不限制。这样,当区块链系统中产生新的注册用户时,可以根据该用户的诸如id、地址、id/地址的hash值确定该用户的外部账户的状态,包括执行合约所产生的与该外部账户相关的状态(如前述提到的map类型的key-value),相对固定的存储于某个分片的节点存储中。如果仅仅按照取模或者分段的方式,当需要增加或者减少分片时,都有可能会改变大多数账户存储与分片的映射关系,这样显然是不经济的,而且长时间的调整可能会造成大量与账户存储有关的操作的无法命中正确的分片及节点。考虑到这一点,除了上述取模、分段的方式外,还可以采用一致性哈希的方式将账户的状态存储分配到相应分片上。这种方式中,可以将分片shard映射到数值空间[0,2^32-1],映射规则可以是分片的标识之类,例如通过某种hash算法来进行映射。并且,可以将账户也映射到该数值空间[0,2^32-1],映射规则可以是账户的地址、注册地之类,例如通过同样的hash算法来进行映射。对于某个账户account,如果满足hash(shard)<=hash(account)的节点,选择hash(shard)最大的节点存放这个account。如果没有满足上述条件的shard,选择hash(shard)最小的shard存放该account,如图6中的示意。可以简单的解释为根据账户account的hash值将对应的状态分配至图6中的环的顺时针方向的第一个分片哈希值对应的分片中。采用一致性哈希方式进行分配,当分片发生变化时,仅有较少部分的外部账户相关的存储会发生变化,不至于使大多数的分片的存储进行调整,从而降低命中较低的问题。此外,还可以根据账户注册地将账户的状态存储分配到相应的分片上。所述的注册地可以包括用户注册账户时所连接的区块链节点,例如,用户注册账户时通过客户端连接至区块链节点e,节点e属于分片2,则注册生成的账户对应于分片2。另一些实施场景中,所述的注册地也可以为用户注册账户时所在的地理位置。例如一个用户在注册账户时其ip地址位于香港特别行政区,而区块链系统中有一个分片对应于相关特别行政区的区块链业务,例如分片4,则该用户注册的账户对应至分片4。因此,本说明书提供的另一个实施例中,所述预定的分片策略可以包括:根据账户的注册地确定账户所属的分片。该注册地包括用户注册账户时通过客户端连接至区块链节点所归属的分片,或者用户注册账户时其ip所在的地理位置,或者用户填写/选择的归属地。对于后者,根据用户注册账户时其ip所在的地理位置或用户填写/选择的归属地,可以将该账户的状态存储分配至相同/相近地理位置的分片上,或者将该账户的状态存储分配至系统指定的分片上。通过根据注册地来确定账户的所属分片的分片策略,可以将一些具有地域性的业务集中在同一个分片内处理,尽量将交易涉及新增、删除和修改的状态控制在单个分片内,可以有效减少跨分片的分布式事务,减少跨分片的消息交互以及事务处理,进而可以提高系统吞吐量和性能。例如在一个区块链电子发票的区块链场景中,假如对应中国的省份划分有不同的分片,如广东的用户账户注册到广东的分片中,浙江的用户账户注册到浙江的分片中。在实际应用中,广东的用户通常在广东进行消费,与广东的其他用户发生交易的可能性更大;而浙江的用户通常是在浙江进行消费,与浙江的其他用户发生交易的可能性更大。那么广东的用户多数情况下也是在广东省内开发票,类似的,浙江的用户也多数是在浙江省内开发票。这样,基于用户的账户的注册地来划分确定账户的分片,可以极大的减少跨分片交易,降低区块链系统的复杂度。此外,在另一个实施例中,本申请也提供一种按照业务关系配置账户的状态存储所属的分片。例如在区块链跨境汇款业务中,通过智能合约实现了跨境的转账交易,并且将链下资产锚定到链上发行的资产。通过客户端接入不同银行的账户,发生转账的交易对方可能不同。根据发生业务往来的频次和占比,可以将关联性大的账户的状态存储分配至同一分片。例如,区块链跨境汇款业务中,通过客户端接入银行1的账户a大部分转账发生在与通过客户端接入银行2的账户b之间,即账户a与账户b这两个账户的关联性较大,因此,可以将调用智能合约产生的与账户a和账户b相关的状态存储分配至相同的分片中。当然,上述提到的不同的分配方式中,可以根据业务关系动态调整分片存储的账户状态。此外,如前所述,本说明书实施例中提供的区块链分片机制也支持跨分片的交易,如通过提供可靠消息传输机制的中间节点或区块链主链。当然,区块链系统中除了上述提到的一些汇款、电子发票的跨账户交易外,还存在一些单账户的交易,例如存证交易。这类单账户交易的发起账户,调用智能合约产生的状态存储,集中在发起账户本身,一般不涉及其他账户。由于不存在跨分片交易,适用上述状态存储方案时,可以更为高效、简单的提升吞吐量,提升区块链性能,并且易于克服存储瓶颈的问题。对于例如图2所示的多分片的区块链系统,不同分片中的节点可以存储不同的外部账户集合的状态,包括上述如图5中对应的实施例中执行创建和/或调用合约的交易而产生的与外部账户相关的状态,也可以是普通转账交易产生的外部账户的状态。对于不采用本申请图5对应实施例的状态分片方案,而是将执行创建和/或调用合约的交易产生的与外部账户相关的状态存储于合约账户的状态存储中,可能存在不同分片中的节点存储不同合约账户状态的集合的情况,或者不同分片中的节点存储不同合约账户集合的状态的情况,也适用于下面将要提到的本申请的方案。所述不同分片中的节点存储不同合约账户状态的集合的情况,例如区块链系统存在一个合约,该合约对应的合约账户具有不同的状态,如状态a、状态b、状态c和状态d,较为简单的可以是分片1中的节点存储状态集合{a},分片2中的节点存储状态集合{b},分片3中的节点存储状态集合{c},分片4中的节点存储状态集合{d}。所述不同分片中的节点存储不同合约账户集合的状态的情况,例如整个区块链系统存在4个合约,分别为合约1、合约2、合约3和合约4,则分别对应合约账户1、合约账户2、合约账户3和合约账户4,较为简单的可以是分片1中的节点存储状态集合{合约账户1的状态},分片2中的节点存储状态集合{合约账户2的状态},分片3中的节点存储状态集合{合约账户3的状态},分片4中的节点存储状态集合{合约账户4的状态}。此外,可以理解的,对于存在多个合约且每个合约具有多个状态,也可以是上述两种情况的混合。上述各种情况,笼统的说,可以称为不同分片存储不同的状态集合。在图2所示的区块链系统架构下,示意的区块链系统的操作过程如图7所示。如图7中,分片1和分片2产生新区块的步调可以不一致;当然,也可以步调一致,这里主要以步调不一致加以说明。需要说明的是,这里为了简便,仅示出了2个分片的情况,多于2个分片的情况与此类似,不再赘述。而且,仅示出了分片1顺序产生区块101和102的情况,以及分片2中顺序产生区块201和202的情况。实际上,可以理解的,分片中处理交易请求,通过共识机制达成共识后,执行交易并生成区块。区块的区块号一般是连续的,并且下一区块的区块头中通过一个字段锁定了上一区块的hash值,例如通过如图3中的prevhash字段来锁定。一个区块的hash值一般是该区块头中所有字段的hash计算的结果。在区块的区块头中,如图3中所示,一般可以包括区块号(blocknum),时间戳(timestamp),前一个区块的hash值(prevhash),以及交易根hash(transaction_root)、状态根hash(state_root),还可以包括收据根hash(receipt_root)和随机数(nonce)。在区块的区块体中,一般可以包括原始交易列表,这些交易可以通过树形结构组织,如前述提到的mpt树,或者是merkle树等。通过树形结构组织的原始交易列表的树根的hash值,存放于区块头的transaction_root中。如前所述,state_root可以是当前区块链中所有账户的状态组成的mpt树的根的哈希值,即指向state_root的为一棵mpt形式的状态树。对于区块头中包括receipt_root的情况,receipt_root可以是当前区块中所有收据组成的merkle或mpt树的根的hash值。例如图7中所示,分片1顺序产生区块101和102,分片2顺序产生区块201和202。分片1在区块101有对应的状态集合,在区块102有对应的状态集合。分片2在区块201有对应的状态集合,在区块202有对应的状态集合。本申请实施例中,提供了包含主链的区块链分片的系统。主链中可以包括若干区块链节点。一般的,主链中的节点具有较高的可信度,并且这些节点构成的主链符合拜占庭容错要求。主链可以具有自己的时钟,如图7中所示的主链时间轴即表达主链时钟的时间轴。按照主链的时间轴,分片2区块201的生成时间在主链区块10001的生成时间和主链区块10002的生成时间之间,分片1区块101的生成时间在主链区块10002的生成时间和主链区块10003的生成时间之间,分片2区块202的生成时间在主链区块10003的生成时间和主链区块10004的生成时间之间,分片1区块102的生成时间在主链区块10004的生成时间之后。一般的,主链上生成区块的频率高于各个分片中生成区块的频率,至少不低于各个分片中生成区块的频率。例如,分片1中的节点a在时刻之前收到客户端发起的一笔交易,例如是普通转账交易,该交易是由分片1中的外部账户1转账至分片2中的外部账户6。分片1中的例如节点a收到该交易后,将该交易广播至分片1中的其它节点。一小段时间之后,可以由分片1中的主节点(例如节点c)将包括该交易在内的一定数量的交易打包并发起相应的共识提议。在分片1中经过共识后,由分片1中的各个节点执行这些打包的交易。由于这些交易包括跨分片交易(也称为跨片交易),分片1中仅能执行在外部账户1中扣减一定余额的操作。剩余的在分片2中执行为外部账户6增加一定余额的操作,需要由分片2中的节点来执行。那么,这个过程需要将分片1中接收到的交易的部分操作转发至分片2中,交由分片2来执行。再例如,分片1中的节点b在时刻之前收到客户端发起的一笔交易,例如是调用合约的交易,该交易是由分片1中的外部账户1发起对某个智能合约的调用。分片1中的节点b收到该交易后,将该交易广播至分片1中的其它节点。一段时间之后,可以由分片1中的主节点(例如节点c)将包括该交易在内的一定数量的交易打包并发起相应的共识提议。在分片1中经过共识后,由分片1中的各个节点执行打包的交易。这些交易中的智能合约在执行过程中,可能涉及跨分片交易事务。如前述的例子,分片1中某一账户发起偿还一定数量的某新资产类型,该资产类型下的账户(包括外部账户和合约账户)各自具有一定的余额(balance)。例如,分片1中的外部账户1将一定数量的该类型的资产转移至合约账户,再按照合约中的条件,由合约账户转移至分片2的外部账户6。分片1中可以执行在外部账户1中扣减一定新资产类型余额的操作;分片2中可以执行为外部账户6增加一定新资产类型余额的操作,而且这个操作需要由分片2中的节点来执行。那么,这个过程需要将分片1中接收到的交易的部分操作转发至分片2中,交由分片2来执行。本申请可以通过基于包含主链的区块分片系统执行。由于主链中的节点具有较高的可信度,因此可以将一个分片(后续称为源分片)中接收的跨分片的交易中涉及其它分片(后续称为目标分片)的操作发送至主链,并由主链转发至所述的目标分片。具体的,图8示出了本申请一实施例中在包含分片的区块链系统中执行跨片事务的方法,包括:s81:源分片生成源分片区块的过程中确定所述源分片区块中的跨分片交易,并将所述跨分片交易中需要由目标分片执行的跨片事务发送至主链。客户端可以向源分片中相连的节点发起交易请求。该交易如前所述,可以是转账交易,也可以是创建/调用合约的交易。收到客户端发起交易的源分片中的节点,进而可以将该交易广播至源分片中的其它节点,或者转发至主节点。以采用pbft共识算法为例,一段时间之后,可以由源分片中的主节点将包括该交易在内的一定数量的交易打包并发起相应的共识提议。需要说明的是,所述源分片中的主节点打包的交易中,除了可以包括跨分片交易外,还可以包括分片内交易。对于普通的转账交易来说,交易结构比较简单,可以根据交易的发起方(from字段标明)和接收方(to字段标明)判断是否是跨片交易。一般的,对于前述提到的状态分片方案,不同分片中的节点存储不同的外部账户集合的状态,则发起交易请求的客户端中,登录该客户端的账户在相连的源分片中存储有对应的账户状态。也就是说,一般的,在分片中有存储的外部账户可以通过客户端在本分片中发起交易,交易中的from字段标明的账户在本分片中存储有对应的外部账户状态。进而,本分片中的节点可以根据转账交易中的to字段来判断,如果to字段中的账户在本分片中没有对应的外部账户状态,则该交易为跨片交易。而分片内交易,from字段和to字段标明的账户在本分片中有对应的外部账户状态。对于创建/调用合约交易来说,客户端可以向源分片中相连的节点发起合约相关的交易请求。类似的,交易中的from字段标明的账户在本分片中存储有对应的外部账户状态,而to字段标明了合约的地址(调用合约)或空(创建合约)。合约代码中可能涉及一个或多个目标账户,可能包括外部账户和/或另一个合约的账户。对于目标账户是另一合约账户的情况,一般是通过一个合约调用另一个合约,该另一合约中可能又涉及一些外部账户。更多层级的合约调用的情况以此类推。由于合约的复杂性,很多情况下在执行合约时才能判断涉及的除发起方(from字段标明)之外的其它账户是哪些,例如合约中复杂的条件判断以及合约调用合约的情况。具体的,很可能在合约执行时才能确定涉及的一个或多个目标账户。前述提到的状态分片方案,归属于分片中的区块链节点执行创建和/或调用合约的交易,将产生的待存储的与所述区块链外部账户相关的状态存储于对应的区块链外部账户的状态存储中,与所述区块链外部账户相关的状态包括合约中定义的外部账户与资产的映射关系,例如通过map数据结构定义的外部账户与资产的映射关系。如前所述,还可能存在不同分片中的节点存储不同合约账户状态的集合的情况,或者不同分片中的节点存储不同合约账户集合的状态的情况,不再赘述。这样,源分片在执行合约过程中根据是否涉及存储在本分片以外的其它分片上的账户确定本交易是否是跨片交易,例如源分片中的各节点可以在达成共识后的执行交易的过程中根据是否涉及存储在本分片以外的其它分片上的账户确定本交易是否是跨片交易。对于普通的转账交易来说,源分片可以根据to字段标明的目标账户将其中的跨分片转账交易筛选出来。to字段标明的普通转账交易的目标外部账户,如果不归属于本分片对应的外部账户集合,则该普通转账交易即判断为跨分片转账交易。对于跨片交易,由于源分片对应的外部账户集合中仅有from字段标明源分片中的外部账户,因此,对于普通转账交易,只能通过执行交易来对本分片中from字段标明的源分片中的外部账户进行余额balance的操作。而该普通转账交易中to字段标明的其它分片中的目标外部账户的余额balance的操作,无法在源分片中操作。因此,源分片可以将需要由目标分片执行的事务发送至目标分片。例如,源分片生成的一个源分片区块中,打包了1000条交易,其中普通转账交易为500条,且源分片可以确定这500条普通转账交易中包括200条跨分片交易。源分片可以将这200条跨分片交易中需要在本地执行的事务保持在本地执行,即在本地执行涉及的外部账户的余额的操作,并将这200条跨分片交易中需要由目标分片执行的事务发送至目标分片。对于创建/调用合约的交易来说,如前所述,由于合约的复杂性,很多情况下无法从合约代码本身来判断本次交易是否涉及跨分片交易,尤其是对于调用合约的交易。源分片中的节点可以在达成共识后的执行合约过程中根据是否涉及存储在本分片以外的其它分片上的账户确定本交易是否是跨片交易。类似的,对于跨分片的交易,如调用合约交易涉及的跨分片交易,源分片可以在执行所述交易的过程中执行本分片涉及的账户的事务,即改变所述本分片中涉及账户的状态,包括外部账户和/或合约账户的状态。而对于目标分片对应的账户状态的改变,源分片可以将这些跨分片交易中需要由目标分片执行的事务发送至目标分片。对于源分片来说,由于这些跨分片交易中涉及的目标分片的操作需要发送至目标分片执行,在尚未确定目标分片已经执行前,源分片中的节点即使在本分片中完成了共识并执行了该源分片区块中的这些跨分片交易,也不将该源分片区块中跨分片交易产生的本分片中相关账户的变化后的状态提交至数据库,即不持久化存储。当源分片收到目标分片完成跨分片交易中需要由目标分片执行的事务的响应或提交指示之类的确认后(这取决于交互协议的设计),才由源分片中的节点在本地提交跨分片交易中由源分片执行的事务,完成持久化存储。前述提到,由源分片中的主节点将包括该交易在内的一定数量的交易打包,发起相应的共识提议,达成共识后,源分片中的各个节点可以在本地执行交易,但是并不将执行结果提交至底层数据库。源分片中的各个节点在达成共识后在本地执行交易,本分片中相关账户的状态会发生改变,包括外部账户和/或合约账户的状态的改变。源分片可以根据这些改变后的状态生成分片区块。相关的外部账户和合约账户的状态改变后,源分片中的各个节点可以根据merkle树或mpt树的组织结构,计算得到新的状态树的根节点的hash值(即前述的状态根hash,state_root)。得到的这个state_root可以填入区块的区块头中。以mpt树为例,如前所述,state_root是当前区块中所有账户的状态组成的mpt树的根的哈希值,即指向state_root的为一棵mpt形式的状态树。这个mpt树的根节点可以为一个扩展节点或一个分支节点,state_root中存储的一般为这个根节点的hash值。尽管当前区块中涉及的可能是当前分片对应的账户状态中的一部分账户的状态的改变,即在当前区块收录的交易中,仅与所属分片对应账户中的一部分账户有关,但是可以通过引用之前区块中不变的状态来生成包括当前分片对应全部账户状态的state_root。例如,分片1中涉及的账户包括{外部账户1、外部账户5、外部账户9、外部账户13、外部账户17、外部账户21、外部账户25、外部账户29、外部账户33、外部账户37、外部账户41},而本区块打包的交易中仅涉及{外部账户1、外部账户9、外部账户21、外部账户33}的状态发生改变,而{外部账户5、外部账户13、外部账户17、外部账户25、外部账户29、外部账户37,外部账户41}的状态并没有发生改变,根据mpt树的组织形式,可以在本区块的状态中加入发生变化的外部账户的状态,并引用之前的区块中最近的没有发生变化的账户状态,从而得到这个mpt树的根节点的hash值。源分片中的各个节点在生成源分片区块的过程中,对于transaction_root,可以将主节点打包的交易按照merkle树或mpt树的树形结构组织起来,树根的hash值即为transaction_root。这个transaction_root可以填入源分片区块的区块头中。对于源分片区块的区块头中包括receipt_root的情况,一般与上述transaction_root类似,也可以是在本地执行交易后,将产生的收据receipt按照merkle树或mpt树的组织形式生成receipt_root,并填入源分片区块的区块头中。如前所述,区块头中一般还包括区块号,时间戳,随机数,前一区块的hash,等。上述源分片将跨分片交易中需要由目标分片执行的事务发送至目标分片,可以通过主链来发送。具体的,可以是源分片中对源分片区块达成共识后由主节点发送至主链中的节点,或者可以是源分片中对源分片区块达成共识后由一个或多个节点发送到主节点。一个例子中,可以是源分片中包括的满足拜占庭容错的至少3f+1个节点中的至少2f+1个节点发送相同的需要由目标分片执行的事务至主链中的一个或多个节点。前述提到,在区块的区块体中一般可以包括原始交易列表,该原始交易列表中的交易按照merkle树或mpt树的树形结构组织起来,树根的hash值即为transaction_root。此外,源分片生成的分片区块的区块体中,还可以包括所述原始交易列表中的跨片交易需要由目标分片执行的事务。例如,分片2产生的分片区块201和分片区块202中,在区块体里除了原有的原始交易列表外,还可以包括跨片事务列表,该跨片事务列表中包括跨片交易中需要由目标分片执行的跨片事务。所述跨片事务列表一般可以是区块体中原始交易列表的子集。需要说明的是,由于可能存在分片2与不同目标分片的跨片交易,因此分片2产生的分片区块中的跨片事务列表中,可能包括需要由多个不同目标分片执行的跨片事务。相应的,在区块头中,可以设置一个字段,如跨片事务_root,用于存储所述区块体中跨片事务按照merkle树或mpt树的树形结构组织起来的树根的hash值。通过跨片事务_root,可以将区块体中的跨片事务列表锁定至区块头中。这样,分片区块的hash值,可以是根据区块头中的各个字段计算得到的hash,这些字段可以包括跨片事务_root。分片中后一区块可以通过区块头中的prev_hash字段锁定前一区块的hash值。源分片除了将所述跨片事务发送至主链,还可以将生成的源分片区块的区块头发送至主链。s83:主链生成主链区块的过程中,将接收到的需要由目标分片执行的跨片事务填入主链区块的区块体中,并将所述需要由目标分片执行的跨片事务按照目标分片的标识发送至对应的目标分片中。主链中的节点接收到源分片发来的跨片事务后,可以先对跨片事务进行验证。例如,可以按照树形结构计算该跨片事务构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务是否与之前接收到的跨片事务重复。如果重复,则不再处理本次发来的跨片事务,否则继续处理。主链中的主节点可以收集源分片发来的交易,或者是主链中的非主节点接收源分片发来的交易后将这些交易转发至主链中的主节点,这些交易可以包括源分片发来的跨片事务列表。如前所述,每个源分片发来的跨片事务列表中,可能包括需要由多个不同目标分片执行的跨片事务。在跨片事务中,可以包括目标分片的标识,也可以包括源分片的标识。主链中的主节点可以将一段时间内各分片发来的一定数量的跨片事务打包并发起相应的共识提议。此外,主链中的主节点打包的内容中除了所述跨片事务之外还可以包括其他交易。在主链中达成共识后,由主链中的各个节点执行这些打包的交易,生成主链区块。所述主链中的节点执行这些打包的交易,并不是执行其中的跨片事务。如前所述,这些跨片事务对应的账户状态在目标分片中存储,因此这些跨片事务对应的账户状态的操作需要由目标分片来执行。主链中的各个节点执行这些打包的交易并生成区块,可以包括将所述需要由目标分片执行的跨片事务填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务以相同的树形结构组织成一棵树,并根据这棵树的树根生成hash值并将该hash值填入主链区块的区块头的交易根hash字段中。再在主链区块的区块头中加入区块号,时间戳,前一区块的hash等字段后,就生成了主链区块。主链中的各个节点执行这些打包的交易并生成区块,将所述需要由目标分片执行的跨片事务填入主链区块的区块体中,具体可以是按照主链中的主节点发起相应的共识提议的消息中需要由目标分片执行的跨片事务的顺序,将由目标分片执行的跨片事务填入主链区块的区块体中。此外,也可以是按照目标分片对跨片事务进行分组,将分组后的跨片事务填入主链区块的区块体中。分组后的各组跨片事务,可以按照分组编号升序或降序排列后填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务以相同的树形结构组织成一棵树,根据这棵树的树根生成hash值并填入主链区块的区块头的transaction_root字段中。分组后的跨片事务例如为如下结构:需要由分片1执行的跨片事务......需要由分片n执行的跨片事务表1按照目标分片对跨片事务进行分组,分组后的每个组内跨片事务的顺序,最好与跨片事务的时间顺序一致,即按照时间先后顺序排列。由于交易的先后顺序的不同很可能会导致交易结果的不同,因此,分组后的每个组内跨片事务按照时间先后顺序排列,利于保证后续将这些跨片事务发给目标分片后,目标分片执行这些跨片事务时不会引发由于顺序不一致而导致的错误或异常。主链生成的主链区块,分组后的跨片事务填入该主链区块的区块体,并根据这些跨片事务按照树形结构计算得到的根节点生成hash值,将该生成的hash值填入区块头中的transaction_root。类似的,主链上生成的区块,也可以通过hash来锁定,例如主链中的区块10002的区块头的prevhash中存储上一区块10001的hash值,以此类推。主链中的区块,其区块头(区块nheader)中,可以包括区块号(blocknum),时间戳(timestamp),前一个区块的hash值(prevhash)等字段,以及transaction_root。主链区块的区块体(区块nbody)中,可以包括该主链区块生成之前的各个分片发送至该主链的跨片事务,即需要目标分片所执行的操作。优选的,主链区块的区块体所包括的各个目标分片需要执行的跨片事务,是未经主链在之前已生成的区块中打包的。需要说明的是,主链中生成的主链区块,如果该区块生成前在主节点打包交易时中对于某一分片没有其执行的跨片事务,则该主链区块的区块体中,可以不包括需要由该目标分片执行的跨片事务。前述提到,源分片除了将所述跨片事务发送至主链,还可以将生成的源分片区块的区块头发送至主链。主链接收到源分片发来的源分片区块的区块头和跨片事务后,可以对源分片区块的区块头进行验证。验证可以包括,根据跨片事务按照树形结构计算根节点的hash值,确定该值与区块头中的跨片事务_root一致。如果不一致则验证不通过,反之验证通过。还可以验证源分片本次发来的源分片区块的区块头是否与之前发来的源分片区块的区块头相同,相同则说明与之前的源分片区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的源分片区块的区块头中的prevhash是否是上个区块号的源分片区块的hash值,如果是则通过验证,否则不通过。对于源分片还将生成的源分片区块的区块头发送至主链的情况,主链在生成主链区块的过程中,还可以根据接收到的源分片区块的区块头计算得到该源分片区块的hash值。进而,主链可以将各个源分片发来的分片区块的hash值填入主链区块的区块体中。进一步的,主链还可以将所述各个分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根(shards_blockroot)字段中。如前所述,主链中的节点具有较高的可信度。主链上的节点将分片区块的区块hash锁定至主链区块中,可以避免分片对生成的分片区块进行回滚。这是因为,基于hash算法的性质,分片无法伪造不同交易的情况下而使得区块头保持不变,从而保障了分片交易的安全性。具体的,即可以保障跨分片交易的安全性,也可以保障分片内交易的安全性。主链区块中的各节点执行主节点共识提议中打包的交易,将接收到的需要由目标分片执行的跨片事务填入主链区块的区块体中并生成主链区块,这样可以在主链区块中锁定需要由目标分片执行的跨片事务。之后,可以将所述需要目标分片执行的跨片事务按照目标分片的标识发送至对应的目标分片中。如前述例子,可以将主链区块体中的跨片事务按照需要执行的目标分片的标识分别发送。具体的,主链区块的区块体中的跨片事务列表,可以是按照目标分片对跨片事务进行分组后填入的。如前面表1中的例子。这样,主链可以按照主链区块的区块体中的分组将主链区块体中分组的跨片事务发送至所述分组对应的目标分片。主链生成主链区块后,除了将所述需要目标分片执行的跨片事务按照目标分片的标识发送至对应的目标分片中,还可以将所述主链区块的区块头发送至目标分片,例如与需要对应目标分片处理的跨片事务一并发送至所述目标分片。s85:所述目标分片生成目标分片区块的过程中,将接收到所述主链发来的跨片事务填入所述目标分片区块的区块体中,并执行所述跨片事务。所述目标分片中的节点接收到主链发来的跨片事务后,可以先对跨片事务进行验证。例如,可以按照树形结构计算该跨片事务构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务是否与之前接收到的跨片事务重复。如果重复,则不再处理本次发来的跨片事务,否则继续处理。所述目标分片,作为执行前述跨片事务的分片,也可以接收所述主链发来的需要由所述目标分片执行的跨片事务。具体的,可以是所述目标分片中的主节点接收所述主链发来的需要由所述目标分片执行的跨片事务;也可以是所述目标分片中的非主节点接收所述主链发来的需要由所述目标分片执行的跨片事务,再将这些跨片事务转发至所述目标分片中的主节点。此外,所述目标分片也可以接收与其连接的客户端发起的交易请求。该交易如前所述,可以是转账交易,也可以是创建/调用合约的交易。所述目标分片中的主节点可以将一段时间内接收到的一定数量的交易打包并发起相应的共识提议。所述打包的交易中可以包括前述主链发来的跨片事务,还可以包括所述目标分片接收到的客户端发来的交易。在所述目标分片中达成共识后,由所述目标分片中的各个节点执行这些打包的交易,生成目标分片区块。所述目标分片生成目标分片区块的过程中,可以将接收到所述主链发来的跨片事务填入所述目标分片区块的区块体中,具体如原始交易列表中。此外,所述目标分片还可以将打包的客户端发来的交易填入所述目标分片区块的区块体中,具体如原始交易列表中。填入目标分片区块的区块体中的交易,可以按照树形结构组织起来,根据树根产生的hash值即为生成的目标分片区块的区块头中的transaction_root。所述目标分片中的各节点执行交易,包括执行所述跨片事务。此外,目标分片中的各节点执行的交易还可以包括所述目标分片接收到的客户端发来的交易。由于所述目标分片中存储有所述跨片事务对应的账户状态,因此,执行所述跨片事务会导致所述目标分片中存储的相应账户的状态发生改变。目标分片中的各节点执行所述跨片事务后,并不将执行所述跨片事务后导致的本分片中相应的账户变化后的状态提交至底层数据库,即不持久化存储。当所述目标分片收到源分片对所述跨片事务的提交确认后,才在本地提交跨分片交易中由所述目标分片执行的事务,完成持久化存储。如果所述目标分片中的各节点执行所述跨片事务后,存在部分或全部跨片事务涉及本分片以外其它分片上存储的账户,即这些跨片事务是多重跨片事务。则对于这种多重跨片事务,一方面,执行所述跨片事务后导致的本分片中相应的账户改变后的状态也并不提交至底层数据库,另一方面,将这些跨片事务中进一步涉及的需要由其它分片执行的跨片事务发送至主链,即重复进入到s81、s83、s85的处理,直到不再涉及新的跨片事务。最为简单的跨片事务是单重跨片事务,即从一个源分片到一个目标分片的跨片事务即执行完毕的交易。多重跨片事务,可以是单重跨片事务的叠加。以下主要以单重跨片事务为例加以说明。本领域技术人员可以根据这里给出的单重跨片事务的例子容易的扩展到多重跨片事务的情形,而这些扩展的情形显然也应当属于本专利的范围。此外,对于各节点执行所述目标分片接收到的客户端发来的交易,如果这些交易是分片内交易,即涉及的账户在本分片中都存储有对应的状态,则执行这些交易也会导致本分片中存储的相应账户的状态发生改变。类似的,目标分片中的各个节点在达成共识后在本地执行交易,本分片中相关账户的状态会发生改变,包括外部账户和/或合约账户的状态的改变。相关的外部账户和合约账户的状态改变后,目标分片中的各个节点可以根据merkle树或mpt树的组织结构,计算得到新的状态树的根节点的hash值(即前述的状态根hash,state_root)。得到的这个state_root可以填入生成的目标分片区块的区块头中。此外,区块头中还可以包括区块号、时间戳、前一区块的hash等字段。前述s83中提到,主链除了将所述跨片事务发送至对应的目标分片中,还可以将所述主链区块的区块头发送至目标分片。目标分片接收到主链发来的主链区块的区块头和跨片事务后,可以对主链区块的区块头进行验证。验证可以包括,所述目标分片根据主链本次发来的主链区块的区块头计算所述主链区块的hash,并基于该主链区块的hash判断是否与之前发来的主链区块的区块头相同,相同则说明与之前的主链区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的主链区块的区块头中的prevhash是否是上次发来的主链区块的hash值,如果是则通过验证,否则不通过。对于主链还将生成的主链区块的区块头发送至目标分片的情况,目标分片在生成目标分片区块的过程中,可以根据接收到的主链区块的区块头计算得到该主链区块的hash值。进而,目标分片还可以将该主链区块的hash值填入目标分片生成的目标分片区块的区块头中。对于主链区块的生成速度不低于分片区块的生成速度的情况,目标分片可以将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中。是否最新可以根据主链区块的区块头中的时间戳或者区块号来判断。如前所述,所述目标分片在生成目标分片区块的过程中,还可以验证当前主链区块的hash值是否与之前发来的主链区块重复。如果重复,可以不再处理本次发来的区块头以及对应的跨片事务,否则继续处理。目标分片通过将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中,对于主链区块的生成速度等于分片区块的生成速度的情况,可以在目标分片中标识当前目标分片中处理的跨片事务是哪个主链区块的区块体中的跨片事务,对于主链区块的生成速度高于分片区块的生成速度的情况,可以在目标分片中标识当前目标分片中处理的跨片事务是截止到哪个主链区块的区块体中的跨片事务。由于主链区块的生成速度不低于分片区块的生成速度,对于主链区块的生成速度高于分片区块的生成速度的情况,分片1在生成分片区块101和目标分片区块102之间,主链中已经生成过两个主链区块,分别为主链区块10003和10004。除了主链将主链区块10004的区块头和主链区块10004中的跨片事务发送至分片1,实际上,在此之前,如果主链区块10003中也包含分片1需要处理的跨片事务,主链还可以将主链区块10003的区块头和主链区块10003中的需要由分片1处理的跨片事务发送至分片1。即,正常情况下,主链按照主链区块生成的时间顺序将主链区块的区块头和对应的跨片事务发送至所述跨片事务涉及的分片。这样,目标分片可以将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中,上述例子中,即将主链区块10004的区块hash填入目标分片生成的目标分片区块的区块头中。同时,分片1在生成的分片区块102的区块体的原始交易列表中,可以包括主链区块10003和10004中涉及需要由分片1处理的跨片事务。此外,所述分片区块102的原始交易列表中也可以包括与分片1连接的客户端发起的交易请求。与分片1连接的客户端发起的交易请求,可以是转账交易,也可以是创建/调用合约的交易。另一种情况中,对于生成的分片区块中包括主链发来的多个主链区块的区块头和对应的需要由目标分片执行的跨片事务的情形,除了在分片区块的区块体的原始交易列表中包括所述多个主链区块中的需要由该分片处理的跨片事务以外(当然还可以包括打包的与分片连接的客户端发起的交易请求),在分片区块的区块头中还可以包括所述多个主链区块的区块头。显然的,这种情况下,分片区块的区块头中包含的处理的主链区块的hash的数量可能是不定的。再一种情况中,对于生成的分片区块中包括主链发来的多个主链区块的区块头和对应的需要由目标分片执行的跨片事务的情形,除了在分片区块的区块体的原始交易列表中包括所述多个主链区块中的需要由该分片处理的跨片事务以外(当然还可以包括打包的与分片连接的客户端发起的交易请求),在分片区块的区块体中还可以包括所述多个主链区块的区块hash。分片区块的区块体中包含的这些处理的主链区块的hash,可以按照如前所述的树形结构组织,并将这棵树的根的hash值填入区块头中增加的字段“主链区块根hash”中,即将所述各个主链区块的hash按照树形结构计算得到的根的hash值填入所述分片区块的区块头的主链区块根hash中。这样的好处在于,在分片区块的区块头中可以通过一个固定的字段来锁定所述分片区块的区块体中可能包括的不定数量的处理的主链区块的hash。进而,目标分片在生成的分片区块对应执行的交易,包括该目标分片中锁定的主链区块所对应的需要由所述目标分片执行的跨片事务,此外还可以包括与所述分片连接的客户端发起的交易请求。例如,分片1在分片区块102对应执行的交易,可以包括主链区块10003和10004中涉及分片1的跨片事务,以及分片区块102中打包的与分片1连接的客户端发起的交易请求。目标分片在生成的分片区块对应执行的交易包括主链发来的跨片事务和与所述目标分片相连的客户端发来的交易的情况下,目标分片可以先执行主链发来的跨片事务,再执行与所述目标分片相连的客户端发来的交易。这是因为,主链发来的需要所述目标分片执行的跨片事务实际上发生在前,与所述目标分片相连的客户端发来的交易实际上发生在后,而执行交易的顺序也是保证账户状态发生正确转化的前提条件,因此,为了避免所述目标分片存储的账户状态发生错误的转化而导致交易的失败或状态的错乱,最好按照交易实际的顺序来执行。另外,所述目标分片执行所述跨片事务,和所述目标分片生成目标分片区块的过程中将接收到所述主链发来的跨片事务填入所述目标分片区块的区块体中,两者没有严格的先后顺序,也可以并行执行。目标分片在生成的目标分片区块中锁定了多个主链区块的情况下,所述目标分片按照所述主链区块的生成顺序执行所述多个主链区块中的跨片事务。例如,分片1在生成的分片区块102中锁定了主链区块10003和10004,则分片1按照主链区块10003、10004的顺序执行主链区块10003和10004中的跨片事务,而非按照主链区块10004、10003的顺序执行主链区块10003和10004中的跨片事务。这是因为,主链发来的需要所述目标分片执行的跨片事务,主链先发来的区块头对应的区块中的跨片事务实际上发生在前,主链后发来的区块头对应的区块中的跨片事务实际上发生在后,而执行交易的顺序也是保证账户状态发生正确转化的前提条件,因此,为了避免所述目标分片存储的账户状态发生错误的转化而导致交易的失败或状态的错乱,最好按照交易实际的顺序来执行。此外,主链还可以发送生成的主链区块的时间戳至分片,例如通过之前发送所述主链区块的区块头指示所述主链区块的时间戳,这样,分片在生成分片区块的过程中可以将最新主链区块的时间戳填入分片区块的timestamp中。例如,s85中,分片生成分片区块的过程中,将所述分片区块的区块头中的时间戳设定为所述主链发送的最新的时间戳。类似的,s81中生成分片区块的过程中,也将所述分片区块的区块头中的时间戳设定为之前所述主链发送的最新的时间戳。这样,可以在分片中锚定主链的时间系统,从而使得分片具有与主链相同的时钟系统。分片与主链具有相同的时钟系统的情况下,与所述分片相连的客户端在发起交易时可以确定该交易的发起时间。从而,客户端在发起交易时,可以将该发起时刻的时间戳附在发起的交易上。那么,如前所述,在多个源分片发送至主链的跨片事务中,涉及同一个目标分片的,该目标分片最好也是按照交易的顺序来执行这些跨片事务。这样,目标分片对于同一个主链区块中的跨片事务,不论这些跨片事务是由哪个源分片发起的,可以统一按照这些跨片事务的时间戳(即源分片中发起的跨片交易的时间戳)按顺序来执行,从而保证交易能够正确处理以及交易执行后产生状态的一致。上述本申请提供的执行跨片事务的实施例,在包含分片的区块链系统中通过主链来将源分片中产生的跨分片事务转发至目标分片,提供了包含分片的区块链系统中跨分片事务的执行方案。这个过程,通过构成主链节点的权威性,使得分片中产生的跨片事务能够在主链的见证下可靠的转发和执行,并在源分片、主链和目标分片上均存证。跨片事务的执行和提交,应当具有原子性。具体的,由于跨片事务涉及区块链系统中不同分片上的节点,因此,对于跨片事务,应当在涉及的源分片和目标分片上都执行/提交,或者都不执行/提交,而不应当在源分片和目标分片中的一个执行/提交,在另一个没有执行/提交。否则,将导致事务的最终状态不一致,不同分片间的账本无法一致。可以理解,上文中虽然以跨片事务包括源分片(例如分片2)的事务和一个目标分片(例如分片1)的事务为例进行了描述,在实际中,跨片事务有可能包括多个目标分片,例如,在分片1中执行跨片交易tx1,产生需要在分片2执行的子交易tx2和需要在分片3执行的子交易tx3。该跨片交易tx1也可以为转账交易,其分别对分片2和分片3中的不同账户进行转账,或者,跨片交易tx1也可以为调用/创建智能合约的交易。在该情况中,为了满足跨片事务的原子性,交易tx1、交易tx2和交易tx3必须同时执行失败或同时执行成功。其中,在其中一个目标分片的跨片事务(例如分片2中的子交易tx2)执行失败的情况中,在相关技术中,通常由分片2将退出交易tx1的指令发送给主链,主链将该指令发送给源分片(分片1),从而分片1退出交易tx1,并向主链发送通知分片3退出交易tx1的子交易(即交易tx3)的信息,主链将该信息转发给分片3,从而分片3在接收到该信息之后退出交易tx3。其中分片1退出交易tx1具体可以指:分片1的节点在本地删除执行交易tx1时产生的对状态的更改。在该过程中,分片2在确定执行交易tx2失败之后,分片3需要经过至少两个主链区块的时间才能够获取退出交易tx3的信息,效率较低。图9为本说明书实施例中提供的一种区块链系统中退出跨片事务的方法的流程图。该方法可以应用于包含主链的区块链系统,例如应用于如图2所示的区块链系统,其中实施该方法的装置可以是主链中的区块链节点,也可以是发送/接收跨片事务的分片中的区块链节点。该方法还可以应用于并不包含主链的区块链系统,其中实施该方法的装置可以是发送/接收跨片事务的分片中的区块链节点。如图9所示,该方法可以至少可以包括如下步骤s91和步骤s93。步骤s91,根据跨片事务对应的退出时间信息确定是否退出所述跨片事务。步骤s93,在确定退出所述跨片事务的情况下,指示所述跨片事务对应的源分片和目标分片退出所述跨片事务。需要说明的是,对于某个分片通过执行跨分片交易而产生一个或多个跨片事务的场景,该方法中所述的单个跨片事务对应的源分片是指产生该跨片事务的分片,单个跨片事务对应的目标分片可以包括用于接收并执行该一个或多个跨片事务的一个或多个分片。下文将主要以在包含主链的区块链系统中实施该方法,并具体以主链中的区块链节点来实施该方法为例进行详细描述。更具体地,请参考图2和图8,分片1在执行交易tx1之后,生成例如需要由分片2执行的子交易tx2和需要由分片3执行的子交易tx3,则该方法中所述的跨片事务可以是子交易tx2或者子交易tx3,跨片事务对应的源分片和目标分片可以包括分片1、分片2和分片3。首先,在步骤s91,根据跨片事务对应的退出时间信息确定是否退出所述跨片事务。参考上文对图8所示方法的描述,分片1可以将其生成的子交易tx2和子交易tx3发送给主链,由主链将子交易tx2和子交易tx3分别发送给分片2和分片3,其中子交易tx2和子交易tx3中都带有交易tx1的标识,例如交易tx1的哈希值。主链在接收到子交易tx2和子交易tx3之后,可以记录交易tx1的标识与分片1、分片2和分片3之间的对应关系,实现记录子交易tx2和子交易tx3与分片1、分片2、分片3的对应关系。对于未被提交的跨片事务,即未被分片执行或者已被分片执行但并未提交执行该跨片事务时所产生的状态的跨片事务,可以对该跨片事务设置表征该跨片事务未被提交的状态,直到确定该跨片事务已经在相应的目标分片中提交才取消对该跨片事务设置的状态,其中如何确定跨片事务是否在目标分片中已经被提交则依赖于具体的通信协议。例如,主链中的区块链节点接收到来自分片1的子交易tx2和子交易tx3时,将子交易tx2和子交易tx3标记为pending态,表征子交易tx2和子交易tx3未在相应目标分片中提交;主链确定子交易tx2和子交易tx3已经在分片2和分片3中提交时,则可以清除其针对子交易tx2和子交易tx3标记的pending态。与之相应的,可以在主链每生成一个新的主链区块时,针对主链中被标记为pending态的全部跨片事务执行步骤s91。或者,可以基于预先设置的时间周期,针对主链中被标记为pending态的全部跨片事务周期性的执行步骤s91。在一种可能的实施方式中,交易tx1中可以包括退出时间信息,由分片1生成的子交易tx2和子交易tx3中均可携带包含于tx1中的退出时间信息。例如,交易tx1是来自客户端的跨分片交易,其中用户可以在客户端自定义设置主链区块个数或者存活时间长度,客户端将用户设置的主链区块个数或者存活时间长度作为退出时间信息携带在交易tx1中;或者,客户端可以通过与主链进行信息交互,与主链完成同步时间系统并基于同步的时间系统确定当前时间,或者获得主链在当前时间的当前区块高度,接着用户可以根据确定的当前时间或者当前区块高度,在客户端自定义设置不小于当前时间的退出时间或者不小于当前区块高度的主链区块高度,并将用户设置的退出时间或者主链区块高度作为退出时间信息携带在交易tx1中。在一种可能的实施方式中,交易tx1、子交易tx2和子交易tx3中可以均不携带退出时间信息,退出时间信息可以是预先存储于指定位置的主链区块个数或者存活时间长度,例如是存储于主链中的区块链节点的主链区块个数或者存活时间长度。下面以确定是否退出子交易tx2为例示例性描述步骤s91。当子交易tx2对应的退出时间信息是主链区块高度时,步骤s91中具体可以判断主链在当前时间的实际区块高度是否达到主链区块高度,如果是则说明当前时间已经达到子交易tx2的退出时间,进而确定退出子交易tx2。当子交易tx2对应的退出时间信息是主链区块个数时,步骤s91中具体可以判断主链在当前时间对应的最新生成的主链区块与锁定跨片事务的主链区块之间的当前区块个数是否达到主链区块个数,或者判断最新生成的主链区块的区块号与锁定跨片事务的主链区块的区块号之间的差值是否达到主链区块个数,如果是则说明当前时间已经达到子交易tx2的退出时间,进而确定退出子交易tx2。当子交易tx2对应的退出时间信息是退出时间时,步骤s91中具体可以判断当前时间是否达到该退出时间,如果是则确定退出子交易tx2。当子交易tx2对应的退出时间信息是存活时间长度时,步骤s91中具体可以确定当前时间与客户端发送子交易tx1的第一发送时间(子交易tx1和子交易tx2中可以包括该第一发送时间)之间的第一时间差,或者可以确定当前时间与分片1发送子交易tx2的第二发送时间(子交易tx2中可以包括该第二发送时间)之间的第二时间差,接着判断第一时间差或者第二时间差是否达到存活时间长度,如果是则说明当前时间已经达到子交易tx2的退出时间,进而确定退出子交易tx2。需要说明的是,分片2在接收到子交易tx2之后,可能因多种情况导致子交易tx2在分片2中未能被及时提交而导致子交易tx2在步骤s91中被确定退出。例如,在子交易tx2为普通转账交易或者更改资产类型变量的交易的情况中,如果账户余额设置了上限,当子交易tx2的执行将导致分片2中的账户余额或者资产类型变量的余额超过上限时,将导致子交易tx2执行失败,从而导致子交易无法在分片2中被提交。又如,当在分片2中不能获取子交易tx2所要处理的账户或者合约账户或者资产类型变量时,将导致子交易tx2执行失败,从而导致子交易无法在分片2中被提交,等等。接着,在步骤s93,在确定退出所述跨片事务的情况下,指示所述跨片事务对应的源分片和目标分片退出所述跨片事务。确定退出跨片事务时,可生成该跨片事务对应的跨片事务退出指令,并将该跨片事务退出指令发送至该跨片事务对应的各个分片,通过该跨片事务退出指令指示相应分片退出该跨片事务。例如,主链中的区块链节点确定退出子交易tx2时,基于子交易tx2中包含的交易t1的标识确定出子tx2对应的源分片和目标分片具体包括分片1、分片2和分片3,然后生成相应的跨片事务退出指令并发送至已确定的分片1、分片2和分片3;其中该跨片事务退出指令具体可以用于指示分片1退出交易tx1,用于指示分片2退出子交易tx2,用于指示分片3退出交易tx3。需要说明的是,鉴于子交易tx2和子交易tx3依赖于交易tx1,交易t1、子交易tx2和子交易tx3应当在区块链系统同步的被提交或退出,因此在逻辑意义上可以将分片1退出交易tx1的过程和分片3退出子交易tx3的过程,等同的表述为分片1和分片3退出子交易tx2的过程。在一些实施例中,主链中的区块链节点可以将一段时间内生成的将发送给各个分片的一定数量的跨片事务退出指令打包并发起相应的共识提议。在主链中达成共识后,由主链中的各个节点执行这些打包的跨片事务退出指令以生成主链区块,从而在主链区块的区块体中包括将发送给各个分片的跨片事务退出指令列表。主链生成主链区块的过程中,还可以将各个跨片事务退出指令按照树形结构计算得到的根的hash值填入主链区块的区块头中,具体如填入该区块头的“跨片事务退出指令root”中。更具体地,可以按照主链中的区块链节点发起相应共识提议的消息中需要发送至各个分片的跨片事务退出指令的顺序,将需要由各个分片执行的跨片事务退出指令填入主链区块的区块体中。此外,也可以是按照接收跨片事务退出指令的分片对跨片事务退出指令进行分组,将分组后的跨片事务退出指令填入主链区块的区块体中,例如,分片1_跨片事务退出指令列表为将发送给分片1的跨片事务退出指令列表,其中例如包括退出交易tx1的指令,分片3_跨片事务退出指令列表为将发送给分片3的跨片事务退出指令列表,其中例如包括退出交易tx1(或子交易tx3)的指令。分组后的各组跨片事务退出指令,可以按照分组编号升序或降序排列后填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务退出指令组织成一棵树,并基于这棵树的树根生成hash值后将该hash值填入主链区块的区块头的transaction_root。此外,对于前述提到的主链区块中包括跨片事务列表的情况,可以将跨片事务退出指令列表与跨片事务列表一并组织成树,并基于树根生成hash值后将该hash值填入主链区块的区块头的transaction_root。或者,将跨片事务退出指令组织成一棵单独的树,产生的树的树根的hash值填入主链区块的区块头中(例如跨片事务退出指令root)。在主链区块的区块头中加入区块号,时间戳,前一区块的hash等字段后,即可生成主链区块。与之相应的,主链中的区块链节点可以将主链区块的区块体中分组后的跨片事务退出指令按照分片的标识发送至对应的分片中。此外还可以将主链区块的区块头发送至对应分片,例如将需要对应分片处理的跨片事务退出指令以及该跨片事务指令所在的主链区块的区块头一并发送到相应分片。与之相应的,接收到跨片事务退出指令的分片在生成分片区块的过程中,将接收到所述主链发来的跨片事务退出指令填入分片区块的区块体中,并退出对应的跨片事务,即在本地退出执行跨片事务所产生的状态。以分片3中的区块链节点接收到主链发来的跨片事务退出指令为例,分片3可以先对跨片事务退出指令进行验证。例如,按照树形结构计算跨片事务退出指令构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务退出指令是否与之前接收到的跨片事务退出指令重复。如果重复则不再处理本次接收的跨片事务退出指令,否则继续处理。分片3除了接收主链发来的需要由分片3执行的跨片事务退出指令列表外,还可以接收与其连接的客户端发起的交易请求。分片3中的区块链节点可以将一段时间内接收到的一定数量的交易和退出跨片事务指令打包并发起相应的共识提议。在所述分片3中达成共识后,由所述分片3中的各个节点执行这些打包的交易及跨片事务退出指令,生成分片区块。分片3生成分片区块的过程中,可以将接收到主链发来的跨片事务退出指令填入分片区块的区块体中,具体如跨片事务退出指令列表中。填入分片区块的区块体中的跨片事务退出指令,可以按照树形结构组织起来,树根的hash值即为生成的分片区块的区块头中的跨片事务退出指令_root。如前所述,主链除了将跨片事务退出指令发送至对应的分片中,还可以将主链区块的区块头发送至该分片。与之相应的,分片3接收到主链发来的主链区块的区块头和跨片事务退出指令后,可以对主链区块的区块头进行验证。验证可以包括,分片3根据主链本次发来的主链区块的区块头,计算主链区块的hash,并基于该主链区块的hash判断是否与之前发来的主链区块的区块头相同,相同则说明与之前的主链区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的主链区块的区块头中的prevhash是否是上次发来的主链区块的hash值,如果是则通过验证,否则不通过。对于主链还将生成的主链区块的区块头发送至分片3的情况,分片3在生成分片区块的过程中,可以根据接收到的主链区块的区块头,计算得到该主链区块的hash值。进而,分片3还可以将该主链区块的hash值填入分片3生成的分片区块的区块头中。对于主链区块的生成速度不低于分片区块的生成速度的情况,分片3可以将最新主链区块的hash值填入分片3生成的分片区块的区块头中。是否最新可以根据主链区块的区块头中的时间戳或者区块号来判断。如前所述,分片3在生成分片区块的过程中,还可以验证当前主链区块的hash值是否与之前发来的主链区块重复。如果重复,则不再继续处理本次发来的区块头以及对应的跨片事务退出指令,否则继续处理。分片3通过将最新主链区块的hash值填入分片3生成的分片区块的区块头中,对于主链区块的生成速度等于分片区块的生成速度的情况,可以在分片3中标识当前分片中接收的跨片事务退出指令是哪个主链区块的区块体中的跨片事务退出指令。对于主链区块的生成速度高于分片区块的生成速度的情况,可以在分片3中标识当前分片中接收的跨片事务退出指令是截止到哪个主链区块的区块体中的跨片事务退出指令。由于主链区块的生成速度通常不低于分片区块的生成速度,对于主链区块的生成速度高于分片区块的生成速度的情况,参考图10中所示,分片3在生成分片区块301和分片区块302之间,主链中已经生成过两个主链区块,分别为主链区块10003和10004。主链除了将主链区块10004的区块头和主链区块10004中的跨片事务退出指令发送至分片3,实际上,在此之前,如果主链区块10003中也包含分片3需要处理的跨片事务退出指令,主链还可以将主链区块10003的区块头和主链区块10003中的需要由分片3处理的跨片事务退出指令发送至分片3。即,正常情况下,主链按照主链区块生成的时间顺序将主链区块的区块头和对应的跨片事务退出指令发送至所述跨片事务退出指令涉及的分片。这样,分片3可以将最新主链区块的hash值填入分片3生成的分片区块的区块头中,上述例子中,即将主链区块10004的区块hash填入分片3生成的分片区块的区块头中(图10中并未对其进行示出)。同时,分片3在生成的分片区块302的区块体的原始交易列表中,可以包括主链区块10003和10004中涉及的需要由分片3处理的跨片事务退出指令。此外,所述分片区块302的原始交易列表中也可以包括与分片3连接的客户端发起的交易请求。与分片3连接的客户端发起的交易请求,可以是转账交易,也可以是创建/调用合约的交易。对于生成的分片区块中包括主链发来的多个主链区块的区块头和对应的需要由分片3执行的跨片事务退出指令的情形,除了在分片区块的区块体的跨片事务退出指令列表中包括所述多个主链区块中的需要由该分片处理的跨片事务退出指令以外,在分片区块的区块头中还可以包括所述多个主链区块的区块头。显然的,这种情况下,分片区块的区块头中包含的处理的主链区块的hash的数量可能是不定的。再一种情况如图10所示,对于生成的分片区块中包括主链发来的多个主链区块的区块头和对应的需要由分片3执行的跨片事务退出指令的情形,除了在分片区块的区块体的跨片事务退出指令列表中包括所述多个主链区块中的需要由该分片处理的跨片事务退出指令以外,在分片区块的区块体中还可以包括所述多个主链区块的区块hash,如图10的区块301的区块体中的主链区块hash列表。分片区块的区块体中包含的这些处理的主链区块的hash,可以按照如前所述的树形结构组织,并将这棵树的根的hash值填入区块头中增加的字段“主链区块根hash”中,即将所述各个主链区块的hash按照树形结构计算得到的根的hash值填入所述分片区块的区块头的主链区块根hash中。例如,区块301的区块头中的“主链区块根hash”,是区块301的区块体中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值;区块302的区块头中的“主链区块根hash”,区块302的区块头中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值。这样的好处在于,在分片区块的区块头中可以通过一个固定的字段来锁定所述分片区块的区块体中可能包括的不定数量的处理的主链区块的hash。此外,主链还可以发送生成的主链区块的时间戳到分片3,例如通过之前发送所述主链区块的区块头指示所述主链区块的时间戳,这样,分片在生成分片区块的过程中可以将最新主链区块的时间戳填入分片区块的timestamp中。例如,分片3生成分片区块的过程中,将所述分片区块的区块头中的时间戳设定为所述主链发送的最新的时间戳。这样,可以在分片中锚定主链的时间系统,从而使得分片具有与主链相同的时钟系统。分片与主链具有相同的时钟系统的情况下,与所述分片相连的客户端在发起交易时可以确定该交易的发起时间。从而,客户端在发起交易时,可以将该发起时刻的时间戳附在发起的交易上。分片3中的各区块链节点执行交易,包括执行其接收的跨片事务退出指令。对于执行跨片事务退出指令,包括分片3在本地删除执行相应跨片事务而在底层数据库(例如状态数据库)临时插入的数据,和/或,分片3在本地实现对执行相应跨片事务而变更的状态执行反向操作,以使所述状态回退至所述跨片事务执行前的状态。分片3中的区块链节点在执行子交易tx3之后,可在缓存中记录交易tx1(或子交易tx3)的标识与执行子交易tx3所更改的账户的对应关系,从而分片3在接收到与交易tx1或子交易tx3的标识对应的跨片事务退出指令之后,可基于该对应关系找到执行子交易tx3所更改的账户,并删除该账户的状态存储中临时插入的数据,或者恢复为跨片事务执行前的状态。另外,分片3在本地退出所述跨片事务,和分片3生成分片区块的过程中将接收到主链发来的跨片事务退出指令填入分片区块的区块体中,两者没有严格的先后顺序,也可以并行执行。上文中以分片3为例描述其执行跨片事务退出指令的过程,分片1和分片2执行跨片事务退出指令的过程可参考上述对分片3的描述,在此不再赘述。如前所述,实施如图9所示的方法除了主链中的区块链节点以外,还可以是发送跨片事务的源分片或者接收跨片事务的目标分片中的区块链节点。对于由源分片/目标分片中的区块链节点来执行如图9所示的方法,其相对于由主链中的区块链节点来执行如图9所示的方法,不同之处主要在于跨片事务退出指令是在不同的分片间进行直接交互或者通过主链进行交互,以及区块链节点自身所在分片无需根据从外部接收的跨片事务退出指令来退出相应的跨片事务。例如,区块链系统中至少包括分片a、分片b和分片c,可选的包括与前述各个分片相互连接的主链,其中分片a执行跨分片交易tx1时生成需要由分片b执行的子交易tx2和需要由分片c执行的子交易tx3,当分片a中的区块链节点确定退出子交易tx2时,其自身在本地退出子交易tx2依赖的交易tx1,并向分片2和分片3直接发送或者通过主链转发跨片事务退出指令,从而使分片2在本地退出子交易tx2,分片3在本地退出子交易tx3。与前述方法实施例基于相同的构思,本说明书实施例中海一种在区块链系统中退出跨片事务的装置。如图11所示,所述装置包括:确定单元111,配置为根据跨片事务对应的退出时间信息确定是否退出所述跨片事务;指示单元113,配置为在确定退出所述跨片事务的情况下,指示所述跨片事务对应的源分片和目标分片退出所述跨片事务。在一种可能的实施方式中,所述跨片事务中包括所述退出时间信息。在一种可能的实施方式中,所述确定单元111具体配置为根据跨片事务对应的退出时间信息确定当前时间是否达到退出时间,如果是则确定退出所述跨片事务。在一种可能的实施方式中,所述退出时间信息包括以下各项信息中的任一项:主链区块高度、主链区块个数、退出时间、存活时间长度。在一种可能的实施方式中,所述装置部署在所述源分片中的区块链节点,或者,所述装置部署在所述目标分片中的区块链节点。在一种可能的实施方式中,所述区块链系统还包括主链,所述装置部署在所述主链中的区块节点;所述指示单元113,具体配置为向所述跨片事务对应的源分片和目标分片发送用于指示其退出所述跨片事务的跨片事务退出指令。在一种可能的实施方式中,所述装置还包括区块管理单元,配置为将跨片事务退出指令填入所述主链中的主链区块的区块体中。在一种可能的实施方式中,所述区块管理单元,还配置为将跨片事务退出指令构成的树的根节点的hash值填入所述主链区块的区块头中。在一种可能的实施方式中,所述装置还包括通信单元,配置为将所述主链区块的区块头发送至所述源分片和所述目标分片,以便所述源分片和所述目标分片对其接收的跨片事务退出指令进行验证。与前述方法实施例基于相同的构思,本说明书实施例中还提供了一种区块链节点,被配置为执行本说明书任意一个实施例中提供的在区块链系统中退出跨片事务的方法。本领域技术人员应该可以意识到,在上述一个或多个示例中,本说明书所描述的功能可以用硬件、软件、固件或它们的任意组合来实现。当使用软件实现时,可以将这些功能所对应的计算机程序存储在计算机可读介质中或者作为计算机可读介质上的一个或多个指令/代码进行传输,以便这些功能所对应的计算机程序被计算机执行时,通过计算机实现本说明书任意一个实施例中所述的方法。本说明书实施例中还提供了一种计算机可读存储介质,其上存储有计算机程序,当所述计算机程序在计算设备中执行时,计算设备执行本说明书任意一个实施例中提供的在区块链系统中退出跨片事务的方法。本说明书实施例中还提供了一种计算设备,包括存储器和处理器,所述存储器中存储有可执行代码,所述处理器执行所述可执行代码时,实现本说明书任意一个实施例中提供的在区块链系统中退出跨片事务的方法。本说明书中的各个实施例均采用递进的方式描述,各个实施例中相同、相似的部分互相参见即可,每个实施例中重点说明的都是与其他实施例的不同之处。尤其,对于装置实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。上述对本说明书特定实施例进行了描述。其它实施例在所附权利要求书的范围内。在一些情况下,在权利要求书中记载的动作或步骤可以按照不同于实施例中的顺序来执行并且仍然可以实现期望的结果。另外,在附图中描绘的过程不一定要求示出的特定顺序或者连续顺序才能实现期望的结果。在某些实施方式中,多任务处理和并行处理也是可以的或者可能是有利的。以上所述的具体实施方式,对本发明的目的、技术方案和有益效果进行了进一步详细说明,所应理解的是,以上所述仅为本发明的具体实施方式而已,并不用于限定本发明的保护范围,凡在本发明的技术方案的基础之上,所做的任何修改、等同替换、改进等,均应包括在本发明的保护范围之内。当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1