区块链 Block Chain
区块链提供了比特币的公开总账本, 这个总账本由所有有时序的已确定的交易组成。这个系统被用于防止双花和修改以前的交易记录, 通过被全球P2P网络验证的 工作量证明POW 来保证全球的一致性.
区块链概览
上面的插图展示了一个简化版本的区块链. 一个包含一个或者多个交易的区块 会被收集到区块的交易数据部分. 每个交易的副本都会被哈希,然后将哈希值进行配对,然后再进行哈希,再配对,再哈系,直到只剩下一个哈希值,这个剩下的哈希值就是 Merkle tree(Merkle 树)的Merkle root(根节点)。
Merkle根节点 被存储在 区块头. 每个区块 也会存储上一个区块头的哈希值, 以把所有的区块链接在一起. 这保证了在不修改当前和后面的所有区块的情况下,交易记录是不会被修改的。
交易记录也被链接在一起。比特币钱包 软件只记录了比特币的发送接收, 但比特币确实在交易间转移。 每个标准交易花费的satoshis 是前一个交易转移过来的币, 所以一个交易的输入是上一个交易的输出。
单个比特币交易能把比特币 发送到不同的输出中, 就像你把比特币一次发送到不同的地址一样,但是一次输出在区块链中只能使用一次 所有的后续引用都禁止双花—一种把比特币花两次的尝试。
输出不同于比特币 地址。你可以在多个交易中使用同一个地址, 但是输出 只能被使用一次。输出 与交易id(TXIDs)绑定, txid就是签名交易的哈希值
因为每个交易的输出只能被使用一次, 所有在区块链 中的输出能被分类为未使用交易输出Unspent Transaction Outputs (UTXOs) 或者已使用输出. 为了让支付有效, 必须使用 未使用输出UTXOs 来作为输入.
比特币在产生交易之后,不能留在UTXO中, 否则这个余额会永久的丢失掉, 所以输入和输出之间的差值就是交易费,都是对把这个交易打包到区块的矿工的奖励。例如,在上面的插图中,每次交易收到的都比发出的会少1000聪, 这10000聪就是交易费
Proof Of Work 工作量证明
区块链 是由P2P网络(peer-to-peer network)协作维护的, 比特币网络要求在创建区块的时候要提供一定的工作量证明,以保证那些想改变历史区块的不诚实的节点必须付出比那些仅仅想在链上加一个新区块的诚实节点更多的资源。
如果不修改后面所有的区块,修改已经打包到区块中的交易成为一件不可能的事情,这也是把区块链接到一起的用处。 因此,修改一个区块的费用会随着新区块的增加而增加,工作量证明的作用也就随之变大。
比特币网络中的工作量证明利用了密码学哈希算法的伪随机性。一个好的密码学哈希可以把任意的数据转换成一个看起来随机的数字。如果这个原始数据的任何地方被更改,然后重新计算哈希,将会生成一个完全不同的新的哈希结果。所以修改数据以预知哈希的结果是不可能的。
为了证明你已经做了一些创建区块的工作,你需要计算出一个不大于某个特定值的块头的哈希值。举个例子: 如果这个最大哈希值是2256 − 1,你只要证明你做了两次组合就可以使哈希值小于2256 − 1。
在上面的例子中,你很有可能在第一次尝试的时候就生成了一个成功的哈希值。你甚至可以估算你要达到的某个阈值所需要的尝试的次数。比特币本身并不能控制这个可能性,但是单纯假设这个阈值越小需要尝试的次数越多,平均下来也就是个平均数(这个是概率平均)。
只有当哈系值至少跟P2P网络预期的难度值难度相当的时候,新的区块才会被加到区块链上。比特币网络使用储存在2016个区块头的时间戳的差值来计算下一轮的难度。这个差值的理想的间隔是1,209,600秒(两周)。
• 如果产生2016个区块的时间小于两周,预期的难度将成比例地提高(大约300%)以便于下一个块能够准确地在两周生成,前提是保证在当前的HASH在同一算力.
• 如果产生2016个块的时间超过两周,同样地,预期难度将降低(75%左右)。
(注意: 比特币内核实现的一个差一错误,导致每到2016区块的时候,因为使用了第2015块的时间戳,难度就会更新,这导致了轻微的偏差。
由于每一块头的哈希值必须小于某个阈值,每一区块也必须链接到它前面的一个区块。要在原始区块生成到当前这段时间里传送一个已修改的区块,(一般来说)需要消耗和整个比特币网络消耗的算力一样多的哈系算力。只有你掌握了全网大多数哈希算力,你才能有效地实现对交易历史进行51%的攻击。
区块头提供了一些容易改的字段,例如dedicated nonce field,所以获取新块的哈希不需要等新的交易的到来。同样,只有80字节的区块头会被计算到POW的哈希中,因此添加更多的交易信息不会降低伴有额外I/O的哈希计算速度.
Block Height And Forking
区块高度及分叉
任何成功计算出小于阈值的哈系值的矿工可以把整个区块加到区块链中(假设这个区块是有效的)。这些区块被标记为当前区块的高度--就是当前区块到第一个块(genesis block)的差值. 比如,第2016块是第一个调整难度的块。
多个区块可以有同样的区块高度,这在两个或两个以上的矿工几乎在同一时间创建了一个区块的情况下是很常见的。正如上图所示,区块链上出现了显然的分叉。
当矿工同时在区块链的末端生成区块的时候,每个节点都独立地选择相信哪个区块。(在没有其他考虑的情况下,节点通常选择相信他们接收到的第一个块)。
最终,矿工会创建一个新块,这个区块附在其中一个竞争的并行区块。这会使这个分支比别的分支更长。假设一个分支只包括有效的区块,正常的节点将选择最长的那个分支(最难创建的一个链),然后抛弃比它短的分支。
长期的分叉是可能的,如果这些矿工有其他意图,比如一些矿工在分叉之后的一条分支上奋力计算,尝试51%攻击去修改交易历史。
由于很多区块在分叉的时候会有同样的高度,所以高度不能作为唯一的区分。通常,都用它的SHA256的哈希值来表示这个区块。
Transaction Data
每个区块必须包含一个或者多个交易记录,第一个交易记录必须是coinbase(币基)记录,这个记录包含了区块奖励和本区块的所有的交易费。
由挖矿出来的币有一个特殊的使用条件,就是在此后的100块只能不能使用。这个可以部分防止有的矿工花费可能以后被抛弃的区块奖励(分叉之后,这个矿工的这条链被抛弃)。
区块不是必须包含所有的非-coinbase的交易,但是矿工们通常会为了他们的交易费把这些交易记录给收录进来。
所有的交易记录,包含coinbase记录,会在前面加上交易队列的编报,并被编码为rawtransaction格式的二进制进行存储。
rawtransaction 格式是由txid哈希而来. 这些txids组成了一个Merkle树。Merkle树是一个层级hash树,如果叶节点有两个叶子,节点的值就是这两个值的哈希,如果叶节点只有一个节点,节点的值就是这一个叶节点的哈希值。
如果有并排节点的,就和并排节点一起哈希;所有没有并排节点的节点都自己计算哈希,这样一层一层计算,就计算出Merkle根节点的哈希。
举个例子,这些节点仅仅是组合在一起(并未计算哈希), 五层的交易记录Merkle 树就是像下图这样
ABCDEEEE .......Merkle root / \ ABCD EEEE / \ / AB CD EE .......E is paired with itself / \ / \ / A B C D E .........Transactions
在简单支付验证(SPV)部分,这个Merkle树允许客户端验证他们的在某个块中的交易记录,通过从Merkle根节点进行遍历。所有的节点不用被信任:在区块头作假是一件很昂贵的事情,中间的哈希结果不能被伪造,否则这个认证将失败。
举个例子, 为了证明D交易被添加到这个区块中,一个SPV客户端只需要拷贝C、AB和EEEE 哈希到Merkle根节点;客户端不需要知道其他的交易的任何信息。如果这5个交易都达到了最大的大小,下载整个区块将需要500,0000 字节,但是下载这3个哈希值加上头部只需要140字节。