常见的比特币与区块链入门文章大约分为两类,一类是面向非开发人员的科普读物;另一类是面向开发人员的技术指南。前者易流于浅表,让读者接触了一堆名词和概念,却无法对比特币与区块链有个直观的认识;而后者又往往直接进入细节,使开发人员一叶障目不能从全局了解技术概貌。本文尝试将这两类文章合二为一,同时避免上述两种缺陷。文章前部分适合想了解比特币和区块链的非开发人员,整篇文章适合想转入比特币与区块链相关开发的技术人员。

一. 比特币是什么

  了解一个陌生事物最快的方法,莫过于和一个熟知的事物进行对比,找出差异,研究差异。以转账支付为例,来说明传统货币转账和比特币转账时分别发生了什么。这里说的传统货币特指由各个国家发行的法定货币,如美元,人民币等,也包括这些货币在银行系统中的虚拟形式,如人们在银行的存款。以下统称法币。
  下表为张三分别用法币和比特币向李四转账的步骤:

步骤 法币 比特币 备注
1 张三和李四分别在银行开户,设置对应的密码。 张三和李四各自安装一个称为钱包的软件,并用该软件产生账户及相应账户的密码。 钱包软件产生的账户和密码使用前一般不会让任何第三方机构知晓,只存在于用户自己的手机或优盘上。
2 张三要保证自己银行账户里有足够的钱来转给李四,如果不够先要往银行存入一笔。 张三要保证自己比特币账户里的钱足够转账,如果不够则通过比特币交易平台购买比特币,将比特币存入钱包软件产生的账户里,本质上是将银行里的法币兑换成比特币。 比特币交易平台将比特币划入张三账户的过程,和我们这里讨论的将张三的比特币划入李四账号的过程类似。另外还可以通过挖矿的方式获得比特币,这对普通用户不易实现,该内容我们稍后再讨论。
3 张三通过输入密码的形式授权银行将自己账户的一笔钱转入李四的账户。 张三使用自己钱包软件里对应账户的密码授权并转账到李四的收款账户,并通知区块链网络。 稍后介绍区块链,现在只需知道区块链能记录授权的比特币交易就行了。
4 银行记下张三的操作,从张三的账户扣除一笔钱,并在李四的账户增加同样数目的一笔钱。 区块链网络记录下张三的转账记录。 在第三步中,比特币授权和转账的动作同时发生,因此这一步只需要记录转账。区块链网络和银行完成相同的功能:记账。
5 银行通知张三和李四转账成功。 张三和李四均可通过查询区块链网络确认转账成功。 区块链网络和银行完成相同功能:确认交易

  由上表可知,从用户角度看比特币和法币一样完成转账交易的功能,甚至连步骤都很相似,但每一步又都有差异。
  步骤1:虽然都要有账户和密码,法币账户是在银行设置,银行会保存用户的账户和密码数据;而比特币的账户和密码,在使用之前除了用户自己没有任何第三方机构知晓。
  步骤2:给银行账户充值必须通过银行系统,如果开户银行的系统出了故障(如果光纤被施工队挖断),故障期间张三是无法充值的;而给比特币充值时,如果某家交易平台故障,张三可以随便换其它充值平台,因为比特钱包产生的账户所有交易平台都认可。
  步骤3:法币的密码验证授权,必须要经过银行这样的中心系统;而比特币的密码验证授权不依赖于任何中心系统,它只依赖于密码学提供的算法。和步骤2中一样,比特币不会受特定系统的波动而影响密码验证。
  步骤4和步骤5:法币记账和交易确认需要银行的介入;而比特币则借助于区块链网络,后文我们将讲到区块链是由许多公司或个人共同在维护,即使某些公司或个人的设备出了故障,也不会影响整个区块链网络的运转。
  除了以上,法币和比特币的发行方式也不同:法币一般是由国家发行,并以法律形式保证其流通使用;而比特币的发行方式是:挖矿,理论上所有人都可以参与挖矿来获得比特币。这和地球上的另一种货币黄金很相似。黄金在地球上是稀有的而且也是有限的,比特币也是有限的,而且开采量也是逐年减少直到约一百年后开采完。注意挖矿这词其实只是一个比喻,挖矿和区块链的运作紧密相关,我们在下节讨论。
  总结:法币交易的每一步都需要一个中心机构来保证,要么是国家,要么是国家认可的银行;而比特币几乎不需要任何中心化的机构和设备就可以完成所有交易。另外在区块链中保存的交易数据只是匿名的账户数据(没有张三和李四的任何信息,只是一个很长的数字串),通常也认为它是匿名的。一句话总结:比特币是一种去中心化的匿名数字加密货币,它使用区块链来进行交易记账。
  前文为了方便理解,省去了许多细节,为了在实际接触比特币时不造成困惑,笔者认为有几点有必要说明一下.
  比特币钱包软件产生的账户,在比特币术语里通常叫地址(Bitcoin address),一个比特币钱包可以产生很多个地址,这些地址用来接受别人的转账,这和电子邮地址有点相似,不同的是一个地址只用来接收一次转账。一个地址对应一个密码,比特币术语里叫密钥(private key),用户对地址里资金的使用权完全由密钥来保障,因此安全地保存密钥至关重要,一旦丢了,不存在重置密码的说法。
  实际中,不少公司发行的钱包程序往往要用户注册,以便将用户钱包软件里的账户密钥数据加密存储在公司服务器,用户只要记得在该公司的账户密码,即使弄丢了钱包程序里的数据,还是可以通过存储在该公司的备份找回,但这并非比特币本身的内容。这相当于用户自己有些金条(比特币),在某个公司开了个保险柜存放这些金条,但把这些金条放在家里的保险柜(加密的优盘)也是一样的。将金条放在一家公司,意味着你对这家公司的实力非常有信心,它不会被盗贼攻 击,也不会监守自盗。

