比特币开发者指南(一)--- 区块链

申明:本文为译文,原文档地址为官网

开发者指南旨在提供有助于理解比特币以及开始构建比特币应用所需的应用程序所需的信息,但这不是规格说明。为了最有效的利用此文档,你可能想要安装最新的比特币客户端(Bitcoin-Core,可以从源代码直接构建或者下载预编译版本)。

有关于比特币开发的问题最好到比特币开发社区里面提问。此文档(Bitcoin.org上的)的错误或者疑问可以提交到比特币文档的邮件列表里。

区块链

区块链提供了比特币的公开账簿---一个有序的、带有时间戳的交易记录。这个系统被用来防止双重消费和篡改交易记录的问题。

比特币网络中的每一个全结点都会存储一个整个区块链的备份,其中每个块都经过了验证。当一些结点拥有同样的区块时,它们被称之为达成了“一致”。本节描述比特币使用的一些一致性规则

区块链概览


上面的图展示了一个区块链的简化版本。一个或多个交易信息被收集到了区块的交易部分。交易信息通过默克尔树的形式组织起来,默克尔树的树根被存储到了区块的头部中。区块头部中还存储了前面一个块的哈希,这样就可以将区块连接成一个有序的串。这样就可以保证一个若要修改一个交易信息,不但要修改当前块,而且要修改当前块之后的所有块。

交易通过区块,也形成了一个隐形的串。比特币钱包软件存储了发送到或者从钱包中发出的‘’(比特币的单位),这里虽然从用户角度来看‘聪’是从一个一个用户转移到了另一个用户,但是比特币的‘聪’实际上是从一笔交易被转移到另一笔交易的。(译者注:这里在了解完比特币的原理之后就可以理解)。每一笔交易将之前交易中输出的’聪‘作为下一笔交易的输入,下一笔交易的输出又被作为下下笔交易的输入,以此类推。可以看下图:


一笔交易可以产生多个输出,如在将‘聪’发送到多个地址的情况,但是每一个输出在整个区块链中只能被花一次。任何对一个输出的第二次引用是被禁止的,因为这会造成双重消费问题。

输出(outputs)被绑定到了交易标识符(TXIDs),也就是真个交易信息的哈希值。

由于每一笔交易的输出只能被花一次,因此整个区块链上的输出可以被分为没有被花的(Unspent Transaction Outputs: UTXO)和已经被花的。一个支付信息只有在输入是UTXO的时候才是合法的。

除了coinbase交易(后面会描述),如果一笔交易的输出超过了他的输入,它会被拒绝。但是如果输入超过了输出,这之间的差值会被用作交易费用用来奖励下一个产生区块的用户。举例来说,在上面的图中,每一笔交易的输入都比他的输出多了10000聪,这10000聪就被作为交易费了。

工作量证明(PoW)

区块链有网络上所有的匿名结点共同维护着,因此比特币需要每一个块证明它在被“铸造”出来的时候消耗了足够多的工作量。这是为了确保哪些不值得信任的节点如果想要篡改区块链的信息必须消耗比诚实节点更多的工作量,因为诚实节点只需要增加新的区块(译者注:而妄图篡改旧区块的结点却需要额外付出创造被篡改区块的工作量)。

区块链的这种一个连接着一个的有序结构使得想要篡改一个区块必须要篡改该区块之后所有的区块。这样修改一个区块的开销就变成了,修改该区块及其之后所有区块的工作量,这就放大了工作量证明的影响。

区块链的工作量证明利用了密码学中哈希函数的随机性。一个好的密码学哈希算法会将任意数据转化为一个看似随机的数。只要数据中任何一个比特被改变了,那么数据的哈希就会变得完全不一样,因此无论怎么改变数据,其哈希值改变的规律是无法把握的。

为了证明你为了创建一个区块确实付出了一定的工作量,你必须找出一个比特定阈值小的哈希。举例来说,如果最大可能的哈希值是$2{256}-1$,那么需要产生一个比$2{255}$小的哈希值,平均只需要$2 = 2 ^ {256 - 255} = 2 ^ {1}$次尝试不同类型的组合。

在上面的例子中平均每两次尝试就会产生一个有效的哈希值。在目标哈希值已知的情况下,你甚至可以预测每次计算哈希值达到阈值成功的概率。比特币每次计算哈希值达到阈值的概率与其尝试的次数是成线性关系的(译者注:就是尝试次数越多,成功的概率越大---废话 o|||)。

新的块只有在它所包含的哈希值达到目标值的时候才会被夹到区块链中去。这个目标值是通过一致性协议得到的。每2016个区块,比特币网络会使用存储在这2016个区块头部中的时间戳来计算生成这2016个区块的第一个到最后一个区块所花费的时间。理想值是1209600s(也就是两星期)。

  • 如果花了少于两星期,那么难度就会做相应的增加(最多300%),这样下一批2016个区块,在全网的计算哈希的能力没变的情况下,就会在精确的两星期的时间内产生(译者注:实际上没有那么精确)。

  • 如果画了多于两星期的时间来产生区块,那么难度就会按比例下降(最多75%)。

