• 收款地址是公钥的hash。
  • 区块结构:
数据项 描述 长度
Magic No 魔数 总是 0xD9B4BEF9 4 字节(定长)
BlockSize 区块大小 到区块结束的字节长度 4字节(定长)
BlockHeader 区块头 包含六个数据项 80字节(定长)
Transaction Counter 交易计数器 正整数 VI=VarInt 1-9字节(变长)
BlockHeader 区块头 包含六个数据项 80字节(定长)
Transactions 交易 交易列表(非空) 由Transaction Counter 描述的长度(变长)

由此表可见,只有交易计数器和交易明细列表是变长的。

  • 比特币使用 SHA256 算法,它的结果哈希值大小为 256 位。也就是说,只要输入超过2的256次方个数,就一定会发生碰撞,即使只有2的255次方个数,也有百分之九十九的几率发生碰撞(为什么?)。
  • 当前(这一百年内),每个区块都至少包含一个 Transaction,它被称为生产交易,或者coinbase交易,用于给生成这个区块的矿工以奖励,它经常是区块中第一个交易。
  • 奖励每21万个区块减半一次。
  • 区块客户端的目标总是每小时产生6个区块。每2016个区块(大约2周)后,所有客户端(即矿工节点)收集当前区块的实际数目,和目标数目做对比,借此调整目标 Hash值,来调节产生区块的难度。
  • 区块链的客户端总是接受最长链。在这里,长度指的是“难度”,而不是具有最大区块数量的链,可以防止某些人构造大量低难度的链制造分叉。
  • 如果能够制造分叉,则可以在比特币网络里为所欲为,双花攻击只是其中之一。
  • 创世区块讽刺了银行动用准备金而导致金融系统稳定性下降。创世区块中的50个比特币无法被花掉。简而言之,是每个客户端的创世区块不尽相同:

创世块的收益不可能被花掉,因为创世块是用代码表示的(这个巧合可能是故意的),尽管如此,其50BTC收益还是被发送到地址:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa。
(译者按:创世块的收益花不掉,原因如下:比特币客户端把区块和交易分开存贮在两个数据库中,当客户端发现区块数据库为空时,用代码直接生成一个创世块,但是没有生成这个交易,所以客户端中的交易数据库中是没有发送到上述地址这个交易的,因而一旦收到要花掉该收益的交易时,都会拒绝,所以无法得到任何确认,就花不掉这50个币。出现这种情况很可能是中本聪故意的。)

  • 区块和区块链把交易的world history break down 成了若干个小的时间片内的记录,而记录之间又因为数学相关性互相串联,形成了可追溯又抗篡改的强大特性。
  • 区块的奖励有一个100个区块的成熟时间:

    译者按:区块成熟时间(Maturation Time),是指矿工产生一个新区块得到25BTC收益后,要等过了100个块后,才能使用这些币;这个100区块时间,即收到100个确认的时间,就是区块成熟时间。为什么要设这个时间?如果这个区块在分叉时变成了孤立区块,25个BTC的收益将消失,如果矿工挖到比特币后可以马上花掉,就会造成后续的一系列接收者损失比特币,因而设定了100个确认的限制,在这之后产生分叉的可能性非常小,即使产生分叉,也只会影响矿工收益,不会影响到其他人。

  • 区块头的格式:

数据项 目的 更新时间 大小
Version 版本 区域版本号 更新软件后,它指定了一个新版本号(也就是说,客户端是有自己的版本号区别的) 4字节
hashPrevBlock 前一个区块Hash 前一区块的256位HASH值 新的区块进来时 32字节 恰好等于 SHA256散列的结果字符串长度
hashMerkleRoot Merkele根节点HASH值 基于一个区块中所有交易产生的默克尔树的 256位SHA值(也就是32个字节,32个 Ascii码) 接受一个交易时(也就是说在区块更新时会一直更新?) 32字节 恰好等于 SHA256散列的结果字符串长度
Time 时间戳 从1970-01-01 00:00 UTC开始到现在,以秒为单位的当前时间戳(类似 Unix epoch) 这个时间戳在全球范围内可能出现不准的情况,怎么办? 每几秒就更新一次(终止于区块生成时?) 4字节(对毫秒而言不够,对秒而言就够了)
Bits 压缩格式当前的目标值 当挖矿难度调整时 4字节(4 * 8 = 32位) 使用特殊的方法用4字节表达32字节的 SHA256 散列字符串
Nonce 随机数 从0开始的32位随机数 产生Hash时(每次产生Hash随机数都要增长,为什么?) 4字节

