BTC devguide(1)

Block Chain

区块链系统提供了公共分类帐,有序且带有时间戳记的交易记录。 该系统用于防止重复支出和修改以前的交易记录。

Introduction

比特币 网络 中的每个完整节点都独立存储一个区块链,其中仅包含该节点验证的区块。 当几个节点的块链中都具有相同的块时,它们被认为是一致的。 这些节点遵循以维持共识的验证规则称为 共识规则 。 本节描述了比特币核心使用的许多共识规则。

上图显示了区块链的简化版本。 一个或多个新事务的块被收集到一个块的事务数据部分中。 将每个事务的副本进行哈希处理,然后对哈希进行配对,哈希处理,再次配对和再次哈希处理,直到剩下一个哈希(即默克尔树的默克尔根)为止。

merkle根存储在块标题中。 每个块还存储前一个块头的哈希,将这些块链接在一起。 这样可确保在不修改记录该记录的块以及所有后续块的情况下,无法修改该事务。

交易也被链接在一起。 比特币钱包软件给人的印象是,satoshis是在钱包之间来回发送的,但是比特币真正地在交易之间转移。 每笔交易都花费了先前在一个或多个更早的交易中接收到的satoshis,因此一个交易的输入就是前一个交易的输出

单个交易可以创建多个输出,就像发送到多个地址时一样,但是特定事务的每个输出只能在块链中用作一次输入。 随后的任何参考都是禁止重复支出-尝试两次将相同的satoshis花费两次。

由于特定交易的每个输出只能使用一次,因此可以将包含在区块链中的所有交易的输出分类为未花费的交易输出(UTXO)或已花费的交易输出。 为了使付款有效,它只能使用UTXO作为输入。

忽略币基交易(稍后描述),如果交易的输出值超过其输入,则交易将被拒绝;但是,如果输入的值超过输出的值,则任何价值差均可被比特币要求为交易费。 创建包含该交易的区块的矿工。 例如,在上图中,每笔交易比从合并输入中获得的支出少10,000聪,有效地支付了10,000聪交易费用

Proof of Work

区块链由网络上的匿名对等方协作维护,因此比特币要求每个区块都证明在其创建上投入了大量工作,以确保想要修改过去区块的不可信对等方比仅对诚实对等方更努力。 想要向区块链添加新的区块。

将块链接在一起使得无法修改任何块中包含的事务而不修改所有后续块。 结果,每增加一个新块,修改特定块的成本就会增加,从而扩大了工作量证明的效果。

比特币中使用的工作量证明充分利用了加密散列的明显随机性。 好的加密哈希算法可将任意数据转换为看似随机的数字。 如果以任何方式修改了数据并重新运行了哈希,则会生成一个新的看似随机数,因此无法修改数据以使哈希数可预测。

为了证明您做了一些额外的工作来创建一个块,您必须创建一个不超过特定值的块头哈希。 例如,如果最大可能的哈希值是2256 -1,则可以通过产生小于2255的哈希值来证明尝试了两种组合。

在上面给出的示例中,平均每隔尝试一次,您将产生一个成功的哈希。 您甚至可以估计给定哈希尝试将生成低于目标阈值的数字的可能性。 比特币假设线性概率使得达到目标阈值的水平越低,则平均需要进行的哈希尝试越多。

如果新块的哈希值至少与共识协议预期的难度值一样具有挑战性,则仅将其添加到块链中。 网络每隔2016个块,将使用存储在每个块头中的时间戳来计算生成最后2016个块中的第一个和最后一个之间所经过的秒数。 理想值为1,209,600秒(两周)。

  • 如果花费不到两周的时间来生成2,016块,则预期的难度值将成比例地增加(多达300%),因此,如果以相同的速率检查哈希,则接下来的2,016块应该恰好花费两周的时间来生成。

  • 如果花了两周以上的时间来生成区块,则出于相同的原因,预期的难度值将成比例地降低(降低多达75%)。

(注意:Bitcoin Core实施中的一次性错误会导致使用时间戳(仅2,015个块)来每2,016个块更新一次难度,从而造成轻微的偏差。)

区块标头提供了几个易于修改的字段,例如专用的随机数字段,因此获取新的哈希值不需要等待新的交易。 此外,仅散列80字节的块头以进行工作量证明,因此在块中包含大量事务数据不会减慢具有额外I / O的散列,并且添加其他事务数据仅需要重新计算 merkle树中的祖先哈希。

Block Height And Forking

任何成功将区块头散列到目标阈值以下的比特币矿工都可以将整个区块添加到区块链中(假设该区块是有效的)。 这些块通常通过其块高度来解决-它们与第一个比特币块之间的块数(块0,最通常称为创世块)。 例如,方框2016是可以首先调整难度的位置。

多个块都可以具有相同的块高度,这是两个或多个矿工各自大致同时生产一个块时的常见现象。 如上图所示,这会在区块链中创建一个明显的分叉。

当矿工在区块链的末端同时生产区块时,每个节点都会分别选择要接受的区块。 在没有其他考虑的情况下(如下所述),节点通常使用它们看到的第一个块。

最终,一个矿工生产了另一个块,该块仅附着在竞争的同时开采的一个块上。 这使叉子的那一侧比另一侧更坚固。 假设一个分叉仅包含有效块,普通对等方总是遵循最困难的链来重新创建并丢弃属于较短分叉的陈旧块。 (过时的块有时也称为孤立块或孤立块,但这些术语也用于没有已知父块的真实孤立块。)

