一、故事的开端
小龙、小蓉、小盈、小嫣合租一套公寓,因为大家都是打工人,并非阔绰之辈,出去消费的时候往往采用的是AA制。如此就会产生一些比如相互垫钱这样的事情,为了方便起见,她们在客厅放置了一块白板用来记录账目并约定好月底结账。 账本1.0方案(白板)一开始运转正常,大家都老老实实按照记录并在月底将款项结清,看上去没什么问题。直到某一天,小龙来在账本上搞了这样一笔虚假记录: 那么问题来了,因为谁都可以在这个白板上来一笔,记录的真伪靠的是良心,白板这种原始方案显然就不灵了。
于是她们想出了一个新的办法,即任何一条记录,付款方必须在后面添加一个签名才能生效,账本2.0诞生了: 这个方案果然凑效,支付方不签名则该条记录不生效,解决了良心帐的问题。但是,随着她们彼此间的账目往来越来越多,单靠这么一块白板显然是装不下的,于是她们决定用电脑来记录这个账目。
二、电子化记录
将账本搬上电脑倒是很容易,做一个简单Excel表格就可以了。现在,尽管账本3.0诞生了,但这个方案一开始就碰到了一个棘手的问题:签名怎么解决?总不至于直接在屏幕上涂写吧。即使有类似手写板这样的设备将签名变成图片嵌到Excel文档中也不管用,因为图片是可以复制粘贴的。
因此她们必须找到一种方法,能实现类似像在白板上进行手写签名一样的效果。
三、加密与数字签名
所谓的加密,就是将需要传递的信息(明文)通过某种方式(密钥)将其混淆为不能理解的信息(密文),而所谓解密就是将密文通过密钥还原成明文的过程。
最简单的加密形式称为“对称式加密”,比如明文是5201314(意思是“我爱你一生一世”),密钥是+1,那么这串数字的每一位全部+1就成了:6312425这串不知所云的东西(密文),接收方如果知道密钥是+1,对它进行逆运算(也就是-1),就可以还原5201314这串数字了。
管非对称加密简单明了,但因为它只有一个密钥,因此无法应用在数字签名上。
非对称加密要复杂一些,它拥有两个密钥,一个用于加密(私钥),一个用于解密(公钥),我的另一篇博文曾经讨论过一个基于乘法关系的非对称算法,感兴趣的可以去看看。限于篇幅,现在不打算深入这个算法的实现。只需要记住一点:用私钥加密的内容,只能用与之配对的公钥才能解开就行了。
那么两把密钥是怎样实现数字签名呢?下面我们以:小龙需要支付给小蓉50元 这条记录为例:
观察这个Excel文档,文档的上半部分记录了3个人的公钥,这部分内容公开透明。
首先,小龙使用自己的私钥(不公开,只有她自己知道),将小龙需要支付给小蓉50元这句话加密,形成一段密文:4fc3fb920f0a9e99,并将这段密文填写到Excel文档的“签名”一栏。
那么,如何验证这段密文确实是小龙亲自生成的呢?
现在,任何人都可以使用小龙的公钥:92474aba4fc3,对密文:4fc3fb920f0a9e99进行解密,如果能准确还原出:小龙需要支付给小蓉50元这段文字,则说明这段密文确实是小龙亲自操作的。
因为非对称加密算法的公钥和私钥,是一一配对的关系,既然这段密文能被小龙的公钥成功地解密,则说明这段密文一定是与之对应的私钥的持有者(小龙本人)所加密的。
至此,就解决了数字签名的真实性问题。
但是,这个账本仍然没有达到实用的程度。第一问题是:如何确定支付方的支付能力?简单地说就是余额问题怎么解决,总不至于自己设置一个余额吧,又或者说,自己给自己设置的余额,除了自己还有多少人相信呢?
四、基于交易的记账系统
“基于交易记账”源于传统会计学。比如说,汤姆在他的银行账户上存入了100美元,对银行而言,需要在账本上计入一笔贷方金额。未来的某一天,Tom取回了25美元,银行不会直接把100美元修改成75美元,而是在同一个账本上,新增一笔借方金额25美元。
从这个例子中可以看出,这是一种特殊的数据存储方式,它不允许修改历史数据,要改变账户的余额只能通过新增和追加记录来实现。
这里非常关键的一点就是理解只能通过新增记录去修改已有的数据。如果需要修改100美元的账户余额,只需要新增一笔借方或贷方记录就可以了,而不需要改变以前的记录。
回到我们的账本,看看“基于交易的记账系统”是如何运用在我们的账本里的。 (PS:接下来我们去掉原来存在于账本里的一些无关紧要的词汇,比如“小龙需要支付给小蓉50元”,现在简化为“小龙支付小蓉50元”)
下面,我们来看看这几条记录: 以“小蓉支付小盈50元”为例,这笔交易成功的前提是:
1.在这笔交易之前,必须有人支付了X 元给小蓉。 2.X必须大于或者等于50 3.小蓉的这X元没有被使用过
现在查看账本中的第1条记录:
表示小龙曾经向小蓉支付过50元,并且也没有记录显示小蓉的这50元曾经被使用过,因此这笔交易符合要求,支付成功。
如果我们将这条交易记录生成为一条交易消息的话,则是这样: 小龙支付小蓉50元 -> 支付小盈50元
第二个例子: 这是一个合并交易的例子,如果将这笔记录生成一条交易消息的话,则是:
小龙支付小蓉50元+小嫣支付小蓉10元 -> 支付小盈60元
看到了吗?上面的所有例子,都是在每一次交易之前,通过回朔支付方历史交易数据的方法来计算出“余额”的。
看起来好像问题解决了,但仔细想想似乎还有什么不对,我们来看下一个例子:
这同样是一次合并支付的例子,但不同的是,第二笔记录小嫣支付给小蓉的金额是20元,这两笔记录如果相加,则超出了最后一笔交易需要支付的金额,这怎么办?我们将它变成交易消息来看看:
小龙支付小蓉50元+小嫣支付小蓉20元 -> 支付小盈60元
显而易见,50 + 20 > 60,而“基于交易记账”是不允许将 小嫣支付小蓉20元 这笔交易进行拆分的,这该怎么办呢?很简单,比特币系统采用找零的方式来解决。
说得再直白一点,比如你怀揣两张10元钞票去买菜,菜价值15元,你总不可能把你手中的其中一张10元撕成两半交给老板吧?一定是将两张10元先给老板,然后老板再找你一张5元的钞票。从钱的角度来看,买菜这个过程出现了两次交易:第一次是你给老板20元,第二次是老板给你5元。
因此,上面那条交易就变成了这样:
小龙支付小蓉50元+小嫣支付小蓉20元 -> 支付小盈60元 + 支付小龙10元
现在,交易的左右两边都是70了,红字部分相当于找零。
至此,因为账本引入了“基于交易的记账系统”,解决了支付方是否有能力完成支付这个问题,账本5.0研制成功。
故事并没有终结,基于交易的记账系统只是一个框架,尽管它解决了一些问题,但离目标还很远。现在我们面临的第二个大问题就是:如何保证交易记录不被篡改?
要解决这个问题需要绕一个大弯,几乎要贯穿本文全部内容了,因此现在诸位看官不要着急,我们一个一个概念慢慢讲。
现在,主角终于登场了:区块链,在谈区块链之前,我们还需要花一点时间了解另一个大家可能经常会看到,但又一直比较模糊的概念:哈希。
五、哈希 (Hash)
哈希就是英文Hash的音译。意译的话则是散列、杂凑的意思。是指将任意长度的输入(又叫做预映射Pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。
以上是关于哈希的百度百科定义,感觉很拗口不是吗?其实哈希很简单,哈希值也称之为“散列值”,那么为什么会用散列这个词来形容它呢?举个最简单的例子:
现在我们约定,从书架中任意挑选一本书,翻开第一页,记录下第1页第2段的第5个字,然后往后翻10页,用同样的方法,记录第10页的第2段的第5个字。如此反复,总共记录10次,也就是说我们将记录10个字。
比如从书架中取出《水浒传》,按照我们之前约定好的规则,提取出了10个字:
京除寻宫天洪尉林长艺
那么,这10个字就是《水浒传》的“哈希值”,而所谓的“哈希算法”就是我们之前定义的:
从第1页开始,每隔10页,找到第2段的第5个字并记录下来,合计10次
当然,尽管这只是一个为了方便叙述而临时想出来的、拙劣的“哈希算法”,但它也可以实现一些哈希算法的基本要素。
要素1:单向性 简单地说就是从输入到输出很容易,但从输出反推出输入很困难。先说输入到输出,实际上就是将《水浒传》抽出来,按照我们的规则,找出10个字,这很简单。
但是,现在我仅仅告诉你这10个字,却不告诉你源自哪本书。除了利用穷举法,将书架上所有书全部处理一遍之外,几乎没办法仅凭这10个字就知道他们是源自《水浒传》的。
单向性这个特别有一个优势,那就是难于计算却易于验证。这与数独游戏有一点类似,一局初始的数独,想要将之走通,需要花费不少的时间,但是一旦走通之后,验证它却很简单。
类似的,在上例中,当我们仅仅知道10个字的摘要,而不知道书名的时候,只能通过穷举法去反推书名,这势必是一个大工程。但当我们已经知道答案的情况下,要验证这个结果就很简单了,按照规则重新对《水浒传》做一次抽取(仅需一次)即可。
要素2:输出固定 按照我们的规定,就只能抽取10个字,无论书薄书厚,总共就只有10个字,不会多也不会少。
要素3:唯一性 想象一下,从《水浒传》里抽取出来的10个字,它能(也仅能)代表《水浒传》而不是别的书。比如,现在我们对《红楼梦》和《三国演义》也做一次一模一样的处理,各自抽取出10个字。仅从直觉而言,你会认为这3者的哈希值发生重合的概率基本为零不是吗?
那么问题又来了:如果天底下就有这么巧的事,不同的书,按照相同的规则抽取的10个字就是发生了重合,我们把这称之为:哈希碰撞。
当然,在真实的区块链上采用的哈希算法(或称散列算法)远比我们想出来这个算法要复杂得多。比如早年广泛应用在密码存储领域的一种哈希算法称为MD5。而比特币使用的是一种称为SHA256的通用算法,以太坊则使用了一种由其团队自研的ETHASH等等。
要完整阐述这些算法的原理需要相当程度的数论及密码学基础,这大大超出了本文的范畴,我们只需要记住:所谓的哈希算法(或称散列算法)就是使用一种方式,将任意长度的数据,通过摘要的方式,转换为一种固定长度数据的方法。
一个哈希算法最重要也是最基础的要求是不允许(或理解为极低概率)产生哈希碰撞,即不同的输入值,如果散列后产生了相同的输出值,那这种算法就不能称之为好算法了。比如早年的MD5算法,即被山东大学的王小云教授验证了有产生哈希碰撞的可能,此后MD5逐渐退出了历史舞台。
比特币采用的SHA-256算法的理论碰撞概率是:尝试2的130次方的随机输入,有99.8%的概率碰撞。注意2的130次方是一个非常大的数字,大约是1361万亿亿亿亿。以现有的计算机的计算能力,是不可能在短期内破解的。
一个优秀的哈希算法还需要做到输出无规律,也就是说,输入与输出之间不能产生某种能够察觉的“规律”,比如我们输入:
“我想吃1个苹果”
这段文字通过SHA256算法之后输出: ddf630666f33472e688c1f984aa7309769810380ed75a5eaffbf97b3abe4d231”
那么,现在我们在原文上哪怕改动1个字符,输出内容也会变得面目全非,现在,我们将1个苹果改为2个苹果:
输入:“我想吃2个苹果” 输出:8512d4ab4344068ac94465f96c3adda0546387ab88262e25ea696f7c616f517b”
看到了吗?仅仅1字之差,输出的内容就产生了翻天覆地的变化,毫无规律可言,这恰恰说明SHA256是一种优秀的哈希算法。 一个好的哈希算法还要做到输入长度无限制,输出长度固定。比如SHA256的256,指的是:无论你输入多少个字符,通过SHA256哈希算法加工后,总是固定输出一个长度为256位的二进制内容。
有朋友这时候可能会问了,你在上面举的那两个“想吃苹果”的例子,输出并没有256位那么长呀,明明只有64位嘛。这里其实牵扯到一个进制转换问题。篇幅所限,上面的例子采用的是16进制数,大家应该都知道:1个16进制数需要用4个2进制数来表达,而64 * 4 刚好等于256。
回到之前的例子: “我想吃1个苹果”
通过SHA256算法加工后, 如果以16进制输出,则是: ddf630666f33472e688c1f984aa7309769810380ed75a5eaffbf97b3abe4d231
以2进制输出的话,则是: 1000010100010010110101001010101101000011010001000000011010001010110010010100010001100101111110010110110000111010110111011010000001010100011000111000011110101011100010000010011000101110001001011110101001101001011011110111110001100001011011110101000101111011
显然,如果都按照二进制方式来书写,就很浪费篇幅了,因此大多数情况下我们提到哈希算法的输出值的时候都是以16进制来表达。简而言之,上面长的那串256位2进制数, 与短的那串64位16进制数,两者就数值而言是完全相等的。实际上,在真实的比特币系统,SHA256值通常也是以16进制来表达。
至此,就讲完了公私钥加密和哈希,大家一定要清楚两者的区别。私钥是一种加密算法,而哈希则是一种摘要。两者起不同的作用。
公私钥加密算法是一种“无损”算法,密文可以通过密钥将原始信息完整还原。
而哈希则是一种“有损”算法,它从原文中抽取一部分,形成的是对原文摘要,是不能通过哈希值反推出完整原文的,这是它与公私钥加密所不同的地方。
公私钥确定了交易人的身份,杜绝了冒名顶替的可能性。而哈希则解决了交易记录无法被篡改的难题,为什么这么说呢?诸位看官请稍安勿躁,继续往下看。
六、回到账本
那么,在引入了SHA256哈希算法之后的账本会发生什么变化呢,首先我们来观察第一笔记录:
首先将“小龙支付给小蓉50元”这句话通过SHA256算法生成哈希值,然后使用ECC非对称算法 + 小龙的私钥对这个哈希值进行加密,其结果就是签名。
PS: 比特币采用一种称为“ECC(椭圆曲线)”的算法作为其签名的加密方案,其原理非常复杂本文不做深究)
那么,我们如何验证这个签名确实是小龙本人操作的呢?
首先我们用小龙的公钥对此签名进行解密,解密之后的明文是一段哈希值,我们将它记作SHA1。那么,这段哈希值到底是不是通过“小龙支付小蓉50元”这串字符串运算出来的呢?
SHA256作为一种通用的开源算法,网上有许多SHA256在线验证网站,只需将“小龙支付小蓉50元”这段汉字输入进去,网站就会显示其对应的哈希值,我们将它记作SHA2。
现在,我们比较SHA1和SHA2,如果 SHA1 = SHA2,这就说明:
1.确实是小龙本人的签名 2.文字内容没有被篡改过
乍看上去,冒名顶替和记录篡改问题都解决了,但细想一下,似乎还有什么地方不对?
首先,记录篡改问题并没有真正解决,尽管没有私钥确实无法直接篡改记录的内容,但是记录的插入与删除问题仍然无解。例如,如果将“小龙支付小蓉50元”,这行记录完整地插入到一个新行(包括签名),又或者将这条记录整个删除掉则无能为力。
还有一种场景,比如小龙本人将“小龙支付小蓉50元”,篡改为为 “小龙支付小蓉60元”(多给10元),因为小龙本人就是小龙私钥的持有者,它可以很轻松地对篡改后的记录重新进行签名。
以目前的账本机制,是无法有效应对以上两种情况的。现在,一个新的概念登场了:分布式账本。
七、分布式账本
所谓分布式账本,就是在不同的电脑中存储一个内容完全相同的账本,并用网络将这些电脑连接起来共同维护同一本账本的记账方式。
现在,姑娘们的账本不再存储在一台公用的电脑上,而是放在了她们各自的私人电脑里。也就是说现在的“账本”由4个一模一样的文件存储在4台电脑里组成。
如此,试图篡改4台不同电脑上的记录就比在1台电脑上困难很多了。这正是分布式记账系统简单而朴素的底层逻辑。
但是,采用分布式账本后,又诞生了一堆新的问题:如何进行账本的同步? 简单地说,当一笔新的记录产生时,如何同时写进4台电脑?万一其中一台电脑坏了开不了机怎么办?此外,交易记录到底以哪台电脑为准?
等等问题接踵而来。
其实如果我们换一个思路,这些问题对于中心化交易系统(比如银行)来说,是很容易处理的。首先,银行不存在多个账本这一说,也就不用考虑所谓账本同步问题。其次,交易记录是否被篡改,也是银行说了算,它拥有对记录的最终裁定权。
但是数字货币的原则本身就是要建立一个“去中心化”交易系统。它面临的是这样一种环境:
1.没有权威机构,也没有哪个成员拥有最终裁定权,所有成员地位平等。 2.成员间彼此不存在信任关系。 3.需要在1、2点成立的情况下,创造一个高度可靠且稳健的交易系统。
看起来,似乎是一件不可能的事情?
下面,就让我们深入区块链,将这些疑问逐个击破。
八、深入区块链
区块链是由区块组成的一个链条。这意味着它是由多个区块前后连接在一起的,而交易记录则是保存在每个区块的内部,那么,采用这种方式后,是怎样保证存储在区块里面的交易记录就不可能再被更改呢?
比特币网络由许许多多安装了比特币客户端的电脑组成,这些电脑称为比特币节点。每个节点的本地硬盘里都存着一个账本文件,换句话说,每个节点的硬盘里都存放着一个完整的比特币区块链副本,且每个节点中的这个副本长得都一样。 节点通过网络互相连接在一起,就组成了一张巨大的点对点(P2P)网络。其网络结构非常类似于早年的BT下载,区别是对于BT节点而言,硬盘中存储的东西五花八门,可能是某部热门电影,也可能是一首MP3。而比特币节点存储的东西就单纯得多,只是一份账本文件。这份文件记录了从比特币从创世那天起的所有交易记录。
此外,比特币网络与BT网络还有一个不同的地方。BT下载存储的文件往往不会再发生变化,比如说一个电影文件,从发布者上传到BT网络那一刻开始,这个文件基本上就不会再产生变化了。但比特币网络的账本文件却是动态的,因为随时都有新的交易在产生,而这个账本文件又需要不断记录这些交易信息,所以它会一直膨胀下去。
让我们以一笔交易记录为例。现在,“小龙向小蓉发送5个BTC”连同小龙的公钥一起。将作为一条广播,向整个比特币网络扩散。
比特币网络的其中一个或数个节点,收到了这条交易信息,将对它做这几件事:
1.用小龙的公钥解密签名,得到SHA1
2.用标准SHA256算法对交易内容进行哈希运算,得到SHA2
3.判断SHA1是否等于SHA2?
4.通过对小龙的历史交易信息进行回溯,计算其余额是否足够支付本次交易?历史交易信息是否之前就被使用过?等等。
如果上述结果验证后都没有问题,节点将这条消息视为有效交易。反之,如果验证有误,则会被视为无效交易而被舍弃。
节点会一直等待足够多的合规记录,直到凑够一定数量后,将这些合规的交易记录打包存放在一起,形成一个区块。
一个区块内部可以存储多条交易记录,例如比特币的一个区块可以存储总量为1M大小的交易记录。(PS:篇幅所限,本文以4条记录为一个区块来进行叙事。)
举例来说,当某个节点(图中节点A)接收到4条合规的交易记录后,这4条记录会被A节点打包成一个新区块,并向整个比特币网络广播。
当其他节点(例如B、C节点)接收到这条广播后,将这个新生成的区块添加到自己维护的区块链副本的末尾。
乍看上去没毛病,通过这种方式,比特币区块链就实现了所有节点副本数据的一致性,节点虽然众多,但是大家保存的数据是一样的。但是请细想,大家有没有发现这个方案其实是有问题的?
因为所有节点都是同时在进行验证和打包工作的,那么,如果某两个或几个节点几乎“同时”验证完毕的时候。又以谁的结果为准呢?分歧因此产生:
节点分布在世界各地,比特币网络的核心原则就是让所有节点维护一条唯一的区块链(简称主链)。换句话说,因为比特币网络只允许一根主链的存在,所以在单位时间内也只允许唯一一个新区块添加到主链的末端。那么问题来了:如果单位时间内产生了太多的新区块。那么,到底应该在主链的末尾续上哪一个呢?
这就是所谓的“拜占庭将军”问题。话说当年的拜占庭帝国国土辽阔,为了达到防御目的,每个军队都分隔很远,将军与将军之间只能靠信使传递消息。
每个将军都有自己的军队,每支军队都位于他们打算攻击的城市周围的不同位置。这些将军就需要对指令达成一致。即所有将军如何达成共识,经过协调后决定共同执行同一个指令?
如果我们将这个困境对应到区块链上,则每个将军代表一个网络节点,而节点需要就系统的当前状态达成共识。换句话来说,分布式网络中的大多数参与者必须同意并执行相同的操作以避免扯皮。
为了解决拜占庭将军困境,我们需要引入两个新的概念:共识机制与工作量证明。
九、工作量证明(POW)
工作量证明(Proof-of-Work,PoW)是在区块链网络上达成一致,从而确认交易并为区块链生成新区块的一种共识机制(Consensus mechanisms)。
前文所述,因为验证交易的时间实在太快了,将导致出块时间也很快,因此假如以瞬态完成时间作为一个新区块是否记录到主链的共识的话,这个机制不仅在技术上难以实现,同时也因为时间差距太小,也不能被参与者所信服。
比特币需要控制出块时间,实则就是需要一个让所有人都信服、认可的机制,在一个特定的时间段内确定只有一个新区块记录到主链。比特币的创始人中本聪认为:这个时间段需要控制在大约10分钟左右。
那么到底该如何确认这个共识机制呢,POW(工作量证明)就是这样一个机制。
这个机制的受众,称为“矿工”。
矿工完成这个共识的过程,称为“挖矿”。
回到POW,矿工是如何通过额外的工作,让比特币的出块时间被延时的呢?
这个额外的工作分为两步:
第一步: 新制作的区块需包含的以下内容:
1.前一个区块的SHA-256哈希值 2.这个区块的基本信息 3.这个区块所包含的所有交易记录
将以上三个信息全部拼接起来,形成一个字符串。
那么,我们来看第一点,什么是“前一个区块的SHA-256哈希值”呢,要说明这个问题,我们需要观察到底比特币区块链中的区块是如何链接在一起的呢?
观察第二个区块的哈希值(绿色),这个值是通过对第一个区块的哈希值(浅蓝色)进行二次哈希运算得到的。第3个区块又是对第2个区块的哈希值进行二次哈希运算的来的,以此类推。每一个区块都记录了上一个区块的哈希值,块块相扣,于是才形成了一根链条。
第二个问题,什么是“这个区块的基本信息”呢? 这个比较容易理解,它包括本区块的版本号、时间戳等。
第三点,什么是“这个区块所包含的所有交易记录”呢?实际上就是对本区块的每一条交易记录拼接起来做一次哈希运算,例如:
就是将这4条交易记录做一次哈希运算,形成一个哈希值。
第二步:
好了,下面我们将这3个东西串成一个整体,然后再串接一个随机数,再整体做一次哈希运算: 看到这里,你一定会觉得很奇怪,为什么要在尾部再串一个随机数呢?
这就是POW和矿工的终极秘密了,比特币白皮书规定,只有当这个SHA256哈希值的前72位为0的时候,才可以被认为竞争到了区块写入权。
仔细观察这个步骤,需要参与SHA256运算的前3项都是固定值,只有第4项“随机数”是不确定的。
现在,假设我们把随机数设为“5150”代进去试试看。发现最后的SHA256哈希结果的前72位有很多1,那么很可惜,本次尝试作废: 那么如何才能获得一个“前72位为0”的SHA256哈希值呢?回忆一下我们最初提到的那个“从书架中找到《水浒传》”的案例,其实就是穷举法。我们不断地改变这个随机数,让它与固定不变的前3项进行拼接组合,接着再做一次SHA256运算,如此反反复复,直到结果的前72位等于0为止。
假设现在我们经过了无数次尝试,终于当随机数位落在“69732”的时候,SHA256的结果前72位终于全部为0,这就表示成功了: 实现这个目标的概率有多小呢?前72位为0的概率是:2的72次方之1,换句话说,平均要进行2的72方次SHA256运算,才能找到一个符合要求的随机数。这个算力差不多就是当下所有比特币矿机全部开动的情况下,10分钟左右产生的算力。
我们在前面的哈希算法一节,曾经说过一个优秀的哈希算法是不允许产生碰撞的,但是现在矿工所做的工作本质上就是在做一种局部意义的“哈希碰撞”。之所以说是“局部”,因为这个碰撞并不是要求256位全部相同,而仅需要前72位。
那为什么不多不少刚好就是72位呢?这并非一个固定值,也是比特币的高明之处,它相当于一个阀门控制着整个比特币网络的算力需求。
通过对SHA256结果头部需求加零的方法来增大运算难度,头部需要0的位数越多,需要的运算量就越大,进而控制出块速度恒定保持在10分钟左右。
随着新一代矿机的问世,算力越来越强,将来肯定也不止需要前72为0,到时候可能会改为73位、74位等等。
当然,也不排除当比特币由于币价过低,矿工没有挖矿意愿的时候,参与挖矿的矿机就会变少,整个比特币网络的算力又会随之下降,即出块时间将会超过10分钟。这时候就可以考虑降低难度值,例如将72改为71或者70。无论难度增加或是减少,其目的都只有一个:将出块时间控制在10分钟左右。
这时候你可能会问,矿工们难道就没有一种现成的数学公式去“推算出”一个哈希值的前72位为0的方法吗?
答案是否定的。
回到之前我们提到SHA256算法的时候,它的第3个特性是“输出无规律”,既然没有规律,这就意味着矿工们只能通过“试”这种笨办法去不断穷举碰撞,能否碰出中奖结果,纯粹是靠运气。那么,在单位时间内去碰运气的次数越多,则中奖的概率也越大。算力强的矿机运算速度快,单位时间内就比算力弱的矿机尝试的次数更多,也更容易中奖。
现在我们应该能很好地理解何谓“工作量证明”了。因为要实现SHA256哈希结果前72位为0这个目标。确实需要尝试做大量运算才能实现,我们的矿机也实打实地付出了“工作量”。显而易见,这的确是一个能让所有矿工都服气的、公平的共识。
书归正传,当某个矿工通过尝试,找到了一个最终SHA256结果前72为0的随机数之后,就是俗称的“挖到矿”了。这名幸运矿工将这条消息广播到比特币网络上,当其他矿工接收到这条消息后,怎么验证这条消息的真伪呢?
其实原理很简单,再次复习一下哈希的一个知识点:单向性。当其他矿工收到这条记录着幸运随机数的广播信息时,只需对其再进行一次(仅需一次)验算即可。唯一区别是,幸运矿工经历了无数次的碰撞才找到了这个随机数。而对其他矿工而言,这个数是现成的,就好像我们前面提到的数独游戏,虽然你花了很长时间才完成了一盘数独,但是让你的朋友验证一遍却是易如反掌。
当越来越多的矿工收到这条挖矿成功的广播后,他们将验证这条广播是否真的符合SHA256结果的前72位为零。如果验证成功,他们将立即停止自身的挖矿行为,然后将这个区块添加到各自维护的区块链的尾端,最终整个比特币网络的所有节点都将完成这个动作,实现全链同步。
按照比特币规则,第一个找到SHA256哈希值前72为0的那位幸运矿工将会被奖励6.25个比特币(2022年的标准,每4年奖励减半),以及本区块上产生的所有交易的手续费奖励。
以2022年7月的比特币币价而言,尽管刚刚经历了一波熊市,但这6.25个BTC仍然大约与100万人民币等值。奖励不可谓不大,因此才能吸引了大量矿工前仆后继地加入到这场竞争中。反过来,因为矿工的陆续加入,又相当于扩充了比特币网络的节点数量,让比特币网络能够更加健康、稳定地运转,形成一个良性循环。
十、最长链原则
上面我们已经将比特币网络的基本运行原理讲完了,我们知道了通过POW工作量证明,可以将比特币出块时间控制在每10分钟一块。但是有没有考虑过这样一种情况:10分钟之内有两个或以上的矿工找到了幸运随机数,换句话说就是产生了两个有效区块,这种情况该如何解决?
由于网络广播的顺序是不确定的,不同的矿工先收到的新区块是有可能的不同的。这个时候,我们说区块链发生了分叉(支链): 在区块发生分叉的时候,有的矿工先接收到了紫色区块,而有的则先收到绿色区块。因为这两个区块都是有效的,因此有的矿工在紫色区块这条路径下继续向前挖,而另一些矿工则在绿色这条路径下继续挖。那么问题来了,比特币只承认唯一一条区块链,在出现分叉的时候又以哪条路径为准呢?
答案是:最长链原则。
如上图,在下一个十分钟,如果紫色路径比绿色路径更快地挖出了一个新区块,那么整个主链就以紫色路径为准,绿色这根分支则将被舍弃,在绿色区块中所有已经打包好的交易记录将会被退回交易池,重新标定为“未确认状态”。
因此,在比特币主链上,10分钟内不管产生多少个分支,最终都要看哪个分支首先算出下一个区块为准。 尽管连续多次产生分支的可能微乎其微,但我们仍要注意:当在比特币网络上产生一笔交易后,不要急着认为转账已经成功了。因为此时这笔记录的状态有可能还处于两个未确认的支链中,只有这两个支链的其中一个竞争成为主链的一部分后才算稳妥。如果是大额转账,等待3到6个区块,则基本上万无一失了。
十一、双花问题
双花即“双重花费”,或者称为双重支付(Double-spending),指的是同一笔资金同时支付给两位收款方。
例如上图,假设小龙目前只有50个BTC,但她同时向比特币网络发送AB两笔交易且收款方各不相同。
此时,有的矿工会先接收到A交易消息,而另一些矿工则会先接收到B消息。
前面我们说过,矿工的一个重要工作就是回溯支付方账号的历史交易记录,以确定是否能够有余额进行本次交易。当A组矿工确认交易A后,就会排斥交易B,因为A交易已经让支付方账户余额为0了,所以B交易只能作废。
反过来B组矿工也一样,类似的,他们又会认为A交易是无效的。
那么,到底以哪笔交易为准呢?
回到我们的最长链原则,处理方法很简单: A、B两组矿工哪边首先产生下一个区块,则以哪边为准。
看到了吗,现在A组矿工中的某一位首先完成了新区块制作,那么主链上则以A记录为准了。反之亦然,也就是说无论最终写入主链的是A还是B,反正只有一个记录会被写入主链,因此也就解决了双花问题。
十二、记录篡改问题
绕了这么一大圈,终于回到了我们之前提出的那个灵魂拷问:如何防止记录被篡改?
首先,冒名顶替问题是不可能出现的,请往上翻,本文在数字签名那一节已经详细解释了为什么在没有私钥的情况下不可能伪造他人的身份。当然,如果私钥本身被比如黑客攻击或者被木马等方式窃取了又另当别论,不在本文的范畴。
我们着重讲一下上文曾经提到过的三种作弊方式:记录新增、记录删除、支付方作恶。其实这三种情况本质上没有区别,都可以被统一理解为记录篡改。
以记录删除为例,假设比特币主链上曾经出现过“小龙支付50BTC小蓉”这条记录,而小蓉想删除掉这条记录。首先,因为分布式账本的存在,她只能修改存放在她自己硬盘里那条比特币主链的副本。而世界上有成千上万的节点,要删除全世界节点其中的某一条记录,几乎是不现实的。
PS: 假如她真的实现了这一点,则称为区块链发生了“集体窜供”,这在一些小规模的区块链上曾经发生过,但对于比特币这样的巨型区块链,这个可能微乎其微。
即使真有神助,她真的篡改了全世界节点的数据,别急,这才闯过了第一关。
第二,比特币区块链上的每一个区块都有一个SHA256哈希值,相当于区块编号,前一个区块的编号链接在下一个区块上,环环相扣。而对于其中一个区块的编号而言,又是由内藏其中的交易记录通过SHA256函数运算出来的。这里再次复习一下哈希算法的“无规律性”这个特点,即输入内容哪怕有一点点变化,输出也会变得面目全非。
因此,哪怕她对历史记录做一丁点改变,无论是删除、新增还是修改,就会改变该区块的哈希值,而这个哈希值又是链接到下一个区块的凭据,哈希值改变后就无法再链到下一个区块,这就会导致区块链断链。
好吧,这也不行那也不行,那她就在篡改的那个区块上另起炉灶,用创建一个支链的方式强行作弊,不得不说,这个方法理论上是可行的,如图:
假如需要修改的那条交易是存放在第2个区块中的,现在将它删除,这必然会导致第2号区块的SHA256哈希值产生变化,因此就没办法链到第3个区块去了。此时,如果在第2个区块开始另起炉灶,创造一条支链可以吗?答案是肯定的。但是前面我们讲过,比特币的最长链原则,因为她另起炉灶这条支链短于主链,所以它是不能被认可的。
那么,如果她拥有特别强大的算力,她的这条支链挖掘速度赶上了主链的速度呢?
恭喜!终于成功地突破了比特币网络的最后防线。但是,要实现这个目标,需要拥有的算力必须超过全网算力的50%,否则另起炉灶那条支链将永远不可能追上主链的增长速度,并且想修改的区块离主链越远,耗时也越长,也越难修改。这也就是所谓“51%攻击”典故的由来,简而言之,51%攻击并不是不能实现,但前提是必须拥有和全世界人对抗的能力,而这将是一笔天文数字的资金投入。
从人性的角度来说,如果作弊成本远高于诚信收入的话,人们就会放弃作弊的念头,转而去老老实实挖矿得了。
再者,如果真的发生了51%攻击,那么整个比特币就会陷入灭顶之灾,进而造成币价崩溃,而作为始作俑者能否在这种情况下收回因作弊而带来的巨大资金投入,这也得打个问号。
后记(FAQ)
1、比特币是怎么发行的,有类似央行那样的机制吗? 答: 没有,新比特币通过对矿工的奖励产生,也就是说,当矿工通过运算成功打包了一个新区块时,比特币网络中就增加了相应个数的BTC,以2022年为例这个数值是6.75个。
2、比特币有上限吗? 答: 有,总量大约是2100万个。 比特币最小可以细分到小数点后8位,单位是“聪”(源自创始人中本聪的名字),比特币每10分钟产生一个区块,每个区块发行50个比特币(矿工奖励),每21万个区块后,每个区块的产量减半。
不难算出,每挖出21万个区块所需要的时间为 210000/10×6×24×365≈4,即每四年时间,区块发行的比特币奖励减半。以此类推,当比特币进行到第33次减半的时候,每个区块的奖励将降至1聪以下,无法继续分割减半,网络便会停止产生新币。此时的比特币总数量为20999999.97690000个。约等于2100万,所以比特币数量上限就是2100万枚。比特币到达恒定产量2100万枚的时间预计是2140年。
3、比特币挖完了矿工怎么办? 答:比特币被设计为一种有发行上限的通缩型货币,其本质上是想让它成为类似数字黄金一样的存在。当比特币到达上限后,出块仍然不会停,但是矿工的出块奖励将会消失,而只剩下交易费收益。不过距离2140年还早,比特币到底何去何从现在下结论还为时过早。
4、比特币到底牛在什么地方? 答:有的人说比特币没有政府背书,本身又不像真正的黄金那样看得见摸得着。它根本就没有任何价值,甚至就是一个骗局。对于这些质疑,我想从货币的共识开始说起。
首先,什么是货币的共识?
在蛮荒年代,人们物物交换,这个阶段连货币都不存在,因此也不需要有什么货币共识,你牵来一头牛,我换你五把镰刀,交易完成。
但是物物交换的效率实在太低,于是人们开始寻找一些大家都觉得有价值的东西来充当中介的作用,比如稀有的石头、贝壳之类,因为如果大家都觉得这些东西有价值,于是就形成了共识:这些东西可以充当中介物来使用,而不需要将交易物品费时费力地进行物理转移。
是因为人类需要摆脱物物交换的枷锁,中介物才会出现,从本质上讲,货币是一种用于交换价值的工具。任何物品都可以作为货币使用,只要当地社群接受它作为商品和服务的付款。
时至今日,这种作为中介物的东西实际价值已经越来越低。从金币、银币到铜币,直至现在的纸币。纸币本身除了纸张墨水那点几乎微不足道的成本之外,并没有真正的价值。
随著金本位制的废除,我们事实上就在使用一种没有价值的货币。然而,我们仍然可以用钱支付食物、账单、房租和其他东西。正如我们所讨论的,货币的价值来自于集体的信任。
因此,信任才是某种事物能否成为货币的关键。而比特币则是可以成为这样一种让大家都信任的事物,因为它从原理层面就解决了许多传统货币所不能的问题。
首先它的记账方式可靠,能够在预设所有人都没有信任关系的前提下进行安全可靠的交易。比特币用户不需要相互信任。他们只需要相信比特币的技术,该技术已被证明非常可靠和安全,并且源代码对任何人都开放。工作量证明(POW)是一个透明的机制,任何人都可以自己验证和检查。在这里可以产生几乎没有错误的共识。 其次它的发行机制透明,没有滥发的可能,而这正是传统货币的一个顽疾。并且使用它方便快捷,能够在不需要中介的情况下,在全球范围内快速转移大量价值。
最后也是最重要的,它是一种去中心化的系统,去中心化的区块链网络中,没有可攻击的中心节点,系统安全性高。也没有哪个人或者组织能够对它进行黑箱操作。
因为普遍缺乏知识和误解,导致一些人觉得比特币没有任何价值。一些人甚至会用“骗局”和“庞氏骗局”来形容它。
本文除了科普之外,还有一个目的,就是要让这些人意识到他们的恐惧和偏见是毫无根据的。
|