比特币区块链是一个分布式的数据库,它的数据可以存在于任何人的电脑中,只要你的电脑接入了互联网,有足够大的磁盘空间可以装下。关于数据库的体积,我们可以计算一下,目前的区块高度大约是50w,每个区块的大小上限是1M,那数据库的体积上限也就是500G,一个普通的移动硬盘就够了。而实际数据库的体积比这个数还要小太多,因为比特币早期几乎没有人进行交易,区块的大小仅215个字节左右。目前这个体积大概是70个G左右。
既然数据有这么多份拷贝,那算法又是如何保证这些数据是完全一致的呢,如果有人要篡改数据,会不会就不那么安全了?
比特币为了解决数据库的安全性和一致性,使用了两个重要机制。数据的安全性机制可以用一句简单的成语来描述就是【牵一发而动全身】,数据一致性机制也可以用一个简单的原理概括那就是【大多数人都是好的】。
挖矿很难
区块链是一个分布式数据库,全世界的人都在查询这个数据库,但是负责往数据库里写数据的角色则只有矿工。矿工的操作就是构造一个区块,使得这个区块能满足一定的算法条件,就可以加入到全局的区块链数据库中,然后矿工就可以获得巨额回报。
那问题是矿工在自己的挖矿机上构造出了一个区块,这个区块是如何同步到全世界的呢?它使用的是P2P的广播机制,可以理解为【击花传鼓】。首先矿工将这个区块加入到本地的区块链中,然后将区块的信息通过路由器传递到互联网上,在网路上监听的所有设备都可以读取到这个区块的信息,然后对这个区块的信息进行校验,看看这个区块是否满足算法限定的苛刻条件。如果满足了算法条件,就将这个区块加入到自己的区块链中,并且继续对外传播新区块信息。
如果挖矿很容易,不但挖矿挣不到钱,互联网网路上还会引起P2P广播风暴。那算法究竟对区块限定了什么条件使得挖矿如此艰难呢?
我们来看一个区块头
图中的hash字段就是当前区块的hash值,prev_block是前一个区块的hash值。区块正是通过hash值串起来形成了一个区块链。hash值是将上一个块的hash值和当前区块头内容信息拼接起来进行两次sha256哈希得到的16进制字符串。
我们发现这些hash值前面都有很多个零,那为什么会有这么多零呢?还有就是sha256哈希算法得到的hash值应该是非常随机的才对,那如何hash的前缀会有这么多零呢?
正是这些零造就了挖矿如此艰难。
矿工要随机出合适的nonce值,使得两次sha256哈希出来的值前缀至少包含N个零才可以被算法接受。假设使得前缀的第一位冒出一个零的概率是1/16,那使得N个位都要为零就必须平均进行随机16的N次方次nonce值才可以哈希出满足条件的hash值。图中有17个零,16的17次方是一个非常可怕的数字。
算法还规定随着区块的高度增加,需要的N值越大。
我们看创世区块,也就是中本聪先生挖的第一个区块
这个区块的hash值前缀才10个零,如今挖矿难度已经足足上升了16的7次方倍。矿工们如果想要持续获得挖矿收益就必须扩大矿场升级计算硬件。这也是为什么比特币被环保人士诟病的原因之一,因为它耗费了太多的能源去做这些【无意义】的计算。
未来挖矿的难度继续增大,计算机的算力会不会遇到瓶颈,挖矿的收益会不会难以填平能量费用,我们不知道,只能继续观察。
区块链分叉
有这样一种可能,两个矿工几乎同一时间挖出了一个区块,然后广播到互联网建议其它节点接受自己的区块。节点收到这两个区块时会感到迷惑,该接受哪个区块呢,它很矛盾怎么办?能不能随机接受一个呢?不可以,如果每个节点都随机的话,全球区块链数据库就不一致了。
于是区块链干脆就分叉,分成两个支链,然后就等着这两个支链发展壮大,看谁的支链发展的越长,最终就选择谁。算法规定优先保留长度较长的链条。随着区块链的继续发展,相对较短的弱小的分支链条将会被抛弃掉,于是全球数据库仍将继续保持一致。那会不会永远这两个分支链条一样长呢,有这个可能,只是概率太小,小到几乎没可能发生。正所谓一山不容二虎,最终只有一个霸王。那些因为分支长度太短被淘汰掉的区块是作废了的,辛苦挖出这些分支块的矿工也不会有任何奖励,因为这些分支块上的内容不会被承认。
伪造区块
区块链上登记的BTC很诱人,能不能把链条上的UTXO记录改成自己的账户地址,这样不就可以毫不费力拿到很多BTC直接成为世界首富了么?
前文提到区块的hash串是根据前驱区块的hash串加上当前区块的内容整体hash出来的结果。如果前驱区块的内容如果变了,前驱区块的hash也得变,然后后续区块节点的hash串也会跟着变,一直传递下去,就需要改变指定区块的后续所有区块节点。
假定你在本地的数据库里把这个区块链给修改了,还需要将这些修改的区块通过互联网广播出去,让其它的节点也能接受,这就是个问题了。收到区块的节点干的第一件事就是校验区块是否合法,也就是区块的hash值是否满足前置N个零的苛刻条件。待合法后,它会将区块接到合适的位置引出一个分支来,这个位置不会比当前最长链的位置还低6层,因为算法规定落后6层的分支链是会被抛弃的。这意味着你不可能篡改6层之前的任何区块,因为6层之前的区块已经尘埃落定了。
如果算力足够强大到找到后6层区块的目标nonce值,确是可以达到串改数据库的目的。但是这样的篡改行为实际上是和挖矿行为等价的。你所做的不过就是争取最长的区块链,在分支竞争长度时尽可能取胜而已。
阅读更多相关文章,关注头条号【码洞】