首页 > Bitcoin 区块和交易数据结构

比特币账单数据结构,Bitcoin 区块和交易数据结构

互联网 2021-03-03 19:20:56

图来自http://learnmeabitcoin.com/guide/blockchain

区块链是一种账本数据库,分布式,数据存储的每个节点都会同步复制整个账本,信息透明难以篡改。

区块中存放着交易,区块按照高度有序链接起来的这种数据结构被称为区块链。每个区块都指向前一个区块,一个区块由 区块头 和 交易 组成。

区块

区块由一个包含元数据的区块头和紧跟其后的构成区块主体的一长串交易列表组成。区块结构如图:

图来自http://learnmeabitcoin.com/glossary/

区块头中数据有:

区块版本前个区块哈希Merkle Root 哈希时间戳Bits 难度Nonce “挖矿” 随机数

Coinbase 交易:每个区块中的第一条交易都是 Coinbase 交易,用于奖励 “矿工” 将交易打包到区块。奖励分为两部分,一是区块奖励,一是区块中除 Coinbase 交易外其它交易手续费总和。

区块头

区块头的长度是80字节,将区块头数据进行两次 Sha256 运算将得到区块哈希。

区块头结构如下:

FieldSizeDataVersion4 bytesLittle-endian ⟲Previous Block Hash32 bytesLittle-endian ⟲MerkleRoot32 bytesLittle-endian ⟲Timestamp4 bytesLittle-endian ⟲Bits (Difficulty Target)4 bytesLittle-endian ⟲Nonce4 bytesLittle-endian ⟲Merkle Root

Merkle Tree 是一种哈希二叉树,用于归纳一个区块中的所有交易,同时生成整个交易集合的数字签名,且提供了一种校验区块是否存在某交易的高效途径。

区块链中的每个区块都包含了产生于该区块的所有交易,且以Merkle树表示。那么如何获得它呢?

从区块交易列表中获取每对Txid,并对它们进行两次 Sha256 运算,得到哈希。如果为奇数,则复制一份凑成偶数再进行两次 Sha256 运算,得到哈希。递归1、2,直到最终获得一个哈希,它就是Merkle Root。

图来自http://learnmeabitcoin.com/glossary/merkle-root

为什么使用 Merkle Root 方式呢,为什么不对区块内所以交易一次性进行哈希呢,那样不是更快么?

使用 Merkle Root 原因有二:

完整性验证,任何一个节点的哈希发生变化,都会导致最终的 Root 节点哈希发生变化。这一特性也可用于快速定位问题节点。零知识证明,如下图,16 条交易的节点能够通过生成一条仅有 4 个 32 字节哈希值长度(总128字节)的 Merkle 路径,来证明区块中存在一笔交易 K,该路径有4个哈希值 HL、HIJ、HMNOP 和 HABCDEFGH。由这4个哈希值产生的认证路径,再通过计算另外四对哈希值 HKL、HIJKL、HIJKLMNOP 和 Merkle Root,任何节点都能证明 HK 包含在Merkle Root。

图来自https://github.com/bitcoinbook/bitcoinbook/

关于 Merkle 路径,我们来看一张图:

交易数量区块大小路径数量路径大小164 KB4128 bytes512128 KB9288 bytes2048512 KB11352 bytes40961 MB12384 bytes65,53516 MB16512 bytes

即使增长到交易数量为 262144,区块大小到 65M,路径数也才 18。所以使用 Merkle Root 非常高效,如果是所有交易进行一次哈希,虽然获得 Hash 是快些,但对于要验证问题交易或节点,将是个灾难。

Bits 和 Nonce

Bits 是挖矿目标难度 Target 的紧凑格式。

Nonce 是挖矿遍历时的随机数。

关于 “挖矿” 的具体内容,我会单独总结一篇,感兴趣可以关注后续文章。这里有一个在线的模拟挖矿,各种数据显示都很直观,适合了解挖矿内部运作:点我前往模拟挖矿

交易

目前存在两种交易结构。比特币白皮书中定义的交易结构和新的隔离见证交易结构。

