白话比特币和它的原理机制

白话比特币和它的原理机制

比特币的通俗小故事

从前,有个古老的村落,里面住着一群古老的村民,这个村庄没有银行为大家存钱、记账。没有一个让所有村民都信赖的村长来维护和记录村民之间的账务往来,也就是没有任何中间机构或个人来记账。于是,村民想出一个不需要中间机构或个人,而是大家一起记账的方法。

比如,张三要给李四 1000 块钱。张三在村里大吼一声:“大家注意了,我张三给李四转了1000块钱”。附近的村民听到了之后做两件事:

  1. 通过声音判断这是张三喊的,而不是别人冒名张三喊的,从而防止别人去花张三的钱;
  2. 检查张三是否有足够的钱

每个村民都有个小账本记录了各个村民有多少钱,当确认张三真的有 1000 块钱后,每个村民都会在自己的小账本记录:“××××年×月×日,张三转给李四1000块钱”。 除此之外,这些村民口口相传,把张三转账的事情告诉了十里八村,当所有人都知道转账的事情后,大家就能够共同证明 “张三转给李四1000块钱” 。这样,一个不需要村长(中心节点)却能让所有村民都能达成一致的记账系统诞生了。这个记账系统就可以类比为我们今天常说的比特币系统。

图 3

故事到此并未结束,由此引出了三个值得思考的问题。

  1. 记的账在后面会不会被篡改?
  2. 村民有什么动力帮别人记账?
  3. 这么多人记账,万一记的不一致岂不是坏了,以谁记的为准?

比特币系统巧妙地解决了这三个问题。

第一

比特币采用两种策略保证账本不可篡改:

  • 人人记账。人人手上都维护一本账本,这样即使某个人改了自己的账本,他也无权修改其他村民手上的账本,修改自己的账本相当于“掩耳盗铃”,别人是不会认可的。
  • 采用“区块+链”的特殊账本结构。在这种账本结构中,每一个区块保存着某段时间内所发生的交易,这些区块通过链式结构连接在一起,形成了一个记录全部交易的完整账本。如果对区块内容进行了修改就会破坏整个区块链的链式结构,导致链条断了,从而很容易被检测到,这两个策略保证了从全局来看整个账本是不可篡改的。

第二

前面一条中提到了人人参与记账,大家肯定会问 凭啥要我帮别人记账呢 。这就涉及比特币系统中的激励机制。参与记账的村民,被称为 矿工 。这些矿工中,首个记账被认可的人:

  • 将获得一笔奖励,这笔奖励就是若干个比特币,这也是比特币发行的唯一来源,这种奖励措施使众多矿工积极参加记账;
  • 谁在某一块账本被认可,其他人都会分别拷贝这一块账本,从而保证所有人维护的账本是完全一致的。这两点保证了区块链的自动安全运行。

第三

既然有了激励,大家就会争抢着记账并努力让自己的记账被认可,怎么确定以谁记的为准呢?

为了能够确定以谁记的账为准,村民们想到了一个公平的办法:对每一块账本(类比为我们现实账本上的一页),他们从题库中找了一道难题,让所有参与记账的 矿工 都去破解这道难题,谁若最先破解了,该页的块就以他记的账为准。这个破解难题的过程,就被称为 挖矿,也即工作量证明的过程。这里需要说明的是,这个难题的解题过程需要不断地尝试,较为困难,但是找到答案发给别人后,别人是很容易验证的。

因此,比特币通过 区块+链 的分布式账本保障了交易的不可篡改,通过发放比特币的激励措施激励了 矿工 的参与,通过计算难题(矿工挖矿)解决了记账一致性的问题。这样,完美地形成了一个不依赖任何中间人即可完成记账的自动运行系统。如图,这其中具有 区块+链 不可篡改账本、多方参与、结果共识的技术,就是比特币背后的区块链技术。

图 4

比特币交易

要对比特币交易进行介绍,我们首先要了解比特币地址的概念。要参与比特币系统中的交易过程,需要一个类似于现实世界中银行 账户 的实体。
实际上,比特币的交易参与方实体为一组公私钥的组合,其中,私钥是由程序生成的一串随机数,而其公钥则是根据私钥经过一系列的计算生成的,公私钥之间存在一一对应的关系。其中,公钥作为参与交易的 账户名 ,而私钥则作为交易过程中的 验证密码,用于确认某一交易的合法性,在转账时进行身份验证,从而保证用户的资金安全。

