Skip to main content

区块

区块链(Blockchain)本身是一种数据结构。区块大致由区块头和区块主体两部分组成。因为每个区块(头)里都存有上一个区块的hash值(参见区块头部分中的PrevHash),从而形成了一种链式结构。

区块头#

区块头的数据结构见下:

字节数字段名称类型描述
4Version区块版本uint区块版本号,目前为 0
32PrevHash上一个区块HashUInt256上一个区块的hash值
32MerkleRootMerkle树Uint256该区块中所有交易的Merkle树的根
8Timestamp时间戳ulong该区块生成的大致时间
8Nonce随机数ulong该区块的随机数
4Index区块高度uint创世块的高度为0
1PrimaryIndex议长索引byte本次共识过程中提案验证人的索引
20NextConsensus下一轮共识验证人的地址UInt160下一轮出块的三分之二以上的验证人的签名脚本hash
?Witness见证人Witness可执行验证脚本

区块头包含了一个区块的基本信息,用以保证这个区块能正确地连入区块链。

区块hash值和区块高度Index都可以用作区块的标识。区块hash值是对区块头的前7个数据拼合在一起进行两次SHA256运算而得。正常运行时,Neo只会有一条链,且每个区块均由共识节点三分之二以上的节点确认之后才被加入到区块链中,所以区块链上的每一个块的高度唯一。区块高度必须等于前一个区块高度加1。因为任何区块内的信息变化都会造成区块hash值改变,所以区块hash值是区块的唯一标识。区块高度不受区块内信息影响,安全性稍低,无法成为唯一标识。

Timestamp是每个区块的时间戳,必须晚于其前一个区块的时间戳。两个块确认的时间间隔在15秒左右,由系统配置文件config.json中,变量MillisecondsPerBlock所设定。

NextConsensus是一个多方签名脚本的hash值,脚本验证时,需要三分之二以上的共识节点的签名作为参数。示例脚本如下图。每一个区块,都会带有NextConsensus字段,锁定了参与下一轮共识的节点。在上一轮共识中,当时的议长节点根据当时的投票结果计算出了下一轮的共识节点,再生成多方签名合约,并将合约脚本hash值存入到提案块的NextConsensus字段中。若提案块最后达成共识,成为被确认的块,则本轮的共识验证人是上一个被确认的块里的多方签名合约地址之一。

Witness是这个区块的验证脚本。它的结构是执行脚本(InvocationScript)加上验证脚本(VerificationScript)。执行脚本就包含进行验证所需要的参数,而验证脚本就是具体验证要使用的脚本。

区块#

区块的数据结构见下:

字节数字段名称类型描述
Header区块头Header区块头
?*?Transactions交易列表Transaction[]区块的主数据

除去区块头,剩下的便是由一个交易列表组成的区块主体。严格讲,区块主体以交易列表长度开始,后面罗列各条交易。此轮共识的议长将从其内存池队列中挑出通过验证的一系列交易,将其交易哈希放入一个共识消息(PrePareRequest)中再发送到网络里。共识过程相对复杂,请参见 共识机制 章节。

目前,每一个块中最多有512笔交易。

note

Block在做持久化(persist)时,存放的是交易hash列表,而交易的数据另外单独存放,以方便查询。