(注意:Bitcoin Core实现中的一个差一错误会引起难度的更新重原本的每2016个块更新一次难度变成了每2015个块更新一次,这产生了一个小小的偏差)

因为每一个区块的头部的哈希必须小于一个目标阈值,同时一个区块被连接到现前一个区块的后面,如果要传播一个被更改的区块,在平均情况下,就需要付出从那个区块开始到当前最新区块全网付出的所有哈希计算量。只有在你拥有了全网大部分计算能力,你就可以轻易的发动51%攻击(可以改变比特币区块链的交易历史,已经有工作表明这种攻击在没大于全网的50%的计算能力下,也很有可能攻击成功)。

区块头部提供了一些可以被更改的字段,比如一个专用的nonce字段,因此为了获得一个新的哈希值不笔在等待新的交易到来,只需要改变一下nonce字段就好了。再有,只有80字节的区块头部才会被用于计算用于证明工作量的哈希值,因此,包含大量的交易并不会增加计算哈希所需的IO,增加额外的交易只需要重新计算默克尔树的根哈希就行了。

区块链高度和分叉

任何一个矿工在成功将区块头部的哈希调整到一个目标阈值之下的时候,都可以将整个区块添加到区块链上(当然是在区块有效的情况下)。这些区块可以通过区块高度(该区块到创始块区块的数量)来索引,创世块的高度为0。比如,块2016是区块链难度系数第一次调整的地方。

当两个或多个矿工在同一个区块上都挖出了新的区块之后,那么就可能产生多个区块高度一样的情况。这样就会在区块链上产生一个分支(如上图)。

当矿工在区块链尾部同时产生区块时,那么每个矿工会自由选择在哪一个区块上继续工作。在没有其他考虑的情况下,像下面讨论的那样,结点通常选择它们首次发现的区块。

最终某个矿工会在同样高度的某个分叉上产生一个新的区块,这样这个分支就会比其他分支工作量多。假设一个分支只包含有效块,一般的结点都会在工作量最大的链上继续寻找新的区块,而将旧的分支区块抛弃。(哪些旧的区块通常被称之为孤儿或者孤块,这些属于也被用作描述真正的孤块(就是在它前面没有区块))。

分叉长期存在是又可能的,比如说不同的矿工的工作目的不一样。比如:诚实的矿工们在勤奋的为了拓展区块链的时候,一些矿工却在为了篡改交易历史在发动51%攻击。

由于在有分枝存在的情况下,多个区块可能有同样的高度,区块高度不应该作为一个全局唯一的标识符。取而代之的是区块头部的哈希值(通常是16进制形式的,并且是反字节序的)。

交易数据

每一个区块必须包含一个或者多个交易。而区块所包含交易集合中的第一个一定是coinbase交易,这个交易也被称作生成交易(generation transaction),这个交易中包含了一定数额的比特币奖励以及交易费用的奖励。

Coinbase 交易的输出(UTXo)(就是全新出炉的比特币)是不能被立即花掉的,而必须等待其后产生了100个新的区块。这可以防止矿工花了之后被证明是孤块中的比特币。

虽然区块没有被要求一定要包含coinbase交易,但是几乎所有的矿工都总会包含这样一个交易用来收集它们的交易费及额外的交易奖励。

包括coinbase交易之内的所有交易都被以未经处理的二进制形式编码进区块中去。

这种未经处理的形式的交易信息的哈希被用作交易标识符。这些交易标识符被用来构建默克尔树。由于构建默克尔树需要偶数数量的叶子结点,如果存在基数数量的交易,那么最后一个交易就会产生一个自身的副本。

一个包含五个交易的默克尔树如下图所示:

       ABCDEEEE ....... 默克尔树的树根
      /        \
   ABCD        EEEE
  /    \      /
 AB    CD    EE ....... E和他自己组成一组
/  \  /  \  /
A  B  C  D  E ......... 5个交易

在简单支付验证(SPV)那一章中,摩尔棵树可以让客户端自己验证一笔交易已经被包含到区块中去了(通过区块头部中的默克尔树来证明)。全结点没有不笔是可信的:假冒一个区块头部的代价是昂贵的,而默克尔树的中间结点的哈希是无法篡改的,不然验证就会失败。

举例来说,为了验证交易D已经被添加到了区块中去,一个SPV客户端只需要C,AB和EEEE的哈希加上默克尔树的根哈希就行了。客户端不需要知道其他交易的任何信息。如果这个块中的5个交易所在的区块是当前允许的最大大小500000字节(译者注:现在是4M),那么下载整个区块的需要500K的数据量而下载我们验证交易的信息只需要140字节(包括区块头在内)。