由于公私钥对为一个交易实体的唯一标记,所以需要保证各个用户所持有的比特币地址之间互不冲突,否则就可能出现安全问题。由于私钥本质上是随机生成的比特串,若有两个用户的私钥不巧是相同的,则一个用户完全可以用自己的私钥去替代另一个用户的私钥,从而使用另一个用户的资金。然而,在比特币的设计中,私钥的长度被设定为 256比特 ,其可能的取值范围为 [0,2^256-1] ,这是一个巨大的范围,可以认为与世界上沙子的数量相当,能够保证在随机算法实现正确的情况下,基本不可能发生碰撞(生成两个完全相同的私钥)。这也是比特币乃至整个密码学的基础。

简单来说,比特币的一对公私钥以及其对应的钱包地址是按照如下的流程产生的:首先,通过某种随机数生成算法产生出一个 256比特 的比特串作为私钥,然后再使用 椭圆曲线加密算法(Elliptic Curves Cryptography, ECC) 对这个私钥计算生成公钥。此后,公钥再通过一系列的哈希计算和 Base58 编码得到钱包地址。比特币交易即为从一个比特币地址向另一个比特币地址进行转账的过程,每个交易可能会包含多笔转账。

每笔交易会产生手续费,会被发送给挖出包含这个交易的区块的矿工,作为挖矿奖励的一部分。
比特币交易有两种类型,一种是 Coinbase 交易,也就是挖矿奖励的比特币,这种交易没有发送人。另一种就是我们常见的普通交易了,即普通地址之间的转账交易。

  • 比特币钱包

比特币钱包是一个形象的概念,就是保存和管理比特币地址以及对应公私钥对的软件。根据终端类型的不同,比特币钱包可以分为桌面钱包、手机钱包、网页钱包和硬件钱包。不同钱包的安全程度不同,对于少量比特币来说,选用网页钱包这种轻量级的钱包存储;而对于较大额度的比特币,建议使用更高级的钱包存储方式,比如硬件钱包,硬件钱包的成本最高,安全性也相对较高。

  • 如何获得比特币?获得比特币有3种途径。
  1. 矿工挖矿所得;
  2. 线下通过中间人购买,线下支付法币或者任何等价物之后,转出方将比特币从他的地址转到购买者的地址,也可以通过线上 交易所 购买;
  3. 商家收取比特币,比如有个佛罗里达程序员花1万个比特币购买比萨的店主就收到了比特币。

比特币挖矿

比特币系统是一个参与节点互相验证的公开记账系统,而比特币挖矿的本质则是争夺某一个区块的记账权。 挖矿 成功即是该节点成功获得当前区块记账权,也就是说其他节点就 照抄 该挖矿成功的节点的当前区块。获得记账权的节点会获取一定数量的比特币奖励,以此激励比特币网络中的所有节点积极参与记账工作。该奖励包含系统奖励和交易手续费两部分,系统奖励则作为比特币发行的手段。最初每生产一个 交易记录区块 可以获得 50比特币 的系统奖励,为控制比特币发行数量,该奖励每 4年 就会 减半,到 2140 年即会基本发放完毕,最终整个系统中最多只能有 2100万 个比特币。

比特币系统大约每 10分钟 会记录一个数据块,这个数据块里包含了这 10分钟 内全网待确认的部分或全部交易。所谓的 挖矿,就是争夺将这些交易打包成 交易记录区块 的权利。比特币系统会随机生成一道数学难题,后续会详细描述该数学难题,所有参与挖矿的节点一起参与计算这道数学难题,首先算出结果的节点将获得记账权。

每个节点会将过去一段时间内发生的、尚未经过网络公认的交易信息进行收集、检验、确认,最后打包并加签名为一个无法被篡改的 交易记录区块,并在获得记账权后将该区块进行广播,从而让这个区块被全部节点认可,让区块中的交易成为比特币网络上公认已经完成的交易记录,永久保存。

挖矿的原理

