区块链 - 比特币开发指南

原文链接: https://bitcoin.org/en/developer-guide#block-chain
翻译:terryc007
版本: 1.0


比特币开发指南

1. 区块链

2. 交易

3.合约

4.钱包

5.支付处理

6.工作模式

7.P2P网络

8.挖矿


比特币开发指南主要是为你提供一些必要的信息,方面你理解比特币,以及基于比特币来开发一些应用程序。 但它并不是关于比特币的说明书。 为了更好的使用本开发指南,你可以安装当前比特币核内核源码,或者编译好的比特币内核客户端

有关比特币开发的问题,最好去比特币开发社区提问。 在Bitcoin.org上,有关文档的错误或建议,可作为一个问题提交,或在比特币文档邮件列表发贴。

在下面的开发文档,有一些文字会被省略或隐藏起来: "[…]" 表示额外的数据已被删掉,行尾带有""符号,表示下面部分还是该行内容。如果你移动鼠标停在段落时,带有交叉引用链接的文字会变成蓝色。如果你把鼠标停在带有交叉引用链接的术语上,会显示这个术语的简要提示信息。

区块链

区块链提供了比特币公共账簿,里面包含了有序的,带有时间戳的交易记录。区块链系统被用来防止双发,防止之前的交易记录被篡改。

在比特币网络,每个全节点,各自独立的保存了一份区块链,该区块链中包含仅由自己验证的区块数据。当节点的区块链中,都有相同的区块时,他们被认为有一致的共识。这些被用节点来维持共识的验证规则叫做共识规则。 本节会介绍很多在比特币内核中用到共识规则

区块链概要

上面的插图是个简易版区块链。一条或多条新的交易记录被收集到区块中,用于存放交易数据的地方。为每条交易生成哈希值,然后哈希值两两配对,再生成哈希值, 然后再对之前的生成的哈希值两两配对,再生成哈希,直到只剩下一个哈希值,最后这个哈希值就是默克树根。

默克尔树根被存放在区块头。每个区块会存放前一个区块头的哈希值,这样把所有的区块串联起来,便成了区块链。 这就保证了,在不修改交易所在的区块,以及该区块后续所有区块前提下,交易是不能被篡改的。

交易记录也会被串联在一起。比特币钱包给我们一个直观的印象是:satoshis(比特币最少的单位 1btc = 100,000,000 satoshis)在钱包之间来回发送,但实际上比特币是从一个交易到另外一个交易的转移。 每个交易会花之前一个或多个交易的satoshis,所以一个交易的输入就是前一个交易的输出

一个交易可以创建多个输出,就如同当发送到多个地址,但在区块链中,每个特定的交易输出只能被交易输入使用一次。任何后续的引用都是一个禁止的双发 — 试图使用两次satoshis

交易输出会跟交易id(TXIDS)绑定在一起,所谓的交易id就是交易的哈希值。

因为每个特定交易的输出只能被使用一次,区块链中所有的交易的输出可以被归类为: 未使用交易输出(UTXOs)或者 发费交易输出。对于一个有效的支付,它必须且只能使用UTXOs作为输入。

coinbase类型交易(区块中的第一个交易,通常被矿工创建,用来认领挖矿奖励,以及提供100个字节的空间,可存放任何数据)外,如果一个交易的输出值大于它的输入值,交易将会被拒绝。 但是如果交易输入值大于交易输出值,其中的差额就是交易费用,用于支付比特币矿工(他们负责创建包含交易的区块)。比如,在上面的图示中,每个交易交易费用少于交易输入总和,实际上支付了10000 satoshis。

工作量证明

网络中的匿名节点一起协作来维持区块链,因此比特币在创建区块时,需要一个有效数量的工作证明,以确保试图修改历史区块的不可信节点,比起可信的节点付出更多的工作量。

把区块串联起来,在不修改当前区块以及后续所有区块情况下,使得修改任何区块中的交易变的不可能。因此,每增加一个新的区块到区块链上,就会增加修改一个特定区块的成本,也就放大了工作量证明的效果。