二. 区块链是什么

  上文步骤三中我们说过,比特币的使用授权不用经过像银行这样的中心系统,它是用户自己通过密码算法来授权的。那为什么两个用户不直接交易,像金条一样从自己荷包里掏出来给对方就行了?为什么每次交易要像通知银行一样通知区块链网络?尽管比特币在很多方面和天然货币黄金很相似,但却有一个很大的不同:黄金没法复制;而比特币只是存在于优盘或电脑手机的数据,可以无限复制。这意味着张三把一份金条给李四后,他无法再把同样的金条给别人;而张三把一份比特币给李四后,他还可以再复制一份给其他人。怎么解决这个问题呢?这就要用到区块链了。
  简单的说区块链就是一个很多人或团体共同维护,所有人都可以访问的账本,账本用来记录每一次的比特币转账,所有的用户可以通过查询账本来了解自己钱包里的余额以及比特币交易是否成功完成。

  如上图所示,区块链账本分为一个个区块,每个区块存储了很多交易记录,这些区块按生成时间先后通过一定的方式连接起来,形成了一个链结构,这就是区块链名字的来历。图中黄 色部分是上文例子在区块链中形成的记录。
  再来看区块链怎么解决上面的多重支付问题。收款方通过查询区块链是否有对应的转账记录来检查转款是否到账(对李四而言就是检查是否有b到c的转账记录);区块链在记录一笔转账交易前会先查询同样的一笔钱是否已经在区块链记录中转给其它账户(张三的b账户是否已经转出过钱),如果已经转过,则认定当前转账非法而拒绝记录该转账,这样收款方就不能在区块链账本中找到对应的转账。
  在传统的银行交易系统中同样存在类似账本的设施,区块链有什么特别之处呢?在于我们上文所说的多人或团体共同维护,即去中心化。共同维护,意味着都可以往区块链账本中记账,这带来新的问题:怎么保证每个记账人都会诚实的记账?比如怎么防止张三给李四转账后,自己作为记账人,修改账本把同样的钱转给自己?这要提到比特币的另一个机制,就是通常所说的挖矿。
  假设每一个参与记账(挖矿)的人都是唯利是图,怎么赚钱怎么做(不考虑任何道德的约束),区块链营造出了一个算法系统,让每一个参与记账的人都宁愿通过诚实的记账来获取报酬。举个栗子,有两份工作:一份是抢银行要花两天时间,一份是挖金矿只花一天时间,挖金矿能获得的报酬等于或大于抢银行,理智的人都会选择后者。区块链的算法让每个记账的人都要花费一定的代价才能记账,同时给记账人奖励。这里的代价是计算时间,奖励包括两部分:一是从每笔交易抽取的佣金,二是由系统新产生的比特币奖励。第二项奖励就是比特币把记账称为挖矿的原因了。
  区块链记账以区块为单位,把最新的交易记录写入一个区块。记账人拥有的计算设备,如矿机(专门用于挖矿的计算机)每次创建一个区块记账前都要先完成一道很难的迷题,谁先完成谜题谁就获得记账的权利和获得报酬,大家也就以他生成的区块,作为最新的交易记录追加到之前的账本,当然新区块要满足一些基本规则,比如不和之前的账本冲突,没有记录授权不正确的交易(这是靠前文说所的用户地址和私钥授来保证的)。
  这是什么样的一道谜题呢?有个很形象的比喻:掷骰子,谁先掷出满足条件的骰子组合谁就获胜。以两颗骰子为例,要扔出两颗骰子之和不大于6的概率是41.6%,很容易,平均掷二到三次就有一次满足。增加点难度,要求三颗骰子之和不大于4,那么概率就只有1.8%,就是说平均掷50次以上骰子才能有一次机会满足条件,要花点时间来掷骰子了。但考虑到是很多计算机在掷骰子,速度很快,一般的矿机能轻易的一秒钟掷上百亿次,我们继续通过增加骰子数和降低骰子数之和来增加难度,一直增加到全世界所有参加掷骰子的计算机一起玩,也才平均每十分钟掷出一个满足要求的组合。这大约会是怎样的一种组合呢:一亿个骰子掷出的总和不超过一亿零几十,想想掷一亿颗骰子,几乎每一颗都是1的概率。
  每个矿机都争先记账,谁先算出来谜题,谁就获得记账权和获得报酬,即使某个矿机要做假账,它也必须如此。同时由于区块的链结构保证如果谁想要修改其中一个区块的交易记录,它必须重新创建这个区块以及这个区块以后所有已经创建的区块,而每创建一个区块都要花费大量时间去解决谜题。上文提到的比特币加密授权机制能保证用户最多能修改从自己账户转出的交易记录,为了一笔交易的钱,他需要自己伪造多个区块,由于之前已经存在正确的区块,伪造区块很有可能不被承认,从而损失挖矿收入。即使存在着某些愿意做损人不利己买卖的记账人能凭借自身先进的计算设备比较快速的产生区块来修改账本,它也无法和整个区块链网络对抗,因为正确的区块链在不断增长,而区块链网络总是以最长的区块链为正确的账本。只要有51%的记账人(假设每个记账人有同样的计算设备)觉得挖矿比抢银行靠谱,区块链网络就能正常运作下去。以张三给李四转账以后,试图修改账本把钱又转给自己为例:

  图中CDE这几个区块是很多个记账人共同算出来的,而C’D’只能靠张三一家计算,他的计算速度几乎不可能赶上整个网络的区块生成速度,而且他生成的区块会因为得不到整个网络的承认不能产生任何收益。实际中李四确认转账并不是在区块C产生后立即确认,还会等到C,D,E等后面五个区块形成后才确认(交易数额越大,往往等的区块越多),这会进一步增加张三伪造区块的难度。