挖矿最主要的工作就是计算上文提到的数学难题,最先求出解的矿工即可获得该块的记账权。

比特币系统中采用 SHA-256 哈希算法,该算法最终输出的哈希值长度为 256bit 。比特币中每个区块生成时,需要把上一个区块的哈希值、本区块的交易信息的 默克尔树根一个未知的随机数(nonce) 拼在一起计算一个新的哈希值。为了保证 10分钟 产生一个区块,该工作必须具有一定难度,即哈希值必须以若干个0开头。哈希算法中,输入信息的任何微小改动即可引起哈希值的巨大变动,且这个变动不具有规律性。因为哈希值的位数是有限的,通过不断尝试 随机数nonce ,总可以计算出一个符合要求的哈希值,且该随机数无法通过寻找规律计算出来。这意味着,该随机数只能通过暴力枚举的方式获得。挖矿中计算数学难题即为寻找该随机数的过程。

哈希值由 16进制 数字表示,即每一位有16种可能。根据哈希算法的特性,出现任何一个数字的概率是均等的,即每一位为 0 的概率为 1/16 。要求某一位为 0 平均需要 16次 哈希运算,要求前n位为 0,则需要进行哈希计算的平均次数为 16n次方。矿工为了计算出该随机数,需要花费一定的时间进行大量的哈希运算。某个矿工成功计算出该随机数后,则会进行区块打包并全网广播。其他节点收到广播后,只需对包含随机数的区块按照同样的方法进行一次哈希运算即可,若哈希值以 0 开头的个数满足要求,且通过其他合法性校验,则接受这个区块,并停止本地对当前区块随机数的寻找,开始下个区块随机数的计算。

随着技术的发展,进行一次哈希计算速度越来越快,同时随着矿工的逐渐增多,算出满足哈希值以一定数量 0 开头的随机数的时间越来越短。为保证比特币始终按照平均每 10分钟 一个区块的速度出块,必须不断调整计算出随机哈希计算的平均次数,即调整哈希值以 0 开头的数量要求,以此调整难度。比特币中,每生成 2016个区块 就会调整一次难度,即调整周期大约为两周(2016×10min=14天)。也就是说,对比生成最新 2016个区块 花费的实际时间和按照每 10分钟 出一个块生成 2016个块 的期望时间,若实际时间大于期望时间则降低难度,若实际时间小于期望时间则增加难度。同时,为防止难度变化波动太大,每个周期调整幅度必须小于一个因子(当前为4倍)。若幅度大于4倍,则按照4倍调整。由于按照该幅度调整,出块速度仍然不满足预期,因此会在下一个周期继续调整。

矿池的原理

随着区块链的日渐火爆,参与挖矿的人越来越多,按照比特币原本的设计模式,只有成功打包一个区块的人才能获取奖励。如果每个矿工都独立挖矿,在如此庞大的基数下,挖矿成功的概率几乎为0,只有一个幸运儿可以获取一大笔财富,其他矿工投入的算力、电力资源就会白白亏损。或许投入一台矿机,持续挖矿好几年甚至更久才能挖到一个区块。为了降低这种不确定性,矿池应运而生。

假如有 10万矿工 参与挖矿工作,这 10万矿工 的算力和占这个网络的10%,则这10万个矿工中的某个矿工成功挖到下个块的概率即为 1/10。即平均每个矿工成功挖到下个区块的概率为 1/1000000,即平均每个矿工要花费19年可以成功挖到一个区块,然后获得相应的比特币奖励。这种挖矿模式风险过大,几乎没人可以承受。但是假设这10万个矿工共同协作参与挖矿,则平均每100分钟即可成功挖到一个区块,然后按照每个矿工提供的算力分配该次收益。这10万个矿工的收益也会趋于稳定。

当然上述只是对矿池原理进行一个简化的分析,实际情况则要复杂得多。当前大部分矿池是托管式矿池,一般由一个企业维护一个矿池服务器,运行专业的软件,协调矿池中矿工的计算任务。矿工不需要参与区块的验证工作,仅由矿池服务器验证即可,因此矿工也不需要存储历史区块,这极大地降低了矿工的算力及存储资源消耗。

协调矿工