比特币中使用的工作量证明利用了密码学哈希中的自然随机。一个好的加密哈希算法可把任意数据转化成看似随机的数字。如果数据修改,不管任何方式,当重新计算数据的哈希值时,会产生一个新的随机数,因此没有任何方法在修改数据之后,可以预测其哈希值。

为了证明你为创建区块而做了一些工作,你必须生成一个区块头的哈希值,该哈希值不能超过一个特定的值。比如,如果最大的哈希值是2256-1 , 你可通过生成一个小于2255的哈希值来证明你尝试了两种组合。[?]

在上面的例子中,你生成一个符合要求的哈希值所做的每次尝试在概率上是相同的。 甚至可以估算出一次哈希计算尝试能生成一个小于特哈希值的概率。比特币采用的是线性概率 , 即哈希目标值越小,就需要越多的哈希计算尝试。

新区块只有其生成的哈希值,符合共识协议所预期的难度值,才能被加入到区块链中。 每2016个区块,比特币网络使用保存在区块头中的时间戳,来计算从生成第一个区块到第2016个区块所经历的时间(秒)。这实际的值是 1209600秒(两个星期)。

  • 如果生成2016个区块所用的时间少于2个星期,那么生成下2016个区块时,在同一算力的情况下,为保证2016个区块生成所需的时间,恰好是2个星期,那么预期的难度值会按比例提升(差不多300%)。

  • 如果生成2016个区块所用的时间多于2个星期,同理,其预期难度会按比例下调(大约75%)。

(注意:在比特币内核实现中,一个单个偏移的错误导致难度的更新从仅需2015个区块变成了2016个区块,这了导致了一点偏移)[?]。

因为每个区块头在生成哈希值时,必须要小于目标阀值,同时每个区块要跟它之前的区块链接起来,要在整个比特币网络中广播修改过的区块,平均上讲,它就需要消耗:从被修改的区块其创建时间起,到当前时间之间所有区块需要的算力。 只有你掌握了大量的哈希算力,你才能可靠的执行51算力攻击(然而需要注意的是,即使是低于50%的哈希算力, 也是有可能成功的实施这样的攻击)。

区块头提供了好几个易于修改的字段,比如一个专用的临时字段,这样可以在不需要等待新的交易,就可以获得新的哈希值。[?] 同样,用于工作量证明时,只需对只有80个字节的区块头计算哈希值就可以,所以在区块中大量的交易数据并不会降低计算哈希值的速度,而只是增加了一些额外的交易数据,需要重新计算默克树中的父节点哈希值。

区块高度和分叉

任何比特币矿工可以把整个区块加入到区块链中,只要它生成的区块头哈希值低于目标阀值。这些区块通过区块高度来寻址。所谓的区块高度 - 指的是当前区块到第一个比特币区块(通常也叫创世块)之间区块的个数。比如,区块高度为2016的区块,就是第一次难度调节后的区块。

多个区块可以同时有相同的区块高度,因为当二个或多个矿工在同一时间产出一个区块是很常见的。这会在区块链创建一个明显的分叉,如下图所示。

当矿工在区块链末端同时产出多个区块时,每个节点会各自接受区块。在不考虑其他节点的情况下,节点通常会选择他们第一次看到的区块,下面我们会讨论。

最终,每个矿工会产出另外一个区块,它会被添加到具有并发竞争挖取的区块链中[?]。这使得分叉链比其他侧链难度更大。假如一个分叉仅包含有效的区块,普通的节点通常会基于难度最大的链进行重建区块链,同时会剔除掉属于较短链上的陈腐区块(有时候也叫孤块,但是孤块,也用来表示那些没有父区块的区块。)。

陈腐区块

就是那些不在难度最大的区块链上,而在其他分叉侧链上的区块,有时候也叫孤块,但是也指那些还没有被本地节点处理的,没有父区块的区块。

很长的分叉是有可能的。 比如不同的矿工为不同的目的而工作,比如一些矿工勤恳的扩展区块链,同时,其他的矿工企图通过实施51%算力攻击修改交易记录。