如果不同的矿工可以跨部门工作,则可以进行长期分叉,例如,一些矿工努力工作以扩展区块链,而其他矿工则试图发起51%的攻击来修改交易历史。

由于在块链叉期间多个块可以具有相同的高度,因此不应将块高度用作全局唯一标识符。 取而代之的是,块通常由其标题的哈希引用(通常以相反的字节顺序并以十六进制表示)。

Transaction Data

每个区块必须包含一个或多个交易。 这些交易中的第一个必须是coinbase交易,也称为generation交易,该交易应收集并使用大宗交易奖励(包括大宗交易补贴和该大宗交易中所含交易支付的任何交易费用)。

Coinbase交易的UTXO具有特殊条件,即至少100个块不能花费(用作输入)。 这暂时阻止了矿工在区块链分叉之后花费交易费用和来自某个区块的区块奖励,该区块后来被确定为陈旧(因此销毁了coinbase交易)。

区块不需要包含任何非Coinbase交易,但是矿工几乎总是包含其他交易以收取交易费用。

所有交易,包括coinbase交易,都以二进制原始交易格式编码为块。

原始交易格式被散列以创建交易标识符(txid)。 根据这些txid,通过将每个txid与另一个txid配对,然后将它们散列在一起,来构建merkle树。 如果txid的数量为奇数,则不带伙伴的txid将以其自身的副本进行哈希处理。

产生的散列本身各自与另一个散列配对并散列在一起。 没有伙伴的任何哈希都将自身哈希。 重复该过程,直到仅保留一个散列(merkle根)为止。

例如,如果仅连接事务(不进行哈希处理),则five-transaction merkle树将类似于以下文本图:

如简化付款验证(SPV)小节中所述,merkle树允许客户通过从区块头获取merkle根以及从完整对等方获得中间哈希的列表,来自己验证交易是否包含在区块中。 完整的对等点不需要被信任:伪造块头是昂贵的,并且中间的哈希不能被伪造,否则验证将失败。

例如,要验证是否已将交易D添加到块中,SPV客户端除了需要添加Merkle根以外,还仅需要C,AB和EEEE哈希的副本。 客户不需要了解其他任何交易。 如果此块中的五个事务全部达到最大大小,则下载整个块将需要超过500,000字节-但是下载三个散列和块头仅需要140字节。

Consensus Rule Changes

为了保持共识,所有完整节点都使用相同的共识规则来验证块。 但是,有时会更改共识规则以引入新功能或防止网络滥用。 实施新规则后,未升级的节点将遵循旧规则,而升级后的节点将遵循新规则,这可能会产生一段时间,从而形成可能破坏共识的两种方式:

  • A block following the new consensus rules is accepted by upgraded nodes but rejected by non-upgraded nodes. For example, a new transaction feature is used within a block: upgraded nodes understand the feature and accept it, but non-upgraded nodes reject it because it violates the old rules

  • A block violating the new consensus rules is rejected by upgraded nodes but accepted by non-upgraded nodes. For example, an abusive transaction feature is used within a block: upgraded nodes reject it because it violates the new rules, but non-upgraded nodes accept it because it follows the old rules.

在第一种情况下,被未升级的节点拒绝,从那些未升级的节点获取块链数据的挖掘软件拒绝与从升级的节点获取数据的挖掘软件在同一链上构建。 这将创建永久性的分歧链(一个用于非升级节点,一个用于升级节点),称为hard fork。

尽管分叉实际上是区块链中的分歧,但是共识规则的更改通常通过其创建硬分叉或软分叉的潜力来描述。 例如,“将块大小增加到1 MB以上需要硬分叉。” 在此示例中,不需要实际的区块链分叉,但这是可能的结果。

Detecting Forks

未升级的节点可能会在两种类型的分叉期间使用和分发不正确的信息,从而造成可能导致财务损失的多种情况。 特别是,未升级的节点可能会中继并接受被升级的节点视为无效的交易,因此永远不会成为公认的最佳区块链的一部分。 未升级的节点也可能拒绝中继已经添加到最佳区块链或将很快添加到最佳区块链的区块或事务,因此提供的信息不完整。

Bitcoin Core包含通过查看区块链工作证明来检测硬分叉的代码。 如果未升级的节点接收到的块链头比其认为有效的最佳链至少证明了六个块的工作量证明,则该节点将在“ getnetworkinfo” RPC结果中报告警告,并运行-alertnotify命令(如果设置)。 这会警告操作员,未升级的节点无法切换到可能最好的区块链。

完整节点还可以检查区块和交易版本号。 如果最近几个区块中看到的区块或交易版本号高于节点使用的版本号,则可以假定它未使用当前的共识规则。 Bitcoin Core通过“ getnetworkinfo” RPC和-alertnotify命令(如果设置)报告这种情况。

无论哪种情况,如果区块和交易数据来自显然没有使用当前共识规则的节点,都不应依赖该数据。

连接到完整节点的SPV客户端可以通过连接到多个完整节点并确保它们全部位于同一链上且具有相同的块高(加上或减去几个块)来考虑传输延迟和陈旧的块,从而检测出可能的硬分叉。 如果存在分歧,客户端可以从链数较弱的节点断开连接。

SPV客户还应该监视阻止和交易版本号的增加,以确保他们处理接收到的交易并使用当前的共识规则创建新的交易。