协调矿工进行计算的思路也非常简单,矿池将打包区块需要的交易等信息验证完成后发送给矿工,然后降低矿工的挖矿难度。比如某个时段比特币系统需要哈希值 0 开头的个数大于50个,矿池可以将难度降低到40个 0 开头,矿工找到一个40个 0 开头哈希值的方案后,即可提交给矿池。矿池收到一个满足哈希值 0 开头个数大于50个的方案时,即可提交至比特币网络。

当然,你也许会想:如果矿工计算得到一个 0 开头个数大于50的哈希值后,则直接提交给比特币网络,独享该区块的收益;如果计算得到一个 0 开头数在40到50之间的则提交到矿池,享受整个矿池分配的收益。该方案当然是行不通的,因为区块内容是由矿池发送给矿工的,即受益者地址已经包含在该区块中了,即使直接提交,最终受益的也是矿池。如果修改该地址,即意味着区块内容改变,则前面计算的哈希值也无效了。最后矿池按照矿工提交方案数量计算贡献的算力,最后根据算力分配收益。

当前矿池为协调矿工计算工作所采用的最为流行的协议为 Stratum协议 ,该协议采用 主动分配任务 的方式。矿工首先需要连接到矿池订阅任务,矿池会返回 订阅号ID矿池给矿工指定的难度 及后续构造区块所需要的信息。连接成功后,需要在矿池注册一个账户,添加矿工,每个账户可以添加多个矿工。注册完成后即可申请授权,矿池授权成功后才会给矿工分配任务。矿池分配任务时,会提供 任务号ID打包区块 需要的相关信息。收到任务后,矿工即开始哈希计算并打包区块。如果矿工收到新任务,将直接终止旧任务,开始新任务,同时矿工也可以主动申请新任务。这种托管式矿池一直饱受争议,矿池的存在大大降低了挖矿的门槛,使普通设备也可以参与到挖矿中,吸引更多矿工参与区块链网络,同时降低矿工的风险。但是弊病也非常明显,矿池的存在一定程度上违背了区块链去中心化的理念。于是有人提出了 P2P 矿池来取代托管式矿池,但是由于其效率远低于托管式矿池,收益低下,司马迁说的好:天下熙熙,皆为利来,天下攘攘,皆为利往。 大部分矿工都更愿意因为利益而选择托管式矿池。

由于托管式矿池掌握着大量的算力资源,拥有非常大的话语权,甚至某个矿池或者几个矿池联合掌握的算力超过整个网络的 50% 时,可以随意决定出块内容、双花等。但是也不用太过担心,从经济学的角度来讲,拥有大量算力的矿池,已经是既得利益者,为保障自己的利益,肯定会不遗余力地保障比特币网络的平稳运行

比特币的分叉

软件由于方案优化、BUG修复等原因进行升级是一种非常常见的现象。如手机应用等传统软件,升级非常简单,只需厂商发布,用户接受升级即可。但是对于比特币这种去中心化的系统,升级是非常困难的,需要协调网络中每个参与者。软件升级意味着运行逻辑的改变,但是在比特币中,升级必然会导致不同节点在一定时间内运行不同的版本,于是就会产生分叉。分叉主要包含软分叉和硬分叉两种。如果比特币升级后,新的代码逻辑向前兼容,即新规则产生的区块仍然会被旧节点接受,则为软分叉;如果新的代码逻辑无法向前兼容,即新产生的规则产生的区块无法被旧节点接受,则为硬分叉

软分叉