在一个分叉链上,因为多个区块可能其区块高度是一样的,因此,区块高度不能用于全局唯一标识。而是,通过区块的区块头的哈希值(16进制,反字节序)来引用区块。

交易数据

每个区块必须包含一个,或多个交易。第一个交易必须是coinbase交易。也叫创世交易。它用来接收,消费区块奖励(包括挖出一个区块的补贴,以及该区块内所有交易支付的交易费用)。

创世交易的UTXO有一个特定的条款,就是少于100个区块确认,它是不能被发掉的(即不能做为其他交易的输入)。这可暂时防止矿工发掉从区块获取的区块奖励,因为在一个分叉的链上,矿工挖出的区块有可能以后被认定为是孤块。

区块并不要求包含任何非coinbase交易,但是矿工为了获得他们的交易费用,他们几乎总是会往区块中加一些额外的交易。

所以的交易,包括coinbase交易,会以二进制源交易[?]格式编码存储到区块中。

通过对源交易格式进行哈希来生成交易id(txid). 对于这些交易id,通过对txid两两配对,让后对他们进行哈希计算,来构建默克尔树。如果是个奇数个交易id,则跟自己配对来实现两两配对,再进行哈希计算。

这些哈希计算结果(即哈希值)让后又两两配对,再计算哈希值。任何哈希值如果没有配对的,就跟自己配对,再计算哈希值。这个过程会不断的重复,直到只剩下一个哈希值。这个值就是默克树根。

比如,如果交易不做哈希处理,那么5个交易的默克尔树看起来如下图所示:

 ABCDEEEE .......Merkle root
        /        \
     ABCD        EEEE
    /    \      /
   AB    CD    EE .......E is paired with itself
  /  \  /  \  /
  A  B  C  D  E .........Transactions

如简化支付认证(SPV)段落中所讨论的,通过区块头中的默克尔树根,以及从一个全节点中获取的,一个中间哈希值列表[?],默克尔树允许客户端根自己验证一个交易是否在一个区块中。全节点不必是可信的,因为伪造区块头的成本很高,同时中间哈希值列表是不能伪造的,否则验证会失败。

比如,要验证交易D是否已被加入区块中,一个SPV客户端仅需要交易C,AB,EEEE的哈希值,以及区块的默克尔树根;客户端不需要知道其他任何交易。在这个区块中,假如按这个5个交易所占最大的大小来算,下载这整个区块需要大约500,000字节 - 但是下载3个哈希值,再加上区块头仅需要140字节。

注意: 如果在同一个区块中发现相同的交易id,默克尔树可能会跟区块发生冲突, 会导致一些或者全部交易id被删掉去,这取决于非平衡默克尔树[?]是如何实现的(复制孤立的哈希值)。 因为不同交易有相同的交易id是不可能的,这对于那些忠实的软件不是一个负担,但是如果一个区块的无效状态被缓存,那么必须要对该区块进行检查;否则,一个去除重复交易id的有效区块本可以有相同的默克尔树根,区块哈希值,但因缓存的无效的区块状态,会导致安全bug(比如)CVE-2012-2459, 而使得区块被拒绝掉。

共识规则改变

为维持共识,所以的全节点使用同样的共识规则来验证区块。然而,有时候为了引进新的功能以防止比特币网的滥用,就需要对共识规则进行改变。当新的共识规则被实施后,非升级节点会继续遵循久的共识规则,升级节点遵循新的共识规则,这种情况可能会持续一段时间,这样会导致两种不同的共识。

  1. 遵循新共识规则的区块被升级节点接受,但非升级节点会拒绝接受。比如,一个的交易功能在被区块使用: 升级节点知道这个功能并接受它,而非升级节点因其他违反老的共识规则而拒绝接受它。

  2. 违反新的共识规则的区块被升级节点拒绝,但被非升级节点接受。比如,一个滥用的交易功能在区块中使用:升级节点会拒绝它,因为它违反了新的共识规则,而非升级节点则接受它,因为它遵守了老的共识规则。