BIP 141 定义一种新的交易结构,我们称之为 “Segregated Witness (隔离见证)” 交易。旧交易结构签名数据放在交易输入里,隔离见证交易则将签名数据 “分离” 出来,放在交易的 Locktime 之前。

交易结构:

[nVersion] [n] [tx inputs] [n] [tx outputs] [nLockTime]| | || 4 bytesvarintvarint 4 bytes

隔离见证(Segregated Witness)交易结构:

[nVersion] [marker] [flag][n] [tx inputs] [n] [tx outputs] [witness][nLockTime]| \/ \/| |\ / | 4 bytes 0x000x01 varint varintscriptSig4 bytesFieldSizeDataVersion4 bytesLittle-endian ⟲* Marker1 bytes0x00* Flag1 bytes0x01Input Counter1–9 bytesVarIntInputsVariable Output Counter1–9 bytesVarIntOutputsVariable * WitnessVariable Locktime4 bytesLittle-endian ⟲

* 为 Segregated Witness 交易字段。

我们解析一条 Segregated Witness (P2SH-P2WPKH)交易:

如果你对 P2SH-P2WPKH 交易感兴趣可以查看我之前写的一篇介绍 Segregated Witness 的文章。

{"txid": "af0c4cdd2537ae367b0e03db0cd795fa37543bd672c9234b2c307009a9a8108f","hash": "ff300093626745127aad29e8628ee4606b87cb660f7ff63817dd4857cd15a175","version": 2,"size": 248,"vsize": 166,"locktime": 0,"vin": [],"vout": []}

HEX 数据:

Inputs

交易输入结构:

FieldSizeDataTXID32 bytesLittle-endian ⟲VOUT4 bytesLittle-endian ⟲ScriptSig Size1–9 bytesVarIntScriptSigVariable Sequence4 bytesLittle-endian ⟲

输入JSON:

{"txid": "6635d3f451478f0e1f88692d5cfb9194f133fbb314cb87fa9483f89bd296284b","vout": 0,"scriptSig": {"asm": "0014db75523757a256579a197746568f331103417b85","hex": "160014db75523757a256579a197746568f331103417b85"},"txinwitness": ["3045022100c8b2a6027f939bb964e395c94cd6f1d8ff9d1f406e41975b2ac979a6007c3ac4022019953dfe376d0152152955e02d72e7a7b9a61f8d5700642c97a2dc4ba13628b801","02983f3687310bcfe2ad1ad55d011112c3f8d659950c10cab9ff43ae34d7b6280e"],"sequence": 4294967293}outputs

交易输出结构:

FieldSizeDataValue8 bytesLittle-endian ⟲ScriptPubKey Size1–9 bytesVarIntScriptPubKeyVariable

输出JSON:

{"value": 1.00000000,"n": 0,"scriptPubKey": {"asm": "OP_HASH160 2228cecac3c1fa3143ba2ac7d2525d8b9b05c87b OP_EQUAL","hex": "a9142228cecac3c1fa3143ba2ac7d2525d8b9b05c87b87","reqSigs": 1,"type": "scripthash","addresses": ["2MvMqrBRct4F2zuyrpgrq2qqq61VZc1znPB"]}},{"value": 48.99996680,"n": 1,"scriptPubKey": {"asm": "OP_HASH160 22e2f5339cdf0778935e8127dc51e4a0ae62d162 OP_EQUAL","hex": "a91422e2f5339cdf0778935e8127dc51e4a0ae62d16287","reqSigs": 1,"type": "scripthash","addresses": ["2MvRgr7SeyTVutrUaJdmZ5ETVdoPp5eWoj5"]}}VarInt

比特币使用可变字节表示脚本长度,当一个字节不够表示时,如下规律:

SizeExampleDescription
免责声明:非本网注明原创的信息,皆为程序自动获取自互联网,目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责;如此页面有侵犯到您的权益,请给站长发送邮件,并提供相关证明(版权证明、身份证正反面、侵权链接),站长将在收到邮件24小时内删除。

相关阅读