软分叉由于向前兼容,新旧节点仍然运行在同一条区块链上,并不会产生两条链,对整个系统影响相对较小。到目前为止,比特币发生过多次软分叉,如 BIP-34BIP-65BIP-66BIP-9等。其中比特币改进建议(Bitcoin ImprovementProposal, BIP)指的是比特币社区成员针对比特币提出的一系列改进建议,这些改进建议的具体内容感兴趣的读者可以通过访问 BIP 的网站自行查阅。此处以 BIP-34 为例,简单说明软分叉的过程。在旧版本中,存在一个无意义的字段 coinbase data ,矿工不会去验证该字段的内容。BIP-34 升级的新版本则要求该字段必须包含区块高度,同时将版本信息由 1 修改为 2。该升级共包含三个阶段。

  • 第一个阶段:矿工将版本号修改为 2,此时所有矿工验证区块时,按照旧的规则验证,即不关心 coinbase data 字段内容,所有矿工不论以新规则还是旧规则打包区块,均可以被整个网络接受。
  • 第二阶段:如果最新产生的1000个区块中,版本号为 2的区块个数超过 75% 时,则要求版本号为 2 的矿工必须按照新的规则打包区块,升级的矿工收到版本号为 2 的区块时,只会接受 coinbase data 字段包含区块高度的区块,对于版本号为 1 的区块,仍然不校验该字段并接受。
  • 第三阶段:如果最新产生的1000个区块中,版本号为 2 的区块个数超过95%,则升级的矿工只接受版本号为 2 的区块,并会对 coinbase data 字段进行校验,版本号为 1 的区块则不被接受,以此来逼迫剩余少量矿工进行升级。软分叉虽然对系统的影响较小,但是为了保证向前兼容,不能新增字段,只能在现有数据结构下修改,即可升级的内容非常有限。同时,因为这些限制,软分叉一般升级方案比较复杂,复杂的方案往往更容易产生 BUG,并且可维护性很差。

硬分叉

硬分叉相比软分叉则会 暴力 很多,由于不向前兼容,旧版本矿工无法验证新版本的区块而拒绝接受,仍然按照旧的逻辑只接受旧版本矿工打包的区块。而新版本产生的区块则会被新版本矿工接受,因此新版本矿工保存的区块会和旧版本矿工保存的区块产生差别,即会形成两条链。硬分叉修改余地很大,方案设计比较简单,但是如果整个网络中有两种不同的意见,就会导致整个生态的分裂。当前比特币影响最广泛的硬分叉事件即为 2017年8月1日 的硬分叉,比特币由一条链分叉产生一条新的链 比特现金(Bitcoin Cash,BCH)

这次硬分叉的起因是开发者与矿工在比特币扩容方案上的分歧。比特币区块大小为 1MB ,按照每 10分钟 一个区块的速度,全球每秒只能完成大约7笔交易。比特币发展初期,1MB 的区块足够打包出块间隔内产生的所有交易,但是在比特币如此火爆的今天,这种处理速度显然达不到要求。一笔交易往往需要等待数个小时甚至更久,当前比特币网络已经有大约几十万交易排队等待打包确认。比特币交易可以支付手续费(不强制要求),由于矿工逐利的属性,矿工在打包区块时,往往会选择手续费更高的交易打包。这意味着,如果不想排队,则需要支付更高的手续费,以期望获得优先处理权。而过高的手续费显然违背了比特币的设计初衷。为了解决以上问题,经过社区讨论,最终形成了两个改进方案,分别是扩容方案隔离见证方案

  • 扩容方案的想法比较直接,既然现在因为区块太小而导致交易处理速度低下,那就直接扩大区块的容量,使其能容纳更多的交易。原来 1MB 不够用,那么就扩成 2MB8MB,甚至直接扩到 2MB

隔离见证

隔离见证方案的想法是,将交易分为两部分,一部分是交易信息,另一部分是见证信息,这两部分信息分开进行处理。
好比一辆车太小,要搭车的人太多,于是让车上所有人将背包和行李放在另一辆跟着的货车上,这样原来的车就可以容纳更多的人了。

支持扩容方案的主要是矿工们。矿工们认为交易的高效才是最重要的,这样才能体现比特币的世界货币价值。矿工的利益来源于挖矿,如果比特币交易处理吞吐量较低,用户为使自己的交易尽早得到打包处理会倾向于向矿工提供更高的手续费,矿工因此可以获得超额手续费,其短期收益是增加的。但长期来看,只有比特币价格维持上涨,挖矿的收益才会持续提升。因而,从长远考虑,扩容是必须的,毕竟只有比特币交易更加顺畅,入场人数增多,资金盘越来越大,矿工的收益才会获得显著增长。采用扩容方案,矿工可以在每个区块中包含更多的交易,从而获取更多的手续费,然而若使用隔离见证的扩容方案,小额的交易将不通过区块确认,矿工的手续费收益会大幅降低,因此矿工更倾向于支持扩容方案。