注意:(译者注:这个是比特币客户端的一个Bug,感兴趣的点这里查看详情)

一致性规则变更

为了维持区块链的一致性,所有的全结点(译者注:相对于SPV客户端而言的)使用同样的规则来验证区块的有效性。但是,有时候一致性规则需要被改变来引进新的特性或者放置网络被滥用。新的规则被实现之后,需要一定时间来让使用旧规则的结点更新到新的结点,在此过程当中一致性就会被打破。

译者注:这里有几段内容主要是为了解释软分叉和硬分叉,但是就我看来,不知所云,所以就没有翻译。这里简单讲一下译者个人理解:软分叉就是老用户对升级之后用户发出的交易虽然无法识别但是不拒绝,也会接受,因此不会产生分叉;而硬分叉是指老用户直接拒绝了新的交易,这样显然会产生分叉。另外一点就是:硬分叉应该会产生永久的分叉。(不知道理解对不对)


一致性协议的改变会以不同的方式被激活。在比特币的头两年里,中本聪通过一些在客户端的后向兼容的改变来立即强制执行新的规则,这进行了几次软分叉。多个软分叉(比如:BIP30)在某一个预先设置好的某一天或者比特币区块链达到固定高度的时候被激活。这些通过某个预设的时间点导致的分叉被称为用户激活软分叉(User Activated Soft Forks (UASF)),这些软分叉依赖于大量的有效的全结点的共同努力来在某一个时间点之后强制执行某些新的规则。

之后,软分叉就等待大部分(典型的是75%和95%)哈希计算力释放出接受新规则的信号。一旦达到了阈值(75%或95%),所有节点就强制执行新规则。这种分叉被称为矿工激活软分叉(Miner Activated Soft Forks (MASF))。

其他资源BIP16, BIP30BIP34 这些改进措施也是为了辅助软分叉的。BIP50描述了一个可以通过将升级结点降级暂时降级的方法来解决意外出现的硬分叉,同时还描述了一个人为的当临时降级被去除时出现的分叉。Gavin Andresen的给出了一个文档《未来规则变更如何实现》

分叉检测

未升级的节点可能会在两种类型的分支中使用和分发不正确的信息,从而创建可能导致经济损失的几种情况。特别地,未升级的节点可以中继和接受被升级的节点认为无效的交易,因此这些包含这些交易的区块永远不会成为普遍认可的最佳块链(最长的)的一部分。未升级的节点还可以拒绝中继已被添加到或者即将被添加到最佳块链中的区块或交易,并且因此提供不完整的信息(译者注:这里应该是指那些升级之后的交易信息被抛弃了,所以信息时不完整的)。

Bitcoin Core中包含了检测硬叉的代码,这段代码会检查区块链的工作量证明。如果未升级的结点收到区块链头部信息中可以证明至少有连续的六个块比其认为有效的最佳链更多的工作证明(译者注:就是网络上的最长链已经超过他本地的链至少6个了),则该节点在getnetworkinfoRPC结果中报告警告,并且运行-alertnotify命令(需要配置)。这警告操作者,未升级的节点不能切换到最可能的最佳块链。

全节点也可以检查区块和交易的版本号。如果在几个最近的块中看到的区块或交易的版本号高于本节点使用的版本号,就会认为它并没有使用当前(最新)的一致性规则。Bitcoin Core通过getnetworkinfoRPC和-alertnotify命令(如果设置了)来报告这种情况。

不管在什么情况下,交易和区块数据都不应该依赖其是否来自使用最新规则的结点还是来自使用旧规则的结点。

SPV客户端可以通过连接到几个全结点来检测硬分叉,并确保它们都位于具有相同块高度(加上或减去几个可能由于网络延迟带来的不一致)的同一条链上。一旦检测到了不一致,客户端就可以和弱链断开连接,而去连接强的链。

SPV客户端还应监控区块和交易版本号的增加,以确保他们使用当前最新的一致性规则处理接收到的以及创建新的事务。

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

推荐阅读更多精彩内容

  • 导语:比特币作为近年来最成功的数字加密货币,引起了全球高度关注,不同于其它数字货币,比特币使用由众多节点构成的去中...
    点融黑帮阅读 1,261评论 1 31
  • 雨打芭蕉深闭门,断弦声声不忍闻。 最是流光好春色,再回头已百年身。 柳绿江南雨纷纷,醒来犹忆是故人。 最是离人歌一...
    慕容锦瑟阅读 539评论 5 5
  • 语文: 今天学习的整体认读音节shi和ri,各写一行(前三个不加声调,后四个分别加一、二、三、四声调)书中lao ...
    瑞睿家阅读 153评论 0 0
  • 首发于公众号:睿之笔记 爱一个人真的可以只是一个人的事 文末给我留言吧 -1- 前些天重看《琅琊榜》,抛开那些错综...
    郭睿之阅读 257评论 0 3