CN113254538B - 在区块链中执行交易的方法和区块链节点 - Google Patents
在区块链中执行交易的方法和区块链节点 Download PDFInfo
- Publication number
- CN113254538B CN113254538B CN202110674714.0A CN202110674714A CN113254538B CN 113254538 B CN113254538 B CN 113254538B CN 202110674714 A CN202110674714 A CN 202110674714A CN 113254538 B CN113254538 B CN 113254538B
- Authority
- CN
- China
- Prior art keywords
- account
- transaction
- state
- contract
- blockchain
- 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
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/27—Replication, distribution or synchronisation of data between databases or within a distributed database system; Distributed database system architectures therefor
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/22—Indexing; Data structures therefor; Storage structures
- G06F16/2228—Indexing structures
- G06F16/2246—Trees, e.g. B+trees
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/22—Indexing; Data structures therefor; Storage structures
- G06F16/2228—Indexing structures
- G06F16/2255—Hash tables
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/23—Updating
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06Q—INFORMATION AND COMMUNICATION TECHNOLOGY [ICT] SPECIALLY ADAPTED FOR ADMINISTRATIVE, COMMERCIAL, FINANCIAL, MANAGERIAL OR SUPERVISORY PURPOSES; SYSTEMS OR METHODS SPECIALLY ADAPTED FOR ADMINISTRATIVE, COMMERCIAL, FINANCIAL, MANAGERIAL OR SUPERVISORY PURPOSES, NOT OTHERWISE PROVIDED FOR
- G06Q20/00—Payment architectures, schemes or protocols
- G06Q20/08—Payment architectures
- G06Q20/10—Payment architectures specially adapted for electronic funds transfer [EFT] systems; specially adapted for home banking systems
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06Q—INFORMATION AND COMMUNICATION TECHNOLOGY [ICT] SPECIALLY ADAPTED FOR ADMINISTRATIVE, COMMERCIAL, FINANCIAL, MANAGERIAL OR SUPERVISORY PURPOSES; SYSTEMS OR METHODS SPECIALLY ADAPTED FOR ADMINISTRATIVE, COMMERCIAL, FINANCIAL, MANAGERIAL OR SUPERVISORY PURPOSES, NOT OTHERWISE PROVIDED FOR
- G06Q40/00—Finance; Insurance; Tax strategies; Processing of corporate or income taxes
- G06Q40/04—Trading; Exchange, e.g. stocks, commodities, derivatives or currency exchange
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Business, Economics & Management (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Databases & Information Systems (AREA)
- Accounting & Taxation (AREA)
- Data Mining & Analysis (AREA)
- General Engineering & Computer Science (AREA)
- Finance (AREA)
- Development Economics (AREA)
- Economics (AREA)
- Strategic Management (AREA)
- General Business, Economics & Management (AREA)
- Software Systems (AREA)
- Marketing (AREA)
- Technology Law (AREA)
- Computing Systems (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
- Management, Administration, Business Operations System, And Electronic Commerce (AREA)
Abstract
本说明书实施例提供了一种在区块链中执行交易的方法和区块链节点,所述方法包括:执行第一交易,存储所述第一交易更改的第一账户的状态信息,将待由第二区块链执行的跨链操作的信息提供给所述第二区块链,其中,所述跨链操作的信息中包括所述第一交易的标识;记录第一交易的标识与第一账户的对应关系;从第二区块链接收对所述跨链操作的执行结果,所述执行结果中包括所述第一交易的标识;基于所述记录的第一交易的标识与第一账户的标识的对应关系,在状态数据库中获取第一账户的状态;根据所述执行结果和所述状态信息,修改所述第一账户的状态。
Description
技术领域
本说明书实施例涉及区块链技术领域,更具体地,涉及一种在区块链中执行交易的方法和区块链节点。
背景技术
区块链(Blockchain)是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构,并以密码学方式保证的不可篡改和不可伪造的分布式账本。由于区块链具有去中心化、信息不可篡改、自治性等特性,区块链也受到人们越来越多的重视和应用。
其中,区块链分片技术是一种用于对区块链进行扩容的方案。区块链分片的基本思路是将区块链网络中的节点分成若干个相对独立的子网络,每个子网络构成一个区块链,一个子网络也就是一个分片(shard)。通过多个分片的并行处理,可提升整个网络的吞吐量。
在区块链中,通常每执行一个区块之后,在区块数据库中更新该区块对应的世界状态。然而,当区块中存在产生跨链操作的跨链交易的情况中,通常不立即将该交易的执行结果提交到状态数据库中,而是等跨链操作的执行结果返回之后,再根据跨链操作的执行结果确定是否提交交易的执行结果。此时,通常通过遍历状态数据库找到该交易更改的账户的状态,并对该账户的状态进行更新。
在申请公布号为CN112261163A的专利“一种区块链***中的状态存储方法及区块链***、节点”中,公开了一种状态存储方法,该区块链***至少包括两个分片,不同分片中的节点存储不同的外部账户集合的状态;所述方法包括:归属于分片中的区块链节点执行创建和/或调用合约的交易,产生待存储的与区块链外部账户相关的状态;将待存储的与所述区块链外部账户相关的状态存储于对应的区块链外部账户的状态存储中。在该方案中,当归属于分片中的区块链节点执行跨片交易时,类似地,通常不立即将该交易的执行结果提交到状态数据库中,而是等跨链操作的执行结果返回之后,再根据跨链操作的执行结果确定是否提交交易的执行结果,因此类似地,需要通过遍历外部账户中的状态存储,以进行状态更新。
发明内容
本说明书实施例旨在提供一种更有效的在区块链中执行交易的方案,使得可以便捷地对跨链交易对应的账户的状态进行更新。
为实现上述目的,本说明书第一方面提供一种在区块链中执行交易的方法,所述方法由第一区块链的节点执行,包括:执行第一交易,存储所述第一交易更改的第一账户的状态信息,将待由第二区块链执行的跨链操作的信息提供给所述第二区块链,其中,所述跨链操作的信息中包括所述第一交易的标识;记录第一交易的标识与第一账户的对应关系;从第二区块链接收对所述跨链操作的执行结果,所述执行结果中包括所述第一交易的标识;基于所述记录的第一交易的标识与第一账户的标识的对应关系,在状态数据库中获取第一账户的状态;根据所述执行结果和所述状态信息,修改所述第一账户的状态。
本说明书第二方面提供一种区块链节点,包括:执行单元,用于执行第一交易,存储所述第一交易更改的第一账户的状态信息,将待由第二区块链执行的跨链操作的信息提供给所述第二区块链,其中,所述跨链操作的信息中包括所述第一交易的标识;记录单元,用于记录第一交易的标识与第一账户的对应关系;接收单元,用于从第二区块链接收对所述跨链操作的执行结果,所述执行结果中包括所述第一交易的标识;
获取单元,用于基于所述记录的第一交易的标识与第一账户的标识的对应关系,在状态数据库中获取第一账户的状态;
修改单元,用于根据所述执行结果和所述状态信息,修改所述第一账户的状态。
本说明书第三方面提供一种计算机可读存储介质,其上存储有计算机程序,当所述计算机程序由计算机或处理器执行时,令计算机或处理器执行如第一方面所述的方法。
本说明书第四方面提供一种区块链节点,包括存储器和处理器,所述存储器中存储有可执行代码,所述处理器执行所述可执行代码时,实现如第一方面所述的方法。
在本说明书实施例提供的执行跨链交易的方案中,在执行跨链交易之后,记录跨链交易的标识与其更改的变量的标识的对应关系,从而,在该跨链交易的跨链操作的执行结果返回时,可以根据该对应关系在状态数据库中快速地定位跨链交易更改的账户,并对账户的状态进行更新,提高了区块链的处理效率。
附图说明
通过结合附图描述本说明书实施例,可以使得本说明书实施例更加清楚:
图1是一实施例中区块链***架构示意图;
图2是一实施例中区块链***分片架构的示意图;
图3是本说明书一实施例中的区块链数据存储的结构示意图;
图4是本说明书一实施例中的一个简化版的状态树示意图;
图5是本说明书一实施例中的一种区块链状态树的存储结构;
图6是本说明书一实施例中的一种区块链状态树的存储结构;
图7是本说明书一实施例中的一种区块链状态树的存储结构;
图8是本说明书一实施例中的一种区块链状态树的存储结构;
图9是本说明书一实施例中的一种区块链***中的状态存储方法流程图;
图10是本说明书一实施例中的一种区块链分片架构的示意图;
图11是本说明书一实施例中的一致性哈希的原理示意图;
图12是本说明书一实施例中的一种区块链状态树的存储结构;
图13是本说明书一实施例中的基于主链的区块链分片***示意图;
图14是本说明书一实施例中的一种在区块链中执行交易的方法流程图;
图15是本说明书一实施例中的一种区块链节点的架构图。
具体实施方式
下面将结合附图描述本说明书实施例。
为了使本技术领域的人员更好地理解本说明书中的技术方案,下面将结合本说明书实施例中的附图,对本说明书实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本说明书一部分实施例,而不是全部的实施例。基于本说明书中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都应当属于本说明书保护的范围。
目前限制区块链技术大规模落地应用的一个很重要因素是性能,即吞吐量,这个吞吐量一般可以通过每秒交易笔数(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树的根节点可以为一个扩展节点(Extension Node)或一个分支节点(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可以存储状态变量的实际值。在另一种实施方式中,两种类型的状态变量的key都可以取为变量名称的哈希值,通过这样设置,各个状态变量的key的长度相同,便于以树的形式存储。
前面提到,如果区块链的状态树中存在10000个外部账户,则通过智能合约,每个外部账户可以对应持有/交易balanceA类型的资产,即存在10000个外部账户→balanceA的映射。具体的,该合约账户下,存储树中可以存储这些map的值。如上所述,具体是通过key-value的方式存储在存储树中。类似的,这个存储树也可以是MPT形式的树,一般也是16叉树,每一层最多可以有16个孩子节点,最多可以有64层的深度。从这个MPT的根节点到叶子节点中存储的一部分数据连起来可以作为key,叶子节点中存储的信息为这个key对应的value。这样,就构成了key-value键值对。
当区块链中的外部账户的数量达到一定量时,状态树的深度可能接近或达到64层的深度。类似的,合约中map类型的状态变量的数量也可能达到相同的量,这时存储树也接近或达到64层的深度。此外,对于一个智能合约来说,合约中基本数据类型的变量不会太多,一般不会超过32个。这样,当外部账户的数量较大时,加上合约中基本数据类型的变量,合约中的状态变量的总数与外部账户基本是差不多的。
图4是一个简化版的状态树示意图。区块链***中存在若干外部账户,例如图4中分别编号的外部账户 1、外部账户 2,…。此外,区块链***中存在若干合约账户,例如图4中的分别编号的合约账户 1,合约账户 2,…。这些外部账户和合约账户及其信息内容例如通过MPT树的形式组织,构成状态树。区块头中的state_root存储这个MPT树的根节点的hash值。图4中以节点1、节点2、节点3共三个节点来示意性的表示MPT树的形式,具体的,可以表示MPT树中的扩展节点、分支节点。
外部账户可以通过创建合约的交易在区块链上部署智能合约。此外,智能合约也可以是原生合约,即融合在区块链平台的代码中,与区块链平台代码一同编译后完成部署。不论是哪种形式部署的智能合约,在合约创建后,区块链上出现一个与该智能合约对应的合约账户,并拥有一个特定的地址,合约代码和账户存储将保存在该合约账户中。智能合约的账户存储保存了这个合约的状态。合约创建之后,外部账户可以调用创建的智能合约,也可以是外部账户通过智能合约来调用智能合约(也可以通过1个或多个智能合约来调用智能合约)。被调用的智能合约,将产生的状态变量以key-value的形式写入该智能合约的账户存储中,如图4所示。这些key-value,可以组织成MPT树的形式,构成存储树。存储树中,key-value除了包括基本数据类型的状态变量外,还可以包括map类型的状态变量。一般的,一个合约中不超过32个基本类型的状态变量,即一般一个存储树中包括不超过32个key-value来对应基本类型的状态变量的存储。一个合约中,map类型的状态变量一般与外部账户对应。存在N个外部账户的情况下,一个合约中一般存在对应的N个key-value来对应map类型的状态变量的存储。
合约账户中的map类型的状态变量的数量一般与外部账户对应,此外,合约账户中还包括基本类型的状态变量。当外部账户的数量比较多时,合约账户中的map类型的状态变量的数量也很多。状态树实际上包括了两层MPT结构,每一层最大深度是64层。对于区块链***中大量的合约操作,都要涉及合约的状态变量。这样,在现有的账户体系结构中,虽然建立了外部账户和合约账户,但是操作的热点将集中于合约账户中的状态变量,而关于外部账户的操作却很少。这就形成了单账户热点。单账户热点导致合约账户存储的负载压力比较大,将限制和影响区块链***的性能。
本说明书实施例提供一种区块链状态树的存储结构。如图5所示。
区块头中的state_root存储整个状态树的根节点的hash值。树形结构例如可以采用图3中的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中所示,在外部账户的状态存储中的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所在的地理位置或用户填写/选择的归属地,可以将该账户的状态存储分配至相同/相近地理位置的分片上,也可以将该账户的状态存储分配至***指定的分片上。
所述不同分片中的节点存储不同的外部账户集合的状态,可以包括:
按照业务关系配置账户的状态存储所属的分片。
所述区块链***还可以包括主链,用于接收所述调用合约的交易,并将该交易路由至存储所述外部账户的分片内。
所述由主链接收所述调用合约的交易,可以根据该调用合约的交易涉及的发生状态改变的外部账户,将该交易路由至存储所述外部账户的分片内。
上述状态分片方案,是本申请中给出的一种解决方案。除此之外,还可能存在其它状态分片方案。不论对于何种状态分片方案,只要不同分片中的节点存储不同的外部账户集合的状态,都会涉及确定不同分片的全部账户的世界状态的问题。
例如,分片1中的某一账户可能会发生与分片2中的另一账户相关的一笔交易。具体的,例如由分片1中的某一账户转账至分片2中的另一账户,或者分片1中的某一账户发起某个调用合约的交易,而该被调用的合约在执行时,涉及对分片2中某一账户的操作。调用合约的情况,按照前述所述的合约中定义的外部账户与资产的映射关系,具体的一个例子中,例如是分片1中某一账户发起偿还某新资产类型,该资产类型下的账户(包括外部账户和合约账户)各自具有一定的余额(balance)。如图13中的分片1中的外部账户1将一定数量的该类型的资产转移至合约账户,再按照合约中的条件,由合约账户转移至如图13中分片2的外部账户6。
显然的,上述例子涉及跨分片的交易。本申请提出一种基于主链的跨分片交易方法,能够在基于主链的区块链分片***中实现。本申请的基于主链的区块链分片***例如如图13所示,除了若干分片以外,还存在主链。主链包括若干区块链节点,如图中的Q1、Q2、Q3和Q4。主链与各个分片相连。如前所述,尽管图示中各个分片之间通过连接线示意出各个分片之间相连,但是,也可能各个分片并非是全部互通的,或者是每个分片均不与其它分片相通。对于最后一种情况,也就是说,各个分片之间可以互不相连,而仅与主链相连。这里,分片之间相通,可以是一个分片中的一个节点与另一分片中的任一节点都相通,也可以是一个分片中的一个节点与另一分片中的一个或部分节点相通。类似的,分片与主链相通,可以是分片中的一个节点与主链中的任一节点都相通或分片中的一个节点主链中的一个或部分节点相通,也可以是主链中的一个节点与分片中的任一节点都相通或分片中的一个或部分节点相通。
不同分片中的节点可以存储不同的外部账户集合的状态,包括上述如图5-12中对应的实施例中执行创建和/或调用合约的交易而产生的与外部账户相关的状态,也可以是普通转账交易产生的外部账户的状态。对于不采用本申请图5-12对应实施例的状态分片方案,而是将执行创建和/或调用合约的交易产生的与外部账户相关的状态存储于合约账户的状态存储中,可能存在不同分片中的节点存储不同合约账户状态的集合的情况,或者不同分片中的节点存储不同合约账户集合的状态的情况,也适用于下面将要提到的本申请的方案。所述不同分片中的节点存储不同合约账户状态的集合的情况,例如区块链***存在一个合约,该合约对应的合约账户具有不同的状态,如状态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的状态}。此外,可以理解的,对于存在多个合约且每个合约具有多个状态,也可以是上述两种情况的混合。上述各种情况,笼统的说,可以称为不同分片存储不同的状态集合。
在不同的区块链存储不同的状态集合的情况下,当区块链中的交易用于对另一个区块链中的账户改变状态时,该交易即为跨链交易,该跨链交易例如为跨链转账交易或者跨链调用合约的交易。其中,分片为区块链的一种具体实例,当一个分片中的交易用于对另一个分片中的账户改变状态时,该交易也称为为跨分片交易(或跨片交易),下文将以执行跨片交易为例描述本说明书实施例的方案。
例如,分片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)。如图13中的分片1中的外部账户1将一定数量的该类型的资产转移至合约账户,再按照合约中的条件,由合约账户转移至如图13中分片2的外部账户6。分片1中可以执行在外部账户1中扣减一定新资产类型余额的操作;分片2中可以执行为外部账户6增加一定新资产类型余额的操作,而且这个操作需要由分片2中的节点来执行。那么,这个过程需要将分片1中接收到的交易的部分操作转发至分片2中,交由分片2来执行。
本申请可以通过基于包含主链的区块分片***执行。由于主链中的节点具有较高的可信度,因此可以将一个分片(后续称为源分片)中接收的跨分片的交易中涉及其它分片(后续称为目标分片)的操作发送至主链,并由主链转发至所述的目标分片。
分片1中的节点在完成对上述跨片交易的执行之后,直到在获取分片2中对该交易的跨分片操作为执行成功之后,才能将交易对世界状态的改变提交到状态数据库中,否则,可能使得该跨片交易的执行不符合事务的原子性,即该跨片交易对应的在分片1的操作和在分片2的操作必须同时成功或同时失败。
在相关技术中,分片1在执行完包括跨片交易的一批交易之后,在分片2中对跨分片操作的执行结果还未返回时,并不将跨片交易对特定账户的状态的更改信息持久化存储,而是将该更改信息存储到以追加的形式存储到状态数据库中,即在状态数据库中仍保留原有的账户状态,并对该账户的状态进行锁定。在进行该锁定之后,如果后续交易也用于对该账户的状态进行修改,在账户未解锁的情况中,可确定该后续交易执行失败。其中对更改信息的锁定信息中例如包括该跨片交易的哈希值。当分片1接收到分片2中对跨分片操作的执行结果之后,该执行结果例如包括跨片交易的哈希值,为了找到该跨片交易已经修改的账户,可在状态数据库中遍历各个锁定信息,以找到包括该跨片交易的哈希值的锁定信息,并根据跨片操作的执行结果(即执行失败获成功)对账户的世界状态进行修改。具体是,如果跨片操作执行成功,则将账户的世界状态更新为上述更改信息,如果跨片操作执行失败,则删除上述更改信息和锁定信息。由于状态数据库存储了较多的账户的信息,在状态数据库中进行遍历将非常耗时,导致降低了分片中的处理效率。
为此,本说明书实施例提供一种执行跨链交易的方案,通过本说明书实施例提供的方案,在执行跨分片交易之后,记录跨分片交易的标识与其修改的账户信息之间的对应关系,从而可在跨分片操作返回时,基于该对应关系快速在状态数据库中定位跨片交易修改的账户,并根据跨分片操作的执行结果更新世界状态,提高了分片的处理效率。下文将详细描述本说明书实施例提供的一种执行跨链交易的方案。
图14示出根据本说明书实施例的一种在区块链中执行交易的方法流程图,如图14所示,该方法中执行的交易(例如交易Tx1)为跨链交易(图14中即跨片交易),因此,所述方法由源分片和目标分片两个分片(例如图10中的分片1和分片2)各自的节点执行,其中源分片为执行跨片交易的分片,目标分片为从源分片获取跨片交易中的跨片操作并执行该跨片操作的分片。图14中示出的源分片和目标分片表示源分片中的各个节点和目标分片中的各个节点。可以理解,图14中虽然仅示例示出了源分片和目标分片,本说明书实施例不限于此,例如在如图13所示的包括主链的区块链***中,分片1的节点可通过主链(即主链节点)与分片2的节点通信,发送信息或数据,主链的节点也可以根据从分片1或分片2接收到的信息或数据生成区块进行存证等。所述方法包括以下步骤S1401-S1411。
首先,在步骤S1401,源分片的节点执行跨片交易Tx1,生成交易Tx1更改的账户的状态信息和待由目标分片的节点执行的跨片操作的信息,其中,所述跨片操作的信息中包括交易Tx1的标识,存储交易Tx1更改的账户的状态信息。
客户端可以向源分片中相连的节点发起交易请求。该交易如前所述,可以是转账交易,也可以是创建/调用合约的交易。收到客户端发起交易的源分片中的节点,进而可以将该交易广播至源分片中的其它节点,或者转发至主节点。以采用PBFT共识算法为例,一段时间之后,可以由源分片中的主节点将包括该交易在内的一定数量的交易打包并发起共识提议。需要说明的是,所述源分片中的主节点打包的交易中,除了可以包括跨分片交易外,还可以包括分片内交易。
对于普通的转账交易来说,交易结构比较简单,可以根据交易的发起方(from字段标明)和接收方(to字段标明)判断是否是跨片交易。一般的,对于前述提到的状态分片方案,不同分片中的节点存储不同的外部账户集合的状态,则发起交易请求的客户端中,登录该客户端的账户在相连的源分片中存储有对应的账户状态。也就是说,一般的,在分片中有存储的外部账户可以通过客户端在本分片中发起交易,交易中的from字段标明的账户在本分片中存储有对应的外部账户状态。进而,本分片中的节点可以根据转账交易中的to字段来判断,如果to字段中的账户在本分片中没有对应的外部账户状态,则该交易为跨片交易。而分片内交易,from字段和to字段标明的账户在本分片中有对应的外部账户状态。
对于创建/调用合约交易来说,客户端可以向源分片中相连的节点发起合约相关的交易请求。类似的,交易中的from字段标明的账户在本分片中存储有对应的外部账户状态,而to字段标明了合约的地址(调用合约)或空(创建合约)。合约代码中可能涉及一个或多个目标账户,可能包括外部账户和/或另一个合约的账户。对于目标账户是另一合约账户的情况,一般是通过一个合约调用另一个合约,该另一合约中可能又涉及一些外部账户。更多层级的合约调用的情况以此类推。由于合约的复杂性,很多情况下在执行合约时才能判断涉及的除发起方(from字段标明)之外的其它账户是哪些,例如合约中复杂的条件判断以及合约调用合约的情况。具体的,很可能在合约执行时才能确定涉及的一个或多个目标账户。前述提到的状态分片方案,归属于分片中的区块链节点执行创建和/或调用合约的交易,将产生的待存储的与所述区块链外部账户相关的状态存储于对应的区块链外部账户的状态存储中,与所述区块链外部账户相关的状态包括合约中定义的外部账户与资产的映射关系,例如通过map数据结构定义的外部账户与资产的映射关系。如前所述,还可能存在不同分片中的节点存储不同合约账户状态的集合的情况,或者不同分片中的节点存储不同合约账户集合的状态的情况,不再赘述。这样,源分片在执行合约过程中根据是否涉及存储在本分片以外的其它分片上的账户确定本交易是否是跨片交易,例如源分片中的各节点可以在达成共识后的执行交易的过程中根据是否涉及存储在本分片以外的其它分片上的账户确定本交易是否是跨片交易。
对于普通的转账交易来说,源分片可以根据to字段标明的目标账户将其中的跨分片转账交易筛选出来。to字段标明的普通转账交易的目标外部账户,如果不归属于本分片对应的外部账户集合,则该普通转账交易即判断为跨分片转账交易。对于跨片交易,由于源分片对应的外部账户集合中仅有from字段标明源分片中的外部账户,因此,对于普通转账交易,只能通过执行交易来对本分片中from字段标明的源分片中的外部账户(例如账户A1)进行余额balance的操作,生成对账户A1的新的余额信息。而该普通转账交易中to字段标明的其它分片(即目标分片)中的目标外部账户的余额balance的操作,无法在源分片中操作。因此,源分片中可以生成待由目标分片执行的跨片操作的信息以发送给目标分片。该跨片操作信息例如可以为交易Tx1的子交易Tx2的形式,也可以同样地具有from字段和to字段,其中from字段例如可以为源分片中执行交易Tx1的节点的账户地址,to字段为交易Tx1中的目标外部账户的地址。在一种实施方式中,该跨片操作信息可以为指示生成交易Tx1的子交易Tx2的信息,从而目标分片中的节点在接收到该信息之后,可以根据该信息生成子交易Tx2,此时子交易Tx2的from字段可以为目标分片中的节点的账户地址,to字段同样为交易Tx1中的目标外部账户的地址。该跨分片操作信息中带有交易Tx1的标识,例如交易Tx1的哈希值,以用于标记其为与交易Tx1对应的跨片操作信息。
对于创建/调用合约的交易来说,如前所述,由于合约的复杂性,很多情况下无法从合约代码本身来判断本次交易是否涉及跨分片交易,尤其是对于调用合约的交易。源分片中的节点可以在达成共识后的执行合约过程中根据是否涉及存储在本分片以外的其它分片上的账户确定本交易是否是跨片交易。类似的,对于跨分片的交易,如调用合约交易涉及的跨分片交易,源分片可以在执行所述交易的过程中执行本分片涉及的账户的操作,生成改变所述本分片中涉及账户的状态的信息,包括外部账户和/或合约账户的状态。而对于目标分片对应的账户状态的改变,源分片可以生成这些跨分片交易中需要由目标分片执行的操作的信息。
对于源分片来说,由于这些跨分片交易中涉及的目标分片的操作需要发送至目标分片执行,在尚未确定目标分片已经执行前,源分片中的节点即使在本分片中完成了共识并执行了该源分片区块中的这些跨分片交易,也不将该源分片区块中跨分片交易产生的本分片中相关账户的变化后的状态提交至状态数据库。在一种实施方式中,例如对于上述跨片交易Tx1,源分片中的节点在执行交易Tx1之后,可以将对账户A1的更改信息记录到其他数据库中,直到目标分片返回跨片操作的执行结果时,再更新到状态数据库中。在另一种实施方式中,源分片中的节点在执行交易Tx1之后,可将账户A1的更新的余额以追加的方式记录到状态数据库中的账户A1的状态存储中,即保留账户A1的原余额,并对该账户A1的状态进行锁定。例如,在状态数据库中,账户A1的值为“b1/b2(锁定标记)”,其中,b1为账户A1在执行交易Tx1之前的原余额,b2为账户A1在执行交易Tx1之后更新的余额,该锁定标记用于指示账户A1已经被锁定,后续交易在解锁之前将不能对账户A1的状态进行改变,其中,该锁定标记中例如可包括交易Tx1的标识(例如交易Tx1的哈希值)。可以理解,上述记录的账户A1的值“b1/b2(锁定标记)”仅仅是示意性的,而不用于限制本说明书实施例的范围,例如,b2不一定为更改后的值,而可以为对b1的减少值,等等,多次不作限定。
前述提到,由源分片中的主节点将包括该交易在内的一定数量的交易打包,发起共识提议,达成共识后源分片中的各个节点可以在本地执行交易,但是并不将执行结果提交至底层数据库。源分片中的各个节点在达成共识后在本地执行交易,本分片中相关账户的状态会发生改变,包括外部账户和/或合约账户的状态的改变。源分片可以根据这些改变后的状态生成分片区块。相关的外部账户和合约账户的状态改变后,源分片中的各个节点可以根据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个节点发送相同的需要由目标分片执行的事务至主链中的一个或多个节点。
在步骤S1403,源分片的节点将跨片操作的信息提供给目标分片的节点。
源分片中的例如预设的主节点在执行跨片交易Tx1之后,可以将产生的跨片操作信息发送给目标分片中预设的主节点,从而可以使得目标分片中的各个节点执行跨片操作,并将该跨片操作的相关信息持久性存储。在区块链***中包括主链的情况中,源分片的节点可通过主链的转发,将跨片操作信息发送给目标分片的节点。在一种实施方式中,源分片的节点可在执行完上述多个打包的交易之后,将多个打包的交易中的一个或多个跨片交易产生的跨片操作集中到与各个其它分片对应的集合中,并将该跨片操作信息的集合一起发送给相应的分片。
在步骤S1405,源分片的节点记录交易Tx1的标识与更改的账户的对应关系。
如上文所述,源分片的节点发送给目标分片的节点的跨片操作信息中通常包括跨片交易的哈希值。目标分片节点在接收跨片操作并执行该跨片操作之后,将该跨片操作是否执行成功的信息返回给源分片,该执行结果信息中通常也仅包括源分片中的跨片交易的哈希值。源分片的节点在获取跨片操作的执行结果信息之后,需要找到跨片交易更改的账户,并根据执行结果在状态数据库中更新该账户的状态。然而,如果在源分片中已经执行完包括跨片交易Tx1的多个打包交易,并且对该多个交易进行入块,在源分片中的节点中仅能从相应的区块中获取交易Tx1的交易体,尤其在交易Tx1为创建/调用合约的交易的情况中,如上文所述,仅从交易Tx1的交易体并不能直接确定交易Tx1对源分片中的哪些账户的状态进行了更改。
为此,在本说明书实施例中,在执行跨片交易之后,可以在特定的数据库(非区块数据库和状态数据库)中记录跨片交易的标识(例如哈希值)与该交易更改的账户(即账户地址)的对应关系。从而,在目标分片返回该交易的跨片操作的执行结果时,可以直接基于该对应关系找到跨片交易更改的账户。在一种实施方式中,可以在执行完打包的多个交易之后,在生成该多个交易所属的区块时,在特定的数据库(专用于记录跨链交易与其更改的账户的对应关系的数据库)中记录各个跨片交易的标识与其更改的账户的对应关系。
在一种实施方式中,跨片交易Tx1为转账交易,源分片中的节点在执行跨片交易Tx1之后,可在上述特定的数据库中记录交易Tx1的哈希值与交易Tx1的From字段中的账户地址(即账户A1的地址)的对应关系。在一种实施方式中,源分片中的节点还可以在该特定数据库中记录交易Tx1对账户A1的状态更改信息(即账户A1的更新的余额),以等待更新到状态数据库中。
在一种实施方式中,跨片交易Tx1为创建/调用合约的交易,该合约的执行对外部账户A1的余额进行了更改或初始化,则可在上述特定的数据库中记录交易Tx1的哈希值与账户A1的账户地址的对应关系。
在一种实施方式中,跨片交易Tx1为创建/调用合约的交易,该合约的执行对合约中定义的变量b的状态进行了更改或初始化,则可在上述特定的数据库中记录交易Tx1的哈希值与该合约的合约地址的对应关系。在一种实施方式中,可记录交易Tx1与该合约地址及变量b的对应关系。
在一种实施方式中,跨片交易Tx1为创建/调用合约的交易,该合约的执行对合约中定义的外部账户A1的映射变量balanceA的状态进行更改或初始化。如上文所述,外部账户的映射变量的状态可存储到外部账户的状态存储中,因此可在上述特定数据库中记录交易Tx1的哈希值与账户A1的对应关系。
更具体地,在图5所示的情况中,在外部账户的状态存储中可存储多个智能合约各自定义的该外部账户的多个映射变量的状态,从而,源分片为了在目标分片返回跨片操作的执行结果之后便捷地对交易Tx1中的映射变量balanceA进行状态更改,可在上述特定数据库中记录交易Tx1的哈希值与账户A1、交易Tx1创建或调用的合约的合约地址、及映射变量balanceA的标识的对应关系,其中,映射变量balanceA的标识如上文所述可以为变量balanceA的名称哈希值,或者为变量名称+变量声明位置的哈希值等,对此不作限定。
在图6所示的情况中,在源分片中仅部署一个智能合约,因此,在外部账户的状态存储中仅存储该外部账户的多个映射变量的状态。在该情况中,可在上述特定数据库中记录交易Tx1的哈希值与账户A1和映射变量balanceA的标识的对应关系。
在图7所示的情况中,在源分片中仅部署一个智能合约,并且该智能合约中仅定义了各个外部账户的一个映射变量,即,在外部账户的状态存储中仅存储一个映射变量的状态。在该情况中,可在上述特定数据库中记录交易的Tx1的哈希值与账户A1的对应关系。
在图8所示的情况中,在源分片中部署多个智能合约,并且各个智能合约中仅定义了外部账户的一个映射变量,在该情况中,可在上述特定数据库中记录交易Tx1的哈希值与账户A1、及交易Tx1中创建或部署的合约的合约地址之间的对应关系。
在步骤S1407,目标分片的节点执行所接收的跨分片操作。
所述目标分片中的主节点可以将一段时间内接收到的一定数量的交易打包并发起共识提议。所述打包的交易中可以包括与从上述源分片(或主链)发来的跨片操作信息对应的交易,还可以包括所述目标分片接收到的客户端发来的交易。在所述目标分片中达成共识后,由所述目标分片中的各个节点执行这些打包的交易,生成目标分片区块。
所述目标分片中的各节点执行交易,包括执行所述跨片操作对应的交易。此外,目标分片中的各节点执行的交易还可以包括所述目标分片接收到的客户端发来的交易。由于所述目标分片中存储有所述跨片操作对应的账户状态,因此,执行所述跨片操作会导致所述目标分片中存储的相应账户的状态发生改变。目标分片中的各节点执行所述跨片操作后,并不将执行所述跨片操作后导致的本分片中相应的账户变化后的状态提交至底层数据库,即不持久化存储。当所述目标分片收到源分片对相应的跨片交易的提交确认后,才在本地提交跨分片交易中由所述目标分片执行的操作,完成持久化存储。
如果所述目标分片中的各节点执行所述跨片操作后,存在部分或全部跨片操作涉及本分片以外其它分片上存储的账户,即相应的跨片交易是多重跨片交易。则对于这种多重跨片交易,一方面,执行所述跨片操作后导致的本分片中相应的账户改变后的状态也并不提交至底层数据库,另一方面,将这些跨片操作中进一步涉及的需要由其它分片执行的跨片操作发送至其它分片,并与源分片类似地在本分片的特定数据库中记录跨片交易的哈希值与该交易在本分片更改的账户的对应关系。
最为简单的跨片交易是单重跨片交易,即从一个源分片到一个目标分片的跨片事务即执行完毕的交易。本说明书实施例中主要以单重跨片交易为例加以说明。本领域技术人员可以根据这里给出的单重跨片交易的例子容易的扩展到多重跨片交易的情形,而这些扩展的情形显然也应当属于本专利的范围。
此外,对于各节点执行所述目标分片接收到的客户端发来的交易,如果这些交易是分片内交易,即涉及的账户在本分片中都存储有对应的状态,则执行这些交易也会导致本分片中存储的相应账户的状态发生改变。
类似的,目标分片中的各个节点在达成共识后在本地执行交易,本分片中相关账户的状态会发生改变,包括外部账户和/或合约账户的状态的改变。相关的外部账户和合约账户的状态改变后,目标分片中的各个节点可以根据merkle树或MPT树的组织结构,计算得到新的状态树的根节点的hash值(即前述的状态根hash,State_Root)。得到的这个State_Root可以填入生成的目标分片区块的区块头中。此外,区块头中还可以包括区块号、时间戳、前一区块的hash等字段。
在步骤S1409,目标分片的节点向源分片的节点返回跨分片操作的执行结果。
目标分片的节点在确定跨片交易的跨片操作的执行结果之后可向源分片的节点(例如主节点)返回该执行结果,其中,该执行结果中包括跨片交易的标识(例如哈希值)。例如,目标分片的主节点可以在对跨片交易的执行结果进行共识之后,向源分片的主节点返回该执行结果。该执行结果包括执行成功或执行失败。例如,在交易Tx1为跨片转账交易的情况中,发送到目标分片中的跨片操作为对目标分片中的外部账户(例如账户A2)的转入操作,在账户A2在转入之后的余额超出预定限额的情况中,可确定该跨片操作执行失败,或者,在目标分片中未创建账户A2的情况中,可确定该跨片操作执行失败。在交易Tx1为创建或调用合约的交易的情况中,发送到目标分片中的跨片操作为创建或调用目标分片中的合约的操作,在创建或调用合约失败的情况中,可确定该跨片操作执行失败,等等。
在步骤S1411,源分片的节点根据交易Tx1的标识与更改的账户的对应关系,更新账户的状态。
源分片的节点在接收到跨片操作的执行结果之后,根据该执行结果中的交易Tx1的哈希值,可在上述特定数据库中查找该交易Tx1的哈希值,并根据交易Tx1与更改的账户的对应关系,更新该账户的状态。可以理解,源分片在执行交易Tx1时,可能向多个目标分片发送了多个跨片操作信息,在该情况中,源分片在从多个目标分片接收到全部跨片操作信息的执行结果之后,再根据全部的执行结果确定交易Tx1是否执行成功,从而据此更新账户的状态。
具体是,在跨片交易Tx1为外部账户A1发起的转账交易或者用于对外部账户A1的余额进行更改的创建/调用合约的交易的情况中,在特定数据库中记录了交易Tx1的哈希值与账户A1的对应关系,源分片节点在接收到跨片操作的执行结果之后,可根据该对应关系在状态数据库中找到账户A1,并更新账户A1的状态。例如,在状态数据库中,账户A1的当前余额值为“b1/b2(锁定信息)”,如果跨片操作的执行结果为执行成功,则源分片的节点可将账户A1的余额值更新为“b2”,如果跨片操作的执行结果为执行失败,则源分片的节点可将账户A1的余额值恢复为“b1”,即删除“b2(锁定信息)”。
针对图5所示的情况,在特定数据库中记录了交易Tx1的哈希值与账户A1、交易Tx1创建或调用的合约的合约地址、及映射变量balanceA的标识的对应关系,源分片的节点在接收到跨片操作的执行结果之后,可根据该对应关系在状态数据库中找到账户A1,在账户A1的状态存储中找到对应的合约的状态,并在合约的状态中找到映射变量balanceA,从而更改balanceA的状态。
针对图6所示的情况,在特定数据库中记录了交易Tx1的哈希值与账户A1和映射变量balanceA的标识的对应关系,源分片的节点在接收到跨片操作的执行结果之后,可根据该对应关系在状态数据库中找到账户A1,在账户A1的状态存储中找到映射变量balanceA的状态,从而更改balanceA的状态。
针对图7所示的情况,在特定数据库中记录了交易的Tx1的哈希值与账户A1的对应关系,源分片的节点在接收到跨片操作的执行结果之后,可根据该对应关系在状态数据库中找到账户A1,在账户A1的状态存储中找到包括锁定信息的状态,从而可更改该状态。
针对图8所示的情况,在特定数据库中记录交易Tx1的哈希值与账户A1、及交易Tx1中创建或部署的合约的合约地址之间的对应关系,源分片的节点在接收到跨片操作的执行结果之后,可根据该对应关系在状态数据库中找到账户A1,在账户A1的状态存储中找到交易Tx1中创建或部署的合约的状态,从而更改该合约的状态中值。
图15示出根据本说明书实施例的一种区块链节点的架构图,该区块链节点用于执行图14所示的方法,包括:
执行单元151,用于执行第一交易,存储所述第一交易更改的第一账户的状态信息,将待由第二区块链执行的跨链操作的信息提供给所述第二区块链,其中,所述跨链操作的信息中包括所述第一交易的标识;
记录单元152,用于记录第一交易的标识与第一账户的对应关系;
接收单元153,用于从第二区块链接收对所述跨链操作的执行结果,所述执行结果中包括所述第一交易的标识;
获取单元154,用于基于所述记录的第一交易的标识与第一账户的标识的对应关系,在状态数据库中获取第一账户的状态;
修改单元155,用于根据所述执行结果和所述状态信息,修改所述第一账户的状态。
在一种实现方式中,所述执行单元151还用于,在状态数据库中记录所述第一账户的更改后的状态,保留所述第一账户在该更改前的状态,并对所述第一账户的状态进行锁定。
在一种实现方式中,所述第一账户为第一合约的合约账户,所述第一账户的状态信息为对第一合约中定义的第一变量的更改信息,所述记录单元152还用于,记录第一交易的标识与第一账户的标识、和所述第一变量的标识的对应关系。
在一种实现方式中,所述第一合约中定义了所述第一变量与第二账户的映射关系,所述第二账户为外部账户,所述第一变量的状态存储于所述第二账户的状态存储中,所述记录单元152还用于,记录第一交易的标识与第一账户的标识、所述第二账户的标识和所述第一变量的标识的对应关系。
在一种实现方式中,所述第一交易中调用了第一合约,所述第一账户为外部账户,其中,所述第一区块链中仅部署有所述第一合约,且所述第一合约中仅定义或启用了一种与所述第一账户映射的第一变量,所述第一变量的状态存储于所述第一账户的状态存储中。
在一种实现方式中,所述第一区块链和所述第二区块链为区块链***中的两个分片。
在一种实现方式中,所述区块链***还包括主链,其中,所述执行单元151还用于,将所述跨链操作的信息发送给所述主链,由所述主链将所述跨链操作的信息发送给所述第二区块链。
在一种实现方式中,所述记录单元152还用于,在生成所述第一交易所属的区块时,记录第一交易的标识与第一账户的对应关系。
在一种实现方式中,所述记录单元152还用于,在专用数据库中记录第一交易的标识与第一账户的对应关系。
本说明书实施例还提供一种计算机可读存储介质,其上存储有计算机程序,当所述计算机程序由计算机或处理器执行时,令计算机或处理器执行图14所示的方法。
本说明书实施例还一种区块链节点,包括存储器和处理器,所述存储器中存储有可执行代码,所述处理器执行所述可执行代码时,实现图14所示的方法。
在本说明书实施例提供的执行跨链交易的方案中,在执行跨链交易之后,记录跨链交易的标识与其更改的变量的标识的对应关系,从而,在该跨链交易的跨链操作的执行结果返回时,可以根据该对应关系在状态数据库中快速地定位跨链交易更改的账户,并对账户的状态进行更新,提高了区块链的处理效率。
需要理解,本文中的“第一”,“第二”等描述,仅仅为了描述的简单而对相似概念进行区分,并不具有其他限定作用。
本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于***实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。
上述对本说明书特定实施例进行了描述。其它实施例在所附权利要求书的范围内。在一些情况下,在权利要求书中记载的动作或步骤可以按照不同于实施例中的顺序来执行并且仍然可以实现期望的结果。另外,在附图中描绘的过程不一定要求示出的特定顺序或者连续顺序才能实现期望的结果。在某些实施方式中,多任务处理和并行处理也是可以的或者可能是有利的。
本领域普通技术人员应该还可以进一步意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、计算机软件或者二者的结合来实现,为了清楚地说明硬件和软件的可互换性,在上述说明中已经按照功能一般性地描述了各示例的组成及步骤。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。本领域普通技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本申请的范围。其中,软件模块可以置于随机存储器(RAM)、内存、只读存储器(ROM)、电可编程ROM、电可擦除可编程ROM、寄存器、硬盘、可移动磁盘、CD-ROM、或技术领域内所公知的任意其它形式的存储介质中。
以上所述的具体实施方式,对本发明的目的、技术方案和有益效果进行了进一步详细说明,所应理解的是,以上所述仅为本发明的具体实施方式而已,并不用于限定本发明的保护范围,凡在本发明的精神和原则之内,所做的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。
Claims (20)
1.一种在区块链中执行交易的方法,所述方法由第一区块链的节点执行,包括:
执行第一交易,存储所述第一交易更改的第一账户的状态信息,将待由第二区块链执行的跨链操作的信息提供给所述第二区块链,其中,所述跨链操作的信息中包括所述第一交易的标识;
记录第一交易的标识与第一账户的对应关系;
从第二区块链接收对所述跨链操作的执行结果,所述执行结果中包括所述第一交易的标识;
基于记录的所述对应关系,在状态数据库中获取第一账户的状态;
根据所述执行结果和所述状态信息,修改所述第一账户的状态;
其中,所述存储所述第一交易更改的第一账户的状态信息包括,在状态数据库中记录所述第一账户的更改后的状态,保留所述第一账户在该更改前的状态,并对所述第一账户的状态进行锁定。
2.根据权利要求1所述的方法,其中,所述第一账户为外部账户或合约账户。
3.根据权利要求2所述的方法,其中,所述第一账户为第一合约的合约账户,所述第一账户的状态信息为对第一合约中定义的第一变量的更改信息,所述记录第一交易的标识与第一账户的标识的对应关系包括,记录第一交易的标识与第一账户的标识、和所述第一变量的标识的对应关系。
4.根据权利要求3所述的方法,其中,所述第一合约中定义了所述第一变量与第二账户的映射关系,所述第二账户为外部账户,所述第一变量的状态存储于所述第二账户的状态存储中,所述记录第一交易的标识与第一账户的标识的对应关系包括,记录第一交易的标识与第一账户的标识、所述第二账户的标识和所述第一变量的标识的对应关系。
5.根据权利要求2所述的方法,所述第一交易中调用了第一合约,所述第一账户为外部账户,其中,所述第一区块链中仅部署有所述第一合约,且所述第一合约中仅定义或启用了一种与所述第一账户映射的第一变量,所述第一变量的状态存储于所述第一账户的状态存储中。
6.根据权利要求1所述的方法,其中,所述第一区块链和所述第二区块链为区块链***中的两个分片。
7.根据权利要求6所述的方法,其中,所述区块链***还包括主链,其中,所述将待由第二区块链执行的跨链操作的信息提供给所述第二区块链包括,将所述跨链操作的信息发送给所述主链,由所述主链将所述跨链操作的信息发送给所述第二区块链。
8.根据权利要求1所述的方法,其中,所述记录第一交易的标识与第一账户的对应关系包括,在生成所述第一交易所属的区块时,记录第一交易的标识与第一账户的对应关系。
9.根据权利要求1所述的方法,其中,所述记录第一交易的标识与第一账户的对应关系包括,在专用数据库中记录第一交易的标识与第一账户的对应关系。
10.一种区块链节点,所述区块链节点属于第一区块链,所述区块链节点包括:
执行单元,用于执行第一交易,存储所述第一交易更改的第一账户的状态信息,将待由第二区块链执行的跨链操作的信息提供给所述第二区块链,其中,所述跨链操作的信息中包括所述第一交易的标识;
记录单元,用于记录第一交易的标识与第一账户的对应关系;
接收单元,用于从第二区块链接收对所述跨链操作的执行结果,所述执行结果中包括所述第一交易的标识;
获取单元,用于基于记录的所述对应关系,在状态数据库中获取第一账户的状态;
修改单元,用于根据所述执行结果和所述状态信息,修改所述第一账户的状态;
其中,所述执行单元还用于,在状态数据库中记录所述第一账户的更改后的状态,保留所述第一账户在该更改前的状态,并对所述第一账户的状态进行锁定。
11.根据权利要求10所述的区块链节点,其中,所述第一账户为外部账户或合约账户。
12.根据权利要求11所述的区块链节点,其中,所述第一账户为第一合约的合约账户,所述第一账户的状态信息为对第一合约中定义的第一变量的更改信息,所述记录单元还用于,记录第一交易的标识与第一账户的标识、和所述第一变量的标识的对应关系。
13.根据权利要求12所述的区块链节点,其中,所述第一合约中定义了所述第一变量与第二账户的映射关系,所述第二账户为外部账户,所述第一变量的状态存储于所述第二账户的状态存储中,所述记录单元还用于,记录第一交易的标识与第一账户的标识、所述第二账户的标识和所述第一变量的标识的对应关系。
14.根据权利要求11所述的区块链节点,所述第一交易中调用了第一合约,所述第一账户为外部账户,其中,所述第一区块链中仅部署有所述第一合约,且所述第一合约中仅定义或启用了一种与所述第一账户映射的第一变量,所述第一变量的状态存储于所述第一账户的状态存储中。
15.根据权利要求10所述的区块链节点,其中,所述第一区块链和所述第二区块链为区块链***中的两个分片。
16.根据权利要求15所述的区块链节点,其中,所述区块链***还包括主链,其中,所述执行单元还用于,将所述跨链操作的信息发送给所述主链,由所述主链将所述跨链操作的信息发送给所述第二区块链。
17.根据权利要求10所述的区块链节点,其中,所述记录单元还用于,在生成所述第一交易所属的区块时,记录第一交易的标识与第一账户的对应关系。
18.根据权利要求10所述的区块链节点,其中,所述记录单元还用于,在专用数据库中记录第一交易的标识与第一账户的对应关系。
19.一种计算机可读存储介质,其上存储有计算机程序,当所述计算机程序由计算机或处理器执行时,令计算机或处理器执行权利要求1-9中任一项的所述的方法。
20.一种区块链节点,包括存储器和处理器,所述存储器中存储有可执行代码,所述处理器执行所述可执行代码时,实现权利要求1-9中任一项所述的方法。
Priority Applications (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110674714.0A CN113254538B (zh) | 2021-06-17 | 2021-06-17 | 在区块链中执行交易的方法和区块链节点 |
CN202210023176.3A CN114385756A (zh) | 2021-06-17 | 2021-06-17 | 在区块链中执行交易的方法和区块链节点 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110674714.0A CN113254538B (zh) | 2021-06-17 | 2021-06-17 | 在区块链中执行交易的方法和区块链节点 |
Related Child Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202210023176.3A Division CN114385756A (zh) | 2021-06-17 | 2021-06-17 | 在区块链中执行交易的方法和区块链节点 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN113254538A CN113254538A (zh) | 2021-08-13 |
CN113254538B true CN113254538B (zh) | 2021-11-16 |
Family
ID=77188520
Family Applications (2)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202210023176.3A Pending CN114385756A (zh) | 2021-06-17 | 2021-06-17 | 在区块链中执行交易的方法和区块链节点 |
CN202110674714.0A Active CN113254538B (zh) | 2021-06-17 | 2021-06-17 | 在区块链中执行交易的方法和区块链节点 |
Family Applications Before (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202210023176.3A Pending CN114385756A (zh) | 2021-06-17 | 2021-06-17 | 在区块链中执行交易的方法和区块链节点 |
Country Status (1)
Country | Link |
---|---|
CN (2) | CN114385756A (zh) |
Families Citing this family (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN114050904B (zh) * | 2022-01-11 | 2022-03-22 | 天津眧合数字科技有限公司 | 一种基于两层级领导节点分片结构的共识***及方法 |
Citations (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN108600301A (zh) * | 2018-03-08 | 2018-09-28 | 青岛墨客区块链有限公司 | 一种区块链之间的跨链方法及主区块链 |
CN109035012A (zh) * | 2018-06-11 | 2018-12-18 | 西安纸贵互联网科技有限公司 | 一种区块链***的跨链处理方法和计算机可读存储介质 |
CN109559227A (zh) * | 2018-11-29 | 2019-04-02 | 咪咕文化科技有限公司 | 一种跨区块链网络的交易方法、装置及存储介质 |
KR20190058255A (ko) * | 2017-11-20 | 2019-05-29 | 충남대학교산학협력단 | 블록체인 이중지불 탐지 시스템 및 방법 |
CN112651724A (zh) * | 2020-04-28 | 2021-04-13 | 北京邮电大学 | 跨链交互方法、装置和*** |
CN112732800A (zh) * | 2021-03-30 | 2021-04-30 | 支付宝(杭州)信息技术有限公司 | 提供跨链消息的方法和装置 |
Family Cites Families (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN112862612B (zh) * | 2019-06-28 | 2024-04-30 | 创新先进技术有限公司 | 一种跨链发送资源的方法和装置 |
US10937096B2 (en) * | 2019-07-15 | 2021-03-02 | Advanced New Technologies Co., Ltd. | Transaction processing in a service blockchain |
CN110633970B (zh) * | 2019-09-19 | 2023-06-02 | 深圳前海环融联易信息科技服务有限公司 | 一种数字资产清分方法、装置、计算机设备及存储介质 |
CN113329031B (zh) * | 2019-10-10 | 2023-06-13 | 深圳前海微众银行股份有限公司 | 一种区块的状态树的生成方法及装置 |
CN112257118B (zh) * | 2020-12-21 | 2021-08-03 | 支付宝(杭州)信息技术有限公司 | 一种锁定包含分片的区块链***中跨片事务的方法及*** |
CN112261163B (zh) * | 2020-12-21 | 2021-03-12 | 支付宝(杭州)信息技术有限公司 | 一种区块链***中的状态存储方法及区块链***、节点 |
-
2021
- 2021-06-17 CN CN202210023176.3A patent/CN114385756A/zh active Pending
- 2021-06-17 CN CN202110674714.0A patent/CN113254538B/zh active Active
Patent Citations (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
KR20190058255A (ko) * | 2017-11-20 | 2019-05-29 | 충남대학교산학협력단 | 블록체인 이중지불 탐지 시스템 및 방법 |
CN108600301A (zh) * | 2018-03-08 | 2018-09-28 | 青岛墨客区块链有限公司 | 一种区块链之间的跨链方法及主区块链 |
CN109035012A (zh) * | 2018-06-11 | 2018-12-18 | 西安纸贵互联网科技有限公司 | 一种区块链***的跨链处理方法和计算机可读存储介质 |
CN109559227A (zh) * | 2018-11-29 | 2019-04-02 | 咪咕文化科技有限公司 | 一种跨区块链网络的交易方法、装置及存储介质 |
CN112651724A (zh) * | 2020-04-28 | 2021-04-13 | 北京邮电大学 | 跨链交互方法、装置和*** |
CN112732800A (zh) * | 2021-03-30 | 2021-04-30 | 支付宝(杭州)信息技术有限公司 | 提供跨链消息的方法和装置 |
Also Published As
Publication number | Publication date |
---|---|
CN114385756A (zh) | 2022-04-22 |
CN113254538A (zh) | 2021-08-13 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN110602148B (zh) | 一种区块的状态树的生成和链上数据验证的方法及装置 | |
CN112257118B (zh) | 一种锁定包含分片的区块链***中跨片事务的方法及*** | |
CN109471744B (zh) | 基于区块链的主链加并行多子链***架构 | |
CN109493050B (zh) | 基于区块链主链加并行多子链的转账方法 | |
CN107392608B (zh) | 基于区块链***的数字资产交易方法及区块链*** | |
CN112261162B (zh) | 执行跨片事务的方法及***、主链节点和目标分片节点 | |
CN111680050B (zh) | 一种联盟链数据的分片处理方法、设备和存储介质 | |
CN109472572B (zh) | 基于区块链主链加并行多子链的合约*** | |
CN112261163B (zh) | 一种区块链***中的状态存储方法及区块链***、节点 | |
CN112261157B (zh) | 提交跨片事务的方法及***、主链节点和源分片节点 | |
CN113259478A (zh) | 在区块链***中执行交易的方法、装置及区块链*** | |
CN112579261A (zh) | 退出跨片事务的方法和***、主链节点和目标分片节点 | |
CN108615156A (zh) | 一种基于区块链的数据结构 | |
CN109493052B (zh) | 一种基于主链加并行多子链的跨链合约*** | |
CN112651724A (zh) | 跨链交互方法、装置和*** | |
CN103942281B (zh) | 一种对持久化存储的对象进行操作的方法及装置 | |
CN113094396A (zh) | 基于节点内存的数据处理方法、装置、设备以及介质 | |
CN104539681A (zh) | 分布式gis加速***和gis服务的处理方法 | |
CN112261160B (zh) | 包含分片的区块链***中退出跨片事务的方法及*** | |
CN109493051B (zh) | 可动态进行账户分配及迁移的主链加并行多子链***架构 | |
CN113254538B (zh) | 在区块链中执行交易的方法和区块链节点 | |
CN113379422A (zh) | 基于智能合约的数据处理方法、设备以及可读存储介质 | |
CN113256291A (zh) | 在区块链***中创建账户及分配交易的方法及装置 | |
CN112261156B (zh) | 一种提交跨片事务的方法及***、主链节点和源分片节点 | |
CN112396422B (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 |