隔离见证方案的支持者主要是比特币开发团队的部分核心成员。他们认为,扩容方案是一个 扬汤止沸 的方案,毕竟不可能无限制地对区块的容量进行扩大。同时,区块的变大会使得挖矿的门槛提高,从而降低普通矿工的参与度,导致比特币系统的去中心化程度减弱。2016年2月和2017年3月,争议双方两次进行商讨,希望双方各退一步,接受一个折中的方案,该方案中,区块容量将会被扩大到 2MB ,同时也对比特币部署隔离见证的方案。但是,由于期间有参与方反悔或者反对,导致最终没有达成共识,这也给 硬分叉 埋下了伏笔。在2017年8月1日,比特大陆投资的矿池 ViaBTC 团队,采用比特大陆提出的 UAHF(用户激活的硬分叉) 方案,挖出了第一个区块,对比特币区块链进行了硬分叉。自此,与比特币竞争的分叉币比特币现金诞生。比特币现金区块链的区块容量达到了 8MB,且没有采用隔离见证方案。

比特币类加密数字货币

比特币的流行刺激了全球对于发行电子货币的热情,各式各样的加密数字货币涌现出来。目前全球发行的加密数字货币有两千多种,比如比特币比特现金以太币瑞波币恒星币等,各种加密数字货币市值和影响力不尽相同。很多加密数字货币源自比特币或者以太坊源代码的克隆,也有一些针对特定问题构建了独特解决方案的加密数字货币,从应用场景和技术的角度来讲有一定的创新性,比如:莱特币(LTC)质数币(XPM)Zcash门罗币等。这些币在加密数字货币方面的应用外,也给区块链技术的发展做出了很大的贡献,提供了很多新的思路。

莱特币(LTC)

莱特币(Litecoin, LTC)受到了比特币(BTC)的启发,并且在技术上具有相同的实现原理。莱特币旨在改进比特币,与其相比,莱特币具有三种显著差异:

  • 第一,莱特币网络每 2.5分钟(而不是10分钟)就可以处理一个块,因此可以提供更快的交易确认;
  • 第二,莱特币网络预期产出 8400万 个莱特币,是比特币网络发行货币量的4倍之多;
  • 第三,莱特币在其工作量证明算法中使用了由 Colin Percival 提出的 scrypt 加密算法,这使得相对于比特币,在普通计算机上进行莱特币挖掘更为容易。每一个莱特币被分成 100000000 个更小的单位,通过 8位小数 来界定。

质数币(Primecoin, XPM)

质数币(Primecoin, XPM)号称拥有科研价值和现实意义。质数币仍然使用 PoW 机制,它挖矿的过程就是寻找质数链。质数在数论领域具有极高价值,质数币是一种使挖矿过程中消耗的大量能源产生价值的加密数字货币。

Zcash

Zcash 是首个使用零知识证明机制的区块链系统。零知识证明简单点讲,就是证明者能够在不向验证者提供任何有用的信息的情况下,使验证者相信某个论断是正确的,所以 Zcash 可提供完全的支付保密性。 Zcash 是比特币的分支,保留了比特币原有的模式,不同之处在于, Zcash 交易能够自动隐藏区块链上所有交易的发送者、接受者及数额。只有那些拥有查看密钥的人才能看到交易的内容。用户拥有完全的控制权,他们可自行选择向其他人提供查看密钥。

门罗币(Monero, XMR)

门罗币(Monero, XMR)是另一个比较流行的隐私保护的加密数字货币,它同样具有隐藏地址、保护用户的隐私与匿名的功能。与 Zcash 不同,门罗币采用环签名方式保护用户隐私。环签名环中一个成员利用他的私钥和其他成员的公钥进行签名,但却不需要征得其他成员的允许,而验证者只知道签名来自这个环,但不知道谁是真正的签名者,这个方式解决了对签名者完全匿名的问题

您的支持是对我最大的鼓励!

发表于: 作者:憧憬。
关注互联网以及分享全栈工作经验的原创个人博客和技术博客,热爱编程,极客精神
Github 新浪微博 SegmentFault 掘金专栏