三. 涉及的数据算法

  我们进一步深入,前文至少留下了这三个问题:
  1.用户的交易授权是怎么进行的,为什么不需要一个中心机构来进行密码验证?
  2.为什么修改一个区块,必须修改这个区块后面所有的区块,怎么做到的?
  3.掷骰子这个谜题究竟是怎么实现的?
  在解决这些问题前,我们先回顾一些基本算法。比特币/区块链涉及的算法,主要有两类:1.哈希算法 2.非对称加密。对这两类算法不太了解的读者,可以阅读笔者之前的文章《构成信息安全技术体系的三类基本算法》。这里我们简要列出:
哈希或数据摘要:

byte[] hash(byte[] data);//为了和比特币开发文档保持一致用hash代替digest.

非对称加密:

class KeyPair //密钥对 { byte [] privateKey //私钥 byte [] publicKey; //公钥 }; KeyPair generateKeyPair();//用于产生一个密钥对 byte[] asyEncrypt(byte[] plainData,byte[] publicKey); //用私钥对数据加密 byte[] asyDecrypt(byte[] cipherData,byte[] privateKey); //用公钥对私钥加密的数据解密

四.交易授权

  首先比特币钱包软件为用户生成收款地址和秘钥,这是通过调用generateKeyPair()来产生的,收款地址address=hash(KeyPair.publicKey),加一次hash的目的是为了收款时不暴露用户的publicKey,减少从publicKey推导privateKey的可能性,虽然目前还没有通过publicKey推导出privateKey的案例。和收款地址对应的秘钥就是KeyPair.privateKey,因为比特币采用的keyPair可以从privateKey推导出publicKey,所以钱包里保存的数据就只是privateKey。以张三转账给李四的这个交易为例,在区块链里产生的交易数据简化后如下图所示:

  如图中所示每次交易的授权是通过签名来进行的,每个交易的输入信息来源于之前交易的输出(除了固定放在区块链第一个位置的矿工收入奖励,作为一个特殊的交易,本文不讨论)。图中的签名部分数据本身包含了一个publicKey,这实际上是构成了一个证书,见《构成信息安全技术体系的三类基本算法》数字证书一节。如张三获得李四的收款地址后,就可以通过钱包软件授权转账,即生成签名,如下图:

  生成签名后,钱包软件就将本次交易的输入,输出和签名打包广播到区块链网络中。区块链网络的矿工节点就开始验证这个交易是否合法,验证过程如下图:

  由此可见比特币使用了传统的数字签名手段来完成了交易的授权。实际中比特币的签名和验签过程,是使用其定义的一个脚本来完成的。使用脚本可以做到更多的控制和更复杂的授权,如多方授权的合约交易。另外为了个更强的安全性,许多地方求哈希时,做了多遍哈希,本文为了简便忽略了hash次数。

