资讯专栏INFORMATION COLUMN

Bitcoin 区块和交易数据结构

Kaede / 1025人阅读

摘要:区块中存放着交易,区块按照高度有序链接起来的这种数据结构被称为区块链。区块头区块头的长度是字节,将区块头数据进行两次运算将得到区块哈希。比特币白皮书中定义的交易结构和新的隔离见证交易结构。

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

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

区块

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

区块头中数据有:

区块版本

前个区块哈希

Merkle Root 哈希

时间戳

Bits 难度

Nonce “挖矿” 随机数

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

区块头

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

区块头结构如下:

Field Size Data
Version 4 bytes Little-endian ⟲
Previous Block Hash 32 bytes Little-endian ⟲
MerkleRoot 32 bytes Little-endian ⟲
Timestamp 4 bytes Little-endian ⟲
Bits (Difficulty Target) 4 bytes Little-endian ⟲
Nonce 4 bytes Little-endian ⟲
Merkle Root

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

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

从区块交易列表中获取每对Txid,并对它们进行两次 Sha256 运算,得到哈希。

如果为奇数,则复制一份凑成偶数再进行两次 Sha256 运算,得到哈希。

递归1、2,直到最终获得一个哈希,它就是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。

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

交易数量 区块大小 路径数量 路径大小
16 4 KB 4 128 bytes
512 128 KB 9 288 bytes
2048 512 KB 11 352 bytes
4096 1 MB 12 384 bytes
65,535 16 MB 16 512 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 bytes  varint          varint             4 bytes

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

[nVersion] [marker] [flag][n] [tx inputs] [n] [tx outputs] [witness][nLockTime]
    |           /     /  |               |                     /     |
 4 bytes     0x00    0x01 varint         varint            scriptSig  4 bytes
Field Size Data
Version 4 bytes Little-endian ⟲
* Marker 1 bytes 0x00
* Flag 1 bytes 0x01
Input Counter 1–9 bytes VarInt
Inputs Variable
Output Counter 1–9 bytes VarInt
Outputs Variable
* Witness Variable
Locktime 4 bytes Little-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

交易输入结构:

Field Size Data
TXID 32 bytes Little-endian ⟲
VOUT 4 bytes Little-endian ⟲
ScriptSig Size 1–9 bytes VarInt
ScriptSig Variable
Sequence 4 bytes Little-endian ⟲

输入JSON:

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

交易输出结构:

Field Size Data
Value 8 bytes Little-endian ⟲
ScriptPubKey Size 1–9 bytes VarInt
ScriptPubKey Variable

输出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

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

Size Example Description
<= 0xfc 0x12 1 个字节
<= 0xffff 0xfd1234 前缀是fd,小端表示接下来的2个字节
<= 0xffffffff 0xfe12345678 前缀是fe,小端表示接下来的4个字节
<= 0xffffffffffffffff 0xff1234567890abcdef 前缀是ff,小端表示接下来的8个字节

如:0x48,没有 fdfeff 前缀,所以我们知道它是2 bytes表示的。

VarInt: 0x48
        = 72 bytes

如:fd2606,因为是 fd 前缀,我们读取fd之后的 4 bytes,反转小端再转换为十进制表示。

VarInt: 0xfd2606
        = 0x2602    (next 2 bytes)
        = 0x0226    (Little-Endian)
        = 550 bytes
Little-Endian

小端 (Little-endian) 字节序。如:0x12345678

大端类似于十六进制字节从左到右的阅读顺序。小端最低位字节是 0x78 存储在最低的内存地址处,后面的字节依次往后存。

Big-Endian:    |12|34|56|78|
Little-Endian: |78|56|34|12|

比特币在很多地方数据都是用小端序表示。

参考

https://github.com/bitcoinboo...

http://learnmeabitcoin.com/gl...

http://learnmeabitcoin.com/gl...

http://learnmeabitcoin.com/gl...

http://yogh.io

http://royalforkblog.github.i...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/24422.html

相关文章

  • 区块链与状态爆炸

    摘要:目前整个历史的大小所有区块加起来的大小大约是,而状态的大小只有大约由约万个组成。通过每个区块的,间接限制了历史和状态的增长速度。常见的一个误解是的区块链大小已经超过了。区块链节点为保存历史和状态付出的存储,正是这样一种共享资源。 showImg(https://segmentfault.com/img/bVbsfg9?w=1920&h=815); 如果 Layer 1 的关注点应该是状...

    bigdevil_s 评论0 收藏0
  • 区块链无法解决的状态爆炸问题

    摘要:在本次秘猿科技区块链小课堂中,我们带大家来了解一个全新的状态爆炸问题。目前整个历史的大小所有区块加起来的大小大约是,而状态的大小只有大约由约万个组成。通过每个区块的,间接限制了历史和状态的增长速度。常见的一个误解是的区块链大小已经超过了。 在设计全新的区块链经济模型之前,我们以 SoV(价值存储) 和 MoE(交易媒介) 两个框架分析了比特币和以太坊经济模型,得出了上一篇中的问题。在本...

    Godtoy 评论0 收藏0
  • 区块链笔记(2)直观感受比特币

    摘要:书接上回区块链笔记基础概念扫盲,我们讨论了关于比特币以及区块链的许多基础概念,可能通过我略带类比的描述,让你初步有了一些概念,但是对于一个比特币到底长什么样以及如何使用比特币进行交易可能还不是很清楚,说的直白点就是听过猪叫,但没吃过猪肉。 解惑是每个人都在走的一条路,可谁又能解这漫漫无期呢?路上总是麻醉的人多,释怀的人少。 书接上回区块链笔记(1)基础概念扫盲,我们讨论了关于比特币以及...

    DrizzleX 评论0 收藏0
  • 对比特币的继承与创新!深入理解公链 CKB 的 Cell 模型

    摘要:为了理解底层公链的模型,我们前置了几篇概念性文章,讲述了我们应该以状态为中心设计区块链系统的,以及这么做带来的好处。交易依然表示状态的变化迁移。 为了理解底层公链 CKB 的 Cell 模型,我们前置了几篇概念性文章,讲述了我们应该以状态为中心设计区块链系统的,以及这么做带来的好处。并且在上一篇文章中,详细分析了比特币 UTXO 模型和以太坊的 Account 模型,以及进行了对比分析...

    ruicbAndroid 评论0 收藏0
  • 理解CKB的Cell模型

    摘要:交易依然表示状态的变化迁移。这样一个模型的特点是状态是第一性的所有者是状态的属性,每一份状态只有一个所有者状态不断的被销毁和创建。值得指出的是,的编程模型之所以强大,更多是因为它有状态,而不是因为它的有限图灵完备。 在设计 CKB 的时候,我们想要解决三个方面的问题: 状态爆炸引起的公地悲剧及去中心化的丧失;计算和验证耦合在了一起使得无论是计算还是验证都失去了灵活性,难以扩展;交易与价...

    henry14 评论0 收藏0
  • 比特币核心钱包 bitcoin core(bitcoin-Qt)的使用教程

    摘要:比特币主网络现在已经有数百大小。加密钱包密码应该包括位以上,且不要使用生日名字证件号码等易被猜测的密码。警告遗忘密码等于丢失所有比特币。例如比特币免费领取测试比特币。 showImg(https://upload-images.jianshu.io/upload_images/4834364-4db38e8ae57ed028.png?imageMogr2/auto-orient/str...

    BingqiChen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<