CN112261160B - 包含分片的区块链***中退出跨片事务的方法及*** - Google Patents
包含分片的区块链***中退出跨片事务的方法及*** Download PDFInfo
- Publication number
- CN112261160B CN112261160B CN202011515929.XA CN202011515929A CN112261160B CN 112261160 B CN112261160 B CN 112261160B CN 202011515929 A CN202011515929 A CN 202011515929A CN 112261160 B CN112261160 B CN 112261160B
- Authority
- CN
- China
- Prior art keywords
- block
- cross
- transaction
- slice
- main chain
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Images
Classifications
-
- H—ELECTRICITY
- H04—ELECTRIC COMMUNICATION TECHNIQUE
- H04L—TRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
- H04L67/00—Network arrangements or protocols for supporting network services or applications
- H04L67/01—Protocols
- H04L67/10—Protocols in which an application is distributed across nodes in the network
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F21/00—Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
- G06F21/60—Protecting data
- G06F21/64—Protecting data integrity, e.g. using checksums, certificates or signatures
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/466—Transaction processing
-
- H—ELECTRICITY
- H04—ELECTRIC COMMUNICATION TECHNIQUE
- H04L—TRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
- H04L67/00—Network arrangements or protocols for supporting network services or applications
- H04L67/01—Protocols
- H04L67/10—Protocols in which an application is distributed across nodes in the network
- H04L67/1097—Protocols in which an application is distributed across nodes in the network for distributed storage of data in networks, e.g. transport arrangements for network file system [NFS], storage area networks [SAN] or network attached storage [NAS]
-
- H—ELECTRICITY
- H04—ELECTRIC COMMUNICATION TECHNIQUE
- H04L—TRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
- H04L9/00—Cryptographic mechanisms or cryptographic arrangements for secret or secure communications; Network security protocols
- H04L9/06—Cryptographic mechanisms or cryptographic arrangements for secret or secure communications; Network security protocols the encryption apparatus using shift registers or memories for block-wise or stream coding, e.g. DES systems or RC4; Hash functions; Pseudorandom sequence generators
- H04L9/0643—Hash functions, e.g. MD5, SHA, HMAC or f9 MAC
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Computer Security & Cryptography (AREA)
- Signal Processing (AREA)
- Computer Networks & Wireless Communication (AREA)
- General Physics & Mathematics (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- Computer Hardware Design (AREA)
- General Health & Medical Sciences (AREA)
- Bioethics (AREA)
- Health & Medical Sciences (AREA)
- Power Engineering (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
一种包含分片的区块链***中提交跨片事务的方法及***。该区块链***中至少包括两个分片和主链;所述方法包括:源分片在本地提交跨片事务相关的操作发生异常或者等待跨片事务相关的消息发生超时:源分片在本地撤回发生异常/超时的跨片事务操作,针对跨片事务产生需要由对应目标分片执行的退出指令,并将跨片事务退出指令发送至主链;主链将接收到的需要由目标分片执行的退出跨片事务的指令填入主链区块的区块体中;主链将需要目标分片执行的退出跨片事务的指令按照目标分片的标识发送至对应的目标分片中;目标分片生成目标分片区块的过程中,将接收到主链发来的跨片事务退出指令填入所述目标分片区块的区块体中,并执行所述退出跨片事务的指令。
Description
技术领域
本说明书实施例属于区块链技术领域,尤其涉及一种包含分片的区块链***中退出跨片事务的方法及***、主链节点和源分片节点。
背景技术
区块链(Blockchain)是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构,并以密码学方式保证的不可篡改和不可伪造的分布式账本。由于区块链具有去中心化、信息不可篡改、自治性等特性,区块链也受到人们越来越多的重视和应用。
发明内容
本发明的目的在于提供一种包含分片的区块链***中退出跨片事务的方法及***、主链节点和源分片节点,包括:
一种包含分片的区块链***中退出跨片事务的方法,该区块链***中至少包括两个分片,不同分片中的节点存储不同的状态集合;所述区块链***还包括主链;
所述方法包括,源分片在本地提交跨片事务相关的操作发生异常,或者等待跨片事务相关的消息发生超时:
源分片在本地撤回发生异常/超时的跨片事务操作,并针对所述跨片事务产生需要由对应目标分片执行的退出指令,并将所述跨片事务退出指令发送至主链;
主链生成主链区块的过程中,将接收到的需要由目标分片执行的退出跨片事务的指令填入主链区块的区块体中;所述主链将所述需要目标分片执行的退出跨片事务的指令按照目标分片的标识发送至对应的目标分片中;
所述目标分片生成目标分片区块的过程中,将接收到所述主链发来的跨片事务退出指令填入所述目标分片区块的区块体中,并执行所述退出跨片事务的指令。
一种包含分片的区块链***中退出跨片事务的***,该区块链***中至少包括两个分片,不同分片中的节点存储不同的状态集合;所述区块链***还包括主链;
源分片在本地提交跨片事务相关的操作发生异常,或者等待跨片事务相关的消息发生超时:
源分片在本地撤回发生异常/超时的跨片事务操作,并针对所述跨片事务产生需要由对应目标分片执行的退出指令,并将所述跨片事务退出指令发送至主链;
主链生成主链区块的过程中,将接收到的需要由目标分片执行的退出跨片事务的指令填入主链区块的区块体中;所述主链将所述需要目标分片执行的退出跨片事务的指令按照目标分片的标识发送至对应的目标分片中;
所述目标分片生成目标分片区块的过程中,将接收到所述主链发来的跨片事务退出指令填入所述目标分片区块的区块体中,并执行所述退出跨片事务的指令。
一种包含分片的区块链***中的源分片节点,包括:
执行单元,用于在本地执行跨片事务相关的操作;
源分片区块生成单元,用于当执行单元在本地提交跨片事务相关的操作发生异常或者等待跨片事务相关的消息发生超时后,生成源分片区块,并在生成源分片区块的过程中产生跨片事务退出指令;
跨片事务退出单元,用于在本地撤回发生异常/超时的跨片事务操作;
发送单元,用于将所述跨片事务退出指令发送至主链。
一种包含分片的区块链***中的主链节点,包括:
接收单元,用于接收需要由目标分片执行的跨片事务退出指令;
主链区块生成单元,用于生成主链区块,并在生成主链区块的过程中,将接收到的跨片事务退出指令填入主链区块的区块体中;
发送单元,用于将所述跨片事务退出指令按照目标分片的标识发送至对应的目标分片中。
上述本申请提供的退出跨片事务的方法实施例,在包含分片的区块链***中通过主链来将源分片中产生的跨分片事务退出指令转发至目标分片,提供了包含分片的区块链***中退出分片事务的方案,从而保证了跨片事务的原子性。这个过程,通过构成主链的节点的权威性,使得源分片中产生的跨片事务退出指令能够在主链的见证下可靠的转发并在目标分片中执行,并在源分片、主链和目标分片上均存证。
附图说明
为了更清楚地说明本说明书实施例的技术方案,下面将对实施例描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本说明书中记载的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
图1是一实施例中区块链***架构示意图;
图2是一实施例中区块链***分片架构的示意图;
图3是本说明书一实施例中的区块链数据存储的结构示意图;
图4是本说明书一实施例中的一个简化版的状态树示意图;
图5是本说明书一实施例中的一种区块链状态树的存储结构;
图6是本说明书一实施例中的一种区块链状态树的存储结构;
图7是本说明书一实施例中的一种区块链状态树的存储结构;
图8是本说明书一实施例中的一种区块链状态树的存储结构;
图9是本说明书一实施例中的一种区块链***中的状态存储方法的示意图;
图10是本说明书一实施例中的一种区块链分片架构的示意图;
图11是本说明书一实施例中的一致性哈希的原理示意图;
图12是本说明书一实施例中的一种区块链状态树的存储结构;
图13是本说明书一实施例中的区块链节点示意图;
图14是本说明书一实施例中的区块链节点示意图;
图15是本说明书一实施例中的基于主链的区块链分片***示意图;
图16是本说明书一实施例中的引入主链的区块链分片***产生区块的示意图;
图17是本说明书一实施例中在包含分片的区块链***中执行跨片事务的方法;
图18是本说明书一实施例中分片2产生的分片区块中包括跨片事务列表并上报该跨片事务列表至主链的示意图;
图19是本说明书一实施例中主链产生的主链区块中包括跨片事务及分片区块根的示意图;
图20是本说明书一实施例中目标分片产生的目标分片区块中的示意图;
图21是本说明书一实施例中目标分片产生的目标分片区块中包括主链区块hash的示意图;
图22是本说明书一实施例中目标分片产生的目标分片区块中包括主链区块hash的示意图;
图23是本说明书一实施例中目标分片产生的目标分片区块中包括主链区块hash的示意图;
图24是本说明书一实施例中返回跨片事务响应至源分片的流程图;
图25是本说明书一实施例中主链产生的主链区块中包括跨片事务响应及分片区块根的示意图;
图26是本说明书一实施例中源分片产生的源分片区块的示意图;
图27是本说明书一实施例中发送提交跨片事务指令及提交跨片事务的示意图;
图28是本说明书一实施例中主链产生的主链区块中包括跨片事务提交指令及分片区块根的示意图;
图29是本说明书一实施例中目标分片产生的目标分片区块的示意图;
图30是本说明书一实施例中发送提交跨片事务响应及提交跨片事务的示意图;
图31是本说明书一实施例中主链产生的主链区块中包括跨片事务提交响应及分片区块根的示意图;
图32是本说明书一实施例中源分片产生的源分片区块的示意图;
图33是本说明书一实施例中发送提交跨片事务指令及提交跨片事务的示意图;
图34是本说明书一实施例中发送提交跨片事务指令及提交跨片事务的示意图;
图35是本说明书一实施例中主链产生的主链区块中包括跨片事务提交指令及分片区块根的示意图;
图36是本说明书一实施例中源分片产生的源分片区块的示意图;
图37是本说明书一实施例中发送跨片事务退出指令及提交跨片事务的示意图;
图38是本说明书一实施例中主链产生的主链区块中包括跨片事务退出指令及分片区块根的示意图;
图39是本说明书一实施例中目标分片产生的目标分片区块的示意图;
图40是本说明书一实施例中包含分片的区块链***中的源分片节点;
图41是本说明书一实施例中包含分片的区块链***中的主链节点。
具体实施方式
为了使本技术领域的人员更好地理解本说明书中的技术方案,下面将结合本说明书实施例中的附图,对本说明书实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本说明书一部分实施例,而不是全部的实施例。基于本说明书中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都应当属于本说明书保护的范围。
目前限制区块链技术大规模落地应用的一个很重要因素是性能,即吞吐量,这个吞吐量一般可以通过每秒交易笔数(Transaction Per Second,TPS)来度量。开发者们提出了各种各样的方案来尝试提升区块的吞吐量,这一过程称为“扩容”。从扩容采用技术的方向上来说,可以分为链上扩容和链下扩容两个方向。链上扩容通常包括扩块、隔离见证、分片、共识层改进这些方案。链下扩容通常包括状态通道、侧链、链下计算这些方案。
分片技术是属于链上扩容的一种方案。分片概念源于数据库领域,本意是指数据库中数据的水平分区(将表的不同行分到不同的分区),每个分片都保存在一个单独的数据库服务器实例上,以分散负载。区块链分片的基本思路是将区块链网络中的节点分成若干个相对独立的子网络,每个子网络中包含一部分节点,一个子网络也就是一个分片(shard)。单个分片处理规模较小的事务,甚至只存储部分网络状态,多个分片并行处理事务,理论上整个网络的吞吐量将会提升。
分片技术根据不同的分片机制可以划分为三种:网络分片(network sharding),交易分片(transaction sharding),状态分片(state sharding)。网络分片是最基础的一种分片方式,包括将整个区块链网络划分成多个子网络,也就是多个分片。这样,区块链网络中的多个分片可以并行处理网络中不同的交易。交易分片是将交易按某种规则分配到不同分片,其思路为按一定规则将交易分配到同一个分片处理,这样既能够达到并行处理的目的又能避免双花问题。交易分片的前提是先进行网络分片。在所有的分片机制当中,状态分片是最具挑战的分片方式。状态分片的关键是将整个存储区分开,让不同的分片存储不同的部分,每个节点只负责存储自己的分片数据,而不是存储完整的区块链状态。状态分片能够解决存储能力瓶颈问题。
一些区块链***架构如图1所示。如图1中,一个区块链***例如包含A、B、C、D、E、F、G、H、I、J、K、L、M、N、O、P共16个全量节点。节点之间的连线示意性的表示P2P(Peer toPeer,点对点)连接。这些节点上都存储全量的账本,即承担着存储全部交易、智能合约和各种状态。随着区块链业务的增长,单个节点存储的数据量也会越来越大,有的达到T数量级(1TB=1024GB),甚至到达P或E的数量级(1PB=1024TB,1EB=1024PB)。为了支撑区块链***的运行和应对业务的持续,对于每一个节点都需要寻求扩容(获得更大的存储空间)而进行巨大的花费。
基于此,本说明书实施例提供了一种区块链***。区块链***中的节点进行分片后例如如图2所示,分为4个分片。每个分片包括4个节点。每个分片内的节点之间的连线表示P2P连接,每个分片之间的连线也表示P2P连接。本实施例仅仅是为了便于举例而示意性的列举4个分片,每个分片包括4个节点。实际上,每个分片中节点的数量可以不同。此外,部分或者全部分片之间可能没有网络连接,也就是说,在一些情况下,部分或者全部分片之间可能并不直接通信。为了支持分片之间的通信,区块链网络中可以包括一个为所有分片提供服务的主链。这个主链在图2中并没有显示出。
为了说明本申请中的状态分片方法,先介绍本申请涉及的区块链状态存储结构。鉴于很多区块链平台和应用是基于以太坊(Ethereum)的底层技术而构建的,这里先介绍以太坊的状态存储结构。当然,基于其他区块链技术构建的区块链***,也可能适用于本申请的核心内容,例如基于Fabric的超级账本(Hyperledger)和企业操作***(EnterpriseOperating System,EOS)、Quorum、Corda等,不再赘述。
以太坊相比于比特币网络进行了拓展,采用账户***和世界状态,可以直接用账户来显示的记录账户的余额和状态。以太坊的账户可以分为两种类型:
外部账户(Externally owned account):用户的账户,例如以太币拥有者账户。
合约账户(contract account):存储执行的智能合约代码以及智能合约代码中状态的值,通常只能通过外部账户调用激活。
外部账户和合约账户的设计,实际上是账户地址到账户状态的映射。账户的状态通常包括 nonce、balance、storage_root、codeHash 等字段。nonce、balance在外部账户和合约账户中都存在。codeHash和storage_root属性一般仅在合约账户上有效。
nonce:计数器。对于外部账户,这个数字代表从账户地址发送的交易数量;对于合约账户,是账户创建的合约数量。
balance:这个地址拥有的以太币的数量。
storage_root :一个MPT树根节点的哈希,这个MPT树对合约账户的状态变量的存储进行组织。
codeHash:智能合约代码的哈希值。对于合约账户,这是智能合约被哈希计算并存储的代码;对于外部账户,由于不包括智能合约,因此codeHash字段一般可以是空字符串/全0字符串。
MPT全称为Merkle Patricia Tree,是结合了Merkle Tree(默克尔树)和PatriciaTree(压缩前缀树,一种更节省空间的Trie树,字典树)的一种树形结构。Merkle Tree,默克尔树算法对每个交易都计算一个Hash值,然后两两连接再次计算Hash,一直到最顶层的Merkle根。以太坊中采用改进的MPT树,例如是16叉树的结构,通常也简称为MPT树。
以太坊MPT树的数据结构包括状态树(state trie)。状态树中包含以太坊网络中每个账户所对应的存储内容的键值对(key and value pair)。状态树中的“键”可以是一个的160bits标识符(以太坊账户的地址),这个账户地址分布于从状态树的根节点开始到叶子节点的存储中。状态树中的“值”是通过对以太坊账户的信息进行编码(使用递归长度字典编码(Recursive-Length Prefix encoding,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)或一个分支节点(Branch Node),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值。不论是外部账户还是合约账户,其账户信息一般都位于一个单独的叶子节点(Leaf Node)中。从根节点的扩展节点/分支节点到每个账户的叶子节点,可能中间会经过若干个分支节点以及扩展节点。
状态树可以是MPT形式的树,一般是16叉树,每一层最多可以有16个孩子节点,而最多可以有64层的深度。对于扩展节点,用于存储共同前缀,其一般有1个孩子节点,这个孩子节点可以是分支节点。对于分支节点,其最多可以有16个孩子节点,其中可能包括扩展节点和/或叶子节点。这样的MPT树最多可以有64层的深度。当区块链中的账户数量达到一定数量时,这棵MPT树可能接近或达到64层的深度。
其中,对于状态树中的一个合约账户来说,其storage_Root指向另一棵同为MPT形式的树,其中存储了合约执行涉及的状态变量(state variable)的数据。这个storage_Root指向的MPT形式的树为存储树,即存储树的根节点的hash值。一般的,这个存储树存储的也是key-value键值对。从根节点到叶子节点的路径上存储的一部分数据连起来构成key,叶子节点中存储value。前面提到,这个存储树也可以是MPT形式的树,一般也是16叉树,即对于分支节点,其最多可以有16个孩子节点,其中可能包括扩展节点和/或叶子节点。而对于扩展节点,其一般可以有1个孩子节点,其可以是分支节点。这棵存储树最多可以有64层的深度。
智能合约中,例如通过以太坊提供的solidity高级开发语言中,可以定义的状态变量包括两种类型,一种是基本数据类型的状态变量,另一种是映射(map或mapping)类型的状态变量。以下是一个用solidity编写的智能合约的代码的片段:
contract Demo {
int a;
int x;
mapping(address => int) public balanceA;
function myfunc() 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可以存储状态变量的实际值。
前面提到,如果区块链的状态树中存在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值。树形结构例如可以采用图1中的MPT,当然也可以采用其他组织形式,这一点以下类似,以MPT为例进行说明。整体上,状态树可以采用三层树形结构。例如对于MPT来说,图5中每一层以节点1、节点2、节点3共三个节点来示意性的表示MPT树的形式,具体的,可以表示MPT树中的扩展节点、分支节点。第一层树形结构的叶子节点可以用来存储外部账户存储的根hash值,此外还可以存储合约账户的一些基本信息。外部账户和合约账户可以分别有若干个。一般的区块链应用场景中,外部账户的数量可能明显多于合约账户的数量。第一层叶子节点中每个外部账户的账户信息的根hash,可以基于包括该外部账户的nonce、balance以及该外部账户涉及的智能合约存储的hash值计算得到。其中,图5中外部账户的nonce、balance可以与图3、图4中相同。第二层为合约存储树(schematic storage trie)。具体的,第二层树形结构的根节点为外部账户涉及的智能合约的存储的hash值。类似的,第二层可以通过一个以节点1、节点2、节点3共三个节点来示意性的表示MPT树的形式,具体的,可以表示MPT树中的扩展节点、分支节点。第二层的存储可以包括一个或多个智能合约,即可以有多个叶子节点。第二层的每个叶子节点可以用来存储该外部账户下涉及的一个智能合约的存储的根hash值,可以基于包括该外部账户涉及的合约ID(contractID)、storage_root计算得到。第三层为存储树。具体的,第三层树形结构的根节点为外部账户涉及的智能合约中的状态变量的根hash值。类似的,第三层可以通过一个以节点1、节点2、节点3共三个节点来示意性的表示MPT树的形式,具体的,可以表示MPT树中的扩展节点、分支节点。第三层的每个叶子节点可以用来存储合约中的一个状态变量的value值。上述的三层树的结构,每棵树的根节点到叶子节点的路径上存储的一部分数据连起来可以构成key,叶子节点中可以存储value。这样,通过这样的存储模型,可以在每个外部账户下存储该外部账户涉及的每个智能合约中的状态变量的key-value。
本说明书实施例提供一种区块链状态树的存储结构。如图6所示。
实际的区块链商业***中,很多情况下一个区块链专注于提供一种服务。一种服务一般可以采用一个智能合约来实现。这种情况下,该区块链***中只有一个智能合约。在只有一个智能合约时,图5中的第二层可以得到简化,不需要图5中的第二层结构,则如图6所示。第一层树形结构的叶子节点中每个外部账户的根hash,可以基于包括该外部账户的nonce、balance以及该外部账户涉及的智能合约存储的hash值计算得到。其中,图6中外部账户的nonce、balance可以与图3、图4中相同。第二层为存储树。具体的,第二层树形结构的根节点为外部账户涉及的智能合约中的状态变量的根hash值。类似的,第二层可以通过一个以节点1、节点2、节点3共三个节点来示意性的表示MPT树的形式,具体的,可以表示MPT树中的扩展节点、分支节点。第二层的每个叶子节点可以用来存储合约中的一个状态变量的value值。上述的两层树的结构,每棵树的根节点到叶子节点的路径上存储的一部分数据连起来可以构成key,叶子节点中可以存储value。这样,通过这样的存储模型,可以在每个外部账户下存储该外部账户涉及的每个智能合约中的状态变量的key-value。
图3、图4的合约账户存储中包括了该合约涉及的所有状态变量。通过本申请上述图5、图6实施例提供区块链状态树的存储结构,实际上将原有的合约账户存储中涉及的该合约中所有状态变量按照关联的外部账户,分解到了对应的外部账户的存储中。例如,原有的合约账户存储中包括了该合约涉及的所有map类型的状态变量1、2、3、…10000,其中1-1000与外部账户1相关,1001-2000与外部账户2相关,以此类推。这样,将与外部账户1相关的map类型的状态变量1-1000,分解到了外部账户1的存储中;将与外部账户2相关的map类型的状态变量1001-2000,分解到了外部账户2的存储中,以此类推。
除了map数据结构,还可以通过其它数据结构定义外部账户地址到一种资产类型的映射,这里并不限制。
最简单的情形例如图7所示,一个区块链***中创建了一个智能合约,而且该智能合约中定义了一种新类型的资产。而且,创建的合约中,可以仅定义一种新类型的资产,或者是定义多种新类型资产的情况下仅启用其中的一种(而另外的新类型资产未启用或未初始化)。这种情况下,由于每个外部账户对应一种类型的资产的余额,所以该类型的资产的余额可以不需要组织成树的形式,通过一个key-value即可以存储。其中,这个map类型中,key = SHA3(map中的关键字,变量声明位置),也就是把map中的关键字和状态变量声明位置拼在一起成为一定长度(例如64字节)的字符串后计算hash值。value可以存储变量的实际值,即balanceA类型的资产的余额。这样,外部账户的storage_root可以是这个key-value的hash值。每个外部账户都可以有一个这样的map数据。例如,外部账户1的storage_root指向其map类型中一个key-value;外部账户2指向其map类型中一个key-value;以此类推。综上,对于区块链***中仅有一个智能合约的情况,且该智能合约中仅定义或启用了一种新类型的资产,则区块链中的状态树的存储包括两层;第一层通过树形结构在每个叶子节点中存储一个外部账户相关的包括所述新类型资产的key-value的hash值;第二层存储所述map定义的包括所述外部账号与所述新类型资产的key-value形式的映射关系。
前面提到,在一个智能合约中,可以定义多个资产类型,例如balanceA、balanceB、balanceC、balanceD、…。这样,每个外部账户可以有分别对应balanceA、balanceB、balanceC、balanceD、…类型的资产的余额。这种情况下,由于每个外部账户对应多种类型的资产的余额,该多种类型的资产的余额可以组织成树的形式。如图6中所示,在第二层的存储树中,通过节点1、节点2、节点3共三个节点来示意性的表示一种树的形式。这个树例如是MPT树,则节点1、节点2、节点3可以示意性的表示MPT树中的扩展节点、分支节点。其中,这个map类型中,key = SHA3(map中的关键字,变量声明位置),也就是把map中的关键字和状态变量声明位置拼在一起成为一定长度(例如64字节)的字符串后计算hash值。value可以存储状态变量的实际值,即balanceA、balanceB、balanceC、balanceD、…类型的资产的余额。如图4中,外部账户1的存储树的叶子节点分别具有balanceA、balanceB、balanceC、balanceD、…类型的资产的余额。这样,外部账户的storage_root可以是balanceA、balanceB、balanceC、balanceD、…类型的资产的key-value组成树的形式后的根hash值。每个外部账户都可以有一个这样的map数据。例如,外部账户1的storage_root指向其map类型中一组key-value的树形结构;外部账户2的storage_root指向其map类型中一组key-value的树形结构。以此类推。这样,对于区块链***中仅有一个智能合约的情况,且该智能合约中定义且启用了至少两种新类型的资产,则区块链中状态树的存储包括两层;第一层通过树形结构在每个叶子节点中存储一个外部账户相关的包括所有所述新类型资产的key-value的根hash值;第二层通过树形结构在每个叶子节点中存储所述map定义的包括所述外部账号与一种所述新类型资产的key-value形式的映射关系。
在一个区块链***中,可以创建多个智能合约。例如一个区块链***中创建了多个智能合约,这些智能合约可以通过树形结构组织起来,如图8所示,即如图中的第二层为合约存储树。大多数智能合约中的每个,可以定义一种或多种新类型的资产。每个智能合约中,有不同的状态。例如图8中,通过树形结构连接外部账户1的,示出了两个合约。每个合约基于其ID、storage_root可以计算得到一个hash值,该hash值可以存储于第二层树形结构的一个叶子节点中,如图中的schematic_storage_root中。对于这两个创建的合约中的每个仅定义一种新类型的资产的情况,或者是定义多种新类型资产的情况下仅启用其中的一种(而另外的新类型资产未启用或未初始化)的情况,每个合约对应一种类型的资产的余额,所以该类型的资产的余额可以不需要组织成树的形式,通过一个key-value即可以存储,类似图7中的第二层结构。这样,一个智能合约的storage_root可以是这个key-value的hash值。以此类推。综上,对于区块链***中有至少两个智能合约的情况,且该智能合约中仅定义或启用了一种新类型的资产,则区块链中状态树的存储包括三层;第一层通过树形结构在每个叶子节点中存储与一个外部账户相关的包括所有智能合约涉及信息的根hash值;第二层通过树形结构在每个叶子节点中存储一个外部账户相关的包括一个智能合约涉及的所述新类型资产的key-value的hash值;第三层存储所述map定义的包括所述外部账号与所述资产的key-value形式的映射关系。
在一个区块链***中,可以创建多个智能合约,并且每个合约中可以定义多个资产类型,例如balanceA、balanceB、balanceC、balanceD、…。该情况可以如图5所示。通过树形结构连接外部账户1的,示出了两个合约。即为第二层合约存储树。实际上,第二层的存储可以包括多个智能合约,即可以有多个叶子节点。每个合约基于其ID、storage_root可以计算得到一个hash值,该hash值可以存储于第二层树形结构的一个叶子节点中,如图中的schematic_storage_root中。第二层的每个叶子节点可以用来存储该外部账户下涉及的一个智能合约的存储的根hash值,可以基于包括该外部账户涉及的合约ID(contract ID)、storage的hash值计算得到。第三层为存储树。具体的,第三层树形结构的根节点为外部账户涉及的智能合约中的状态变量的根hash值。类似的,第三层可以通过以节点1、节点2、节点3共三个节点来示意性的表示MPT树的形式,具体的,可以表示MPT树中的扩展节点、分支节点。第三层的每个叶子节点可以用来存储合约中的一个状态变量的value值。上述的三层树的结构,每棵树的根节点到叶子节点的路径上存储的一部分数据连起来可以构成key,叶子节点中可以存储value。这样,通过这样的存储模型,可以在每个外部账户下存储该外部账户涉及的每个智能合约中的状态变量的key-value。综上,对于区块链***中有至少两个智能合约的情况,且该智能合约中仅定义或启用了至少两种新类型的资产,则区块链中状态树的存储包括三层;第一层通过树形结构在每个叶子节点中存储与一个外部账户相关的包括所有智能合约涉及信息的根hash值;第二层通过树形结构在每个叶子节点中存储一个外部账户相关的包括一个智能合约涉及的所有所述新类型资产的key-value的根hash值;第三层通过树形结构在每个叶子节点存储所述map定义的包括所述外部账号与一种所述新类型资产的key-value形式的映射关系。
上述图5-8的示例中,所述第一层通过树形结构在每个叶子节点中还可以存储该外部账户的交易计数。
上述图5、图8的示例中,显示出所述第二层通过树形结构在每个叶子节点中还存储关联的智能合约的编号的情形。此外,所述第二层还可以不在每个叶子节点中存储关联的智能合约的编号,而是第二层的根节点通过第二层的树形结构到第二层每个叶子节点的路径中存储涉及的智能合约的地址或基于所述涉及的智能合约的地址的映射值。
结合上述内容,本申请一种区块链***中的状态存储方法,如图9所示。该区块链***中至少包括两个分片,而且,不同分片中的节点存储不同的外部账户集合的状态。
所述区块链***,可以如图10所示,例如包括4个分片。每个分片可以包括4个节点。每个分片中的4个节点可以都是全量节点。这仅是一个说明性是的实例,也可以不同的分片具有不同数量的节点,这里并不限定。每个分片中包含的节点可以满足拜占庭容错(Byzantine Fault Tolerance,BFT)要求。所述的拜占庭容错要求可以理解为在分片内部可以存在拜占庭节点,而分片对外不体现拜占庭行为。一般的,一些拜占庭容错算法中要求节点个数大于3f+1,f为拜占庭节点个数,例如实用拜占庭容错算法PBFT(PracticalByzantine Fault Tolerance)。
不同分片中的节点可以存储不同的外部账户集合的状态。如图10中的举例,分片1中的节点A、B、C、D,每个节点的状态存储外部账户1、5、9、13...(例如按照从1起始间隔为4的正整数标明的外部账户构成的集合)的状态。关于外部账户1、5、9、13...的状态在节点A、B、C、D中的存储方式,如图5-8中的任一示例。
以结合最简单的图7中的实现为例,区块链***中创建了一个智能合约,而且该智能合约中定义了一种新类型的资产。创建的合约中可以仅定义一种新类型的资产,或者是定义多种新类型资产的情况下仅启用其中的一种(而另外的新类型资产未启用或未初始化)。这种情况下,由于每个外部账户对应一种类型的资产的余额,所以该类型的资产的余额可以不需要组织成树的形式,通过一个key-value即可以存储。其中,这个map类型中,key= SHA3(map中的关键字,变量声明位置),也就是把map中的关键字和变量声明位置拼在一起成为一定长度(例如64字节)的字符串后计算hash值。value可以存储变量的实际值,即balanceA类型的资产的余额。这样,外部账户的storage_root可以是这个key-value的hash值。每个外部账户都可以有一个这样的map数据。例如,外部账户1的storage_root指向其map类型中一个key-value;外部账户2指向其map类型中一个key-value;以此类推。综上,对于区块链***中仅有一个智能合约的情况,且该智能合约中仅定义或启用了一种新类型的资产,则区块链中的状态树的存储包括两层;第一层通过树形结构在每个叶子节点中存储一个外部账户相关的包括所述新类型资产的key-value的hash值;第二层存储所述map定义的包括所述外部账号与所述新类型资产的key-value形式的映射关系。
以结合图6中的实现为例,在一个智能合约中,可以定义多个资产类型,例如balanceA、balanceB、balanceC、balanceD、…。这样,每个外部账户可以有分别对应balanceA、balanceB、balanceC、balanceD、…类型的资产的余额。这种情况下,由于每个外部账户对应多种类型的资产的余额,该多种类型的资产的余额可以组织成树的形式。这样,对于区块链***中仅有一个智能合约的情况,且该智能合约中定义且启用了至少两种新类型的资产,则区块链中状态树的存储包括两层;第一层通过树形结构在每个叶子节点中存储一个外部账户相关的包括所有所述新类型资产的key-value的根hash值;第二层通过树形结构在每个叶子节点中存储所述map定义的包括所述外部账号与一种所述新类型资产的key-value形式的映射关系。
以结合图8中的实现为例,一个区块链***中创建了多个智能合约,这些智能合约可以通过树形结构组织起来,即如图8中的第二层为合约存储树。对于这两个创建的合约中的每个仅定义一种新类型的资产的情况,或者是定义多种新类型资产的情况下仅启用其中的一种(而另外的新类型资产未启用或未初始化)的情况,每个合约对应一种类型的资产的余额。这样,对于区块链***中有至少两个智能合约的情况,且该智能合约中仅定义或启用了一种新类型的资产,则区块链中状态树的存储包括三层;第一层通过树形结构在每个叶子节点中存储与一个外部账户相关的包括所有智能合约涉及信息的根hash值;第二层通过树形结构在每个叶子节点中存储一个外部账户相关的包括一个智能合约涉及的所述新类型资产的key-value的hash值;第三层存储所述map定义的包括所述外部账号与所述资产的key-value形式的映射关系。
以结合图5中的实现为例,一个区块链***可以创建多个智能合约,并且每个合约中可以定义多个资产类型。这样,对于区块链***中有至少两个智能合约的情况,且该智能合约中仅定义或启用了至少两种新类型的资产,则区块链中状态树的存储包括三层;第一层通过树形结构在每个叶子节点中存储与一个外部账户相关的包括所有智能合约涉及信息的根hash值;第二层通过树形结构在每个叶子节点中存储一个外部账户相关的包括一个智能合约涉及的所有所述新类型资产的key-value的根hash值;第三层通过树形结构在每个叶子节点存储所述map定义的包括所述外部账号与一种所述新类型资产的key-value形式的映射关系。
不同分片中的节点可以存储不同的外部账户集合的状态。除了如图10中对分片1的举例,分片2中的节点E、F、G、H,每个节点的状态存储外部账户2、6、10、14...(例如按照从2起始间隔为4的正整数标明的外部账户构成的集合)的状态;分片3中的节点I、J、K、L,每个节点的状态存储外部账户3、7、11、15...(例如按照从3起始间隔为4的正整数标明的外部账户构成的集合)的状态;分片4中的节点M、N、O、P,每个节点的状态存储外部账户4、8、12、16...(例如按照从4起始间隔为4的正整数标明的外部账户构成的集合)的状态。分片2、3、4中的节点存储对应外部账户的方式,与上述类似,这里了不再赘述。需要说明的是,不同分片对应的不同外部账户集合,这些集合之间可以有一定的交集。例如,分片2和分片3分别对应的两个外部账户集合{外部账户集合}分片2和{外部账户集合}分片3,两个集合之间可以没有交集的外部账户,也可以有一定交集的外部账户。
上面图10的例子中,不同分片对应的外部账户,根据外部账户的唯一标识分别从不同的初始值开始以相同的间隔构成的账户集合,这是一种取模的方式。除了这种取模的方式外,还可以采用分段的方式。例如,区块链***中的外部账户包括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,如图11中的示意。可以简单的解释为根据账户account的hash值将对应的状态分配至图11中的环的顺时针方向的第一个分片哈希值对应的分片中。采用一致性哈希方式进行分配,当分片发生变化时,仅有较少部分的外部账户相关的存储会发生变化,不至于使大多数的分片的存储进行调整,从而降低=命中低的问题。
此外,还可以根据账户注册地将账户的状态存储分配至相应的分片上。所述的注册地可以包括用户注册账户时所连接的区块链节点,例如,用户注册账户时通过客户端连接至区块链节点E,节点E属于分片2,则注册生成的账户对应于分片2。另一些实施场景中,所述的注册地也可以为用户注册账户时所在的地理位置。例如一个用户在注册账户时其IP地址位于香港特别行政区,而区块链***中有一个分片对应于相关特别行政区的区块链业务,例如分片4,则该用户注册的账户对应至分片4。因此,本说明书提供的另一个实施例中,所述预定的分片策略可以包括:根据账户的注册地确定账户所属的分片。该注册地包括用户注册账户时通过客户端连接至区块链节点所归属的分片,或者用户注册账户时其IP所在的地理位置,或者用户填写/选择的归属地。对于后者,根据用户注册账户时其IP所在的地理位置或用户填写/选择的归属地,可以将该账户的状态存储分配至相同/相近地理位置的分片上,或者将该账户的状态存储分配至***指定的分片上。
通过根据注册地来确定账户的所属分片的分片策略,可以将一些具有地域性的业务集中在同一个分片内处理,尽量将交易涉及新增、删除和修改的状态控制在单个分片内,可以有效减少跨分片的分布式事务,减少跨分片的消息交互和事务处理,进而可以提高***吞吐量和性能。例如在一个区块链电子***的区块链场景中,假如对应中国的省份划分有不同的分片,如广东的用户账户注册到广东的分片中,浙江的用户账户注册到浙江的分片中。在实际应用中,广东的用户通常在广东进行消费,与广东的其他用户发生交易的可能性更大;而浙江的用户通常是在浙江进行消费,与浙江的其他用户发生交易的可能性更大。那么广东的用户多数情况下也是在广东省内开***,类似的,浙江的用户也多数是在浙江省内开***。这样,基于用户的账户的注册地来划分确定账户的分片,可以极大的减少跨分片交易,降低区块链***的复杂度。
此外,在另一个实施例中,本申请也提供一种按照业务关系配置账户的状态存储所属的分片。例如在区块链跨境汇款业务中,通过智能合约实现了跨境的转账交易,并且将链下资产锚定到链上发行的资产。通过客户端接入不同银行的账户,发生转账的交易对方可能不同。根据发生业务往来的频次和占比,可以将关联性大的账户的状态存储分配至同一分片。例如,区块链跨境汇款业务中,通过客户端接入银行1的账户a大部分转账发生在与通过客户端接入银行2的账户b之间,即账户a与账户b这两个账户的关联性较大,因此,可以将调用智能合约产生的与账户a和账户b相关的状态存储分配至相同的分片中。当然,上述提到的不同的分配方式中,可以根据业务关系动态调整分片存储的账户状态。
此外,如前所述,本说明书实施例提供的区块链分片机制也支持跨分片的交易,如通过提供可靠消息传输机制的中间节点或区块链主链。
当然,区块链***中除了上述提到的一些汇款、电子***的跨账户交易外,还存在一些单账户的交易,例如存证交易。这类单账户交易的发起账户,调用智能合约产生的状态存储,集中在发起账户本身,一般不涉及其他账户。由于不存在跨分片交易,适用上述状态存储方案时,可以更为高效、简单的提升吞吐量,提升区块链性能,并且易于克服存储瓶颈的问题。
本申请提供的所述状态存储方法,如图9所示,具体包括:
S91:归属于分片中的区块链节点执行调用合约的交易,产生待存储的与所述区块链外部账户相关的状态。
区块链中的交易可以支持创建和调用智能合约。对于创建合约的交易来说,区块链节点例如可以接收客户端发送的包含创建智能合约的交易,完成智能合约的部署。通过P2P网络,该创建智能合约的交易可以传播到其它区块链节点上(或是传播到其它大多数的区块链节点上)。每个接收到这个交易的区块链节点一般会对该交易进行验证和共识。例如对于有主共识算法,例如实用拜占庭容错(Practical Byzantine Fault Tolerance,PBFT),区块链共识网络中的主节点可以发起共识。共识达成后,区块链网络中的区块链节点可以在本地执行这个交易。具体的,区块链节点可以通过本地的虚拟机(例如以太坊虚拟机EVM)执行这个创建合约的交易,并生成对应的合约实例。合约创建后,区块链上出现一个与该智能合约对应的合约账户。该合约账户在区块链上的存储可以包括codehash和部署的合约代码(通常是合约代码的字节码)。codehash的值为部署的合约代码的hash值。这个合约账户一般拥有一个特定的地址。
此外,也可以是与区块链代码一同编译的原生合约,完成智能合约的部署。
智能合约中可以定义新的资产类型,例如前述程序代码片段中的balanceA。当然,在一个智能合约中,可以定义多个资产类型,例如balanceA、balanceB、balanceC、…。如前所述,智能合约中还可以定义状态变量。例如通过以太坊提供的solidity高级开发语言中,可以定义的状态变量包括两种类型,一种是基本数据类型的状态变量,另一种是映射(map或mapping)类型的状态变量。通过map类型的状态变量,可以为每个外部账户赋予持有和交易这种新创建的数字资产的能力。如上述代码的例子,一般的,每个外部账户都可以对应一个balanceA类型的资产。那么,如果区块链的状态树中存在10000个外部账户,则通过智能合约,每个外部账户可以对应持有/交易balanceA类型的资产,即存在10000个“外部账户→balanceA”的映射。类似的,对于包括balanceB类型的资产,可以存在10000个“外部账户→balanceB”的映射。以此类推。如前所述,除了map数据结构,还可以通过其它数据结构定义外部账户地址到一种资产类型的映射,这里并不限制。以下以map形式的数据结构举例说明。
这个合约成功创建之后,后续外部账户可以调用这个合约。智能合约可以以合约代码中规定的方式在区块链网络中每个节点独立的执行,执行的交易、产生的状态和交易的回执可以保存在区块链上。调用合约一般可以通过发起交易的形式。交易的from字段是发起调用智能合约的账户的地址,to字段中可以表示被调用的智能合约的地址,交易的data字段可以包括调用智能合约的方法和传入的参数。通过调用智能合约,map中外部账户对应的合约状态可能发生变化,例如外部账户对应的某一资产类型的余额可能会发生改变。这样,map映射中的value值会发生变化。变化后的value值需要存储在区块链上。这样,所述合约状态包括对应区块链外部账号的状态。
如前所述,所述待存储的合约状态包括合约中定义的外部账户与资产的映射关系。具体的,所述合约中可以通过map数据结构或其它数据结构定义这种映射关系。以map这种数据结构定义为例,该map中定义的一般是外部账号与资产的映射关系。如果在智能合约中定义了一种新的资产,如定义了一种balanceA的资产,则通过map可以定义外部账号与这个balanceA类型资产的映射关系。此外,可以通过对编译器、虚拟机中的适配,设置一种定义类似数据结构的方式,如:
schema {
uint256 balanceP;
bool owner_flag;
};
上述代码示例也可以定义外部账户与资产的映射关系。具体的,uint256表示定义了一种名为balanceP的资产类型,为无符号整数,256bit长度。bool表示布尔类型变量,对应外部账户的标识owner_flag。这样,通过这种方式也实现了定义外部账户与资产的映射关系。当然,需要编译器和虚拟机的适配以支持合约中这样的定义方式。
客户端可以发起调用合约的交易至区块链***。区块链***中,可以由前述的主链接收所述调用合约的交易,并将该交易路由至存储所述外部账户的分片内。该调用合约的交易中,执行后一般涉及相关的外部账户的状态发生变化。所述发生变化后的外部账户的状态,包括合约中涉及的相关外部账户的状态,如通过map数据结构定义的外部账户与资产的映射关系,需要存储至对应分片的节点的状态存储中。所述主链可以作为接收所述交易和路由所述交易的角色。所述路由交易,例如可以根据该调用合约的交易涉及的发生状态改变的外部账户,将该交易路由至存储所述外部账户的分片内。具体的,所述主链按照区块链***采用的取模、分段、注册地之类的策略将该交易路由至存储所述外部账户的分片内。
进而,归属于分片中的区块链节点可以执行调用合约的交易,并产生待存储的与所述区块链外部账户相关的状态。
此外,与S91类似的,归属于分片中的区块链节点还可以是执行创建合约的交易。执行创建合约的交易的过程中,也可能产生待存储的与所述区块链外部账户相关的状态,例如对外无账户相关的状态进行初始化。以下主要以执行调用合约的交易为例进行说明,执行创建合约的交易与此类似,不再赘述。对于创建合约的交易,类似的,可以是由前述的主链接收所述创建合约的交易,并将该交易路由至存储所述外部账户的分片内。
S93:将所述待存储的与所述区块链外部账户相关的状态存储到对应的区块链外部账户的状态存储中。
如图5、图6、图7、图8中所示,storage中的map类型状态变量可以以key-value形式存储。具体的一个例子中,对于map类型,key = SHA3(map中的关键字,变量声明位置),也就是把map中的关键字和变量声明位置拼在一起成为一定长度(例如64字节)的字符串后计算hash值。value可以存储变量的实际值。
最简单的情形例如图7所示,一个区块链***中创建了一个智能合约,而且该智能合约中定义了一种新类型的资产。而且,创建的合约中,可以仅定义一种新类型的资产,或者是定义多种新类型资产的情况下仅启用其中的一种(而另外的新类型资产未启用或未初始化)。这种情况下,由于每个外部账户对应一种类型的资产的余额,所以该类型的资产的余额可以不需要组织成树的形式,通过一个key-value即可以存储。其中,这个map类型中,key = SHA3(map中的关键字,变量声明位置),也就是把map中的关键字和变量声明位置拼在一起成为一定长度(例如64字节)的字符串后计算hash值。value可以存储变量的实际值,即balanceA类型的资产的余额。这样,外部账户的storage_root可以是这个key-value的hash值。每个外部账户都可以有一个这样的map数据。例如,外部账户1的storage_root指向其map类型中一个key-value;外部账户2指向其map类型中一个key-value;以此类推。综上,对于区块链***中仅有一个智能合约的情况,且该智能合约中仅定义或启用了一种新类型的资产,则区块链中的状态树的存储包括两层;第一层通过树形结构在每个叶子节点中存储一个外部账户相关的包括所述新类型资产的key-value的hash值;第二层存储所述map定义的包括所述外部账号与所述新类型资产的key-value形式的映射关系。
前面提到,在一个智能合约中,可以定义多个资产类型,例如balanceA、balanceB、balanceC、balanceD、…。这样,每个外部账户可以有分别对应balanceA、balanceB、balanceC、balanceD、…类型的资产的余额。这种情况下,由于每个外部账户对应多种类型的资产的余额,该多种类型的资产的余额可以组织成树的形式。如图6中所示,在第二层的存储树中,通过节点1、节点2、节点3共三个节点来示意性的表示一种树的形式。这个树例如是MPT树,则节点1、节点2、节点3可以示意性的表示MPT树中的扩展节点、分支节点。其中,这个map类型中,key = SHA3(map中的关键字,变量声明位置),也就是把map中的关键字和变量声明位置拼在一起成为一定长度(例如64字节)的字符串后计算hash值。value可以存储变量的实际值,即balanceA、balanceB、balanceC、balanceD、…类型的资产的余额。如图6中,外部账户1的存储树的叶子节点分别具有balanceA、balanceB、balanceC、balanceD、…类型的资产的余额。这样,外部账户的storage_root可以是balanceA、balanceB、balanceC、balanceD、…类型的资产的key-value组成树的形式后的根hash值。每个外部账户都可以有一个这样的map数据。例如,外部账户1的storage_root指向其map类型中一组key-value的树形结构;外部账户2的storage_root指向其map类型中一组key-value的树形结构。以此类推。这样,对于区块链***中仅有一个智能合约的情况,且该智能合约中定义且启用了至少两种新类型的资产,则区块链中状态树的存储包括两层;第一层通过树形结构在每个叶子节点中存储一个外部账户相关的包括所有所述新类型资产的key-value的根hash值;第二层通过树形结构在每个叶子节点中存储所述map定义的包括所述外部账号与一种所述新类型资产的key-value形式的映射关系。
在一个区块链***中,可以创建多个智能合约。例如一个区块链***中创建了多个智能合约,这些智能合约可以通过树形结构组织起来,如图8所示,即如图中的第二层为合约存储树。大多数智能合约中的每个,可以定义一种或多种新类型的资产。每个智能合约中,有不同的状态。例如图8中,通过树形结构连接外部账户1的,示出了两个合约。每个合约基于其ID、storage_root可以计算得到一个hash值,该hash值可以存储于第二层树形结构的一个叶子节点中,如图中的schematic_storage_root中。对于这两个创建的合约中的每个仅定义一种新类型的资产的情况,或者是定义多种新类型资产的情况下仅启用其中的一种(而另外的新类型资产未启用或未初始化)的情况,每个合约对应一种类型的资产的余额,所以该类型的资产的余额可以不需要组织成树的形式,通过一个key-value即可以存储,类似图7中的第二层结构。这样,一个智能合约的storage_root可以是这个key-value的hash值。以此类推。综上,对于区块链***中有至少两个智能合约的情况,且该智能合约中仅定义或启用了一种新类型的资产,则区块链中状态树的存储包括三层;第一层通过树形结构在每个叶子节点中存储与一个外部账户相关的包括所有智能合约涉及信息的根hash值;第二层通过树形结构在每个叶子节点中存储一个外部账户相关的包括一个智能合约涉及的所述新类型资产的key-value的hash值;第三层存储所述map定义的包括所述外部账号与所述资产的key-value形式的映射关系。
在一个区块链***中,可以创建多个智能合约,并且每个合约中可以定义多个资产类型,例如balanceA、balanceB、balanceC、balanceD、…。该情况可以如图5所示。通过树形结构连接外部账户1的,示出了两个合约。即为第二层合约存储树。实际上,第二层的存储可以包括多个智能合约,即可以有多个叶子节点。每个合约基于其ID、storage_root可以计算得到一个hash值,该hash值可以存储于第二层树形结构的一个叶子节点中,如图中的schematic_storage_root中。第二层的每个叶子节点可以用来存储该外部账户下涉及的一个智能合约的存储的根hash值,可以基于包括该外部账户涉及的合约ID(contract ID)、storage的hash值计算得到。第三层为存储树。具体的,第三层树形结构的根节点为外部账户涉及的智能合约中的状态变量的根hash值。类似的,第三层可以通过以节点1、节点2、节点3共三个节点来示意性的表示MPT树的形式,具体的,可以表示MPT树中的扩展节点、分支节点。第三层的每个叶子节点可以用来存储合约中的一个状态变量的value值。上述的三层树的结构,每棵树的根节点到叶子节点的路径上存储的一部分数据连起来可以构成key,叶子节点中可以存储value。这样,通过这样的存储模型,可以在每个外部账户下存储该外部账户涉及的每个智能合约中的状态变量的key-value。综上,对于区块链***中有至少两个智能合约的情况,且该智能合约中仅定义或启用了至少两种新类型的资产,则区块链中状态树的存储包括三层;第一层通过树形结构在每个叶子节点中存储与一个外部账户相关的包括所有智能合约涉及信息的根hash值;第二层通过树形结构在每个叶子节点中存储一个外部账户相关的包括一个智能合约涉及的所有所述新类型资产的key-value的根hash值;第三层通过树形结构在每个叶子节点存储所述map定义的包括所述外部账号与一种所述新类型资产的key-value形式的映射关系。
上述图5-8的示例中,所述第一层通过树形结构在每个叶子节点中还可以存储该外部账户的交易计数。
上述图5、图8的示例中,显示出所述第二层通过树形结构在每个叶子节点中还存储关联的智能合约的编号的情形。此外,所述第二层还可以不在每个叶子节点中存储关联的智能合约的编号,而是第二层的根节点通过第二层的树形结构到第二层每个叶子节点的路径中存储涉及的智能合约的地址或基于所述涉及的智能合约的地址的映射值。
前述提到,智能合约中可以定义的状态变量包括两种类型,一种是基本数据类型的状态变量,另一种是映射(map或mapping)类型的状态变量。上述map类型的状态变量,与每个外部账户有关。这样,对于每个外部账户来说,这个map类型的状态变量是局部类型的状态变量。此外,智能合约中定义的基本数据类型,可能与每个外部账户都相关,而不仅仅是与一个外部账户相关。这样,基本数据类型的状态变量,属于全局类型的状态变量。
此外,如前所述,创建智能合约后,会出现合约账户。该合约账户也可能与每个外部账户相关,而不仅仅是与一个外部账户相关。例如,一个关于打赌的智能合约中,约定了外部账户A和外部账户B在第二天天气条件下的转账情况。如第二天是晴天,则外部账户A将转账一笔资产(如50元)至外部账户B,如第二天不是晴天,则外部账户B将转账一笔资产(如50元)至外部账户A。而在外部账户A和外部账户B调用这个智能合约时,需要各自将一笔资产(如50元)转入合约账户。这样,合约账户中的状态变量也属于全局类型的状态变量。
前述通过图5-8示例出了局部类型状态变量的存储。以下说明全局类型状态变量的存储。
第一种方式是,在合约账户中,设置智能合约中基本数据类型的状态变量以及合约账户的状态变量的存储。例如,在合约账户的storage中存储基本数据类型的状态变量以及合约账户的状态变量。在图5的基础上,以图12为例加以说明。区块头中的state_root存储整个状态树的根节点的hash值。第一层树形结构的叶子节点可以用来存储外部账户存储和合约账户存储的根hash值。外部账户和合约账户可以分别有若干个。第一层叶子节点中每个合约账户的账户信息的根hash,可以基于包括该合约账户的nonce、balance、codehash以及该合约账户涉及的智能合约的存储的根hash值计算得到。所述智能合约的存储的根hash值如图12中合约账户 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,因此可以满足一般的一个智能合约中可能包括的全局状态的数量。
需要说明的是,本说明书提到的区块链节点,侧重逻辑节点的概念。也就是说,一个物理节点也可以从逻辑上划分为多个逻辑的节点。当然,本说明书中的区块链节点也可以适用于物理节点的情形。
通过上述本申请的实施例,区块链***中至少包括两个分片,不同分片中的节点存储不同的外部账户集合的状态,并且将待存储的与所述区块链外部账户相关的状态存储到对应的区块链外部账户的状态存储中,每个外部账户的状态存储对应的外部账户相关的状态,进而将使区块链***中不同的分片存储不同的外部账户集合的状态。这样,避免了单账户热点的问题,同时,每个分片承担的状态存储的负载压力比较小,可以提升整个区块链***的性能。而且,分散到各个外部账户的状态存储后,由于一个外部账户的状态数量相对比较少,并不存储完整的区块链状态,从而能够解决存储能力瓶颈问题。同时,本申请的方式,并不会像图3中的将所有外部账户的状态集中于合约账户的状态存储中,从而可以大大降低每个外部账户的树形结构的深度,进而缩短了查找、更新外部账户的时间,提升了区块链存储的读写效率。
对于全局状态,即使采用上述第一种的方式全部存储于合约账户的状态存储中,一般也可以满足32个全局状态数量的要求,即采用两层深度的属性结构可以满足存储的需求,从而也可以大大降低树的深度。采用上述第二种或第三种方式,同样可以大大降低树的深度。
如图10所示,本申请实施例还提供一种区块链***,该区块链***中至少包括两个分片,不同分片中的节点用于存储不同的外部账户集合的状态;且,
归属于分片中的区块链节点执行调用合约的交易而产生的与所述区块链外部账户相关的状态,存储于对应的区块链外部账户的状态存储中。
所述与所述区块链外部账户相关的状态可以包括:
所述合约中定义的外部账户与资产的映射关系。
所述合约中定义的外部账户与资产的映射关系可以包括:
通过map数据结构定义的外部账户与资产的映射关系。
所述通过map数据结构定义的外部账户与资产的映射关系可以通过key-value来存储。
对于区块链***中仅有一个智能合约的情况,且该智能合约中仅定义或启用了一种新类型的资产,则区块链中状态树的存储可以包括两层;
第一层通过树形结构在每个叶子节点中存储一个外部账户相关的包括所述新类型资产的key-value的hash值;
第二层存储定义的包括所述外部账户与所述新类型资产的key-value的映射关系。
对于区块链***中仅有一个智能合约的情况,且该智能合约中定义且启用了至少两种新类型的资产,则区块链中状态树的存储可以包括两层;
第一层通过树形结构在每个叶子节点中存储一个外部账户相关的包括所有所述新类型资产的key-value的根hash值;
第二层通过树形结构在每个叶子节点中存储定义的包括所述外部账户与一种所述新类型资产的key-value的映射关系。
对于区块链***中有至少两个智能合约的情况,且该智能合约中仅定义或启用了一种新类型的资产,则区块链中状态树的存储可以包括三层;
第一层通过树形结构在每个叶子节点中存储与一个外部账户相关的包括所有智能合约涉及信息的根hash值;
第二层通过树形结构在每个叶子节点中存储一个外部账户相关的包括一个智能合约涉及的所述新类型资产的key-value的hash值;
第三层存储定义的包括所述外部账户与所述资产的key-value的映射关系。
对于区块链***中有至少两个智能合约的情况,且该智能合约中定义或启用了至少两种新类型的资产,则区块链中状态树的存储可以包括三层;
第一层通过树形结构在每个叶子节点中存储与一个外部账户相关的包括所有智能合约涉及信息的根hash值;
第二层通过树形结构在每个叶子节点中存储一个外部账户相关的包括一个智能合约涉及的所有所述新类型资产的key-value的根hash值;
第三层通过树形结构在每个叶子节点存储定义的包括所述外部账户与一种所述新类型资产的key-value的映射关系。
所述第一层通过树形结构在每个叶子节点中还可以存储该外部账户的交易计数。
所述第二层通过树形结构在每个叶子节点中还可以存储关联的智能合约的编号。
所述区块链节点执行调用合约的交易产生的与所述区块链合约账户相关的状态可以存储于对应的区块链合约账户的状态存储中。
所述与区块链合约账户相关的状态可以包括所述合约中基本数据类型的状态变量以及合约账户的状态变量;所述合约账户的状态存储中可以通过树形结构存储所述区块链合约账户相关的状态的key-value的映射关系。
所述区块链节点执行调用合约的交易产生的与所述区块链合约账户相关的状态可以存储于独立于所述外部账户存储以及所述合约账户存储的全局状态存储中;所述全局状态存储中可以通过树形结构存储所述区块链合约账户相关的状态的key-value的映射关系。
所述合约账户的状态变量可以存储于对应的区块链合约账户的状态存储中;所述合约账户的状态存储中可以通过树形结构存储所述区块链合约账户的状态变量的key-value的映射关系;
所述基本数据类型的状态变量可以存储于独立于所述外部账户存储以及所述合约账户存储的全局状态存储中;所述全局状态存储中可以通过树形结构存储所述基本数据类型的状态变量的key-value的映射关系。
所述不同分片中的节点存储不同的外部账户集合的状态,可以包括:
不同分片对应的外部账户,根据外部账户的唯一标识分别从不同的初始值开始以相同的间隔构成外部账户集合;或,
不同分片对应的外部账户,根据外部账户的唯一标识分段后构成外部账户账户集合;或,
基于外部账户的唯一标识采用一致性哈希的方式将所述外部账户的状态存储分配至相应的分片上;或,
根据账户的注册地确定账户所属的分片。
所述注册地可以包括:
用户注册账户时通过客户端连接至区块链节点所归属的分片;或,
用户注册账户时其IP所在的地理位置;或,
用户填写/选择的归属地。
根据用户注册账户时其IP所在的地理位置或用户填写/选择的归属地,可以将该账户的状态存储分配至相同/相近地理位置的分片上,也可以将该账户的状态存储分配至***指定的分片上。
所述不同分片中的节点存储不同的外部账户集合的状态,可以包括:
按照业务关系配置账户的状态存储所属的分片。
所述区块链***还可以包括主链,用于接收所述调用合约的交易,并将该交易路由至存储所述外部账户的分片内。
所述由主链接收所述调用合约的交易,可以根据该调用合约的交易涉及的发生状态改变的外部账户,将该交易路由至存储所述外部账户的分片内。
如图13所示,本申请一实施例还提供一种区块链节点,该区块链节点归属于区块链***中的一个分片,包括:
存储单元132,用于存储外部账户集合的状态,且对应的外部账户集合不同于其它分片中的区块链节点中的外部账户集合;
执行单元131,用于执行如前所述的状态存储方法。
如图14所示,本申请一实施例还提供一种区块链节点,该区块链节点归属于区块链***中的一个分片,用于存储外部账户集合的状态,且对应的外部账户集合不同于其它分片中的区块链节点中的外部账户集合;
所述区块链节点包括:
处理器141;
存储器142,其中存储有程序,其中在所述处理器执行所述程序时,执行如前所述的状态存储方法。
上述状态分片方案,是本申请中给出的一种解决方案。除此之外,还可能存在其它状态分片方案。不论对于何种状态分片方案,只要不同分片中的节点存储不同的外部账户集合的状态,都会涉及确定不同分片的全部账户的世界状态的问题。
例如,分片1中的某一账户可能会发生与分片2中的另一账户相关的一笔交易。具体的,例如由分片1中的某一账户转账至分片2中的另一账户,或者分片1中的某一账户发起某个调用合约的交易,而该被调用的合约在执行时,涉及对分片2中某一账户的操作。调用合约的情况,按照前述所述的合约中定义的外部账户与资产的映射关系,具体的一个例子中,例如是分片1中某一账户发起偿还某新资产类型,该资产类型下的账户(包括外部账户和合约账户)各自具有一定的余额(balance)。如图15中的分片1中的外部账户1将一定数量的该类型的资产转移至合约账户,再按照合约中的条件,由合约账户转移至如图15中分片2的外部账户6。
显然的,上述例子涉及跨分片的交易。本申请提出一种基于主链的跨分片交易方法,能够在基于主链的区块链分片***中实现。本申请的基于主链的区块链分片***例如如图15所示,除了若干分片以外,还存在主链。主链包括若干区块链节点,如图中的Q1、Q2、Q3和Q4。主链与各个分片相连。如前所述,尽管图示中各个分片之间通过连接线示意出各个分片之间相连,但是,也可能各个分片并非是全部互通的,或者是每个分片均不与其它分片相通。对于最后一种情况,也就是说,各个分片之间可以互不相连,而仅与主链相连。这里,分片之间相通,可以是一个分片中的一个节点与另一分片中的任一节点都相通,也可以是一个分片中的一个节点与另一分片中的一个或部分节点相通。类似的,分片与主链相通,可以是分片中的一个节点与主链中的任一节点都相通或分片中的一个节点主链中的一个或部分节点相通,也可以是主链中的一个节点与分片中的任一节点都相通或分片中的一个或部分节点相通。
不同分片中的节点可以存储不同的外部账户集合的状态,包括上述如图5-12中对应的实施例中执行创建和/或调用合约的交易而产生的与外部账户相关的状态,也可以是普通转账交易产生的外部账户的状态。对于不采用本申请图5-12对应实施例的状态分片方案,而是将执行创建和/或调用合约的交易产生的与外部账户相关的状态存储于合约账户的状态存储中,可能存在不同分片中的节点存储不同合约账户状态的集合的情况,或者不同分片中的节点存储不同合约账户集合的状态的情况,也适用于下面将要提到的本申请的方案。所述不同分片中的节点存储不同合约账户状态的集合的情况,x例如区块链***存在一个合约,该合约对应的合约账户具有不同的状态,如状态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的状态}。此外,可以理解的,对于存在多个合约且每个合约具有多个状态,也可以是上述两种情况的混合。上述各种情况,笼统的说,可以称为不同分片存储不同的状态集合。
对于不同分片存储不同的状态集合,本申请提出的方案中引入主链,示意性的架构如图16所示。如图16中,分片1和分片2产生新区块的步调可以不一致;当然,也可以步调一致,这里主要以步调不一致加以说明。需要说明的是,这里为了简便,仅示出了2个分片的情况,多于2个分片的情况与此类似,不再赘述。而且,仅示出了分片1顺序产生区块101和102的情况,以及分片2中顺序产生区块201和202的情况。实际上,可以理解的,分片中处理交易请求,通过共识机制达成共识后,执行交易并生成区块。生成的区块的区块号一般是连续的,并且下一区块的区块头中通过一个字段锁定了上一区块的hash值,例如通过如图3中的Prev Hash字段来锁定。一个区块的hash值一般是该区块头中所有字段的hash计算的结果。在分片生成的区块的区块头中,如图3中所示,一般可以包括区块号(Block Num),时间戳(Timestamp),前一个区块的hash值(Prev Hash),以及交易根hash(Transaction_Root)、状态根hash(State_Root),还可以包括收据根hash(Receipt_Root)和随机数(Nonce)。在分片生成的区块的区块体中,如图3所示,一般可以包括原始交易列表,这些交易可以通过树形结构组织,如前述提到的MPT树,或者是merkle树等。通过树形结构组织的原始交易列表的树根的hash值,存放于区块头的Transaction_Root中。如前所述,state_root可以是当前区块链中所有账户的状态组成的MPT树的根的哈希值,即指向state_root的为一棵MPT形式的状态树。对于区块头中包括Receipt_Root的情况,Receipt_Root可以是当前区块中所有收据组成的Merkle或MPT树的根的hash值。
例如图16中所示,分片1顺序产生区块101和102,分片2顺序产生区块201和202。分片1在区块101有对应的状态集合,在区块102有对应的状态集合。分片2在区块201有对应的状态集合,在区块202有对应的状态集合。
本申请实施例中,提供了包含主链的区块链分片的***。主链中可以包括若干节点。一般的,主链中的节点具有较高的可信度,并且这些节点构成的主链符合拜占庭容错要求。主链可以具有自己的时钟,如图16中所示的主链时间轴即表达主链时钟的时间轴。按照主链的时间轴,分片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)。如图15中的分片1中的外部账户1将一定数量的该类型的资产转移至合约账户,再按照合约中的条件,由合约账户转移至如图15中分片2的外部账户6。分片1中可以执行在外部账户1中扣减一定新资产类型余额的操作;分片2中可以执行为外部账户6增加一定新资产类型余额的操作,而且这个操作需要由分片2中的节点来执行。那么,这个过程需要将分片1中接收到的交易的部分操作转发至分片2中,交由分片2来执行。
本申请可以通过基于包含主链的区块分片***执行。由于主链中的节点具有较高的可信度,因此可以将一个分片(后续称为源分片)中接收的跨分片的交易中涉及其它分片(后续称为目标分片)的操作发送至主链,并由主链转发至所述的目标分片。具体的,图17示出了本申请一实施例中在包含分片的区块链***中执行跨片事务的方法,包括:
S171:源分片生成源分片区块的过程中确定所述源分片区块中的跨分片交易,并将所述跨分片交易中需要由目标分片执行的跨片事务发送至主链。
客户端可以向源分片中相连的节点发起交易请求。该交易如前所述,可以是转账交易,也可以是创建/调用合约的交易。收到客户端发起交易的源分片中的节点,进而可以将该交易广播至源分片中的其它节点,或者转发至主节点。以采用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。例如如图10所示,分片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。此外,源分片生成的分片区块的区块体中,还可以包括所述原始交易列表中的跨片交易需要由目标分片执行的事务。如图18所示,分片2产生的分片区块201和分片区块202中,在区块体里除了原有的原始交易列表外,还可以包括跨片事务列表,该跨片事务列表中包括跨片交易中需要由目标分片执行的跨片事务。所述跨片事务列表一般可以是区块体中原始交易列表的子集。需要说明的是,由于可能存在分片2与不同目标分片的跨片交易,因此分片2产生的分片区块中的跨片事务列表中,可能包括需要由多个不同目标分片执行的跨片事务。相应的,在区块头中,可以设置一个字段,如跨片事务_root,用于存储所述区块体中跨片事务按照merkle树或MPT树的树形结构组织起来的树根的hash值。通过跨片事务_root,可以将区块体中的跨片事务列表锁定至区块头中。这样,分片区块的hash值,可以是根据区块头中的各个字段计算得到的hash,这些字段可以包括跨片事务_root。分片中后一区块可以通过区块头中的Prev_Hash字段锁定前一区块的hash值。
源分片除了将所述跨片事务发送至主链,还可以将生成的源分片区块的区块头发送至主链。
S173:主链生成主链区块的过程中,将接收到的需要由目标分片执行的跨片事务填入主链区块的区块体中,并将所述需要由目标分片执行的跨片事务按照目标分片的标识发送至对应的目标分片中。
主链中的节点接收到源分片发来的跨片事务后,可以先对跨片事务进行验证。例如,可以按照树形结构计算该跨片事务构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务是否与之前接收到的跨片事务重复。如果重复,可以不再处理本次发来的跨片事务,否则继续处理。
主链中的主节点可以收集源分片发来的交易,或者是主链中的非主节点接收源分片发来的交易后将这些交易转发至主链中的主节点,这些交易可以包括源分片发来的跨片事务列表。如前所述,每个源分片发来的跨片事务列表中,可能包括需要由多个不同目标分片执行的跨片事务。以图15为例加以说明,在包括4个分片的情况下,主链可能收到分片1~分片4发来的跨片事务,分片1发来的跨片事务包括{分片1中的跨片交易需要由分片2执行的跨片事务,分片1中的跨片交易需要由分片3执行的跨片事务},分片2发来的跨片事务包括{分片2中的跨片交易需要由分片1执行的跨片事务,分片2中的跨片交易需要由分片3执行的跨片事务,分片2的中跨片交易需要由分片4执行的跨片事务},分片3发来的跨片事务包括{分片3中的跨片交易需要由分片2执行的跨片事务,分片3中的跨片交易需要由分片4执行的跨片事务},分片4发来的跨片事务包括{分片4中的跨片交易需要由分片1执行的跨片事务,分片4中的跨片交易需要由分片2执行的跨片事务,分片4中的跨片交易需要由分片3执行的跨片事务}。如上例子所示,跨片事务中,可以包括目标分片的标识,也可以包括源分片的标识。
主链中的主节点可以将一段时间内各分片发来的一定数量的跨片事务打包并发起共识提议。此外,主链中的主节点打包的内容中除了所述跨片事务之外还可以包括其他交易。在主链中达成共识后,由主链中的各个节点执行这些打包的交易,生成主链区块。所述主链中的节点执行这些打包的交易,并不是执行其中的跨片事务。如前所述,这些跨片事务对应的账户状态在目标分片中存储,因此这些跨片事务对应的账户状态的操作需要由目标分片来执行。
主链中的各个节点执行这些打包的交易并生成区块,可以包括将所述需要由目标分片执行的跨片事务填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务以相同的树形结构组织成一棵树,并根据这棵树的树根生成hash值并将该hash值填入主链区块的区块头的交易根hash字段中。再在主链区块的区块头中加入区块号,时间戳,前一区块的hash等字段后,就生成了主链区块。
主链中的各个节点执行这些打包的交易并生成区块,将所述需要由目标分片执行的跨片事务填入主链区块的区块体中,具体可以是按照主链中的主节点发起共识提议的消息中需要由目标分片执行的跨片事务的顺序,将由目标分片执行的跨片事务填入主链区块的区块体中,如图19中所示的跨片事务列表中。此外,也可以是按照目标分片对跨片事务进行分组,将分组后的跨片事务填入主链区块的区块体中。分组后的各组跨片事务,可以按照分组编号升序或降序排列后填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务以相同的树形结构组织成一棵树,根据这棵树的树根生成hash值并填入主链区块的区块头的Transaction_root字段中。分组后的跨片事务例如为如下结构:
需要由分片1执行的跨片事务 |
...... |
需要由分片n执行的跨片事务 |
表1
如前述以图15中包括4个分片的例子,分组后的跨片事务按照目标分片具体可以包括4组:
需要由分片1执行的跨片事务(包括分片2和4发来的) |
需要由分片2执行的跨片事务(包括分片1、3、4发来的) |
需要由分片3执行的跨片事务(包括分片1、2、4发来的) |
需要由分片4执行的跨片事务(包括分片2和3发来的) |
表2
按照目标分片对跨片事务进行分组,分组后的每个组内跨片事务的顺序,最好与跨片事务的时间顺序一致,即按照时间先后顺序排列。由于交易的先后顺序的不同很可能会导致交易结果的不同,因此,分组后的每个组内跨片事务按照时间先后顺序排列,利于保证后续将这些跨片事务发给目标分片后,目标分片执行这些跨片事务时不会引发由于顺序不一致而导致的错误或异常。
主链生成的主链区块,分组后的跨片事务填入该主链区块的区块体,并根据这些跨片事务按照树形结构计算得到的根节点生成hash值,将该生成的hash值填入区块头中的Transaction_Root,可以如图18中所示。类似的,主链上生成的区块,也可以通过hash来锁定,例如主链中的区块10002的区块头的Prev Hash中存储上一区块10001的hash值,以此类推。如图18所示,主链的区块的区块头(区块nHeader)中,可以包括区块号(Block Num),时间戳(Timestamp),前一个区块的hash值(Prev Hash)等字段,以及Transaction_Root。主链区块的区块体(区块nBody)中,可以包括该主链区块生成之前的各个分片发送至该主链的跨片事务,即需要目标分片所执行的操作。优选的,主链区块的区块体包括的各个目标分片需要执行的跨片事务,是未经主链在之前已生成的区块中打包的。
需要说明的是,主链中生成的主链区块,如果该区块生成前在主节点打包交易时中对于某一分片没有其执行的跨片事务,则该主链区块的区块体中,可以不包括需要由该目标分片执行的跨片事务。
前述提到,源分片除了将所述跨片事务发送至主链,还可以将生成的源分片区块的区块头发送至主链。主链接收到源分片发来的源分片区块的区块头和跨片事务后,可以对源分片区块的区块头进行验证。验证可以包括,根据跨片事务按照树形结构计算根节点的hash值,确定该值与区块头中的跨片事务_root一致。如果不一致则验证不通过,反之验证通过。还可以验证源分片本次发来的源分片区块的区块头是否与之前发来的源分片区块的区块头相同,相同则说明与之前的源分片区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的源分片区块的区块头中的Prev Hash是否是上个区块号的源分片区块的hash值,如果是则通过验证,否则不通过。
对于源分片还将生成的源分片区块的区块头发送至主链的情况,主链在生成主链区块的过程中,还可以根据接收到的源分片区块的区块头计算得到该源分片区块的hash值。进而,主链可以将各个源分片发来的分片区块的hash值填入主链区块的区块体中,具体例如图19中的Shard1_BlockHash至Shardn_BlockHash中。进一步的,主链还可以将所述各个分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根(Shards_BlockRoot)字段中,如图19所示。如前所述,主链中的节点具有较高的可信度。主链上的节点将分片区块的区块hash锁定至主链区块中,可以避免分片对生成的分片区块进行回滚。这是因为,基于hash算法的性质,分片无法伪造不同交易的情况下而使得区块头保持不变,从而保障了分片交易的安全性。具体的,即可以保障跨分片交易的安全性,也可以保障分片内交易的安全性。图19中为了简化,将表1的内容简化为跨片事务列表。
主链区块中的各节点执行主节点共识提议中打包的交易,将接收到的需要由目标分片执行的跨片事务填入主链区块的区块体中并生成主链区块,这样可以在主链区块中锁定需要由目标分片执行的跨片事务。之后,可以将所述需要目标分片执行的跨片事务按照目标分片的标识发送至对应的目标分片中。如前述例子,可以将主链区块体中的跨片事务按照需要执行的目标分片的标识分别发送。
具体的,主链区块的区块体中的跨片事务列表,可以是按照目标分片对跨片事务进行分组后填入的。如前面表1中的例子。这样,主链可以按照主链区块的区块体中的分组将主链区块体中分组的跨片事务发送至所述分组对应的目标分片。如前面表2中的例子,主链将主链区块的区块体中需要由分片1执行的跨片事务(包括分片2和4发来的)发送至分片1,将需要由分片2执行的跨片事务(包括分片1、3、4发来的)发送至分片2,将需要由分片3执行的跨片事务(包括分片1、2、4发来的)发送至分片3,将需要由分片4执行的跨片事务(包括分片2和3发来的)发送至分片4。
主链生成主链区块后,除了将所述需要目标分片执行的跨片事务按照目标分片的标识发送至对应的目标分片中,还可以将所述主链区块的区块头发送至目标分片,例如与需要对应目标分片处理的跨片事务一并发送至所述目标分片。
S175:所述目标分片生成目标分片区块的过程中,将接收到所述主链发来的跨片事务填入所述目标分片区块的区块体中,并执行所述跨片事务。
所述目标分片中的节点接收到主链发来的跨片事务后,可以先对跨片事务进行验证。例如,可以按照树形结构计算该跨片事务构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务是否与之前接收到的跨片事务重复。如果重复,可以不再处理本次发来的跨片事务,否则继续处理。
所述目标分片,作为执行前述跨片事务的分片,也可以接收所述主链发来的需要由所述目标分片执行的跨片事务。具体的,可以是所述目标分片中的主节点接收所述主链发来的需要由所述目标分片执行的跨片事务;也可以是所述目标分片中的非主节点接收所述主链发来的需要由所述目标分片执行的跨片事务,再将这些跨片事务转发至所述目标分片中的主节点。此外,所述目标分片也可以接收与其连接的客户端发起的交易请求。该交易如前所述,可以是转账交易,也可以是创建/调用合约的交易。
所述目标分片中的主节点可以将一段时间内接收到的一定数量的交易打包并发起共识提议。所述打包的交易中可以包括前述主链发来的跨片事务,还可以包括所述目标分片接收到的客户端发来的交易。在所述目标分片中达成共识后,由所述目标分片中的各个节点执行这些打包的交易,生成目标分片区块。所述目标分片生成目标分片区块的过程中,可以将接收到所述主链发来的跨片事务填入所述目标分片区块的区块体中,具体如原始交易列表中。此外,所述目标分片还可以将打包的客户端发来的交易填入所述目标分片区块的区块体中,具体如原始交易列表中。填入目标分片区块的区块体中的交易,可以按照树形结构组织起来,根据树根产生的hash值即为生成的目标分片区块的区块头中的Transaction_Root。
所述目标分片中的各节点执行交易,包括执行所述跨片事务。此外,目标分片中的各节点执行的交易还可以包括所述目标分片接收到的客户端发来的交易。由于所述目标分片中存储有所述跨片事务对应的账户状态,因此,执行所述跨片事务会导致所述目标分片中存储的相应账户的状态发生改变。目标分片中的各节点执行所述跨片事务后,并不将执行所述跨片事务后导致的本分片中相应的账户变化后的状态提交至底层数据库,即不持久化存储。当所述目标分片收到源分片对所述跨片事务的提交确认后,才在本地提交跨分片交易中由所述目标分片执行的事务,完成持久化存储。
如果所述目标分片中的各节点执行所述跨片事务后,存在部分或全部跨片事务涉及本分片以外其它分片上存储的账户,即这些跨片事务是多重跨片事务。则对于这种多重跨片事务,一方面,执行所述跨片事务后导致的本分片中相应的账户改变后的状态也并不提交至底层数据库,另一方面,将这些跨片事务中进一步涉及的需要由其它分片执行的跨片事务发送至主链,即重复进入到S171、S173、S175的处理,直到不再涉及新的跨片事务。
最为简单的跨片事务是单重跨片事务,即从一个源分片到一个目标分片的跨片事务即执行完毕的交易。多重跨片事务,可以是单重跨片事务的叠加。以下主要以单重跨片事务为例加以说明。本领域技术人员可以根据这里给出的单重跨片事务的例子容易的扩展到多重跨片事务的情形,而这些扩展的情形显然也应当属于本专利的范围。
此外,对于各节点执行所述目标分片接收到的客户端发来的交易,如果这些交易是分片内交易,即涉及的账户在本分片中都存储有对应的状态,则执行这些交易也会导致本分片中存储的相应账户的状态发生改变。
类似的,目标分片中的各个节点在达成共识后在本地执行交易,本分片中相关账户的状态会发生改变,包括外部账户和/或合约账户的状态的改变。相关的外部账户和合约账户的状态改变后,目标分片中的各个节点可以根据merkle树或MPT树的组织结构,计算得到新的状态树的根节点的hash值(即前述的状态根hash,State_Root)。得到的这个State_Root可以填入生成的目标分片区块的区块头中。此外,区块头中还可以包括区块号、时间戳、前一区块的hash等字段,如图20所示。
前述S173中提到,主链除了将所述跨片事务发送至对应的目标分片中,还可以将所述主链区块的区块头发送至目标分片。目标分片接收到主链发来的主链区块的区块头和跨片事务后,可以对主链区块的区块头进行验证。验证可以包括,所述目标分片根据主链本次发来的主链区块的区块头计算所述主链区块的hash,并基于该主链区块的hash判断是否与之前发来的主链区块的区块头相同,相同则说明与之前的主链区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的主链区块的区块头中的Prev Hash是否是上次发来的主链区块的hash值,如果是则通过验证,否则不通过。
对于主链还将生成的主链区块的区块头发送至目标分片的情况,目标分片在生成目标分片区块的过程中,可以根据接收到的主链区块的区块头计算得到该主链区块的hash值。进而,目标分片还可以将该主链区块的hash值填入目标分片生成的目标分片区块的区块头中。对于主链区块的生成速度不低于分片区块的生成速度的情况,目标分片可以将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中,如图21中区块201和区块202中的最新主链区块Hash字段。是否最新可以根据主链区块的区块头中的时间戳或者区块号来判断。如前所述,所述目标分片在生成目标分片区块的过程中,还可以验证当前主链区块的hash值是否与之前发来的主链区块重复。如果重复,可以不再处理本次发来的区块头以及对应的跨片事务,否则继续处理。目标分片通过将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中,对于主链区块的生成速度等于分片区块的生成速度的情况,可以在目标分片中标识当前目标分片中处理的跨片事务是哪个主链区块的区块体中的跨片事务,对于主链区块的生成速度高于分片区块的生成速度的情况,可以在目标分片中标识当前目标分片中处理的跨片事务是截止到哪个主链区块的区块体中的跨片事务。
由于主链区块的生成速度不低于分片区块的生成速度,对于主链区块的生成速度高于分片区块的生成速度的情况,借助图21中所示,分片1在生成分片区块101和目标分片区块102之间,主链中已经生成过两个主链区块,分别为主链区块10003和10004。除了图21中所示的主链将主链区块10004的区块头和主链区块10004中的跨片事务发送至分片1,实际上,在此之前,如果主链区块10003中也包含分片1需要处理的跨片事务,主链还可以将主链区块10003的区块头和主链区块10003中的需要由分片1处理的跨片事务发送至分片1。即,正常情况下,主链按照主链区块生成的时间顺序将主链区块的区块头和对应的跨片事务发送至所述跨片事务涉及的分片。这样,目标分片可以将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中,上述例子中,即将主链区块10004的区块hash填入目标分片生成的目标分片区块的区块头中。同时,分片1在生成的分片区块102的区块体的原始交易列表中,可以包括主链区块10003和10004中涉及需要由分片1处理的跨片事务。此外,所述分片区块102的原始交易列表中也可以包括与分片1连接的客户端发起的交易请求。与分片1连接的客户端发起的交易请求,可以是转账交易,也可以是创建/调用合约的交易。
另一种情况如图22所示,对于生成的分片区块中包括主链发来的多个主链区块的区块头和对应的需要由目标分片执行的跨片事务的情形,除了在分片区块的区块体的原始交易列表中包括所述多个主链区块中的需要由该分片处理的跨片事务以外(当然还可以包括打包的与分片连接的客户端发起的交易请求),在分片区块的区块头中还可以包括所述多个主链区块的区块头,如图22的区块101的区块头中“处理的主链区块m的hash”和“处理的主链区块n的hash值”(这里仅按照图22中的情形示出了2个主链区块的hash,实际上当前分片区块产生前收到的主链区块的区块头的个数显然也可以大于2个)和区块102的区块头中“处理的主链区块p的hash”和“处理的主链区块q的hash”(这里仅按照图22中的情形示出了2个主链区块的hash,实际上当前分片区块产生前收到的主链区块的区块头的个数显然也可以大于2个)。显然的,这种情况下,分片区块的区块头中包含的处理的主链区块的hash的数量可能是不定的。
再一种情况如图23所示,对于生成的分片区块中包括主链发来的多个主链区块的区块头和对应的需要由目标分片执行的跨片事务的情形,除了在分片区块的区块体的原始交易列表中包括所述多个主链区块中的需要由该分片处理的跨片事务以外(当然还可以包括打包的与分片连接的客户端发起的交易请求),在分片区块的区块体中还可以包括所述多个主链区块的区块hash,如图23的区块101的区块体中“主链区块m的hash”和“主链区块n的hash”(这里仅按照图22中的情形示出了2个主链区块的hash,实际上当前分片区块产生前收到的主链区块的区块头的个数显然也可以大于2个)和区块102的区块体中“主链区块p的hash”和“主链区块q的hash值”(这里仅按照图22中的情形示出了2个主链区块的hash,实际上当前分片区块产生前收到的主链区块的区块头的个数显然也可以大于2个)。分片区块的区块体中包含的这些处理的主链区块的hash,可以按照如前所述的树形结构组织,并将这棵树的根的hash值填入区块头中增加的字段“主链区块根Hash”中,即将所述各个主链区块的hash按照树形结构计算得到的根的hash值填入所述分片区块的区块头的主链区块根Hash中。例如,区块101的区块头中的“主链区块根Hash”,是区块101的区块体中“主链区块m的hash”、“主链区块n的hash”所组织成的树形结构的根节点的hash值;区块102的区块头中的“主链区块根Hash”,是区块101的区块体中“主链区块p的hash”、“主链区块q的hash”所组织成的树形结构的根节点的hash值。这样的好处在于,在分片区块的区块头中可以通过一个固定的字段来锁定所述分片区块的区块体中可能包括的不定数量的处理的主链区块的hash。
进而,目标分片在生成的分片区块对应执行的交易,包括该目标分片中锁定的主链区块所对应的需要由所述目标分片执行的跨片事务,此外还可以包括与所述分片连接的客户端发起的交易请求。例如,分片1在分片区块102对应执行的交易,可以包括主链区块10003和10004中涉及分片1的跨片事务,以及分片区块102中打包的与分片1连接的客户端发起的交易请求。
优选的,目标分片在生成的分片区块对应执行的交易包括主链发来的跨片事务和与所述目标分片相连的客户端发来的交易的情况下,目标分片先执行主链发来的跨片事务,再执行与所述目标分片相连的客户端发来的交易。这是因为,主链发来的需要所述目标分片执行的跨片事务实际上发生在前,与所述目标分片相连的客户端发来的交易实际上发生在后,而执行交易的顺序也是保证账户状态发生正确转化的前提条件,因此,为了避免所述目标分片存储的账户状态发生错误的转化而导致交易的失败或状态的错乱,最好按照交易实际的顺序来执行。
另外,所述目标分片执行所述跨片事务,和所述目标分片生成目标分片区块的过程中将接收到所述主链发来的跨片事务填入所述目标分片区块的区块体中,两者没有严格的先后顺序,也可以并行执行。
优选的,目标分片在生成的目标分片区块中锁定了多个主链区块的情况下,所述目标分片按照所述主链区块的生成顺序执行所述多个主链区块中的跨片事务。例如,分片1在生成的分片区块102中锁定了主链区块10003和10004,则分片1按照主链区块10003、10004的顺序执行主链区块10003和10004中的跨片事务,而非按照主链区块10004、10003的顺序执行主链区块10003和10004中的跨片事务。这是因为,主链发来的需要所述目标分片执行的跨片事务,主链先发来的区块头对应的区块中的跨片事务实际上发生在前,主链后发来的区块头对应的区块中的跨片事务实际上发生在后,而执行交易的顺序也是保证账户状态发生正确转化的前提条件,因此,为了避免所述目标分片存储的账户状态发生错误的转化而导致交易的失败或状态的错乱,最好按照交易实际的顺序来执行。
此外,主链还可以发送生成的主链区块的时间戳至分片,例如通过之前发送所述主链区块的区块头指示所述主链区块的时间戳,这样,分片在生成分片区块的过程中可以将最新主链区块的时间戳填入分片区块的timestamp中。例如,S175中,分片生成分片区块的过程中,将所述分片区块的区块头中的时间戳设定为所述主链发送的最新的时间戳。类似的,S171中生成分片区块的过程中,也将所述分片区块的区块头中的时间戳设定为之前所述主链发送的最新的时间戳。这样,可以在分片中锚定主链的时间***,从而使得分片具有与主链相同的时钟***。分片与主链具有相同的时钟***的情况下,与所述分片相连的客户端在发起交易时可以确定该交易的发起时间。从而,客户端在发起交易时,可以将该发起时刻的时间戳附在发起的交易上。那么,如前所述,在多个源分片发送至主链的跨片事务中,涉及同一个目标分片的,该目标分片最好也是按照交易的顺序来执行这些跨片事务。这样,目标分片对于同一个主链区块中的跨片事务,不论这些跨片事务是由哪个源分片发起的,可以统一按照这些跨片事务的时间戳(即源分片中发起的跨片交易的时间戳)按顺序来执行,从而保证交易能够正确处理以及交易执行后产生状态的一致。
上述本申请提供的执行跨片事务的实施例,在包含分片的区块链***中通过主链来将源分片中产生的跨分片事务转发至目标分片,提供了包含分片的区块链***中跨分片事务的执行方案。这个过程,通过构成主链节点的权威性,使得分片中产生的跨片事务能够在主链的见证下可靠的转发和执行,并在源分片、主链和目标分片上均存证。
前述提到,S171中源分片中的节点即使在本分片中完成了共识并执行了该源分片区块中的这些跨分片交易,也不将该源分片区块中跨分片交易产生的本分片中相关账户的变化后的状态提交至数据库,即不持久化存储。类似的,S175中目标分片中的各节点执行所述跨片事务后,也不将执行所述跨片事务后导致的本分片中相应的账户变化后的状态提交至底层数据库,即不持久化存储。为了能够使得源分片和目标分片上涉及的账户产生的变化后的状态能够提交至底层数据库,所述目标分片还需要将执行所述跨片事务产生的响应反馈至源分片。前述附图17所示的过程执行完毕后,还可以包括如图24所示的流程:
S241:目标分片生成目标分片区块的过程中根据所述目标分片执行的跨片事务产生跨片事务响应,并将所述跨片事务响应发送至主链。
S175中,所述目标分片执行跨片事务,如果成功执行,可以生成跨片事务响应,并可以将这些跨片事务响应添加至分片区块的区块体中,例如图25中所示的跨片事务响应列表中。需要说明的是,为了简便,图25中用主链区块Hash列表囊括了图23中的处理的主链区块的Hash。如图25中区块101的主链区块Hash列表实际上包括了图23中的处理的主链区块m的Hash、处理的主链区块n的Hash、……,图25中区块102的主链区块Hash列表实际上包括了图23中的处理的主链区块p的Hash、处理的主链区块q的Hash、……。这些跨片事务响应列表中的跨片事务响应,可以组织成树的形式。进而,目标分片可以在生成的区块头中增加一个跨片事务响应_Root字段,用于存放区块体中的这些跨片事务响应组织成树的树根的hash。这样,目标分片就可以将本区块中执行跨片事务后生成的响应锁定在区块头中。如图25中所示,目标分片生成的分片区块的区块头中可以包括区块号、时间戳、前一区块的hash、交易根hash、主链区块根hash,跨片事务响应_Root等。相应的,分片区块的hash值为包括跨片事务响应_Root字段在内的区块头中的字段计算得到的hash值。
进而,所述目标分片可以将跨片事务响应返回给主链。而且,所述目标分片可以将所述生成的分片区块的区块头与所述跨片事务响应一并发送至主链。此外,所述目标分片在所述生成的分片区块中,也可以处理所述目标分片接收到的客户端发来的交易。而这些客户端发来的交易中,也可能包括跨片的事务。这时,该目标分片同时又是源分片。本领域技术人员可以理解,此时是源分片的情形,可以从S171开始重复执行。这里为了简单,下面仅讨论作为目标分片返回跨片事务响应给主链的情况。
目标分片除了将所述跨片事务响应发送至主链,还可以将产生的目标分片区块的区块头发送至主链。
S243:主链生成主链区块的过程中,将接收到的跨片事务响应填入主链区块的区块体中;所述主链将所述跨片事务响应按照源分片的标识发送至对应的源分片中。
主链中的节点接收到目标分片发来的跨片事务响应后,可以先对跨片事务响应进行验证。例如,可以按照树形结构计算该跨片事务响应构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务响应是否与之前接收到的跨片事务响应重复。如果重复,可以不再处理本次发来的跨片事务响应,否则继续处理。
主链中的主节点可以收集目标分片发来的跨片事务响应,或者是主链中的非主节点接收目标分片发来的跨片事务响应后将这些跨片事务响应转发至主链中的主节点。主链中的主节点可以将一段时间内各分片发来的一定数量的跨片事务响应打包并发起共识提议。在主链中达成共识后,由主链中的各个节点执行这些打包的交易,生成主链区块。
主链中的各个节点执行这些打包的跨片事务响应并生成区块,可以包括将所述需要由源分片执行的跨片事务响应填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务响应组织成一棵树,并基于这棵树的树根生成hash值后将该hash值填入主链区块的区块头的Transaction_Root。例如,对于前述提到的主链区块中包括跨片事务列表的情况,可以将跨片事务响应列表与S173中的跨片事务列表一并组织成树,并基于树根生成hash值后将该hash值填入主链区块的区块头的Transaction_Root。或者,将跨片事务响应组织成一棵单独的树,产生的树的树根的hash值填入主链区块的区块头中(例如一个新的字段,如跨片事务响应_root,图25中未示出)。在主链区块的区块头中加入区块号,时间戳,前一区块的hash等字段后,就生成了主链区块。
所述主链生成主链区块的过程中,还可以计算各个目标分片发来的目标分片区块的区块hash,并将目标分片区块hash填入所述主链区块的区块体中,如分片区块hash列表中。进一步的,所述主链还可以将所述各个分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根(Shards_BlockRoot)中,例如如图25中所示。
主链中的各个节点执行这些打包的交易并生成区块,将所述需要由源分片执行的跨片事务响应填入主链区块的区块体中,具体可以是按照主链中的主节点发起共识提议的消息中需要由源分片执行的跨片事务响应的顺序,将需要由源分片执行的跨片事务响应填入主链区块的区块体中。此外,也可以是按照需要反馈至的源分片对跨片事务响应进行分组,将分组后的跨片事务响应填入主链区块的区块体中。分组后的各组跨片事务响应,可以按照分组编号升序或降序排列后填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务响应以相同的树形结构组织成一棵树,并基于这棵树的树根的hash值得到填入主链区块的区块头的Transaction_root字段(如将跨片事务响应列表与S173中的跨片事务列表一并组织成一棵树,并基于这棵树的树根生成hash值后将该hash值填入主链区块的区块头的Transaction_root)。优选的,主链区块的区块体包括的各个源分片需要收到的跨片交易响应,是未经主链在之前已生成的区块中打包的。此外,主链中生成的主链区块,如果该区块生成前在主节点打包交易时中对于某一源分片没有其接收的跨片事务响应,则该主链区块的区块体中,可以不包括需要由该源分片对应的跨片事务响应。
前述提到,所述目标分片可以将所述生成的目标分片区块的区块头与所述跨片事务响应一并发送至主链。主链接收到目标分片发来的目标分片区块的区块头和跨片事务响应后,可以对目标分片区块的区块头进行验证。验证可以包括,根据跨片事务响应按照树形结构计算根节点的hash值,确定该值与区块头中的跨片事务响应_root一致。或者,根据跨片事务响应按照树形结构计算得到这棵树的根,并基于该树根(可能还包括跨片事务构成的树的根,等)得到hash值,确定该值与区块头中的Transaction_root一致。如果不一致则验证不通过,反之验证通过。还可以验证目标分片本次发来的目标分片区块的区块头是否与之前发来的目标分片区块的区块头相同,相同则说明与之前的目标分片区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的目标分片区块的区块头中的PrevHash是否是上个区块号的目标分片区块的hash值,如果是则通过验证,否则不通过。
之后,主链可以将所述需要源分片接收的跨片事务响应按照源分片的标识发送至对应的源分片中。具体的,可以将所述主链区块的区块体中分组的跨片事务响应按照源分片的标识发送至对应的源分片中。这样,可以将主链区块体中的跨片事务响应按照需要接收的源分片的标识分别发送。除了将所述需要源分片执行的跨片事务响应按照源分片的标识发送至对应的源分片中,还可以将所述主链区块的区块头发送至源分片,例如与需要对应源分片处理的跨片事务响应一并发送至所述源分片。
前述提到,目标分片除了将所述跨片事务响应发送至主链,还可以将产生的目标分片区块的区块头发送至主链。
S245:所述源分片生成源分片区块的过程中,将接收到所述主链发来的跨片事务响应填入所述源分片区块的区块体中。
所述源分片中的节点接收到主链发来的跨片事务响应后,可以先对跨片事务响应进行验证。例如,可以按照树形结构计算该跨片事务响应构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务响应是否与之前接收到的跨片事务响应重复。如果重复,可以不再处理本次发来的跨片事务响应,否则继续处理。
所述源分片可以接收所述主链发来的需要由所述源分片接收的跨片事务响应。此外,所述源分片也可以接收与其连接的客户端发起的交易请求。所述源分片中的主节点可以将一段时间内接收到的一定数量的交易打包并发起共识提议。所述打包的交易中可以包括前述主链发来的跨片事务响应,还可以包括所述源分片接收到的客户端发来的交易。在所述源分片中达成共识后,由所述源分片中的各个节点执行这些打包的交易,生成源分片区块。这里的源分片区块不同于S171中的源分片区块。由于源分片中在不断的成块,所以这里源分片生成的分片区块,晚于S171中的源分片区块。例如S171中如图18所示生成的是区块201,则这里是区块201之后生成的区块,例如是区块202。所述源分片生成源分片区块的过程中,可以将接收到所述主链发来的跨片事务响应填入所述源分片区块的区块体中,具体如跨片事务响应列表中。此外,所述目标分片还可以将打包的客户端发来的交易填入所述源分片区块的区块体中,具体如原始交易列表中。填入源分片区块的区块体中的跨片事务响应列表,可以按照树形结构组织起来,树根的hash值即为生成的目标分片区块的区块头中的跨片事务响应_Root。例如如图26所示。
前述S243中提到,主链除了将所述跨片事务响应发送至对应的源分片中,还可以将所述主链区块的区块头发送至源分片。源分片接收到主链发来的主链区块的区块头和跨片事务响应后,可以对主链区块的区块头进行验证。验证可以包括,所述源分片根据主链本次发来的主链区块的区块头计算所述主链区块的hash,并基于该主链区块的hash判断是否与之前发来的主链区块的区块头相同,相同则说明与之前的主链区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的主链区块的区块头中的Prev Hash是否是上次发来的主链区块的hash值,如果是则通过验证,否则不通过。
对于主链还将生成的主链区块的区块头发送至源分片的情况,源分片在生成源分片区块的过程中,可以根据接收到的主链区块的区块头计算得到该主链区块的hash值。进而,源分片还可以将该主链区块的hash值填入源分片生成的源分片区块的区块头中。对于主链区块的生成速度不低于分片区块的生成速度的情况,源分片可以将最新主链区块的hash值填入源分片生成的源分片区块的区块头中。是否最新可以根据主链区块的区块头中的时间戳或者区块号来判断。如前所述,所述源分片在生成源分片区块的过程中,还可以验证当前主链区块的hash值是否与之前发来的主链区块重复。如果重复,可以不再处理本次发来的区块头以及对应的跨片事务响应,否则继续处理。源分片通过将最新主链区块的hash值填入源分片生成的源分片区块的区块头中,对于主链区块的生成速度等于分片区块的生成速度的情况,可以在源分片中标识当前源分片中接收的跨片事务响应是哪个主链区块的区块体中的跨片事务响应,对于主链区块的生成速度高于分片区块的生成速度的情况,可以在源分片中标识当前源分片中接收的跨片事务响应是截止到哪个主链区块的区块体中的跨片事务响应。
由于主链区块的生成速度不低于分片区块的生成速度,对于主链区块的生成速度高于分片区块的生成速度的情况,借助图26中所示,分片2在生成分片区块201和目标分片区块202之间,主链中已经生成过两个主链区块,分别为主链区块10002和10003。除了图26中所示的主链将主链区块10003的区块头和主链区块10003中的跨片事务响应发送至分片2,实际上,在此之前,如果主链区块10002中也包含分片2需要接收的跨片事务响应,主链还可以将主链区块10002的区块头和主链区块10002中的需要由分片2接收的跨片事务响应发送至分片2。即,正常情况下,主链按照主链区块生成的时间顺序将主链区块的区块头和对应的跨片事务响应发送至所述跨片事务响应涉及的分片。这样,源分片可以将最新主链区块的hash值填入源分片生成的源分片区块的区块头中,上述例子中,即将主链区块10003的区块hash填入源分片生成的源分片区块的区块头中(图26中未示出)。同时,分片2在生成的分片区块202的区块体的原始交易列表中,可以包括主链区块10002和10003中涉及需要由分片2接收的跨片事务响应。此外,所述分片区块202的原始交易列表中也可以包括与分片2连接的客户端发起的交易请求。与分片2连接的客户端发起的交易请求,可以是转账交易,也可以是创建/调用合约的交易。
另一种情况,对于生成的源分片区块中包括主链发来的多个主链区块的区块头和对应的需要由源分片接收的跨片事务响应的情形,除了在分片区块的区块体的跨片事务响应列表中包括所述多个主链区块中的需要由该分片处理的跨片事务响应以外,在分片区块的区块头中还可以包括所述多个主链区块的区块头。显然的,这种情况下,分片区块的区块头中包含的处理的主链区块的hash的数量可能是不定的。
再一种情况如图26所示,对于生成的分片区块中包括主链发来的多个主链区块的区块头和对应的需要由源分片接收的跨片事务响应的情形,除了在分片区块的区块体的跨片事务响应列表中包括所述多个主链区块中的需要由该分片处理的跨片事务响应以外,在分片区块的区块体中还可以包括所述多个主链区块的区块hash,如图26的区块201的区块体中的主链区块hash列表。分片区块的区块体中包含的这些处理的主链区块的hash,可以按照如前所述的树形结构组织,并将这棵树的根的hash值填入区块头中增加的字段“主链区块根Hash”中,即将所述各个主链区块的hash按照树形结构计算得到的根的hash值填入所述分片区块的区块头的主链区块根Hash中。例如,区块201的区块头中的“主链区块根Hash”,是区块201的区块体中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值;区块202的区块头中的“主链区块根Hash”,区块202的区块头中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值。这样的好处在于,在分片区块的区块头中可以通过一个固定的字段来锁定所述分片区块的区块体中可能包括的不定数量的处理的主链区块的hash。
此外,主链还可以发送生成的主链区块的时间戳至源分片,例如通过之前发送所述主链区块的区块头指示所述主链区块的时间戳,这样,分片在生成分片区块的过程中可以将最新主链区块的时间戳填入分片区块的timestamp中。例如,S245中,源分片生成源分片区块的过程中,将所述源分片区块的区块头中的时间戳设定为所述主链发送的最新的时间戳。这样,可以在分片中锚定主链的时间***,从而使得分片具有与主链相同的时钟***。分片与主链具有相同的时钟***的情况下,与所述分片相连的客户端在发起交易时可以确定该交易的发起时间。从而,客户端在发起交易时,可以将该发起时刻的时间戳附在发起的交易上。
上述本申请提供的返回跨片事务响应的方法实施例,在包含分片的区块链***中通过主链来将目标分片中产生的跨分片事务响应转发至源分片,提供了包含分片的区块链***中跨分片事务响应的反馈方案。这个过程,通过构成主链的节点的权威性,使得目标分片中产生的跨片事务响应能够在主链的见证下可靠的转发,并在目标分片、主链和源分片上均存证。
前述提到,S171中源分片中的节点即使在本分片中完成了共识并执行了该源分片区块中的这些跨分片交易,也不将该源分片区块中跨分片交易产生的本分片中相关账户的变化后的状态提交至数据库,即不持久化存储。类似的,S175中目标分片中的各节点执行所述跨片事务后,也不将执行所述跨片事务后导致的本分片中相应的账户变化后的状态提交至底层数据库,即不持久化存储。经过上述图24的流程,所述源分片可以接收到目标分片返回的跨片事务响应。为了能够使得源分片和目标分片上涉及的账户产生的变化后的状态能够提交至底层数据库,所述源分片还需要发送指令跨片事务提交的消息至目标分片。
图27示出了该流程,包括:
S271:源分片生成源分片区块的过程中根据所述跨片事务响应产生跨片事务提交指令,并将所述跨片事务提交指令发送至主链。
所述源分片中的各节点接收到所述跨片事务响应后,可以确定S171中发送至主链的跨片事务已经由对应的目标分片执行。源分片和这些跨片交易涉及的目标分片在本地都未将执行的跨片交易导致的相关账户状态的变化提交至底层数据库,即尚未进行持久化存储。源分片可以产生所述跨片事务响应对应的跨片事务提交指令。
源分片对于产生的跨片事务提交指令,在生成源分片区块的过程中,可以将产生的跨片事务提交指令添加至生成的分片区块的区块体中,例如图28中分片区块201和202中的跨片事务提交指令列表。这些跨片事务提交指令列表中的跨片事务提交指令,可以组织成树的形式。进而,源分片可以在生成的区块头中增加一个跨片事务提交指令_Root字段,用于存放区块体中的这些跨片事务提交指令组织成树的树根的hash。这样,源分片就可以将本区块中生成的跨片事务提交指令锁定在区块头中。此外,图28中分片区块201和202的区块体中还可以包括原始交易列表和主链区块Hash列表。同样的,在区块头中可以用Transaction_root将区块体中的原始交易列表锁定,用主链区块根Hash将区块体中的主链区块Hash列表锁定。在区块体里除了原有的原始交易列表和跨片事务提交指令列表外,还可以包括本区块产生的跨片事务列表(图中未示出)。需要说明的是,该跨片事务提交指令列表针对的是之前区块中的跨片事务列表,而非本区块中的跨片事务。由于可能存在分片2与不同目标分片的跨片交易,因此分片2产生的分片区块中的跨片事务提交指令列表中,可能包括需要发送至多个不同目标分片的跨片事务提交指令。如图28中所示,源分片生成的分片区块的区块头中可以包括区块号、时间戳、前一区块的hash、Transaction_root、主链区块根hash,跨片事务提交指令_Root等。相应的,分片区块的hash值为包括跨片事务提交指令_Root字段在内的区块头中的字段计算得到的hash值。如前所述,源分片生成源分片区块的过程中,可以将接收到所述主链发来的跨片事务响应填入所述源分片区块的区块体中,具体如跨片事务响应列表中,为了简便,图28中省略了跨片事务响应列表。此外,所述主链区块的区块体包括的各个目标分片接收的跨片事务提交指令,优选是未经主链在之前已生成的区块中打包的。
进而,所述源分片可以将跨片事务提交指令发送至主链。而且,所述源分片可以将所述生成的源分片区块的区块头与所述跨片事务提交指示一并发送至主链。此外,所述源分片在所述生成的分片区块中,也可以处理所述源分片接收到的客户端发来的交易。而这些客户端发来的交易中,也可能包括跨片的事务。本领域技术人员可以理解,对于包括跨片事务的情形,可以从S171开始重复执行。这里为了简单,下面仅讨论源分片发送跨片事务提交指令给主链的情况。
源分片除了将所述跨片事务提交指令发送至主链,还可以将产生的源分片区块的区块头发送至主链。
S273:主链生成主链区块的过程中,将接收到的需要发送给目标分片的跨片事务提交指令填入主链区块的区块体中;所述主链将所述跨片事务提交指令按照目标分片的标识发送至对应的目标分片中。
主链中的节点接收到源分片发来的跨片事务提交指令后,可以先对跨片事务提交指令进行验证。例如,可以按照树形结构计算该跨片事务提交指令构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务提交指令是否与之前接收到的跨片事务提交指令重复。如果重复,可以不再处理本次发来的跨片事务提交指令,否则继续处理。
主链中的主节点可以收集源分片发来的跨片事务提交指令,或者是主链中的非主节点接收源分片发来的跨片事务提交指令后将这些跨片事务提交指令转发至主链中的主节点。主链中的主节点可以将一段时间内各分片发来的一定数量的跨片事务提交指令打包并发起共识提议。在主链中达成共识后,由主链中的各个节点执行这些打包的交易,生成主链区块。
所述主链生成主链区块的过程中,还可以计算各个源分片发来的源分片区块的区块hash,并将源分片区块hash填入所述主链区块的区块体中。进一步的,所述主链生成主链区块的过程中,还可以将所述各个分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根中,例如如图28中所示。
主链中的各个节点执行这些打包的跨片事务提交指令并生成区块,可以包括将所述需要由发送至目标分片的跨片事务提交指令填入主链区块的区块体中。具体的,可以是按照主链中的主节点发起共识提议的消息中需要发送至目标分片的跨片事务提交指令的顺序,将需要由目标分片执行的跨片事务提交指令填入主链区块的区块体中。此外,也可以是按照需要发送至的目标分片对跨片事务提交指令进行分组,将分组后的跨片事务提交指令填入主链区块的区块体中。分组后的各组跨片事务提交指令,可以按照分组编号升序或降序排列后填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务提交指令组织成一棵树,并基于这棵树的树根生成hash值后将该hash值填入主链区块的区块头的Transaction_Root。此外,对于前述提到的主链区块中包括跨片事务列表的情况,可以将跨片事务提交指令列表与S173中的跨片事务列表一并组织成树,并基于树根生成hash值后将该hash值填入主链区块的区块头的Transaction_Root。或者,将跨片事务提交指令组织成一棵单独的树,产生的树的树根的hash值填入主链区块的区块头中(例如一个新的字段,如跨片事务提交指令_root,图28中未示出)。在主链区块的区块头中加入区块号,时间戳,前一区块的hash等字段后,就生成了主链区块。
前述提到,所述源分片可以将所述生成的分片区块的区块头与所述跨片事务提交指令一并发送至主链。主链接收到源分片发来的源分片区块的区块头和跨片事务提交指令后,可以对分片区块的区块头进行验证。验证可以包括,根据跨片事务提交指令按照树形结构计算根节点的hash值,确定该值与区块头中的跨片事务提交指令_root一致。或者,根据跨片事务提交指令按照树形结构计算得到这棵树的根,并基于该树根(可能还包括跨片事务构成的树的根,跨片事务响应构成的树的根,等)得到hash值,确定该值与区块头中的Transaction_root一致。如果不一致则验证不通过,反之验证通过。还可以验证源分片本次发来的分片区块的区块头是否与之前发来的分片区块的区块头相同,相同则说明与之前的分片区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的分片区块的区块头中的Prev Hash是否是上个区块号的分片区块的hash值,如果是则通过验证,否则不通过。
之后,主链可以将所述需要目标分片执行的跨片事务提交指令按照目标分片的标识发送至对应的目标分片中。具体的,可以将所述主链区块的区块体中分组的跨片事务提交指令按照目标分片的标识发送至对应的目标分片中。这样,可以将所述主链区块的区块体中分组的跨片事务提交指令按照目标分片的标识发送至对应的目标分片中。除了将所述需要目标分片执行的跨片事务提交指令按照目标分片的标识发送至对应的目标分片中,还可以将所述主链区块的区块头发送至目标分片,例如与需要对应目标分片处理的跨片事务提交指令一并发送至所述目标分片。
S275:所述目标分片生成目标分片区块的过程中,将接收到所述主链发来的跨片事务提交指令填入所述目标分片区块的区块体中,并在本地提交执行所述跨片事务所产生的状态。
所述目标分片中的节点接收到主链发来的跨片事务提交指令后,可以先对跨片事务提交指令进行验证。例如,可以按照树形结构计算该跨片事务提交构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务提交指令是否与之前接收到的跨片事务提交指令重复。如果重复,可以不再处理本次发来的跨片事务提交指令,否则继续处理。
所述目标分片可以接收所述主链发来的需要由所述目标分片执行的跨片事务提交指令。此外,所述目标分片也可以接收与其连接的客户端发起的交易请求。所述目标分片中的主节点可以将一段时间内接收到的一定数量的交易打包并发起共识提议。所述打包的交易中可以包括前述主链发来的跨片事务提交指令,还可以包括所述目标分片接收到的客户端发来的交易,还可以包括前述的跨片事务响应。在所述目标分片中达成共识后,由所述目标分片中的各个节点执行这些打包的交易,生成目标分片区块。这里的目标分片区块不同于S245中的目标分片区块。由于目标分片中在不断的成块,所以这里目标分片生成的分片区块,晚于S245中的目标分片区块。例如S245中如图29所示生成的是区块201,则这里是区块201之后生成的区块,例如是区块202。所述目标分片生成目标分片区块的过程中,可以将接收到所述主链发来的跨片事务提交指令填入所述源分片区块的区块体中,具体如跨片事务提交指令列表中。此外,所述目标分片还可以将打包的客户端发来的交易填入所述目标分片区块的区块体中,具体如原始交易列表中。填入目标分片区块的区块体中的跨片事务提交指令,可以按照树形结构组织起来,树根的hash值即为生成的目标分片区块的区块头中的跨片事务提交指令_Root。
前述S273中提到,主链除了将所述跨片事务发送至对应的目标分片中,还可以将所述主链区块的区块头发送至目标分片。目标分片接收到主链发来的主链区块的区块头和跨片事务提交指令后,可以对主链区块的区块头进行验证。验证可以包括,所述目标分片根据主链本次发来的主链区块的区块头计算所述主链区块的hash,并基于该主链区块的hash判断是否与之前发来的主链区块的区块头相同,相同则说明与之前的主链区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的主链区块的区块头中的Prev Hash是否是上次发来的主链区块的hash值,如果是则通过验证,否则不通过。
对于主链还将生成的主链区块的区块头发送至目标分片的情况,目标分片在生成目标分片区块的过程中,可以根据接收到的主链区块的区块头计算得到该主链区块的hash值。进而,目标分片还可以将该主链区块的hash值填入目标分片生成的目标分片区块的区块头中。对于主链区块的生成速度不低于分片区块的生成速度的情况,目标分片可以将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中。是否最新可以根据主链区块的区块头中的时间戳或者区块号来判断。如前所述,所述目标分片在生成目标分片区块的过程中,还可以验证当前主链区块的hash值是否与之前发来的主链区块重复。如果重复,可以不再处理本次发来的区块头以及对应的跨片事务提交指令,否则继续处理。目标分片通过将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中,对于主链区块的生成速度等于分片区块的生成速度的情况,可以在目标分片中标识当前目标分片中接收的跨片事务提交指令是哪个主链区块的区块体中的跨片事务提交指令,对于主链区块的生成速度高于分片区块的生成速度的情况,可以在目标分片中标识当前目标分片中接收的跨片事务提交指令是截止到哪个主链区块的区块体中的跨片事务提交指令。
由于主链区块的生成速度不低于分片区块的生成速度,对于主链区块的生成速度高于分片区块的生成速度的情况,借助图29中所示,分片1在生成分片区块101和目标分片区块102之间,主链中已经生成过两个主链区块,分别为主链区块10003和10004。除了图29中所示的主链将主链区块10004的区块头和主链区块10004中的跨片事务提交指令发送至分片1,实际上,在此之前,如果主链区块10003中也包含分片1需要处理的跨片事务提交指令,主链还可以将主链区块10003的区块头和主链区块10003中的需要由分片1处理的跨片事务提交指令发送至分片1。即,正常情况下,主链按照主链区块生成的时间顺序将主链区块的区块头和对应的跨片事务提交指令发送至所述跨片事务提交指令涉及的分片。这样,目标分片可以将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中,上述例子中,即将主链区块10004的区块hash填入目标分片生成的目标分片区块的区块头中(图29中未示出)。同时,分片1在生成的分片区块102的区块体的原始交易列表中,可以包括主链区块10003和10004中涉及需要由分片1处理的跨片事务提交指令。此外,所述分片区块102的原始交易列表中也可以包括与分片1连接的客户端发起的交易请求。与分片1连接的客户端发起的交易请求,可以是转账交易,也可以是创建/调用合约的交易。
另一种情况,对于生成的目标分片区块中包括主链发来的多个主链区块的区块头和对应的需要由源分片执行的跨片事务提交指令的情形,除了在分片区块的区块体的跨片事务提交指令列表中包括所述多个主链区块中的需要由该分片处理的跨片事务提交指令以外,在分片区块的区块头中还可以包括所述多个主链区块的区块头。显然的,这种情况下,分片区块的区块头中包含的处理的主链区块的hash的数量可能是不定的。
再一种情况如图29所示,对于生成的分片区块中包括主链发来的多个主链区块的区块头和对应的需要由目标分片执行的跨片事务提交指令的情形,除了在分片区块的区块体的跨片事务提交指令列表中包括所述多个主链区块中的需要由该分片处理的跨片事务提交指令以外,在分片区块的区块体中还可以包括所述多个主链区块的区块hash,如图29的区块101的区块体中的主链区块hash列表。分片区块的区块体中包含的这些处理的主链区块的hash,可以按照如前所述的树形结构组织,并将这棵树的根的hash值填入区块头中增加的字段“主链区块根Hash”中,即将所述各个主链区块的hash按照树形结构计算得到的根的hash值填入所述分片区块的区块头的主链区块根Hash中。例如,区块101的区块头中的“主链区块根Hash”,是区块101的区块体中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值;区块102的区块头中的“主链区块根Hash”,区块102的区块头中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值。这样的好处在于,在分片区块的区块头中可以通过一个固定的字段来锁定所述分片区块的区块体中可能包括的不定数量的处理的主链区块的hash。
此外,主链还可以发送生成的主链区块的时间戳至目标分片,例如通过之前发送所述主链区块的区块头指示所述主链区块的时间戳,这样,分片在生成分片区块的过程中可以将最新主链区块的时间戳填入分片区块的timestamp中。例如,S275中,目标分片生成目标分片区块的过程中,将所述目标分片区块的区块头中的时间戳设定为所述主链发送的最新的时间戳。这样,可以在分片中锚定主链的时间***,从而使得分片具有与主链相同的时钟***。分片与主链具有相同的时钟***的情况下,与所述分片相连的客户端在发起交易时可以确定该交易的发起时间。从而,客户端在发起交易时,可以将该发起时刻的时间戳附在发起的交易上。
所述目标分片中的各节点执行交易,包括执行所述跨片事务提交指令。对于执行所述跨片事务提交指令,包括将所述跨片事务提交指令对应的所述目标分片中相关的变化后的状态提交至底层数据库,即持久化存储。
另外,所述目标分片在本地提交执行所述跨片事务所产生的状态,和所述目标分片生成目标分片区块的过程中将接收到所述主链发来的跨片事务提交指令填入所述目标分片区块的区块体中,两者没有严格的先后顺序,也可以并行执行。
上述本申请提供的指令提交跨片事务的方法实施例,在包含分片的区块链***中通过主链来将源分片中产生的跨分片事务提交指令转发至目标分片,提供了包含分片的区块链***中指令提交分片事务的方案。这个过程,通过构成主链的节点的权威性,使得源分片中产生的跨片事务提交指令能够在主链的见证下可靠的转发并在目标分片中执行,并在源分片、主链和目标分片上均存证。
前述提到,S171中源分片中的节点即使在本分片中完成了共识并执行了该源分片区块中的这些跨分片交易,也不将该源分片区块中跨分片交易产生的本分片中相关账户的变化后的状态提交至数据库,即不持久化存储。S275中,目标分片中的各节点执行所述跨片事务提交指令后,将执行所述跨片事务后导致的本分片中相应的账户变化后的状态提交至底层数据库,即进行持久化存储。为了能够使得源分片上跨片事务涉及的账户所产生的变化后的状态也能够提交至底层数据库,所述目标分片还需要发送跨片事务提交响应至源分片。
图30示出了该流程,包括:
S301:目标分片生成目标分片区块的过程中根据所述目标分片执行的跨片事务提交指令产生跨片事务提交响应,并将所述跨片事务提交响应发送至主链。
S275中,所述目标分片执行跨片事务,如果成功执行,可以生成跨片事务提交响应,并可以将这些跨片事务提交响应添加至分片区块的区块体中,例如图31中所示的跨片事务提交响应列表中。这些跨片事务提交响应列表中的跨片事务提交响应,可以组织成树的形式。进而,目标分片可以在生成的区块头中增加一个跨片事务提交响应_Root字段,用于存放区块体中的这些跨片事务提交响应组织成树的树根的hash。这样,目标分片就可以将本区块中执行跨片事务提交指令后生成的提交响应锁定在区块头中。此外,如前述S275中所述,目标分片生成的目标分片区块中还可以包括跨片事务提交指令列表。类似的,目标分片可以在生成的区块头中增加一个跨片事务提交指令_Root字段,用于存放区块体中的这些跨片事务提交指令组织成树的树根的hash(图中未示出)。如图31中所示,目标分片生成的分片区块的区块头中可以包括区块号、时间戳、前一区块的hash、交易根hash、主链区块根hash,跨片事务提交响应_Root等。相应的,分片区块的hash值为包括跨片事务提交响应_Root字段在内的区块头中的字段计算得到的hash值。
进而,所述目标分片可以将跨片事务提交响应返回给主链。而且,所述目标分片可以将所述生成的分片区块的区块头与所述跨片事务提交响应一并发送至主链。此外,所述目标分片在所述生成的分片区块中,也可以处理所述目标分片接收到的客户端发来的交易。而这些客户端发来的交易中,也可能包括跨片的事务。这时,该目标分片同时又是源分片。本领域技术人员可以理解,此时是源分片的情形,可以从S171开始重复执行。这里为了简单,下面仅讨论作为目标分片返回跨片事务提交响应给主链的情况。
目标分片除了将所述跨片事务提交响应发送至主链,还可以将产生的目标分片区块的区块头发送至主链。
S303:主链生成主链区块的过程中,将接收到的跨片事务提交响应填入主链区块的区块体中;所述主链将所述跨片事务提交响应按照源分片的标识发送至对应的源分片中。
主链中的节点接收到目标分片发来的跨片事务提交响应后,可以先对跨片事务提交响应进行验证。例如,可以按照树形结构计算该跨片事务提交响应构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务提交响应是否与之前接收到的跨片事务提交响应重复。如果重复,可以不再处理本次发来的跨片事务提交响应,否则继续处理。
主链中的主节点可以收集目标分片发来的跨片事务提交响应,或者是主链中的非主节点接收目标分片发来的跨片事务提交响应后将这些跨片事务提交响应转发至主链中的主节点。主链中的主节点可以将一段时间内各分片发来的一定数量的跨片事务提交响应打包并发起共识提议。在主链中达成共识后,由主链中的各个节点执行这些打包的交易,生成主链区块。
主链中的各个节点执行这些打包的跨片事务提交响应并生成区块,可以包括将所述需要由源分片执行的跨片事务提交响应填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务提交响应组织成一棵树,并基于这棵树的树根生成hash值后将该hash值填入主链区块的区块头的Transaction_Root。例如,对于前述提到的主链区块中包括跨片事务列表的情况,可以将跨片事务提交响应列表与跨片事务列表一并组织成树,并基于树根生成hash值后将该hash值填入主链区块的区块头的Transaction_Root。或者,将跨片事务提交响应组织成一棵单独的树,产生的树的树根的hash值填入主链区块的区块头中(例如一个新的字段,如跨片事务提交响应_root,图31中未示出)。在主链区块的区块头中加入区块号,时间戳,前一区块的hash等字段后,就生成了主链区块。
所述主链生成主链区块的过程中,还可以计算各个目标分片发来的目标分片区块的区块hash,并将目标分片区块hash填入所述主链区块的区块体中,如分片区块hash列表中。进一步的,所述主链还可以将所述各个分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根(Shards_BlockRoot)中,例如如图31中所示。
主链中的各个节点执行这些打包的交易并生成区块,将所述需要由源分片执行的跨片事务提交响应填入主链区块的区块体中,具体可以是按照主链中的主节点发起共识提议的消息中需要由源分片执行的跨片事务提交响应的顺序,将需要由源分片执行的跨片事务提交响应填入主链区块的区块体中。此外,也可以是按照需要反馈至的源分片对跨片事务提交响应进行分组,将分组后的跨片事务提交响应填入主链区块的区块体中。分组后的各组跨片事务提交响应,可以按照分组编号升序或降序排列后填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务提交响应以相同的树形结构组织成一棵树,并基于这棵树的树根得到hash值后将该hash值填入主链区块的区块头的Transaction_root字段(如将跨片事务提交响应列表与S173中的跨片事务列表一并组织成一棵树,并基于这棵树的树根生成hash值后将该hash值填入主链区块的区块头的Transaction_root)。优选的,主链区块的区块体包括的各个源分片需要收到的跨片交易提交响应,是未经主链在之前已生成的区块中打包的。此外,主链中生成的主链区块,如果该区块生成前在主节点打包交易时中对于某一源分片没有其接收的跨片事务提交响应,则该主链区块的区块体中,可以不包括需要由该源分片对应的跨片事务提交响应。
前述提到,所述目标分片可以将所述生成的目标分片区块的区块头与所述跨片事务提交响应一并发送至主链。主链接收到目标分片发来的目标分片区块的区块头和跨片事务提交响应后,可以对目标分片区块的区块头进行验证。验证可以包括,根据跨片事务提交响应按照树形结构计算根节点的hash值,确定该值与区块头中的跨片事务提交响应_root一致。或者,根据跨片事务提交响应按照树形结构计算得到这棵树的根,并基于该树根(可能还包括跨片事务构成的树的根,跨片事务响应构成的树的根,跨片事务提交指令构成的树的根,等)得到hash值,确定该值与区块头中的Transaction_root一致。如果不一致则验证不通过,反之验证通过。还可以验证目标分片本次发来的目标分片区块的区块头是否与之前发来的目标分片区块的区块头相同,相同则说明与之前的目标分片区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的目标分片区块的区块头中的Prev Hash是否是上个区块号的目标分片区块的hash值,如果是则通过验证,否则不通过。
之后,主链可以将所述需要源分片接收的跨片事务提交响应按照源分片的标识发送至对应的源分片中。具体的,可以将所述主链区块的区块体中分组的跨片事务提交响应按照源分片的标识发送至对应的源分片中。这样,可以将主链区块体中的跨片事务提交响应按照需要接收的源分片的标识分别发送。除了将所述需要源分片执行的跨片事务提交响应按照源分片的标识发送至对应的源分片中,还可以将所述主链区块的区块头发送至源分片,例如与需要对应源分片处理的跨片事务提交响应一并发送至所述源分片。
前述提到,目标分片除了将所述跨片事务提交响应发送至主链,还可以将产生的目标分片区块的区块头发送至主链。
S305:所述源分片生成源分片区块的过程中,将接收到所述主链发来的跨片事务提交响应填入所述源分片区块的区块体中,并在本地提交执行所述跨片事务所产生的状态。
所述源分片中的节点接收到主链发来的跨片事务提交响应后,可以先对跨片事务提交响应进行验证。例如,可以按照树形结构计算该跨片事务提交响应构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务提交响应是否与之前接收到的跨片事务提交响应重复。如果重复,可以不再处理本次发来的跨片事务提交响应,否则继续处理。
所述源分片可以接收所述主链发来的需要由所述源分片接收的跨片事务提交响应。此外,所述源分片也可以接收与其连接的客户端发起的交易请求。所述源分片中的主节点可以将一段时间内接收到的一定数量的交易打包并发起共识提议。所述打包的交易中可以包括前述主链发来的跨片事务提交响应,还可以包括所述源分片接收到的客户端发来的交易。在所述源分片中达成共识后,由所述源分片中的各个节点执行这些打包的交易,生成源分片区块。这里的源分片区块不同于S271中的源分片区块。由于源分片中在不断的成块,所以这里源分片生成的分片区块,晚于S271中的源分片区块。例如S271中如图28所示生成的是区块201,则这里是区块201之后生成的区块,例如是区块202。所述源分片生成源分片区块的过程中,可以将接收到所述主链发来的跨片事务提交响应填入所述源分片区块的区块体中,具体如跨片事务提交响应列表中。此外,所述目标分片还可以将打包的客户端发来的交易填入所述源分片区块的区块体中,具体如原始交易列表中。填入源分片区块的区块体中的跨片事务提交响应列表,可以按照树形结构组织起来,树根的hash值即为生成的目标分片区块的区块头中的跨片事务提交响应_Root。例如如图32所示。
前述S303中提到,主链除了将所述跨片事务提交响应发送至对应的源分片中,还可以将所述主链区块的区块头发送至源分片。源分片接收到主链发来的主链区块的区块头和跨片事务提交响应后,可以对主链区块的区块头进行验证。验证可以包括,所述源分片根据主链本次发来的主链区块的区块头计算所述主链区块的hash,并基于该主链区块的hash判断是否与之前发来的主链区块的区块头相同,相同则说明与之前的主链区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的主链区块的区块头中的Prev Hash是否是上次发来的主链区块的hash值,如果是则通过验证,否则不通过。
对于主链还将生成的主链区块的区块头发送至源分片的情况,源分片在生成源分片区块的过程中,可以根据接收到的主链区块的区块头计算得到该主链区块的hash值。进而,源分片还可以将该主链区块的hash值填入源分片生成的源分片区块的区块头中。对于主链区块的生成速度不低于分片区块的生成速度的情况,源分片可以将最新主链区块的hash值填入源分片生成的源分片区块的区块头中。是否最新可以根据主链区块的区块头中的时间戳或者区块号来判断。如前所述,所述源分片在生成源分片区块的过程中,还可以验证当前主链区块的hash值是否与之前发来的主链区块重复。如果重复,可以不再处理本次发来的区块头以及对应的跨片事务提交响应,否则继续处理。源分片通过将最新主链区块的hash值填入源分片生成的源分片区块的区块头中,对于主链区块的生成速度等于分片区块的生成速度的情况,可以在源分片中标识当前源分片中接收的跨片事务提交响应是哪个主链区块的区块体中的跨片事务提交响应,对于主链区块的生成速度高于分片区块的生成速度的情况,可以在源分片中标识当前源分片中接收的跨片事务提交响应是截止到哪个主链区块的区块体中的跨片事务提交响应。
由于主链区块的生成速度不低于分片区块的生成速度,对于主链区块的生成速度高于分片区块的生成速度的情况,借助图32中所示,分片2在生成分片区块201和目标分片区块202之间,主链中已经生成过两个主链区块,分别为主链区块10002和10003。除了图32中所示的主链将主链区块10003的区块头和主链区块10003中的跨片事务提交响应发送至分片2,实际上,在此之前,如果主链区块10002中也包含分片2需要接收的跨片事务提交响应,主链还可以将主链区块10002的区块头和主链区块10002中的需要由分片2接收的跨片事务提交响应发送至分片2。即,正常情况下,主链按照主链区块生成的时间顺序将主链区块的区块头和对应的跨片事务提交响应发送至所述跨片事务提交响应涉及的分片。这样,源分片可以将最新主链区块的hash值填入源分片生成的源分片区块的区块头中,上述例子中,即将主链区块10003的区块hash填入源分片生成的源分片区块的区块头中(图32中未示出)。同时,分片2在生成的分片区块202的区块体的原始交易列表中,可以包括主链区块10002和10003中涉及需要由分片2接收的跨片事务提交响应。此外,所述分片区块202的原始交易列表中也可以包括与分片2连接的客户端发起的交易请求。与分片2连接的客户端发起的交易请求,可以是转账交易,也可以是创建/调用合约的交易。
另一种情况,对于生成的源分片区块中包括主链发来的多个主链区块的区块头和对应的需要由源分片接收的跨片事务提交响应的情形,除了在分片区块的区块体的跨片事务提交响应列表中包括所述多个主链区块中的需要由该分片处理的跨片事务提交响应以外,在分片区块的区块头中还可以包括所述多个主链区块的区块头。显然的,这种情况下,分片区块的区块头中包含的处理的主链区块的hash的数量可能是不定的。
再一种情况,对于生成的分片区块中包括主链发来的多个主链区块的区块头和对应的需要由源分片接收的跨片事务提交响应的情形,除了在分片区块的区块体的跨片事务提交响应列表中包括所述多个主链区块中的需要由该分片处理的跨片事务提交响应以外,在分片区块的区块体中还可以包括所述多个主链区块的区块hash。分片区块的区块体中包含的这些处理的主链区块的hash,可以按照如前所述的树形结构组织,并将这棵树的根的hash值填入区块头中增加的字段“主链区块根Hash”中,如图32所示,即将所述各个主链区块的hash按照树形结构计算得到的根的hash值填入所述分片区块的区块头的主链区块根Hash中。例如,区块201的区块头中的“主链区块根Hash”,是区块201的区块体中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值;区块202的区块头中的“主链区块根Hash”,区块202的区块头中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值。这样的好处在于,在分片区块的区块头中可以通过一个固定的字段来锁定所述分片区块的区块体中可能包括的不定数量的处理的主链区块的hash。
此外,主链还可以发送生成的主链区块的时间戳至源分片,例如通过之前发送所述主链区块的区块头指示所述主链区块的时间戳,这样,分片在生成分片区块的过程中可以将最新主链区块的时间戳填入分片区块的timestamp中。例如,S305中,源分片生成源分片区块的过程中,将所述源分片区块的区块头中的时间戳设定为所述主链发送的最新的时间戳。这样,可以在分片中锚定主链的时间***,从而使得分片具有与主链相同的时钟***。分片与主链具有相同的时钟***的情况下,与所述分片相连的客户端在发起交易时可以确定该交易的发起时间。从而,客户端在发起交易时,可以将该发起时刻的时间戳附在发起的交易上。
所述源分片中的各节点执行交易,包括将所述跨片事务提交响应对应的所述目标分片中相关的变化后的状态提交至底层数据库,即持久化存储。另外,所述源分片在本地提交执行所述跨片事务所产生的状态,和所述源分片生成源分片区块的过程中将接收到所述主链发来的跨片事务提交响应填入所述源分片区块的区块体中,两者没有严格的先后顺序,也可以并行执行。
上述本申请提供的提交跨片事务的方法实施例,在包含分片的区块链***中通过主链来将目标分片中产生的跨分片事务提交响应转发至源分片,提供了包含分片的区块链***中跨分片事务提交响应的反馈方案以及源分片提交跨片事务的方案。这个过程,通过构成主链的节点的权威性,使得目标分片中产生的跨片事务提交响应能够在主链的见证下可靠的转发,并在目标分片、主链和源分片上均存证。
经过上述图24的流程,所述源分片可以接收到目标分片返回的跨片事务响应。此时,源分片可以在本地提交执行所述跨片事务所产生的状态。同时,为了能够使得目标分片上涉及的账户产生的变化后的状态能够提交至底层数据库,所述源分片还需要发送指令跨片事务提交的消息至目标分片。
图33示出了该流程,包括:
S331:源分片生成源分片区块的过程中根据所述跨片事务响应产生跨片事务提交指令,并在本地提交执行所述跨片事务所产生的状态,还将所述跨片事务提交指令发送至主链。
所述源分片中的各节点接收到所述跨片事务响应后,可以确定S171中发送至主链的跨片事务已经由对应的目标分片执行。源分片和这些跨片交易涉及的目标分片在本地都未将执行的跨片交易导致的相关账户状态的变化提交至底层数据库,即尚未进行持久化存储。源分片可以产生所述跨片事务响应对应的跨片事务提交指令。所述源分片在本地提交执行所述跨片事务所产生的状态,和在生成源分片区块的过程中根据所述跨片事务响应产生跨片事务提交指令,两者没有严格的先后顺序,也可以并行执行。
源分片对于产生的跨片事务提交指令,可以在生成源分片区块的过程中,可以将产生的跨片事务提交指令添加至生成的分片区块的区块体中,例如图28中分片区块201和202中的跨片事务提交指令列表。这些跨片事务提交指令列表中的跨片事务提交指令,可以组织成树的形式。进而,源分片可以在生成的区块头中增加一个跨片事务提交指令_Root字段,用于存放区块体中的这些跨片事务提交指令组织成树的树根的hash。这样,源分片就可以将本区块中生成的跨片事务提交指令锁定在区块头中。此外,图28中分片区块201和202的区块体中还可以包括原始交易列表和主链区块Hash列表。同样的,在区块头中可以用Transaction_root将区块体中的原始交易列表锁定,用主链区块根Hash将区块体中的主链区块Hash列表锁定。在区块体里除了原有的原始交易列表和跨片事务提交指令列表外,还可以包括本区块产生的跨片事务列表(图中未示出)。需要说明的是,该跨片事务提交指令列表针对的是之前区块中的跨片事务列表,而非本区块中的跨片事务。由于可能存在分片2与不同目标分片的跨片交易,因此分片2产生的分片区块中的跨片事务提交指令列表中,可能包括需要发送至多个不同目标分片的跨片事务提交指令。如图28中所示,源分片生成的分片区块的区块头中可以包括区块号、时间戳、前一区块的hash、Transaction_root、主链区块根hash,跨片事务提交指令_Root等。相应的,分片区块的hash值为包括跨片事务提交指令_Root字段在内的区块头中的字段计算得到的hash值。如前所述,源分片生成源分片区块的过程中,可以将接收到所述主链发来的跨片事务响应填入所述源分片区块的区块体中,具体如跨片事务响应列表中,为了简便,图28中省略了跨片事务响应列表。此外,所述主链区块的区块体包括的各个目标分片接收的跨片事务提交指令,优选是未经主链在之前已生成的区块中打包的。
进而,所述源分片可以将跨片事务提交指令发送至主链。而且,所述源分片可以将所述生成的源分片区块的区块头与所述跨片事务提交指示一并发送至主链。此外,所述源分片在所述生成的分片区块中,也可以处理所述源分片接收到的客户端发来的交易。而这些客户端发来的交易中,也可能包括跨片的事务。本领域技术人员可以理解,对于包括跨片事务的情形,可以从S171开始重复执行。这里为了简单,下面仅讨论源分片发送跨片事务提交指令给主链的情况。
源分片除了将所述跨片事务提交指令发送至主链,还可以将产生的源分片区块的区块头发送至主链。
S333:主链生成主链区块的过程中,将接收到的需要发送给目标分片的跨片事务提交指令填入主链区块的区块体中;所述主链将所述跨片事务提交指令按照目标分片的标识发送至对应的目标分片中。
主链中的节点接收到目标分片发来的跨片事务提交指令后,可以先对跨片事务提交指令进行验证。例如,可以按照树形结构计算该跨片事务提交指令构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务提交指令是否与之前接收到的跨片事务提交指令重复。如果重复,可以不再处理本次发来的跨片事务提交指令,否则继续处理。
主链中的主节点可以收集源分片发来的跨片事务提交指令,或者是主链中的非主节点接收源分片发来的跨片事务提交指令后将这些跨片事务提交指令转发至主链中的主节点。主链中的主节点可以将一段时间内各分片发来的一定数量的跨片事务提交指令打包并发起共识提议。在主链中达成共识后,由主链中的各个节点执行这些打包的交易,生成主链区块。
所述主链生成主链区块的过程中,还可以计算各个源分片发来的源分片区块的区块hash,并将源分片区块hash填入所述主链区块的区块体中。进一步的,所述主链生成主链区块的过程中,还可以将所述各个分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根中,例如如图28中所示。
主链中的各个节点执行这些打包的跨片事务提交指令并生成区块,可以包括将所述需要由发送至目标分片的跨片事务提交指令填入主链区块的区块体中。具体的,可以是按照主链中的主节点发起共识提议的消息中需要发送至目标分片的跨片事务提交指令的顺序,将需要由目标分片执行的跨片事务提交指令填入主链区块的区块体中。此外,也可以是按照需要发送至的目标分片对跨片事务提交指令进行分组,将分组后的跨片事务提交指令填入主链区块的区块体中。分组后的各组跨片事务提交指令,可以按照分组编号升序或降序排列后填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务提交指令组织成一棵树,并基于这棵树的树根生成hash值后将该hash值填入主链区块的区块头的Transaction_Root。此外,对于前述提到的主链区块中包括跨片事务列表的情况,可以将跨片事务提交指令列表与S173中的跨片事务列表一并组织成树,并基于树根生成hash值后将该hash值填入主链区块的区块头的Transaction_Root。或者,将跨片事务提交指令组织成一棵单独的树,产生的树的树根的hash值填入主链区块的区块头中(例如一个新的字段,如跨片事务提交指令_root,图28中未示出)。在主链区块的区块头中加入区块号,时间戳,前一区块的hash等字段后,就生成了主链区块。
前述提到,所述源分片可以将所述生成的分片区块的区块头与所述跨片事务提交指令一并发送至主链。主链接收到源分片发来的源分片区块的区块头和跨片事务提交指令后,可以对分片区块的区块头进行验证。验证可以包括,根据跨片事务提交指令按照树形结构计算根节点的hash值,确定该值与区块头中的跨片事务提交指令_root一致。或者,根据跨片事务提交指令按照树形结构计算得到这棵树的根,并基于该树根(可能还包括跨片事务构成的树的根,跨片事务响应构成的树的根,等)得到hash值,确定该值与区块头中的Transaction_root一致。如果不一致则验证不通过,反之验证通过。还可以验证源分片本次发来的分片区块的区块头是否与之前发来的分片区块的区块头相同,相同则说明与之前的分片区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的分片区块的区块头中的Prev Hash是否是上个区块号的分片区块的hash值,如果是则通过验证,否则不通过。
之后,主链可以将所述需要目标分片执行的跨片事务提交指令按照目标分片的标识发送至对应的目标分片中。具体的,可以将所述主链区块的区块体中分组的跨片事务提交指令按照目标分片的标识发送至对应的目标分片中。这样,可以将所述主链区块的区块体中分组的跨片事务提交指令按照目标分片的标识发送至对应的目标分片中。除了将所述需要目标分片执行的跨片事务提交指令按照目标分片的标识发送至对应的目标分片中,还可以将所述主链区块的区块头发送至目标分片,例如与需要对应目标分片处理的跨片事务提交指令一并发送至所述目标分片。
S335:所述目标分片生成目标分片区块的过程中,将接收到所述主链发来的跨片事务提交指令填入所述目标分片区块的区块体中,并在本地提交执行所述跨片事务所产生的状态。
所述目标分片中的节点接收到主链发来的跨片事务提交指令后,可以先对跨片事务提交指令进行验证。例如,可以按照树形结构计算该跨片事务提交构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务提交指令是否与之前接收到的跨片事务提交指令重复。如果重复,可以不再处理本次发来的跨片事务提交指令,否则继续处理。
所述目标分片可以接收所述主链发来的需要由所述目标分片执行的跨片事务提交指令。此外,所述目标分片也可以接收与其连接的客户端发起的交易请求。所述目标分片中的主节点可以将一段时间内接收到的一定数量的交易打包并发起共识提议。所述打包的交易中可以包括前述主链发来的跨片事务提交指令,还可以包括所述目标分片接收到的客户端发来的交易,还可以包括前述的跨片事务响应。在所述目标分片中达成共识后,由所述目标分片中的各个节点执行这些打包的交易,生成目标分片区块。这里的目标分片区块不同于S245中的目标分片区块。由于目标分片中在不断的成块,所以这里目标分片生成的分片区块,晚于S245中的目标分片区块。例如S245中如图29所示生成的是区块201,则这里是区块201之后生成的区块,例如是区块202。所述目标分片生成目标分片区块的过程中,可以将接收到所述主链发来的跨片事务提交指令填入所述源分片区块的区块体中,具体如跨片事务提交指令列表中。此外,所述目标分片还可以将打包的客户端发来的交易填入所述目标分片区块的区块体中,具体如原始交易列表中。填入目标分片区块的区块体中的跨片事务提交指令,可以按照树形结构组织起来,树根的hash值即为生成的目标分片区块的区块头中的跨片事务提交指令_Root。
前述S333中提到,主链除了将所述跨片事务发送至对应的目标分片中,还可以将所述主链区块的区块头发送至目标分片。目标分片接收到主链发来的主链区块的区块头和跨片事务提交指令后,可以对主链区块的区块头进行验证。验证可以包括,所述目标分片根据主链本次发来的主链区块的区块头计算所述主链区块的hash,并基于该主链区块的hash判断是否与之前发来的主链区块的区块头相同,相同则说明与之前的主链区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的主链区块的区块头中的Prev Hash是否是上次发来的主链区块的hash值,如果是则通过验证,否则不通过。
对于主链还将生成的主链区块的区块头发送至目标分片的情况,目标分片在生成目标分片区块的过程中,可以根据接收到的主链区块的区块头计算得到该主链区块的hash值。进而,目标分片还可以将该主链区块的hash值填入目标分片生成的目标分片区块的区块头中。对于主链区块的生成速度不低于分片区块的生成速度的情况,目标分片可以将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中。是否最新可以根据主链区块的区块头中的时间戳或者区块号来判断。如前所述,所述目标分片在生成目标分片区块的过程中,还可以验证当前主链区块的hash值是否与之前发来的主链区块重复。如果重复,可以不再处理本次发来的区块头以及对应的跨片事务提交指令,否则继续处理。目标分片通过将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中,对于主链区块的生成速度等于分片区块的生成速度的情况,可以在目标分片中标识当前目标分片中接收的跨片事务提交指令是哪个主链区块的区块体中的跨片事务提交指令,对于主链区块的生成速度高于分片区块的生成速度的情况,可以在目标分片中标识当前目标分片中接收的跨片事务提交指令是截止到哪个主链区块的区块体中的跨片事务提交指令。
由于主链区块的生成速度不低于分片区块的生成速度,对于主链区块的生成速度高于分片区块的生成速度的情况,借助图29中所示,分片1在生成分片区块101和目标分片区块102之间,主链中已经生成过两个主链区块,分别为主链区块10003和10004。除了图29中所示的主链将主链区块10004的区块头和主链区块10004中的跨片事务提交指令发送至分片1,实际上,在此之前,如果主链区块10003中也包含分片1需要处理的跨片事务提交指令,主链还可以将主链区块10003的区块头和主链区块10003中的需要由分片1处理的跨片事务提交指令发送至分片1。即,正常情况下,主链按照主链区块生成的时间顺序将主链区块的区块头和对应的跨片事务提交指令发送至所述跨片事务提交指令涉及的分片。这样,目标分片可以将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中,上述例子中,即将主链区块10004的区块hash填入目标分片生成的目标分片区块的区块头中(图29中未示出)。同时,分片1在生成的分片区块102的区块体的原始交易列表中,可以包括主链区块10003和10004中涉及需要由分片1处理的跨片事务提交指令。此外,所述分片区块102的原始交易列表中也可以包括与分片1连接的客户端发起的交易请求。与分片1连接的客户端发起的交易请求,可以是转账交易,也可以是创建/调用合约的交易。
另一种情况,对于生成的目标分片区块中包括主链发来的多个主链区块的区块头和对应的需要由源分片执行的跨片事务提交指令的情形,除了在分片区块的区块体的跨片事务提交指令列表中包括所述多个主链区块中的需要由该分片处理的跨片事务提交指令以外,在分片区块的区块头中还可以包括所述多个主链区块的区块头。显然的,这种情况下,分片区块的区块头中包含的处理的主链区块的hash的数量可能是不定的。
再一种情况如图29所示,对于生成的分片区块中包括主链发来的多个主链区块的区块头和对应的需要由目标分片执行的跨片事务提交指令的情形,除了在分片区块的区块体的跨片事务提交指令列表中包括所述多个主链区块中的需要由该分片处理的跨片事务提交指令以外,在分片区块的区块体中还可以包括所述多个主链区块的区块hash,如图29的区块101的区块体中的主链区块hash列表。分片区块的区块体中包含的这些处理的主链区块的hash,可以按照如前所述的树形结构组织,并将这棵树的根的hash值填入区块头中增加的字段“主链区块根Hash”中,即将所述各个主链区块的hash按照树形结构计算得到的根的hash值填入所述分片区块的区块头的主链区块根Hash中。例如,区块101的区块头中的“主链区块根Hash”,是区块101的区块体中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值;区块102的区块头中的“主链区块根Hash”,区块102的区块头中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值。这样的好处在于,在分片区块的区块头中可以通过一个固定的字段来锁定所述分片区块的区块体中可能包括的不定数量的处理的主链区块的hash。
此外,主链还可以发送生成的主链区块的时间戳至目标分片,例如通过之前发送所述主链区块的区块头指示所述主链区块的时间戳,这样,分片在生成分片区块的过程中可以将最新主链区块的时间戳填入分片区块的timestamp中。例如,S335中,目标分片生成目标分片区块的过程中,将所述目标分片区块的区块头中的时间戳设定为所述主链发送的最新的时间戳。这样,可以在分片中锚定主链的时间***,从而使得分片具有与主链相同的时钟***。分片与主链具有相同的时钟***的情况下,与所述分片相连的客户端在发起交易时可以确定该交易的发起时间。从而,客户端在发起交易时,可以将该发起时刻的时间戳附在发起的交易上。
所述目标分片中的各节点执行交易,包括执行所述跨片事务提交指令。对于执行所述跨片事务提交指令,包括将所述跨片事务提交指令对应的所述目标分片中相关的变化后的状态提交至底层数据库,即持久化存储。
另外,所述目标分片在本地提交执行所述跨片事务所产生的状态,和所述目标分片生成目标分片区块的过程中将接收到所述主链发来的跨片事务提交指令填入所述目标分片区块的区块体中,两者没有严格的先后顺序,也可以并行执行。
上述本申请提供的提交跨片事务的方法实施例,在包含分片的区块链***中通过主链来将源分片中产生的跨分片事务提交指令转发至目标分片,提供了包含分片的区块链***中提交分片事务的方案。这个过程,通过构成主链的节点的权威性,使得源分片中产生的跨片事务提交指令能够在主链的见证下可靠的转发并在目标分片中执行,并在源分片、主链和目标分片上均存证。
前述提到,S171中源分片中的节点即使在本分片中完成了共识并执行了该源分片区块中的这些跨分片交易,也不将该源分片区块中跨分片交易产生的本分片中相关账户的变化后的状态提交至数据库,即不持久化存储。进一步的,源分片通过主链来将源分片中产生的跨分片事务转发至目标分片。
目标分片中的各节点执行所述跨片事务后,也可以判断所执行的跨片事务是否还涉及其它分片需要执行的跨片事务。如果目标分片中判断所执行的跨片事务不涉及其它分片,可以将目标分片中相应的账户变化后的状态提交至底层数据库,即持久化存储。进而,目标分片可以通过主链通知源分片提交所述跨片事务产生的状态。
图34示出了该流程,包括:
S341:目标分片生成目标分片区块的过程中根据所述目标分片执行的跨片事务判断没有其它分片需要执行的跨片事务后,在本地提交执行所述跨片事务所产生的状态,产生并发送跨片事务提交指令至主链。
所述目标分片在本地提交执行所述跨片事务所产生的状态,和在生成目标分片区块的过程中产生跨片事务提交指令,两者没有严格的先后顺序,也可以并行执行。
前述提到,还存在多重跨片事务的情况,例如存在一类跨片交易,当源分片生成需要由第一分片执行的第一跨片事务后,将第一跨片事务发送至第一分片,由第一分片执行;第一分片执行第一跨片事务后,产生需要由目标分片执行的第二跨片事务,并将第二跨片事务发送至目标分片;进而,由目标分片执行第二跨片事务,并且目标分片执行第二跨片事务的过程中,不再生成需要由第二分片以外的其它分片执行的跨片事务。类似的,更复杂的跨片交易,在源分片和目标分片之间可能涉及第一分片、第二分片、……。
多重跨片事务的情况,再例如存在一类跨片交易,当第一分片生成需要由第二分片执行的第一跨片事务后,将第一跨片事务发送至第二分片,由第二分片执行;第二分片执行第一跨片事务后,产生需要由第一分片执行的第二跨片事务,并将第二跨片事务发送至第一分片;进而,由第一分片执行第二跨片事务,并且第一分片执行第二跨片事务的过程中,不再生成需要由第一分片以外的其它分片执行的跨片事务。
上述的例子中,往往一个分片在执行跨片事务时,可以在执行过程中判断是否有需要其它分片继续执行的跨片事务。如果判断没有需要其它分片继续执行的跨片事务,则该分片一个跨片事务的最后一个执行环节。对于执行跨片事务最后一个执行环节的分片,可以在执行完所述跨片事务后,在本地提交执行所述跨片事务所产生的状态。执行跨片事务最后一个执行环节的分片,这里称为目标分片。执行目标分片上一环节的跨片事务的分片,相对于目标分片即为源分片。多重跨片事务可以是多个单重跨片事务的叠加。那么,一个单重跨片事务的目标分片,可以是另一单重跨片事务的源分片。
所述目标分片执行跨片事务,如果成功执行,可以生成跨片事务提交指令,并可以将这些跨片事务提交指令添加至分片区块的区块体中,例如图35中所示的跨片事务提交指令列表中。这些跨片事务提交指令列表中的跨片事务提交指令,可以组织成树的形式。进而,目标分片可以在生成的区块头中增加一个跨片事务提交指令_Root字段,用于存放区块体中的这些跨片事务提交指令组织成树的树根的hash。这样,目标分片就可以将本区块中执行跨片事务后生成的提交指令锁定在区块头中。如图35中所示,目标分片生成的分片区块的区块头中可以包括区块号、时间戳、前一区块的hash、交易根hash、主链区块根hash,跨片事务提交指令_Root等。相应的,分片区块的hash值为包括跨片事务提交指令_Root字段在内的区块头中的字段计算得到的hash值。
进而,所述目标分片可以将跨片事务提交指令返回给主链。而且,所述目标分片可以将所述生成的分片区块的区块头与所述跨片事务提交指令一并发送至主链。此外,所述目标分片在所述生成的分片区块中,也可以处理所述目标分片接收到的客户端发来的交易。而这些客户端发来的交易中,也可能包括跨片的事务。这时,该目标分片同时又是源分片。本领域技术人员可以理解,此时是源分片的情形,可以从S171开始重复执行。这里为了简单,下面仅讨论作为目标分片返回跨片事务提交指令给主链的情况。
目标分片除了将所述跨片事务提交指令发送至主链,还可以将产生的目标分片区块的区块头发送至主链。
S343:主链生成主链区块的过程中,将接收到的跨片事务提交指令填入主链区块的区块体中;所述主链将所述跨片事务提交指令按照源分片的标识发送至对应的源分片中。
主链中的节点接收到目标分片发来的跨片事务指令后,可以先对跨片事务提交指令进行验证。例如,可以按照树形结构计算该跨片事务提交指令构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务提交指令是否与之前接收到的跨片事务提交指令重复。如果重复,可以不再处理本次发来的跨片事务提交指令,否则继续处理。
主链中的主节点可以收集目标分片发来的跨片事务提交指令,或者是主链中的非主节点接收目标分片发来的跨片事务提交指令后将这些跨片事务提交指令转发至主链中的主节点。主链中的主节点可以将一段时间内各分片发来的一定数量的跨片事务提交指令打包并发起共识提议。在主链中达成共识后,由主链中的各个节点执行这些打包的交易,生成主链区块。
主链中的各个节点执行这些打包的跨片事务提交指令并生成区块,可以包括将所述需要由源分片执行的跨片事务提交指令填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务提交指令组织成一棵树,并基于这棵树的树根生成hash值后将该hash值填入主链区块的区块头的Transaction_Root。例如,对于前述提到的主链区块中包括跨片事务列表的情况,可以将跨片事务提交指令列表与跨片事务列表一并组织成树,并基于树根生成hash值后将该hash值填入主链区块的区块头的Transaction_Root。或者,将跨片事务提交指令组织成一棵单独的树,产生的树的树根的hash值填入主链区块的区块头中(例如一个新的字段,如跨片事务提交指令_root,图35中未示出)。在主链区块的区块头中加入区块号,时间戳,前一区块的hash等字段后,就生成了主链区块。
所述主链生成主链区块的过程中,还可以计算各个目标分片发来的目标分片区块的区块hash,并将目标分片区块hash填入所述主链区块的区块体中,如分片区块hash列表中。进一步的,所述主链还可以将所述各个分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根(Shards_BlockRoot)中,例如如图35中所示。
主链中的各个节点执行这些打包的交易并生成区块,将所述需要由源分片执行的跨片事务提交指令填入主链区块的区块体中,具体可以是按照主链中的主节点发起共识提议的消息中需要由源分片执行的跨片事务提交指令的顺序,将需要由源分片执行的跨片事务提交指令填入主链区块的区块体中。此外,也可以是按照需要反馈至的源分片对跨片事务提交指令进行分组,将分组后的跨片事务提交指令填入主链区块的区块体中。分组后的各组跨片事务提交指令,可以按照分组编号升序或降序排列后填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务提交指令以相同的树形结构组织成一棵树,并基于这棵树的树根得到hash值后将该hash值填入主链区块的区块头的Transaction_root字段(如将跨片事务提交指令列表与S173中的跨片事务列表一并组织成一棵树,并基于这棵树的树根生成hash值后将该hash值填入主链区块的区块头的Transaction_root)。优选的,主链区块的区块体包括的各个源分片需要收到的跨片交易提交指令,是未经主链在之前已生成的区块中打包的。此外,主链中生成的主链区块,如果该区块生成前在主节点打包交易时中对于某一源分片没有其接收的跨片事务提交指令,则该主链区块的区块体中,可以不包括需要由该源分片对应的跨片事务提交指令。
前述提到,所述目标分片可以将所述生成的目标分片区块的区块头与所述跨片事务提交指令一并发送至主链。主链接收到目标分片发来的目标分片区块的区块头和跨片事务提交指令后,可以对目标分片区块的区块头进行验证。验证可以包括,根据跨片事务提交指令按照树形结构计算根节点的hash值,确定该值与区块头中的跨片事务提交指令_root一致。或者,根据跨片事务提交指令按照树形结构计算得到这棵树的根,并基于该树根(可能还包括跨片事务构成的树的根,等)得到hash值,确定该值与区块头中的Transaction_root一致。如果不一致则验证不通过,反之验证通过。还可以验证目标分片本次发来的目标分片区块的区块头是否与之前发来的目标分片区块的区块头相同,相同则说明与之前的目标分片区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的目标分片区块的区块头中的Prev Hash是否是上个区块号的目标分片区块的hash值,如果是则通过验证,否则不通过。
之后,主链可以将所述需要源分片接收的跨片事务提交指令按照源分片的标识发送至对应的源分片中。具体的,可以将所述主链区块的区块体中分组的跨片事务提交指令按照源分片的标识发送至对应的源分片中。这样,可以将主链区块体中的跨片事务提交指令按照需要接收的源分片的标识分别发送。除了将所述需要源分片执行的跨片事务提交指令按照源分片的标识发送至对应的源分片中,还可以将所述主链区块的区块头发送至源分片,例如与需要对应源分片处理的跨片事务提交指令一并发送至所述源分片。
前述提到,目标分片除了将所述跨片事务提交指令发送至主链,还可以将产生的目标分片区块的区块头发送至主链。
S345:所述源分片生成源分片区块的过程中,将接收到所述主链发来的跨片事务提交指令填入所述源分片区块的区块体中,并在本地提交执行所述跨片事务所产生的状态。
所述源分片中的节点接收到主链发来的跨片事务提交指令后,可以先对跨片事务提交指令进行验证。例如,可以按照树形结构计算该跨片事务提交指令构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务提交指令是否与之前接收到的跨片事务提交指令重复。如果重复,可以不再处理本次发来的跨片事务提交指令,否则继续处理。
所述源分片可以接收所述主链发来的需要由所述源分片接收的跨片事务提交指令。此外,所述源分片也可以接收与其连接的客户端发起的交易请求。所述源分片中的主节点可以将一段时间内接收到的一定数量的交易打包并发起共识提议。所述打包的交易中可以包括前述主链发来的跨片事务提交指令,还可以包括所述源分片接收到的客户端发来的交易。在所述源分片中达成共识后,由所述源分片中的各个节点执行这些打包的交易,生成源分片区块。这里的源分片区块不同于S271中的源分片区块。由于源分片中在不断的成块,所以这里源分片生成的分片区块,晚于S271中的源分片区块。例如S271中如图28所示生成的是区块201,则这里是区块201之后生成的区块,例如是区块202。所述源分片生成源分片区块的过程中,可以将接收到所述主链发来的跨片事务提交指令填入所述源分片区块的区块体中,具体如跨片事务提交指令列表中。此外,所述目标分片还可以将打包的客户端发来的交易填入所述源分片区块的区块体中,具体如原始交易列表中。填入源分片区块的区块体中的跨片事务提交指令列表,可以按照树形结构组织起来,树根的hash值即为生成的目标分片区块的区块头中的跨片事务提交指令_Root。例如如图36所示。
前述S343中提到,主链除了将所述跨片事务提交指令发送至对应的源分片中,还可以将所述主链区块的区块头发送至源分片。源分片接收到主链发来的主链区块的区块头和跨片事务提交指令后,可以对主链区块的区块头进行验证。验证可以包括,所述源分片根据主链本次发来的主链区块的区块头计算所述主链区块的hash,并基于该主链区块的hash判断是否与之前发来的主链区块的区块头相同,相同则说明与之前的主链区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的主链区块的区块头中的Prev Hash是否是上次发来的主链区块的hash值,如果是则通过验证,否则不通过。
对于主链还将生成的主链区块的区块头发送至源分片的情况,源分片在生成源分片区块的过程中,可以根据接收到的主链区块的区块头计算得到该主链区块的hash值。进而,源分片还可以将该主链区块的hash值填入源分片生成的源分片区块的区块头中。对于主链区块的生成速度不低于分片区块的生成速度的情况,源分片可以将最新主链区块的hash值填入源分片生成的源分片区块的区块头中。是否最新可以根据主链区块的区块头中的时间戳或者区块号来判断。如前所述,所述源分片在生成源分片区块的过程中,还可以验证当前主链区块的hash值是否与之前发来的主链区块重复。如果重复,可以不再处理本次发来的区块头以及对应的跨片事务提交指令,否则继续处理。源分片通过将最新主链区块的hash值填入源分片生成的源分片区块的区块头中,对于主链区块的生成速度等于分片区块的生成速度的情况,可以在源分片中标识当前源分片中接收的跨片事务提交指令是哪个主链区块的区块体中的跨片事务提交指令,对于主链区块的生成速度高于分片区块的生成速度的情况,可以在源分片中标识当前源分片中接收的跨片事务提交指令是截止到哪个主链区块的区块体中的跨片事务提交指令。
由于主链区块的生成速度不低于分片区块的生成速度,对于主链区块的生成速度高于分片区块的生成速度的情况,借助图36中所示,分片2在生成分片区块201和目标分片区块202之间,主链中已经生成过两个主链区块,分别为主链区块10002和10003。除了图36中所示的主链将主链区块10003的区块头和主链区块10003中的跨片事务提交指令发送至分片2,实际上,在此之前,如果主链区块10002中也包含分片2需要接收的跨片事务提交指令,主链还可以将主链区块10002的区块头和主链区块10002中的需要由分片2接收的跨片事务提交指令发送至分片2。即,正常情况下,主链按照主链区块生成的时间顺序将主链区块的区块头和对应的跨片事务提交指令发送至所述跨片事务提交指令涉及的分片。这样,源分片可以将最新主链区块的hash值填入源分片生成的源分片区块的区块头中,上述例子中,即将主链区块10003的区块hash填入源分片生成的源分片区块的区块头中(图36中未示出)。同时,分片2在生成的分片区块202的区块体的原始交易列表中,可以包括主链区块10002和10003中涉及需要由分片2接收的跨片事务提交指令。此外,所述分片区块202的原始交易列表中也可以包括与分片2连接的客户端发起的交易请求。与分片2连接的客户端发起的交易请求,可以是转账交易,也可以是创建/调用合约的交易。
另一种情况,对于生成的源分片区块中包括主链发来的多个主链区块的区块头和对应的需要由源分片接收的跨片事务提交指令的情形,除了在分片区块的区块体的跨片事务提交指令列表中包括所述多个主链区块中的需要由该分片处理的跨片事务提交指令以外,在分片区块的区块头中还可以包括所述多个主链区块的区块头。显然的,这种情况下,分片区块的区块头中包含的处理的主链区块的hash的数量可能是不定的。
再一种情况,对于生成的分片区块中包括主链发来的多个主链区块的区块头和对应的需要由源分片接收的跨片事务提交指令的情形,除了在分片区块的区块体的跨片事务提交指令列表中包括所述多个主链区块中的需要由该分片处理的跨片事务提交指令以外,在分片区块的区块体中还可以包括所述多个主链区块的区块hash。分片区块的区块体中包含的这些处理的主链区块的hash,可以按照如前所述的树形结构组织,并将这棵树的根的hash值填入区块头中增加的字段“主链区块根Hash”中,如图36所示,即将所述各个主链区块的hash按照树形结构计算得到的根的hash值填入所述分片区块的区块头的主链区块根Hash中。例如,区块201的区块头中的“主链区块根Hash”,是区块201的区块体中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值;区块202的区块头中的“主链区块根Hash”,区块202的区块头中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值。这样的好处在于,在分片区块的区块头中可以通过一个固定的字段来锁定所述分片区块的区块体中可能包括的不定数量的处理的主链区块的hash。
此外,主链还可以发送生成的主链区块的时间戳至源分片,例如通过之前发送所述主链区块的区块头指示所述主链区块的时间戳,这样,分片在生成分片区块的过程中可以将最新主链区块的时间戳填入分片区块的timestamp中。例如,S345中,源分片生成源分片区块的过程中,将所述源分片区块的区块头中的时间戳设定为所述主链发送的最新的时间戳。这样,可以在分片中锚定主链的时间***,从而使得分片具有与主链相同的时钟***。分片与主链具有相同的时钟***的情况下,与所述分片相连的客户端在发起交易时可以确定该交易的发起时间。从而,客户端在发起交易时,可以将该发起时刻的时间戳附在发起的交易上。
所述源分片中的各节点执行交易,包括将所述跨片事务提交指令对应的所述目标分片中相关的变化后的状态提交至底层数据库,即持久化存储。另外,所述目标分片在本地提交执行所述跨片事务所产生的状态,和所述目标分片生成目标分片区块的过程中将接收到所述主链发来的跨片事务提交指令填入所述目标分片区块的区块体中,两者没有严格的先后顺序,也可以并行执行。
上述本申请提供的提交跨片事务的方法实施例,在包含分片的区块链***中通过主链来将目标分片中产生的跨分片事务提交指令转发至源分片,提供了包含分片的区块链***中跨分片事务提交指令的反馈方案以及源分片提交跨片事务的方案。这个过程,通过构成主链的节点的权威性,使得目标分片中产生的跨片事务提交指令能够在主链的见证下可靠的转发,并在目标分片、主链和源分片上均存证。
跨片事务的执行和提交,应当具有原子性。具体的,由于跨片事务涉及区块链***中不同分片上的节点,因此,对于跨片事务,应当在涉及的源分片和目标分片上都执行/提交,或者都不执行/提交,而不应当在源分片和目标分片中的一个执行/提交,在另一个没有执行/提交。否则,将导致事务的最终状态不一致,不同分片间的账本无法一致。前述实施例主要给出了成功执行/提交的过程。假如在源分片和目标分片中的任一个没有能够成功执行/提交,或等待主链发送的跨片事务响应/跨片事务提交响应/跨片事务提交指令发生超时,为了保证跨片事务的原子性,自身应当退出跨片事务,并且应当通知另一个也退出跨片事务。
图37示出了本申请一种包含分片的区块链***中退出跨片事务的方法,该区块链***中至少包括两个分片,不同分片中的节点存储不同的状态集合;所述区块链***还包括主链;
所述方法包括:
S371:源分片在本地执行跨片事务相关的操作发生异常,或者等待跨片事务相关的消息发生超时,源分片在本地撤回发生异常/超时的跨片事务,并针对所述跨片事务产生需要由对应目标分片执行的退出指令,将所述跨片事务退出指令发送至主链。
S171中,源分片在本地执行跨片事务相关操作时,可能会发生异常。例如,源分片在本地执行跨片事务中对应于所述源分片的操作时,由于程序代码出错而导致异常,或者由于内存无法分配等软、硬件情况导致异常,再或者由于操作的帐户不满足操作条件,如帐户余额或者资产低于转移要求之类,等等异常情况。S271中,源分片可能由于某种原因无法产生跨片事务提交指令,也属于一种异常情况。类似的,S331/S345中源分片可能由于某种原因无法在本地提交执行跨片事务所产生的状态,也属于一种异常情况。
源分片在本地执行跨片事务相关操作时,也可能会发生超时的情况。例如,S171中,源分片将所述跨分片交易中需要由目标分片执行的跨片事务发送至主链,但是后续由于某种原因,例如消息丢失等,主链或者目标分片并没有收到需要由所述目标分片执行的跨片事务,从而S175中目标分片无法执行相应的跨片事务,S241中所述目标分片也就不会返回跨片事务响应,这样,S245中源分片等待主链发送跨片事务响应会发生超时。此外,可能S241中目标分片出现错误或者S243中主链出现错误,则S245中源分片等待主链发送跨片事务响应也会发生超时。类似的,S301中目标分片发生错误或者S303中主链出现错误,则S305中源分片等待主链发送跨片事务提交响应也会发生超时。类似的,S341中目标分片发生错误或者4中主链出现错误,则S345中源分片等待主链发送跨片事务提交响应也会发生超时。
上述例举了源分片在本地执行跨片事务相关的操作发生异常,或者等待跨片事务相关的消息发生超时,并不是穷尽性的枚举。可能还存在其它导致异常或者超时的情况。
当源分片产生上述异常或超时时,可以在本地撤回发生异常/超时的跨片事务操作。例如,对于源分片在本地产生跨片事务提交指令发生异常,或在本地提交执行跨片事务所产生的状态发生异常,源分片可以撤回本地发生异常的跨片事务操作,例如可以撤回之前的在本地执行跨片事务的操作。再例如,对于源分片等待跨片事务响应超时/源分片等待跨片事务提交响应超时/源分片等待跨片事务提交指令超时,则源分片可以撤回之前在本地执行跨片事务的操作。一个具体的例子中,例如是对某个属性类的状态进行修改,如将某个变量由某种属性的状态1修改为该属性的状态2。在提交至底层数据库前,源分片在本地撤回该操作,可以是在本地删除执行跨片事务而在底层数据库临时***的数据。
例如对于在本地执行的跨片事务,如前所述,对于尚未在底层数据库提交的,实际上可以是在底层数据库中增加一条数据,并将该数据标记为临时***。那么,撤回本地发生异常的跨片事务操作,可以是删除该临时***的数据,具体可以是将临时***的标记更改为删除。对于底层数据库来说,并不一定是马上删除该数据,也可以是在压缩(compaction)环节删除底层数据库标记为删除的数据,从而删除所述数据。此外,对于源分片在本地产生跨片事务提交指令,或源分片在本地提交执行跨片事务所产生的状态,类似的,如果这些操作发生异常,也可以将底层数据库中相关的数据的临时***标记更改为删除,进而在compaction环节删除底层数据库标记为删除的数据。
当源分片产生上述异常或超时时在本地撤回发生异常/超时的跨片事务操作,还可以是源分片在本地对执行跨片事务而变更的状态执行反向操作,以使所述状态回退至所述跨片事务执行前的值。例如,对于源分片中的某一账户,执行跨片事务前余额为10,执行所述跨片事务,例如为转账事务,该帐户余额-6,变为4。该-6操作虽然没有导致执行该跨片事务变更后的值4提交至数据库,但是在源分片中锁定了该帐户的6个单位的余额,导致该账户暂时可使用的余额为4。这里,可以对该账户的状态执行反向操作,即执行+6操作,这样,这些操作提交至数据库后,可以使得状态回退至10,即回退至执行该跨片事务之前的状态。
当源分片产生上述异常或超时时,除了可以在本地撤回发生异常/超时的跨片事务操作,为了确保跨片事务的执行和提交具备原子性,还可以针对所述跨片事务产生需要由对应目标分片执行的退出指令,并将所述跨片事务退出指令发送至主链。
源分片对于产生的跨片事务退出指令,在生成源分片区块的过程中,可以将产生的跨片事务退出指令添加至生成的分片区块的区块体中,例如图38中分片区块201和202中的跨片事务退出指令列表。这些跨片事务退出指令列表中的跨片事务退出指令,可以组织成树的形式。进而,源分片可以在生成的区块头中增加一个跨片事务退出指令_Root字段,用于存放区块体中的这些跨片事务退出指令组织成树的树根的hash。这样,源分片就可以将本区块中生成的跨片事务退出指令锁定在区块头中。此外,图38中分片区块201和202的区块体中还可以包括原始交易列表和主链区块Hash列表。同样的,在区块头中可以用Transaction_root将区块体中的原始交易列表锁定,用主链区块根Hash将区块体中的主链区块Hash列表锁定。在区块体里除了原有的原始交易列表和跨片事务退出指令列表外,还可以包括本区块产生的跨片事务列表(图中未示出)。需要说明的是,该跨片事务退出指令列表针对的是之前区块中的跨片事务列表,而非本区块中的跨片事务。由于可能存在分片2与不同目标分片的跨片交易,因此分片2产生的分片区块中的跨片事务退出指令列表中,可能包括需要发送至多个不同目标分片的跨片事务退出指令。如图38中所示,源分片生成的分片区块的区块头中可以包括区块号、时间戳、前一区块的hash、Transaction_root、主链区块根hash,跨片事务退出指令_Root等。相应的,分片区块的hash值为包括跨片事务退出指令_Root字段在内的区块头中的字段计算得到的hash值。此外,所述主链区块的区块体包括的各个目标分片接收的跨片事务退出指令,优选是未经主链在之前已生成的区块中打包的。
源分片除了将所述跨片事务退出指令发送至主链,还可以将产生的源分片区块的区块头发送至主链。
S373:主链生成主链区块的过程中,将接收到的需要由目标分片执行的退出跨片事务的指令填入主链区块的区块体中;所述主链将所述需要目标分片执行的退出跨片事务的指令按照目标分片的标识发送至对应的目标分片中。
主链生成主链区块的过程中,将接收到的需要发送给目标分片的跨片事务退出指令填入主链区块的区块体中;所述主链将所述跨片事务退出指令按照目标分片的标识发送至对应的目标分片中。
主链中的节点接收到源分片发来的跨片事务退出指令后,可以先对跨片事务退出指令进行验证。例如,可以按照树形结构计算该跨片事务退出指令构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务退出指令是否与之前接收到的跨片事务退出指令重复。如果重复,可以不再处理本次发来的跨片事务退出指令,否则继续处理。
主链中的主节点可以收集源分片发来的跨片事务退出指令,或者是主链中的非主节点接收源分片发来的跨片事务退出指令后将这些跨片事务退出指令转发至主链中的主节点。主链中的主节点可以将一段时间内各分片发来的一定数量的跨片事务退出指令打包并发起共识提议。在主链中达成共识后,由主链中的各个节点执行这些打包的交易,生成主链区块。
所述主链生成主链区块的过程中,还可以计算各个源分片发来的源分片区块的区块hash,并将源分片区块hash填入所述主链区块的区块体中。进一步的,所述主链生成主链区块的过程中,还可以将所述各个分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根中,例如如图38中所示。
主链中的各个节点执行这些打包的跨片事务退出指令并生成区块,可以包括将所述需要由发送至目标分片的跨片事务退出指令填入主链区块的区块体中。具体的,可以是按照主链中的主节点发起共识提议的消息中需要发送至目标分片的跨片事务退出指令的顺序,将需要由目标分片执行的跨片事务退出指令填入主链区块的区块体中。此外,也可以是按照需要发送至的目标分片对跨片事务退出指令进行分组,将分组后的跨片事务退出指令填入主链区块的区块体中。分组后的各组跨片事务退出指令,可以按照分组编号升序或降序排列后填入主链区块的区块体中。进而,主链中的各个节点可以将这些跨片事务退出指令组织成一棵树,并基于这棵树的树根生成hash值后将该hash值填入主链区块的区块头的Transaction_Root。此外,对于前述提到的主链区块中包括跨片事务列表的情况,可以将跨片事务退出指令列表与S173中的跨片事务列表一并组织成树,并基于树根生成hash值后将该hash值填入主链区块的区块头的Transaction_Root。或者,将跨片事务退出指令组织成一棵单独的树,产生的树的树根的hash值填入主链区块的区块头中(例如一个新的字段,如跨片事务退出指令_root,图38中未示出)。在主链区块的区块头中加入区块号,时间戳,前一区块的hash等字段后,就生成了主链区块。
前述提到,所述源分片可以将所述生成的分片区块的区块头与所述跨片事务退出指令一并发送至主链。主链接收到源分片发来的源分片区块的区块头和跨片事务退出指令后,可以对分片区块的区块头进行验证。验证可以包括,根据跨片事务退出指令按照树形结构计算根节点的hash值,确定该值与区块头中的跨片事务退出指令_root一致。或者,根据跨片事务退出指令按照树形结构计算得到这棵树的根,并基于该树根(可能还包括跨片事务构成的树的根,跨片事务响应构成的树的根,等)得到hash值,确定该值与区块头中的Transaction_root一致。如果不一致则验证不通过,反之验证通过。还可以验证源分片本次发来的分片区块的区块头是否与之前发来的分片区块的区块头相同,相同则说明与之前的分片区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的分片区块的区块头中的Prev Hash是否是上个区块号的分片区块的hash值,如果是则通过验证,否则不通过。
之后,主链可以将所述需要目标分片执行的跨片事务退出指令按照目标分片的标识发送至对应的目标分片中。具体的,可以将所述主链区块的区块体中分组的跨片事务退出指令按照目标分片的标识发送至对应的目标分片中。这样,可以将所述主链区块的区块体中分组的跨片事务退出指令按照目标分片的标识发送至对应的目标分片中。除了将所述需要目标分片执行的跨片事务退出指令按照目标分片的标识发送至对应的目标分片中,还可以将所述主链区块的区块头发送至目标分片,例如与需要对应目标分片处理的跨片事务退出指令一并发送至所述目标分片。
S375 :所述目标分片生成目标分片区块的过程中,将接收到所述主链发来的跨片事务退出指令填入所述目标分片区块的区块体中,并执行所述退出跨片事务的指令。
所述目标分片生成目标分片区块的过程中,将接收到所述主链发来的跨片事务退出指令填入所述目标分片区块的区块体中,并在本地退出执行所述跨片事务所产生的状态。
所述目标分片中的节点接收到主链发来的跨片事务退出指令后,可以先对跨片事务退出指令进行验证。例如,可以按照树形结构计算该跨片事务退出构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务退出指令是否与之前接收到的跨片事务退出指令重复。如果重复,可以不再处理本次发来的跨片事务退出指令,否则继续处理。
所述目标分片可以接收所述主链发来的需要由所述目标分片执行的跨片事务退出指令。此外,所述目标分片也可以接收与其连接的客户端发起的交易请求。所述目标分片中的主节点可以将一段时间内接收到的一定数量的交易打包并发起共识提议。在所述目标分片中达成共识后,由所述目标分片中的各个节点执行这些打包的交易,生成目标分片区块。所述目标分片生成目标分片区块的过程中,可以将接收到所述主链发来的跨片事务退出指令填入所述源分片区块的区块体中,具体如跨片事务退出指令列表中。填入目标分片区块的区块体中的跨片事务退出指令,可以按照树形结构组织起来,树根的hash值即为生成的目标分片区块的区块头中的跨片事务退出指令_Root。
前述S373中提到,主链除了将所述跨片事务退出指令发送至对应的目标分片中,还可以将所述主链区块的区块头发送至目标分片。目标分片接收到主链发来的主链区块的区块头和跨片事务退出指令后,可以对主链区块的区块头进行验证。验证可以包括,所述目标分片根据主链本次发来的主链区块的区块头计算所述主链区块的hash,并基于该主链区块的hash判断是否与之前发来的主链区块的区块头相同,相同则说明与之前的主链区块重复,验证不通过,反之验证通过。此外,还可以验证本次发来的主链区块的区块头中的PrevHash是否是上次发来的主链区块的hash值,如果是则通过验证,否则不通过。
对于主链还将生成的主链区块的区块头发送至目标分片的情况,目标分片在生成目标分片区块的过程中,可以根据接收到的主链区块的区块头计算得到该主链区块的hash值。进而,目标分片还可以将该主链区块的hash值填入目标分片生成的目标分片区块的区块头中。对于主链区块的生成速度不低于分片区块的生成速度的情况,目标分片可以将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中。是否最新可以根据主链区块的区块头中的时间戳或者区块号来判断。如前所述,所述目标分片在生成目标分片区块的过程中,还可以验证当前主链区块的hash值是否与之前发来的主链区块重复。如果重复,可以不再处理本次发来的区块头以及对应的跨片事务退出指令,否则继续处理。目标分片通过将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中,对于主链区块的生成速度等于分片区块的生成速度的情况,可以在目标分片中标识当前目标分片中接收的跨片事务退出指令是哪个主链区块的区块体中的跨片事务退出指令,对于主链区块的生成速度高于分片区块的生成速度的情况,可以在目标分片中标识当前目标分片中接收的跨片事务退出指令是截止到哪个主链区块的区块体中的跨片事务退出指令。
由于主链区块的生成速度不低于分片区块的生成速度,对于主链区块的生成速度高于分片区块的生成速度的情况,借助图39中所示,分片1在生成分片区块101和分片区块102之间,主链中已经生成过两个主链区块,分别为主链区块10003和10004。除了图39中所示的主链将主链区块10004的区块头和主链区块10004中的跨片事务退出指令发送至分片1,实际上,在此之前,如果主链区块10003中也包含分片1需要处理的跨片事务退出指令,主链还可以将主链区块10003的区块头和主链区块10003中的需要由分片1处理的跨片事务退出指令发送至分片1。即,正常情况下,主链按照主链区块生成的时间顺序将主链区块的区块头和对应的跨片事务退出指令发送至所述跨片事务退出指令涉及的分片。这样,目标分片可以将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中,上述例子中,即将主链区块10004的区块hash填入目标分片生成的目标分片区块的区块头中(图39中未示出)。同时,分片1在生成的分片区块102的区块体的原始交易列表中,可以包括主链区块10003和10004中涉及需要由分片1处理的跨片事务退出指令。此外,所述分片区块102的原始交易列表中也可以包括与分片1连接的客户端发起的交易请求。与分片1连接的客户端发起的交易请求,可以是转账交易,也可以是创建/调用合约的交易。
另一种情况,对于生成的目标分片区块中包括主链发来的多个主链区块的区块头和对应的需要由目标分片执行的跨片事务退出指令的情形,除了在分片区块的区块体的跨片事务退出指令列表中包括所述多个主链区块中的需要由该分片处理的跨片事务退出指令以外,在分片区块的区块头中还可以包括所述多个主链区块的区块头。显然的,这种情况下,分片区块的区块头中包含的处理的主链区块的hash的数量可能是不定的。
再一种情况如图39所示,对于生成的分片区块中包括主链发来的多个主链区块的区块头和对应的需要由目标分片执行的跨片事务退出指令的情形,除了在分片区块的区块体的跨片事务退出指令列表中包括所述多个主链区块中的需要由该分片处理的跨片事务退出指令以外,在分片区块的区块体中还可以包括所述多个主链区块的区块hash,如图39的区块101的区块体中的主链区块hash列表。分片区块的区块体中包含的这些处理的主链区块的hash,可以按照如前所述的树形结构组织,并将这棵树的根的hash值填入区块头中增加的字段“主链区块根Hash”中,即将所述各个主链区块的hash按照树形结构计算得到的根的hash值填入所述分片区块的区块头的主链区块根Hash中。例如,区块101的区块头中的“主链区块根Hash”,是区块101的区块体中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值;区块102的区块头中的“主链区块根Hash”,区块102的区块头中主链区块hash列表中的主链区块hash所组织成的树形结构的根节点的hash值。这样的好处在于,在分片区块的区块头中可以通过一个固定的字段来锁定所述分片区块的区块体中可能包括的不定数量的处理的主链区块的hash。
此外,主链还可以发送生成的主链区块的时间戳至目标分片,例如通过之前发送所述主链区块的区块头指示所述主链区块的时间戳,这样,分片在生成分片区块的过程中可以将最新主链区块的时间戳填入分片区块的timestamp中。例如,S375中,目标分片生成目标分片区块的过程中,将所述目标分片区块的区块头中的时间戳设定为所述主链发送的最新的时间戳。这样,可以在分片中锚定主链的时间***,从而使得分片具有与主链相同的时钟***。分片与主链具有相同的时钟***的情况下,与所述分片相连的客户端在发起交易时可以确定该交易的发起时间。从而,客户端在发起交易时,可以将该发起时刻的时间戳附在发起的交易上。
所述目标分片中的各节点执行交易,包括执行所述跨片事务退出指令。对于执行所述跨片事务退出指令,如前所述,包括目标分片在本地删除执行跨片事务而在底层数据库临时***的数据,和/或,目标分片在本地对执行跨片事务而变更的状态执行反向操作,以使所述状态回退至所述跨片事务执行前的状态。
另外,所述目标分片在本地退出所述跨片事务,和所述目标分片生成目标分片区块的过程中将接收到所述主链发来的跨片事务退出指令填入所述目标分片区块的区块体中,两者没有严格的先后顺序,也可以并行执行。
上述本申请提供的退出跨片事务的方法实施例,在包含分片的区块链***中通过主链来将源分片中产生的跨分片事务退出指令转发至目标分片,提供了包含分片的区块链***中退出分片事务的方案,从而保证了跨片事务的原子性。这个过程,通过构成主链的节点的权威性,使得源分片中产生的跨片事务退出指令能够在主链的见证下可靠的转发并在目标分片中执行,并在源分片、主链和目标分片上均存证。
一种包含分片的区块链***中退出跨片事务的***,该区块链***中至少包括两个分片,不同分片中的节点存储不同的状态集合;所述区块链***还包括主链;
源分片在本地提交跨片事务相关的操作发生异常,或者等待跨片事务相关的消息发生超时:
源分片在本地撤回发生异常/超时的跨片事务操作,并针对所述跨片事务产生需要由对应目标分片执行的退出指令,并将所述跨片事务退出指令发送至主链;
主链生成主链区块的过程中,将接收到的需要由目标分片执行的退出跨片事务的指令填入主链区块的区块体中;所述主链将所述需要目标分片执行的退出跨片事务的指令按照目标分片的标识发送至对应的目标分片中;
所述目标分片生成目标分片区块的过程中,将接收到所述主链发来的跨片事务退出指令填入所述目标分片区块的区块体中,并执行所述退出跨片事务的指令。
所述源分片在本地提交跨片事务相关的操作,包括:
源分片在本地执行跨片事务,或,
源分片在本地产生跨片事务提交指令,或,
源分片在本地提交执行跨片事务所产生的状态。
所述源分片等待跨片事务相关的消息发生超时,包括:
源分片等待跨片事务响应超时,或,
源分片等待跨片事务提交响应超时,或,
源分片等待跨片事务提交指令超时。
所述源分片在本地撤回发生异常/超时的跨片事务操作,具体包括:
源分片在本地删除执行跨片事务而在底层数据库临时***的数据;
和/或,
源分片在本地对执行跨片事务而变更的状态执行反向操作,以使所述状态回退至所述跨片事务执行前的状态。
所述源分片生成的源分片区块的区块体中还包括所述跨片事务退出指令列表,所述跨片事务退出指令列表包括需要发送至目标分片的跨片事务退出指令。
所述源分片生成的源分片区块的区块头中还包括跨片事务退出指令_root字段,用于将所述区块体中的跨片事务退出指令列表锁定至区块头中。
所述主链区块的区块体包括的各个目标分片接收的跨片事务退出指令,是未经主链在之前已生成的区块中打包的。
所述主链生成主链区块前,还包括:主链中的节点接收到源分片发来的跨片事务退出指令后,对所述跨片事务退出指令进行验证。
所述验证包括:主链中的节点按照树形结构计算分片发来的跨片事务退出指令构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务退出指令是否与之前接收到的跨片事务退出指令重复。
所述源分片除了将所述跨片事务退出指令发送至主链,还将生成的源分片区块的区块头发送至主链。
所述主链生成主链区块的过程中,还计算各个源分片发来的源分片区块的区块hash,并将源分片区块hash填入所述主链区块的区块体中。
所述主链生成主链区块的过程中,还将所述各个分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根中。
所述主链接收到源分片发来的源分片区块的区块头和跨片事务退出指令后,还对所述源分片区块的区块头进行验证。
所述验证包括,将跨片事务退出按照树形结构组织后得到的树的hash值,确定该值与所述源分片区块的区块头中的跨片事务退出指令_root一致。
所述主链将所述跨片事务退出指令按照目标分片的标识发送至对应的目标分片中,包括:
将所述主链区块的区块体中分组的跨片事务退出指令按照目标分片的标识发送至对应的目标分片中。
所述主链还将所述主链区块的区块头发送至所述目标分片。
所述目标分片生成目标分片区块前,还包括:所述目标分片中的节点接收到主链发来的跨片事务退出指令后,对所述跨片事务退出指令进行验证。
所述验证包括:所述目标分片中的节点按照树形结构计算该跨片事务退出指令构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务退出指令是否与之前接收到的跨片事务退出指令重复。
所述目标分片接收到主链发来的主链区块的区块头和跨片事务退出指令后,还对主链区块的区块头进行验证。
所述目标分片在生成目标分片区块的过程中,根据接收到的主链区块的区块头计算得到该主链区块的hash值,并将该主链区块的hash值填入所述目标分片生成的目标分片区块的区块头中。
对于主链区块的生成速度不低于分片区块的生成速度的情况,所述目标分片将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中。
对于主链区块的生成速度高于分片区块的生成速度的情况:
所述目标分片将本目标分片区块中打包的跨片事务退出指令对应的多个主链区块的hash值填入目标分片生成的目标分片区块的区块头中;或,
所述目标分片将本目标分片区块中打包的跨片事务退出指令对应的多个主链区块的hash值填入目标分片生成的目标分片区块的区块体中,还将所述各个主链区块的hash按照树形结构计算得到的根的hash值填入所述目标分片区块的区块头的主链区块根Hash中。
所述主链还发送生成的主链区块的时间戳至目标分片,所述目标分片在生成目标分片区块的过程中将所述主链区块的时间戳填入目标分片区块的timestamp中。
所述主链通过发送所述主链区块的区块头将所述主链区块的时间戳发送至所述目标分片。
所述主链发送生成的最新主链区块的时间戳至目标分片,相应的,所述目标分片在生成目标分片区块的过程中将所述最新主链区块的时间戳填入分片区块的timestamp中。
所述目标分片执行所述跨片事务退出指令,包括:
目标分片在本地删除执行跨片事务而在底层数据库临时***的数据;
和/或,
目标分片在本地对执行跨片事务而变更的状态执行反向操作,以使所述状态回退至所述跨片事务执行前的状态。
一种包含分片的区块链***中的源分片节点,如图40所示,包括:
执行单元401,用于在本地执行跨片事务相关的操作;
源分片区块生成单元402,用于生成源分片区块,并当执行单元在本地提交跨片事务相关的操作发生异常或者等待跨片事务相关的消息发生超时后,在生成源分片区块的过程中产生跨片事务退出指令;
跨片事务退出单元403,用于在本地撤回发生异常/超时的跨片事务操作;
发送单元404,用于将所述跨片事务退出指令发送至主链。
所述执行单元401在本地提交跨片事务相关的操作,包括:
执行单元401在本地执行跨片事务,或,
执行单元401在本地产生跨片事务提交指令,或,
执行单元401在本地提交执行跨片事务所产生的状态。
所述执行单元401等待跨片事务相关的消息发生超时,包括:
执行单元401等待跨片事务响应超时,或,
执行单元401等待跨片事务提交响应超时,或,
执行单元401等待跨片事务提交指令超时。
所述跨片事务退出单元403在本地撤回发生异常/超时的跨片事务操作,具体包括:
跨片事务退出单元403在本地删除执行跨片事务而在底层数据库临时***的数据;
和/或,
跨片事务退出单元403在本地对执行跨片事务而变更的状态执行反向操作,以使所述状态回退至所述跨片事务执行前的状态。
所述源分片区块生成单元402生成的源分片区块的区块体中还包括所述跨片事务退出指令列表,所述跨片事务退出指令列表包括需要发送至目标分片的跨片事务退出指令。
所述源分片区块生成单元402生成的源分片区块的区块头中还包括跨片事务退出指令_root字段,用于将所述区块体中的跨片事务退出指令列表锁定至区块头中。
所述发送单元404还将所述源分片区块生成单元生成的分片区块的区块头发送至主链。
一种包含分片的区块链***中的主链节点,如图41所示,包括:
接收单元411,用于接收需要由目标分片执行的跨片事务退出指令;
主链区块生成单元412,用于生成主链区块,并在生成主链区块的过程中,将接收到的跨片事务退出指令填入主链区块的区块体中;
发送单元413,用于将所述跨片事务退出指令按照目标分片的标识发送至对应的目标分片中。
所述主链区块生成单元412生成的区块的区块体包括的各个目标分片接收的跨片事务退出指令,是未经主链在之前已生成的区块中打包的。
所述主链节点还包括验证单元414,所述接收单元接收到目标分片发来的跨片事务退出指令后,所述验证单元对所述跨片事务退出指令进行验证。
所述验证包括:主链中的节点按照树形结构计算分片发来的跨片事务退出指令构成的树的根节点的hash值,根据该hash判断本次接收到的跨片事务提交指令是否与之前接收到的跨片事务退出指令重复。
所述接收单元411还接收源分片区块的区块头。
所述主链区块生成单元412生成主链区块的过程中,还计算各个源分片发来的源分片区块的区块hash,并将源分片区块hash填入所述主链区块的区块体中。
所述主链区块生成单元412生成主链区块的过程中,还将所述各个分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根中。
所述接收单元411接收到源分片发来的源块的区块头和跨片事务退出指令后,所述验证单元414还对所述源分片区块的区块头进行验证。
所述验证包括,将跨片事务退出指令按照树形结构组织后得到的树的hash值,确定该值与所述源分片区块的区块头中的跨片事务退出指令_root一致。
所述发送单元413将所述跨片事务退出指令按照目标分片的标识发送至对应的目标分片中,包括:
将所述主链区块的区块体中分组的跨片事务退出指令按照目标分片的标识发送至对应的目标分片中。
所述发送单元413还将所述主链区块的区块头发送至所述目标分片。
在20世纪90年代,对于一个技术的改进可以很明显地区分是硬件上的改进(例如,对二极管、晶体管、开关等电路结构的改进)还是软件上的改进(对于方法流程的改进)。然而,随着技术的发展,当今的很多方法流程的改进已经可以视为硬件电路结构的直接改进。设计人员几乎都通过将改进的方法流程编程到硬件电路中来得到相应的硬件电路结构。因此,不能说一个方法流程的改进就不能用硬件实体模块来实现。例如,可编程逻辑器件(Programmable Logic Device, PLD)(例如现场可编程门阵列(Field ProgrammableGate Array,FPGA))就是这样一种集成电路,其逻辑功能由用户对器件编程来确定。由设计人员自行编程来把一个数字***“集成”在一片PLD上,而不需要请芯片制造厂商来设计和制作专用的集成电路芯片。而且,如今,取代手工地制作集成电路芯片,这种编程也多半改用“逻辑编译器(logic compiler)”软件来实现,它与程序开发撰写时所用的软件编译器相类似,而要编译之前的原始代码也得用特定的编程语言来撰写,此称之为硬件描述语言(Hardware Description Language,HDL),而HDL也并非仅有一种,而是有许多种,如ABEL(Advanced Boolean Expression Language)、AHDL(Altera Hardware DescriptionLanguage)、Confluence、CUPL(Cornell University Programming Language)、HDCal、JHDL(Java Hardware Description Language)、Lava、Lola、MyHDL、PALASM、RHDL(RubyHardware Description Language)等,目前最普遍使用的是VHDL(Very-High-SpeedIntegrated Circuit Hardware Description Language)与Verilog。本领域技术人员也应该清楚,只需要将方法流程用上述几种硬件描述语言稍作逻辑编程并编程到集成电路中,就可以很容易得到实现该逻辑方法流程的硬件电路。
控制器可以按任何适当的方式实现,例如,控制器可以采取例如微处理器或处理器以及存储可由该(微)处理器执行的计算机可读程序代码(例如软件或固件)的计算机可读介质、逻辑门、开关、专用集成电路(Application Specific Integrated Circuit,ASIC)、可编程逻辑控制器和嵌入微控制器的形式,控制器的例子包括但不限于以下微控制器:ARC 625D、Atmel AT91SAM、Microchip PIC18F26K20 以及Silicone Labs C8051F320,存储器控制器还可以被实现为存储器的控制逻辑的一部分。本领域技术人员也知道,除了以纯计算机可读程序代码方式实现控制器以外,完全可以通过将方法步骤进行逻辑编程来使得控制器以逻辑门、开关、专用集成电路、可编程逻辑控制器和嵌入微控制器等的形式来实现相同功能。因此这种控制器可以被认为是一种硬件部件,而对其内包括的用于实现各种功能的装置也可以视为硬件部件内的结构。或者甚至,可以将用于实现各种功能的装置视为既可以是实现方法的软件模块又可以是硬件部件内的结构。
上述实施例阐明的***、装置、模块或单元,具体可以由计算机芯片或实体实现,或者由具有某种功能的产品来实现。一种典型的实现设备为服务器***。当然,本申请不排除随着未来计算机技术的发展,实现上述实施例功能的计算机例如可以为个人计算机、膝上型计算机、车载人机交互设备、蜂窝电话、相机电话、智能电话、个人数字助理、媒体播放器、导航设备、电子邮件设备、游戏控制台、平板计算机、可穿戴设备或者这些设备中的任何设备的组合。
虽然本说明书一个或多个实施例提供了如实施例或流程图所述的方法操作步骤,但基于常规或者无创造性的手段可以包括更多或者更少的操作步骤。实施例中列举的步骤顺序仅仅为众多步骤执行顺序中的一种方式,不代表唯一的执行顺序。在实际中的装置或终端产品执行时,可以按照实施例或者附图所示的方法顺序执行或者并行执行(例如并行处理器或者多线程处理的环境,甚至为分布式数据处理环境)。术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、产品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、产品或者设备所固有的要素。在没有更多限制的情况下,并不排除在包括所述要素的过程、方法、产品或者设备中还存在另外的相同或等同要素。例如若使用到第一,第二等词语用来表示名称,而并不表示任何特定的顺序。
为了描述的方便,描述以上装置时以功能分为各种模块分别描述。当然,在实施本说明书一个或多个时可以把各模块的功能在同一个或多个软件和/或硬件中实现,也可以将实现同一功能的模块由多个子模块或子单元的组合实现等。以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个***,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。
本发明是参照根据本发明实施例的方法、装置(***)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
在一个典型的配置中,计算设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁盘存储、石墨烯存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitory media),如调制的数据信号和载波。
本领域技术人员应明白,本说明书一个或多个实施例可提供为方法、***或计算机程序产品。因此,本说明书一个或多个实施例可采用完全硬件实施例、完全软件实施例或结合软件和硬件方面的实施例的形式。而且,本说明书一个或多个实施例可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本说明书一个或多个实施例可以在由计算机执行的计算机可执行指令的一般上下文中描述,例如程序模块。一般地,程序模块包括执行特定任务或实现特定抽象数据类型的例程、程序、对象、组件、数据结构等等。也可以在分布式计算环境中实践本说明书一个或多个实施例,在这些分布式计算环境中,由通过通信网络而被连接的远程处理设备来执行任务。在分布式计算环境中,程序模块可以位于包括存储设备在内的本地和远程计算机存储介质中。
本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于***实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。在本说明书的描述中,参考术语“一个实施例”、“一些实施例”、“示例”、“具体示例”、或“一些示例”等的描述意指结合该实施例或示例描述的具体特征、结构、材料或者特点包含于本说明书的至少一个实施例或示例中。在本说明书中,对上述术语的示意性表述不必须针对的是相同的实施例或示例。而且,描述的具体特征、结构、材料或者特点可以在任一个或多个实施例或示例中以合适的方式结合。此外,在不相互矛盾的情况下,本领域的技术人员可以将本说明书中描述的不同实施例或示例以及不同实施例或示例的特征进行结合和组合。
以上所述仅为本说明书一个或多个实施例的实施例而已,并不用于限制本说明书一个或多个实施例。对于本领域技术人员来说,本说明书一个或多个实施例可以有各种更改和变化。凡在本说明书的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在权利要求范围之内。
Claims (70)
1.一种包含分片的区块链***中退出跨片事务的方法,该区块链***中至少包括两个分片,不同分片中的节点存储不同的状态集合;所述区块链***还包括主链;其中,所述不同的状态集合包括以下任意一项或多项:不同的外部账户集合的状态;不同合约账户状态的集合;以及不同合约账户集合的状态;
所述方法包括,源分片在本地提交跨片事务相关的操作发生异常,或者等待跨片事务相关的消息发生超时:
源分片在本地撤回发生异常/超时的跨片事务操作,并针对所述跨片事务产生需要由对应目标分片执行的退出指令,并将所述跨片事务退出指令发送至主链;
主链生成主链区块的过程中,将接收到的需要由目标分片执行的退出跨片事务的指令填入主链区块的区块体中;所述主链将所述需要目标分片执行的退出跨片事务的指令按照目标分片的标识发送至对应的目标分片中;
所述目标分片生成目标分片区块的过程中,将接收到所述主链发来的跨片事务退出指令填入所述目标分片区块的区块体中,并执行所述退出跨片事务的指令。
2.如权利要求1所述的方法,所述源分片在本地提交跨片事务相关的操作,包括:
源分片在本地执行跨片事务,或,
源分片在本地产生跨片事务提交指令,或,
源分片在本地提交执行跨片事务所产生的状态。
3.如权利要求1所述的方法,所述源分片等待跨片事务相关的消息发生超时,包括:
源分片等待跨片事务响应超时,或,
源分片等待跨片事务提交响应超时,或,
源分片等待跨片事务提交指令超时。
4.如权利要求1所述的方法,所述源分片在本地撤回发生异常/超时的跨片事务操作,具体包括:
源分片在本地删除执行跨片事务而在底层数据库临时***的数据;
和/或,
源分片在本地对执行跨片事务而变更的状态执行反向操作,以使所述状态回退至所述跨片事务执行前的状态。
5.如权利要求1所述的方法,所述源分片生成的源分片区块的区块体中还包括所述跨片事务退出指令列表,所述跨片事务退出指令列表包括需要发送至目标分片的跨片事务退出指令。
6.如权利要求5所述的方法,所述源分片生成的源分片区块的区块头中还包括跨片事务退出指令_root字段,用于将所述区块体中的跨片事务退出指令列表锁定至区块头中。
7.如权利要求1所述的方法,所述主链区块的区块体包括的各个目标分片接收的跨片事务退出指令,是未经主链在之前已生成的区块中打包的。
8.如权利要求1所述的方法,所述主链生成主链区块前,还包括:主链中的节点接收到源分片发来的跨片事务退出指令后,对所述跨片事务退出指令进行验证。
9.如权利要求8所述的方法,所述验证包括:主链中的节点按照树形结构计算源分片发来的跨片事务退出指令构成的树的根节点的hash值,根据该hash值判断本次接收到的跨片事务退出指令是否与之前接收到的跨片事务退出指令重复。
10.如权利要求1所述的方法,所述源分片除了将所述跨片事务退出指令发送至主链,还将生成的源分片区块的区块头发送至主链。
11.如权利要求10所述的方法,所述主链生成主链区块的过程中,还计算各个源分片发来的源分片区块的区块hash,并将源分片区块hash填入所述主链区块的区块体中。
12.如权利要求11所述的方法,所述主链生成主链区块的过程中,还将各个所述分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根中。
13.如权利要求12所述的方法,所述主链接收到源分片发来的源分片区块的区块头和跨片事务退出指令后,还对所述源分片区块的区块头进行验证。
14.如权利要求13所述的方法,所述验证包括,将跨片事务退出按照树形结构组织后得到的树的hash值,确定该值与所述源分片区块的区块头中的跨片事务退出指令_root是否一致。
15.如权利要求1所述的方法,所述主链将所述跨片事务退出指令按照目标分片的标识发送至对应的目标分片中,包括:
将所述主链区块的区块体中分组的跨片事务退出指令按照目标分片的标识发送至对应的目标分片中。
16.如权利要求1所述的方法,所述主链还将所述主链区块的区块头发送至所述目标分片。
17.如权利要求1所述的方法,所述目标分片生成目标分片区块前,还包括:所述目标分片中的节点接收到主链发来的跨片事务退出指令后,对所述跨片事务退出指令进行验证。
18.如权利要求17所述的方法,所述验证包括:所述目标分片中的节点按照树形结构计算该跨片事务退出指令构成的树的根节点的hash值,根据该hash值判断本次接收到的跨片事务退出指令是否与之前接收到的跨片事务退出指令重复。
19.如权利要求16所述的方法,所述目标分片接收到主链发来的主链区块的区块头和跨片事务退出指令后,还对主链区块的区块头进行验证。
20.如权利要求16所述的方法,所述目标分片在生成目标分片区块的过程中,根据接收到的主链区块的区块头计算得到该主链区块的hash值,并将该主链区块的hash值填入所述目标分片生成的目标分片区块的区块头中。
21.如权利要求20所述的方法,对于主链区块的生成速度不低于分片区块的生成速度的情况,所述目标分片将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中。
22.如权利要求20所述的方法,对于主链区块的生成速度高于分片区块的生成速度的情况:
所述目标分片将本目标分片区块中打包的跨片事务退出指令对应的多个主链区块的hash值填入目标分片生成的目标分片区块的区块头中;或,
所述目标分片将本目标分片区块中打包的跨片事务退出指令对应的多个主链区块的hash值填入目标分片生成的目标分片区块的区块体中,还将各个所述主链区块的hash按照树形结构计算得到的根的hash值填入所述目标分片区块的区块头的主链区块根hash中。
23.如权利要求1所述的方法,所述主链还发送生成的主链区块的时间戳至目标分片,所述目标分片在生成目标分片区块的过程中将所述主链区块的时间戳填入目标分片区块的timestamp中。
24.如权利要求16所述的方法,所述主链通过发送所述主链区块的区块头将所述主链区块的时间戳发送至所述目标分片。
25.如权利要求23或24所述的方法,所述主链发送生成的最新主链区块的时间戳至目标分片,相应的,所述目标分片在生成目标分片区块的过程中将所述最新主链区块的时间戳填入分片区块的timestamp中。
26.如权利要求1所述的方法,所述目标分片执行所述跨片事务退出指令,包括:
目标分片在本地删除执行跨片事务而在底层数据库临时***的数据;
和/或,
目标分片在本地对执行跨片事务而变更的状态执行反向操作,以使所述状态回退至所述跨片事务执行前的状态。
27.一种包含分片的区块链***中退出跨片事务的***,该区块链***中至少包括两个分片,不同分片中的节点存储不同的状态集合;所述区块链***还包括主链;其中,所述不同的状态集合包括以下任意一项或多项:不同的外部账户集合的状态;不同合约账户状态的集合;以及不同合约账户集合的状态;
源分片在本地提交跨片事务相关的操作发生异常,或者等待跨片事务相关的消息发生超时:
源分片在本地撤回发生异常/超时的跨片事务操作,并针对所述跨片事务产生需要由对应目标分片执行的退出指令,并将所述跨片事务退出指令发送至主链;
主链生成主链区块的过程中,将接收到的需要由目标分片执行的退出跨片事务的指令填入主链区块的区块体中;所述主链将所述需要目标分片执行的退出跨片事务的指令按照目标分片的标识发送至对应的目标分片中;
所述目标分片生成目标分片区块的过程中,将接收到所述主链发来的跨片事务退出指令填入所述目标分片区块的区块体中,并执行所述退出跨片事务的指令。
28.如权利要求27所述的***,所述源分片在本地提交跨片事务相关的操作,包括:
源分片在本地执行跨片事务,或,
源分片在本地产生跨片事务提交指令,或,
源分片在本地提交执行跨片事务所产生的状态。
29.如权利要求27所述的***,所述源分片等待跨片事务相关的消息发生超时,包括:
源分片等待跨片事务响应超时,或,
源分片等待跨片事务提交响应超时,或,
源分片等待跨片事务提交指令超时。
30.如权利要求27所述的***,所述源分片在本地撤回发生异常/超时的跨片事务操作,具体包括:
源分片在本地删除执行跨片事务而在底层数据库临时***的数据;
和/或,
源分片在本地对执行跨片事务而变更的状态执行反向操作,以使所述状态回退至所述跨片事务执行前的状态。
31.如权利要求27所述的***,所述源分片生成的源分片区块的区块体中还包括所述跨片事务退出指令列表,所述跨片事务退出指令列表包括需要发送至目标分片的跨片事务退出指令。
32.如权利要求31所述的***,所述源分片生成的源分片区块的区块头中还包括跨片事务退出指令_root字段,用于将所述区块体中的跨片事务退出指令列表锁定至区块头中。
33.如权利要求27所述的***,所述主链区块的区块体包括的各个目标分片接收的跨片事务退出指令,是未经主链在之前已生成的区块中打包的。
34.如权利要求27所述的***,所述主链生成主链区块前,还包括:主链中的节点接收到源分片发来的跨片事务退出指令后,对所述跨片事务退出指令进行验证。
35.如权利要求34所述的***,所述验证包括:主链中的节点按照树形结构计算源分片发来的跨片事务退出指令构成的树的根节点的hash值,根据该hash值判断本次接收到的跨片事务退出指令是否与之前接收到的跨片事务退出指令重复。
36.如权利要求27所述的***,所述源分片除了将所述跨片事务退出指令发送至主链,还将生成的源分片区块的区块头发送至主链。
37.如权利要求36所述的***,所述主链生成主链区块的过程中,还计算各个源分片发来的源分片区块的区块hash,并将源分片区块hash填入所述主链区块的区块体中。
38.如权利要求37所述的***,所述主链生成主链区块的过程中,还将各个所述分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根中。
39.如权利要求38所述的***,所述主链接收到源分片发来的源分片区块的区块头和跨片事务退出指令后,还对所述源分片区块的区块头进行验证。
40.如权利要求39所述的***,所述验证包括,将跨片事务退出按照树形结构组织后得到的树的hash值,确定该值与所述源分片区块的区块头中的跨片事务退出指令_root是否一致。
41.如权利要求27所述的***,所述主链将所述跨片事务退出指令按照目标分片的标识发送至对应的目标分片中,包括:
将所述主链区块的区块体中分组的跨片事务退出指令按照目标分片的标识发送至对应的目标分片中。
42.如权利要求27所述的***,所述主链还将所述主链区块的区块头发送至所述目标分片。
43.如权利要求27所述的***,所述目标分片生成目标分片区块前,还包括:所述目标分片中的节点接收到主链发来的跨片事务退出指令后,对所述跨片事务退出指令进行验证。
44.如权利要求43所述的***,所述验证包括:所述目标分片中的节点按照树形结构计算该跨片事务退出指令构成的树的根节点的hash值,根据该hash值判断本次接收到的跨片事务退出指令是否与之前接收到的跨片事务退出指令重复。
45.如权利要求42所述的***,所述目标分片接收到主链发来的主链区块的区块头和跨片事务退出指令后,还对主链区块的区块头进行验证。
46.如权利要求42所述的***,所述目标分片在生成目标分片区块的过程中,根据接收到的主链区块的区块头计算得到该主链区块的hash值,并将该主链区块的hash值填入所述目标分片生成的目标分片区块的区块头中。
47.如权利要求46所述的***,对于主链区块的生成速度不低于分片区块的生成速度的情况,所述目标分片将最新主链区块的hash值填入目标分片生成的目标分片区块的区块头中。
48.如权利要求46所述的***,对于主链区块的生成速度高于分片区块的生成速度的情况:
所述目标分片将本目标分片区块中打包的跨片事务退出指令对应的多个主链区块的hash值填入目标分片生成的目标分片区块的区块头中;或,
所述目标分片将本目标分片区块中打包的跨片事务退出指令对应的多个主链区块的hash值填入目标分片生成的目标分片区块的区块体中,还将各个所述主链区块的hash按照树形结构计算得到的根的hash值填入所述目标分片区块的区块头的主链区块根hash中。
49.如权利要求27所述的***,所述主链还发送生成的主链区块的时间戳至目标分片,所述目标分片在生成目标分片区块的过程中将所述主链区块的时间戳填入目标分片区块的timestamp中。
50.如权利要求42所述的***,所述主链通过发送所述主链区块的区块头将所述主链区块的时间戳发送至所述目标分片。
51.如权利要求49或50所述的***,所述主链发送生成的最新主链区块的时间戳至目标分片,相应的,所述目标分片在生成目标分片区块的过程中将所述最新主链区块的时间戳填入分片区块的timestamp中。
52.如权利要求27所述的***,所述目标分片执行所述跨片事务退出指令,包括:
目标分片在本地删除执行跨片事务而在底层数据库临时***的数据;
和/或,
目标分片在本地对执行跨片事务而变更的状态执行反向操作,以使所述状态回退至所述跨片事务执行前的状态。
53.一种包含分片的区块链***中的源分片节点,其中,该区块链***中至少包括两个分片,不同分片中的节点存储不同的状态集合;所述不同的状态集合包括以下任意一项或多项:不同的外部账户集合的状态;不同合约账户状态的集合;以及不同合约账户集合的状态;该源分片节点包括:
执行单元,用于在本地执行跨片事务相关的操作或等待跨片事务相关的消息;
源分片区块生成单元,用于生成源分片区块,并当执行单元在本地提交跨片事务相关的操作发生异常或者等待跨片事务相关的消息发生超时后,在生成源分片区块的过程中产生跨片事务退出指令;
跨片事务退出单元,用于在本地撤回发生异常/超时的跨片事务操作;
发送单元,用于将所述跨片事务退出指令发送至主链。
54.如权利要求53所述的源分片节点,所述执行单元在本地提交跨片事务相关的操作,包括:
执行单元在本地执行跨片事务,或,
执行单元在本地产生跨片事务提交指令,或,
执行单元在本地提交执行跨片事务所产生的状态。
55.如权利要求53所述的源分片节点,所述执行单元等待跨片事务相关的消息发生超时,包括:
执行单元等待跨片事务响应超时,或,
执行单元等待跨片事务提交响应超时,或,
执行单元等待跨片事务提交指令超时。
56.如权利要求53所述的源分片节点,所述跨片事务退出单元在本地撤回发生异常/超时的跨片事务操作,具体包括:
跨片事务退出单元在本地删除执行跨片事务而在底层数据库临时***的数据;
和/或,
跨片事务退出单元在本地对执行跨片事务而变更的状态执行反向操作,以使所述状态回退至所述跨片事务执行前的状态。
57.如权利要求53所述的源分片节点,所述源分片区块生成单元生成的源分片区块的区块体中还包括所述跨片事务退出指令列表,所述跨片事务退出指令列表包括需要发送至目标分片的跨片事务退出指令。
58.如权利要求57所述的源分片节点,所述源分片区块生成单元生成的源分片区块的区块头中还包括跨片事务退出指令_root字段,用于将所述区块体中的跨片事务退出指令列表锁定至区块头中。
59.如权利要求53所述的源分片节点,所述发送单元还将所述源分片区块生成单元生成的分片区块的区块头发送至主链。
60.一种包含分片的区块链***中的主链节点,其中,该区块链***中至少包括两个分片,不同分片中的节点存储不同的状态集合;所述不同的状态集合包括以下任意一项或多项:不同的外部账户集合的状态;不同合约账户状态的集合;以及不同合约账户集合的状态;该主链节点包括:
接收单元,用于接收需要由目标分片执行的跨片事务退出指令;
主链区块生成单元,用于生成主链区块,并在生成主链区块的过程中,将接收到的跨片事务退出指令填入主链区块的区块体中;
发送单元,用于将所述跨片事务退出指令按照目标分片的标识发送至对应的目标分片中。
61.如权利要求60所述的主链节点,所述主链区块生成单元生成的区块的区块体包括的各个目标分片接收的跨片事务退出指令,是未经主链在之前已生成的区块中打包的。
62.如权利要求60所述的主链节点,还包括验证单元,所述接收单元接收到源分片发来的跨片事务退出指令后,所述验证单元对所述跨片事务退出指令进行验证。
63.如权利要求62所述的主链节点,所述验证包括:主链中的节点按照树形结构计算源分片发来的跨片事务退出指令构成的树的根节点的hash值,根据该hash值判断本次接收到的跨片事务提交指令是否与之前接收到的跨片事务退出指令重复。
64.如权利要求62所述的主链节点,所述接收单元还接收源分片区块的区块头。
65.如权利要求64所述的主链节点,所述主链区块生成单元生成主链区块的过程中,还计算各个源分片发来的源分片区块的区块hash,并将源分片区块hash填入所述主链区块的区块体中。
66.如权利要求65所述的主链节点,所述主链区块生成单元生成主链区块的过程中,还将各个所述分片的分片区块hash按照树形结构计算得到的根的hash值填入主链区块的区块头的分片区块根中。
67.如权利要求66所述的主链节点,所述接收单元接收到源分片发来的源区块的区块头和跨片事务退出指令后,所述验证单元还对所述源分片区块的区块头进行验证。
68.如权利要求67所述的主链节点,所述验证包括,将跨片事务退出指令按照树形结构组织后得到的树的hash值,确定该值与所述源分片区块的区块头中的跨片事务退出指令_root是否一致。
69.如权利要求60所述的主链节点,所述发送单元将所述跨片事务退出指令按照目标分片的标识发送至对应的目标分片中,包括:
将所述主链区块的区块体中分组的跨片事务退出指令按照目标分片的标识发送至对应的目标分片中。
70.如权利要求60所述的主链节点,所述发送单元还将所述主链区块的区块头发送至所述目标分片。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202011515929.XA CN112261160B (zh) | 2020-12-21 | 2020-12-21 | 包含分片的区块链***中退出跨片事务的方法及*** |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202011515929.XA CN112261160B (zh) | 2020-12-21 | 2020-12-21 | 包含分片的区块链***中退出跨片事务的方法及*** |
Publications (2)
Publication Number | Publication Date |
---|---|
CN112261160A CN112261160A (zh) | 2021-01-22 |
CN112261160B true CN112261160B (zh) | 2021-04-06 |
Family
ID=74225250
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202011515929.XA Active CN112261160B (zh) | 2020-12-21 | 2020-12-21 | 包含分片的区块链***中退出跨片事务的方法及*** |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN112261160B (zh) |
Families Citing this family (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN113254171B (zh) * | 2021-06-17 | 2021-11-09 | 支付宝(杭州)信息技术有限公司 | 退出跨片事务的方法、区块链***和主链节点 |
CN113254170B (zh) * | 2021-06-17 | 2021-11-05 | 支付宝(杭州)信息技术有限公司 | 在区块链***中退出跨片事务的方法及装置 |
Citations (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN108615153A (zh) * | 2018-04-28 | 2018-10-02 | 百度在线网络技术(北京)有限公司 | 区块链数据的处理方法、装置、***、设备和存储介质 |
Family Cites Families (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN107085810A (zh) * | 2017-04-19 | 2017-08-22 | 朱皞罡 | 一种区块链的跨链操作方法及区块链管理*** |
US20190354518A1 (en) * | 2018-05-01 | 2019-11-21 | Michael Zochowski | Chain mesh network for decentralized transaction systems |
CN110611701B (zh) * | 2018-08-21 | 2022-10-11 | 汇链丰(北京)科技有限公司 | 一种基于区块链的参数配置和交易处理方法 |
CN110808838B (zh) * | 2019-10-24 | 2020-09-22 | 华东师范大学 | 一种面向联盟链的分片方法 |
CN111736963B (zh) * | 2020-06-08 | 2022-10-11 | 中国科学院计算技术研究所 | 一种用于无主链多分片区块链的事务处理***及方法 |
-
2020
- 2020-12-21 CN CN202011515929.XA patent/CN112261160B/zh active Active
Patent Citations (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN108615153A (zh) * | 2018-04-28 | 2018-10-02 | 百度在线网络技术(北京)有限公司 | 区块链数据的处理方法、装置、***、设备和存储介质 |
Also Published As
Publication number | Publication date |
---|---|
CN112261160A (zh) | 2021-01-22 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN112261159B (zh) | 执行跨片事务的方法及***、主链节点和目标分片节点 | |
CN110602148B (zh) | 一种区块的状态树的生成和链上数据验证的方法及装置 | |
CN112257118B (zh) | 一种锁定包含分片的区块链***中跨片事务的方法及*** | |
CN112261162B (zh) | 执行跨片事务的方法及***、主链节点和目标分片节点 | |
CN112261157B (zh) | 提交跨片事务的方法及***、主链节点和源分片节点 | |
CN107392608B (zh) | 基于区块链***的数字资产交易方法及区块链*** | |
CN112579261A (zh) | 退出跨片事务的方法和***、主链节点和目标分片节点 | |
AU2019204722B2 (en) | System and method for parallel-processing blockchain transactions | |
CN112261163B (zh) | 一种区块链***中的状态存储方法及区块链***、节点 | |
CN113259478B (zh) | 在区块链***中执行交易的方法、装置及区块链*** | |
CN112261160B (zh) | 包含分片的区块链***中退出跨片事务的方法及*** | |
CN112651724A (zh) | 跨链交互方法、装置和*** | |
WO2021227319A1 (zh) | 一种工程协作区块链数据结构及应用方法 | |
CN112261156B (zh) | 一种提交跨片事务的方法及***、主链节点和源分片节点 | |
CN112396422B (zh) | 提交跨片事务的方法及***、主链节点和目标分片节点 | |
CN112269423B (zh) | 一种锁定区块链***中全局时钟的方法及区块链*** | |
CN113254538B (zh) | 在区块链中执行交易的方法和区块链节点 | |
CN112261161B (zh) | 一种锁定区块链***中分片区块的方法及区块链*** | |
CN112261158B (zh) | 返回跨片事务响应的方法及***、主链节点和源分片节点 | |
CN113254171B (zh) | 退出跨片事务的方法、区块链***和主链节点 | |
CN113254170B (zh) | 在区块链***中退出跨片事务的方法及装置 | |
CN112287032B (zh) | 一种区块链数据存储方法、装置及区块链节点 | |
CN113656504A (zh) | 一种基于时序属性的区块链交易提交、编辑和查询方法 | |
Miloslavskaya et al. | Blockchain redacting algorithm with storing votes inside the chain | |
CN117421369A (zh) | 基于区块链的数据处理方法、装置、设备及可读存储介质 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant | ||
REG | Reference to a national code |
Ref country code: HK Ref legal event code: DE Ref document number: 40045040 Country of ref document: HK |