区块内包含许多交易,它们通过Merkle根节点间接被HASH,因为所有交易不可能直接被HASH,HASH包含一个交易的区块所花的时间,和HASH包含1万个交易的区块一样。

也就是说区块的Hash里包含了非常多的内容。

目标HASH值的压缩格式是一个特殊的浮点编码类型,首字节是指数(仅使用了5个最低位),后3个字节是尾数,它能表示256位的数值。一个区块头的SHA256值必定要小于或等于目标HASH值,该区块才能被网络所接受,目标HASH越低,产生一个新区块的难度越大。

用特殊的格式用一个4字节的Bit来描述32字节的难度字符串。

上述大部分数据项对所有用户是一致的,可能在时间戳上有些区别。(译者按:该段的以下内容来自:)如果当前区块的时间戳大于前11个区块的的平均时间戳,并且小于“网络调整时间(Network-Adjusted Time)”+2小时,则认为该时间戳是有效的。其中的“网络调整时间”是指与你相连接的所有节点的平均时间。当节点A连接到节点B时,A从B处得到一个UTC标准的时间戳,A先转换成本地UTC标准时间保存起来,网络调整时间等于所有节点的本地UTC时间+所有相连节点的偏移量平均值,然而,该网络时间永远不会调整到超过本地系统时间70分钟以上。

时间戳确实是有用的,不能乱写时间。

Nonce随机数通常不同,但是它以严格的线性方式增长,从0开始,每次HASH时都会增长,当Nonce溢出时(此事经常发生),生产交易的extraNonce项会增长,将改变Merkle树的根节点。

extraNonce有人认为会占用默克尔树的根,也有人认为会占用coinbase

A solo miner increments Nonce until it overflows. Then it increments extraNonce and resets Nonce. extraNonce is located in the coinbase transaction, so changing it alters the Merkle root. extraNonce is reset based on the time.

nonce的增长过程请看接下来的解谜过程详解。

  • 解谜过程详解:

可以在这个字符串后面添加一个整数值(在比特币中为nonce的标记),对变更后的字符串进行SHA256哈希运算,如果得到的哈希结果(以16进制的形式表示)是以”0000”开头的,则验证通过。为了达到这个工作量证明的目标。我们需要不停的递增值,对得到的新字符串进行SHA256哈希运算。按照这个规则,我们预计需要经过4251次计算才能找到恰好前4位为0的哈希散列。

“Hello, world!0” => 1312af178c253f84028d480a6adc1e25e81caa44c749ec81976192e2ec934c64
“Hello, world!1” => e9afc424b79e4f6ab42d99c81156d3a17228d6e1eef4139be78e948a9332a7d8
“Hello, world!2” => ae37343a357a8297591625e7134cbea22f5928be8ca2a32aa475cf05fd4266b7

“Hello, world!4248” => 6e110d98b388e77e9c6f042ac6b497cec46660deef75a55ebc7cfdf65cc0b965
“Hello, world!4249” => c004190b822f1669cac8dc37e761cb73652e7832fb814565702245cf26ebb9e6
“Hello, world!4250” => 0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9

比特币使用双重散列区块头:SHA256(SHA256(区块头))计算HASH,但你要注意字节序。这也就是其他客户端节点验算区块的过程。

例如:以下python代码用于计算某一区块的HASH值,使用2011年6月的区块号125552的最小HASH值。该区块头建立上述6个数据项之上,并且以十六进制的小端结尾方式连接在一起。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>>> import hashlib

>>> header_hex = (“01000000″ +

“81cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000″ +

“e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122b” +

“c7f5d74d” +

“f2b9441a” +

“42a14695″)

>>> header_bin = header_hex.decode(‘hex’)

>>> hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()

>>> hash.encode(‘hex_codec’)

’1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e0000000000000000′

>>> hash[::-1].encode(‘hex_codec’)

’00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d’

  • 比特币是一个附带脚本的货币,也就意味着,汇款可以有附录。这个附录启发了智能合约区块链的诞生:

正如我们所见,每个比特币交易里都有一段比特币脚本语言。这个脚本在这篇文章里被简化成了类似于这样的话 “我Alice要给Bob 10个比特币”。 但是这个脚本语言可以同时被用来表述更复杂的交易。换句话说,比特币是一个可编程的货币。

  • 挖矿硬件的演变:最开始的CPU挖矿,过度到GPU挖矿,最终演化到当前的ASIC(专业矿机)。目前为止,诞生了两种矿池协议:

参考文献:

  1. https://zhuanlan.zhihu.com/p/33114775
  2. http://www.8btc.com/bitcoin-transactions
  3. https://zhuanlan.zhihu.com/p/23558268
  4. http://www.8btc.com/blockchain-tech-mining