五.区块链的链

  熟悉哈希计算的读者应该能猜到区块之间是通过一个个哈希值连接起来的,如下图:

  我们将在下文讨论难度值和随机值。由图可见,区块A的任何修改,均会导致其区块头的变化,从而导致区块B的区块头中哈希值的变化,这种变化会一直传导到A之后的所有区块。需要指出交易记录的哈希值是一个称为“Merkle tree”的根节点,交易记录发生任何变动都会导致“Merkle tree”根节点的变化,详情可参阅相关文档。

六.掷骰子

  掷骰子在区块链中的术语叫工作量证明(Proof Of Work,缩写POW),证明矿工生成区块平均花费了规定的时间。掷骰子的过程,其实就是不停尝试找到一随机值,使得这个随机值和区块头其它信息合在一起后计算出来的哈希值小于指定的难度值(这里难度值越小,难度越大)。


  难度值是一个随着区块链网络总的计算能力动态调整的值。每产生2016个新的区块进行一次统计,如果平均每个区块产生的时间少于10分钟,难度就会增加一点(难度值减小);反之则减小难度(难度值增大)。

七.更多

  作为一篇入门级文章,本文忽略了许多非核心的技术环节,以求在最短的时间内让读者对比特币的技术架构有个初步了解。有进一步学习需求的读者可以访问比特币官网bitcoin.org中的开发指南和参考文档。