在第一种情况,非升级节点拒绝接受,那些从非升级节点获取区块数据的挖矿软件,拒绝构建跟那些从升级节点获取区块数据的挖矿软件同样的区块链。这会创建永久的分叉 — 一个非升级节点所在的链,一个升级节点所在的链 — 这也叫做硬分叉。

在第二种情况,区块被升级节点拒绝接受,如果升级节点控制了绝大部分哈希算力,那么避免硬分叉是有可能的。这是因为,在这种情况,非升级节点会接受所有升级节点中有效的区块,因此升级节点能构建更为健壮的区块链,而非升级节点会接受这条链是最好的有效链。 这叫做软分叉

虽然分叉在区块链中是一个真实的分歧,但是修改共识规则通常使用创建一个硬分叉或软分叉来描述。比如,“增加区块大小到1MB以上需要一个硬分叉”,在这个例子中,是个实际的区块链分叉是不需要的 — 但是这是一个可能的方案。

共识规则的改变可以通过各种方式来激活。在比特币的头两年,中本聪就通过执行过好几次软分叉,他通过发布向后兼容的共识规则更改的客户端,使得这些客户端立即执行新的共识规则。很多的软分叉,如BIP30 ,是通过一个标志日期来激活。就是说新的共识规则在预定的时间或者区块高度被强制激活。像这种通过标志日期来激活的分叉被称之为用户激活软分叉(UASF)。因为在标志日期后,这些分叉要依赖一些有效的用户(节点)去执行新的共识规则。

后来,软叉需要等待大部分哈希算力(通常75%或95%)发出他们已准备好执行新的共识规则的信号。一旦超过所需信号的阈值,所以的节点就会执行新的共识规则。这样的分叉被称之为矿工激活软分叉(MASF),因为分叉依赖矿工去激活。

资源: BIP16, BIP30, BIP34 是通过共识规则的改变来实施的,导致了软分叉。 BIP50 导致了一个意外的硬分叉,后来通过临时降级升级节点的能力,以及当临时的降级被移除后,通过一个有意的硬分叉来解决这个问题。这有一个来自Gavin Andresen,有关未来共识规则改变如何实施的文档。

检测分叉

在上面两种分叉中,非升级节点可以使用,发送不正确的信息,会创建好几个情况导致财产损失。实际上,非升级节点可以转发,接受那些被升级节点认为无效的交易。这些交易永远不会成为全局公认的最佳区块链中的一部分。非升级节点也可以拒绝转发那些已经添加,或即将添加到最佳区块链中的区块,交易,这样就可以提供不完整的信息。

比特币内核里有通过查看区块链工作量证明实现检测硬分叉的代码。如果非升级节点收到一些区块头,这些区块头里面至少有6个区块可以证明,新区块所在的区块链的工作量,比起该节点认为的最佳区块链上的工作量还要多的话,则该节点会在getnetworkinfo RPC结果中报告一个警告,同时,会运行 -alertnotify 命令,如果有设置的话。这会警告运营者非升级节点不能切换到很有可能是最佳的区块链上。

全节点也能检查区块,交易的版本号。如果最近的区块的区块版本号或交易版本号,比改节点用的区块的版本号要高,它就会认为它没有使用当前的共识规则。比特币内核会通过getnetworkinfo RPC 来报告这个情况,以及运行-alertnotify命令,如果有设置的话。

不论哪种情况,如果区块,交易数据明显来自一个没有使用当前共识协议的节点,区块,交易数据就不应该被转发。

SPV客户端会跟全节点链接起来,通过链接多个全节点,同时保证这些全节点在同一区块链的同一个区块高度,考虑到交易延迟,陈腐区块,可加或减掉几个区块,就可以检测可能的硬分叉。如果有分叉,SPV客户端可以断掉那些在更弱链上节点间的连接。

SPV客户端也应监控区块,交易版本号的增加,这样可以保证SPV客户端去处理接收到的交易,并使用新的共识规则创建新的交易。


声明:

文中带有[?]的地方,表示我对此翻译明显感觉不太对的,后续会不断修正。

初次翻译,可能会有些地方翻译的不好,不地道,甚至错误,如果有发现,还请留言,指出,以便我好修正,谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容