导语:比特币作为近年来最成功的数字加密货币,引起了全球高度关注,不同于其它数字货币,比特币使用由众多节点构成的去中心化的分布式网络来记录交易信息,这其中的关键就是区块链:一个在未来十年可能给金融业和其它行业带来巨大改变的技术。今天就结合比特币来了解一下区块链技术。
1、场景描述
想象一下世界上有两个银行:银行 A 和银行 B,以及两个用户:用户 C 和用户 D,用户 C 还使用了一款第三方支付软件 E。
银行 A 用自己的信息系统为用户记录账户余额,银行 B 也用自己的信息系统为用户记录账户余额,第三方支付 E 也用一套系统记录用户 C 的账户余额,这基本上就是今天的金融世界里的样子,如下图:
我们可以很明显的看出如下事实:
银行 A 的系统中记录了银行 B 欠自己 800 万美元,同时银行 B 的系统中也记录了自己欠银行 A 800 万美元的事实,也就是说同样的信息由两个银行的不同系统记录了两次。类似的信息也在银行 B 和第三方支付 E 中记录了。
用户 C 在银行 A 透支了 15,000 人民币,在银行 B 有存款 68,000 人民币,在第三方支付 E 上还有 5,000 人民币的余额,所以只有通过两个银行和一个第三方支付的三个系统才能计算出用户 C 真正拥有的财产。
我们可以看到,每个银行都必须花费大量的时间与金钱去开发和维护系统用来记录信息,更严重的是它们需要花更多的时间和金钱在各银行之间互相检查对账,银行业的数据需要至少两个不同的系统去记录,为了确保各方信息都是正确的,需要有高昂的对账过程。
下面我们做一个改变,只用一张表来记录上面例子中的所有数据,如下图:
上面的一张表和之前的五张表记录的内容是一样的,唯一的不同是这个表多了一列。有了这张表,银行与用户之间不用维护自己的系统,而且最关键的是完全省去了银行之间对账的流程。所以,为什么全世界不能有一个统一的账本呢?有些人可能立刻就会说,哪个单一系统有能力维护这个账本?系统维护这个账本的成本得多高啊?这个系统如果出故障了对全世界的影响得多大啊?这个中心系统如果在账本中作弊怎么办?
为了维护一个统一账本创建一个中心系统看来是不可行的,那么我们可不可以创建一个共享网络,所有银行和用户都在这个网络当中,没有一个中心系统会维护账本,取而代之的是网络中的所有银行和用户都有这个账本的最新内容,账本由网络中的所有参与者共同维护,这样就防止了中心系统故障引起的账本丢失,而且如果有参与者想作弊其它人也都不会同意的,相当于每个参与者都出一份力来保证账本的安全与稳定。
上面这项技术方案可行吗?可行;这个技术方案叫什么?区块链;现在有成功的案例吗?比特币。
2、区块链概念
区块链是一个在网络上的去中心化的分布式共享账本或者数据库,通过某些技术,可以保证这个账本或者数据库的一致性、安全性及可维护性。比特币是区块链首次大规模应用到全球性网络的一个案例,区块链技术本身并不局限于比特币等数字货币中,它还可以应用到支付、证券交易、股票交易、物联网、身份认证、电子合同等很多领域中。
3、比特币中的区块链
比特币概述
2008年,一位神秘人士中本聪发表了一篇论文,阐述了比特币的概念与相关技术,这篇论文被后人成为《比特币白皮书》,或者《中本聪白皮书》。2009年,中本聪和其它一些人实现了相关技术,系统正式在互联网上运行,标志着不受各国中央银行和任何金融机构控制的比特币正式诞生。两年以后,中本聪突然在网络上销声匿迹了,一直到现在也没人知道这个在比特币世界中相当于创世先知的人物在现实世界中的真实身份。而他创造出来的比特币,当前的整体价值已经超过了 100 亿美元,每天有几百万比特币在网络上被交易。
比特币原理
比特币运行在基于互联网的 P2P 网络之上,P2P 是一个运行在 TCP 协议之上的应用层协议,在 P2P 网络中,接入网络的每个设备都彼此对等,网络中不存在中心节点,每个节点都随机连接很多其它节点,为这些节点提供服务,同时也从这些节点获取服务,P2P 网络也因此具有去中心化性、可靠性及开放性等特点。近些年最成功的 P2P 网络应用发生在文件分享领域,如国外的 BitTorrent、国内的迅雷等,都是通过 P2P 网络进行文件下载的。
在比特币的 P2P 网络中,每条交易信息都会以一传十、十传百的方式被通知到网络中的所有节点进行验证,只有网络上的大部分节点都验证通过,这条交易才会被记录到区块链当前的区块中,在比特币网络中平均每 10 分钟会生成一个区块,区块中记录了之前 10 分钟在网络上的所有交易,每个节点都有生成区块的权利,只要节点在这 10 分钟内能计算出一道特定数学题的解,其它节点就会承认这个区块并且把区块添加自己的区块链中,得出解的节点会得到一定数量的比特币作为奖励。在比特币网络中,试图生成区块并得到奖励的节点通常被称为矿工,生成区块的过程被称为挖矿,从 2009年 开始,动态调整的数学题的难度使得比特币网络中平均每 10 分钟就会生成一个区块 (有一个矿工得出数学题的解),随着每次区块的生成,都会生成一定数量的比特币作为奖励付给此矿工,开始时每个区块生成的比特币奖励为 50 个,这个数量每四年就会减半,到 2140年 以后比特币的数量会被固定在 2100 万枚,届时不会再有新的比特币生成。
任何机器都可以运行一个完整的比特币节点,一个完整的比特币节点包括如下功能:比特币钱包,允许用户在比特币网络上进行交易;完整区块链,记录了比特币历史上的所有交易,通过特殊的结构保证历史交易的安全性,并且用来验证新交易的合法性;矿工,通过记录交易及解密数学题来生成新区块,如果成功可以赚取奖励;路由功能,把其它节点传送过来的交易数据等信息再传送给更多的节点。在比特币网络中的节点,除了路由功能以外,其它的功能都不是必须的,有的节点只有钱包功能,有的节点只负责挖矿。
区块链的数据结构
比特币的区块链中记录的是交易信息,每个完整节点都在本地保存有一份完整的区块链,每个完整的区块链中都记录了从 2009年 比特币诞生之日起发生的所有交易信息,每当有一个新交易申请产生时,节点都可以通过完整区块链验证这笔新交易的正确性,被验证通过的交易会被记录到下一个将要生成的新区块中。每个区块由包含元数据的区块头,以及包含之前一段时间内交易信息的区块主体组成,区块头的大小是 80 字节,区块主体通常都很大,如果平均一个区块包含 400 笔交易的话,那么区块主体通常会比区块头大 1000 倍以上。所以区块主体只负责记录交易信息,而区块链的大部分功能都是由区块头实现的。
区块头中主要包括如下信息:
版本号,4 字节,标示软件及协议的相关版本信息;
父区块哈希值,32 字节,引用的区块链中父区块头的哈希值,通过这个值每个区块才首尾相连组成了区块链,并且这个值对区块链的安全性起到了至关重要的作用,在后面会有详细介绍;
Merkle 树根,32 字节,这个值是由区块主体中所有交易的哈希值再逐级两两哈希计算出来的一个数值,主要用于检验一笔交易是否在这个区块中存在;
时间戳,4 字节,记录该区块产生的时间,精确到秒;
难度值,4 字节,该区块相关数学题的难度目标;
Nonce,4 字节,记录解密该区块相关数学题的答案的值;
每个区块的区块头中记录了其引用的父区块的哈希值,这个哈希值是通过 SHA256 算法对父区块的区块头进行二次哈希计算得出的。一个区块链的部分区块的信息如下图:
区块链的构建过程
生成新区块并被添加到区块链的过程在比特币网络中被称为挖矿,通过挖矿,交易信息得以被记录到区块链中,而且正是由于其中的工作量证明机制 (解数学题),才保证了区块链中的交易信息的一致性与安全性;对比特币来说,挖矿成功后的奖励机制使得新的比特币得以进入比特币网络中流通。在比特币网络中,有一些节点被称为矿工节点,这个矿工节点可以是一个用户的一台普通的 PC 机器,也可以是一个企业机房中上百台机器组成的计算集群,还可以是多个矿工组成的矿工池,比特币对矿工节点的机器没有限制,但是拥有更高计算性能的矿工节点会比其它节点更容易得出数学题的解以获得记账的权利和比特币奖励。
在矿工努力生成区块的同时,也会把新的交易信息保存到本地内存中待放入下一个区块,在当前区块被自己或者其它矿工生成并验证通过后,所有矿工就立即开始下一个区块的生成工作,这时会把在本地内存中的交易信息记录到区块主体中,同时在区块主体中生成此区块中所有交易信息的 Merkle 树,把 Merkle 树根的值保存在区块头中。Merkle 树是一种哈希二叉树,使用它可以快速校验大规模数据的完整性。在比特币网络中,Merkle 树被用来归纳一个区块中的所有交易信息,最终生成这个区块所有交易信息的一个统一的哈希值,区块中任何一笔交易信息的改变都会使得使得 Merkle 树改变。下面假设一个区块中有四笔交易,分别是 A、B、C 和 D,首先将交易数据通过两次 SHA256 算法生成一个 32 字节的哈希值,这些值作为叶子节点存储在 Merkle 树中,然后把相邻叶子节点的两个 32 字节的哈希值串联成一个 64 字节的字符串,再对这个字符串通过两次 SHA256 算法生成一个 32 字节的哈希值作为这两个叶子节点的父节点存入 Merkle 树中,以此类推,最终生成区块中所有交易信息的统一的哈希值,这个哈希值就是这个 Merkle 树的根节点,区块头中存储的也就是这个跟节点哈希值,如下图所示:
Merkle 根被填入区块头中后,系统会把上一个刚刚被生成的区块的区块头的数据通过 SHA256 算法生成一个 32 位的哈希值填入到当前区块的父哈希值中,然后把当前 Unix 时间保存在时间戳字段中,难度值字段也会根据之前一段时间区块的平均生成时间进行调整以应对整个比特币网络不断变化的整体计算总量,如果计算总量增长了,则系统会调高数学题的难度值,使得预期完成下一个区块的时间依然在十分钟左右。区块头中最后一个字段是 Nonce,初始值为 0。
区块头及区块主体构建完成以后,挖矿也就是解数学题就可以开始进行了,挖矿的目标就是通过不断改变区块头中的 Nonce 值,使得对区块头使用 SHA256 算法得出的哈希值符合难度值的要求。SHA256 算法是一个加密哈希算法,这个算法的特点是不同的输入会产生完全不同的哈希值,没有任何规律可循,而且无论输入的大小是多少,SHA256 算法的输出的长度总是 256bit 即 32 位。比特币挖矿的目标就是找到一个 Nonce 值,使得在这个值下的区块头的 SHA256 哈希值的输出必须小于难度值中设定的值,这个难度值通常是以多个 0 开头,当前最新难度的要求是得出的 256bit 的哈希值中前 68 个 bit 都必须是 0,这要求整个比特币网络每秒大概进行 6x1020 次哈希计算,才能在 10 分钟左右的时间内能有矿工找到符合要求的 Nonce 值。在挖矿过程中,由于每个矿工创建的新区块头中的时间戳都可能不一样,而且由于每个矿工选择进入本区块的交易集合不一样,区块头中的 Merkle 根的值也不一样,所以即使很多矿工都是从 Nonce 等于 0 开始累加寻找符合条件的哈希值,他们也还是在各自不同的位置寻找,挖矿的过程是整个比特币网络所有矿工节点的计算能力加在一起寻找答案的过程,每个矿工都有找到正确答案的机会,只不过拥有的更高计算性能的矿工找到答案的概率更大一些。
当一个矿工成功找到使得区块头哈希值小于目标难度的 Nonce 值后,他会立刻把这个区块广播到比特币网络中,几秒钟后,网络中的所有矿工就会收到这个区块,当他们验证成功后,就会立即停止自己生成当前区块的努力,把那个矿工找到的区块加到区块链中,完后立刻开始下个区块的生成过程。这样,一个区块就被添加到了完整区块链当中了。
区块链的一致性与安全性
上面讲了区块链的数据结构和构建过程,但是还有两个最关键的问题需要解释:
整个区块链如何在分布式网络中的所有节点中保持其一致性。
如何保证没有节点恶意篡改区块链中的信息 (在比特币中为交易信息),也就是说如何让我们相信区块链中的信息都是真实信息。
对于一致性问题,其实在上面的区块链构建过程的最后已经有所说明,网络中的所有节点都会通过解数学题争取得到创建当前区块的权利,当一个节点解题成功后,就会把题的答案和构建的区块通过比特币网络发送给其它节点,其它节点只要验证通过了这个答案,就会立刻停止自己创建当前区块的努力,把传过来的区块加到本地区块链中,然后根据这个区块的区块头的哈希值填充下一个区块的区块头中的信息,立刻开始下一个区块的构建。这样,网络中就完成了一个区块链中新区块的构建过程。
这个过程看似没有问题,但是考虑一下以下一种情况:同一时间 (1 秒内) 可能有两个或者更多不同的节点都找到了答案,他们立刻把答案和区块发送给与他们连接的节点中,这些节点验证通过后会基于这个区块立刻开始下个区块的构建工作,由于每个节点生成的区块都是不同的 (数学题的解有多个),所以每个区块的哈希值也都不相同,后续区块的哈希值也会改变,这样在整个网络中就形成了多条区块链的分叉,不同的节点在不同的分叉上往后构建新区块。
分叉问题如何解决,答案是等到下个区块或者下下个区块再说,当前区块有多个节点同时解出了答案,但是下个区块很可能就会分出先后,先解出下个区块的分叉被全网认可后,之前在错误分叉上的节点会把自己分叉上之前错误的区块替换掉,使得整个网络重新归于统一。
这也是为什么比特币会把每个区块的解题时间控制在 10 分钟左右,更难的题和更久的解题时间使得同时解出答案的概率更低,在比特币历史上,很少出现分叉中包含两个区块的情况。所以,区块链中最新生成的几个区块的确可能会出现一致性的问题,但是在 6 个区块之前的所有区块就肯定都一致了。
对于安全与信任问题,主要体现在两方便,一是有节点试图更改之前某个区块上的交易信息,二是有节点试图控制新区块的生成,解决这两个问题的关键都在于解数学题背后所代表的巨大计算能力的保证。如果有节点想要更改之前某个区块的交易信息,只要交易信息一更改,这个信息的哈希值就会更改,最终会引起区块头中代表所有交易信息的 Merkle 树跟值的更改,这个区块头的哈希值也就更改了,之前的 Nonce 值已经不是这个被改了的区块头的解了,这个区块的数学题需要重新计算,更严重的是,这个区块下一个区块引用的父哈希值也改变了,所以下一个区块也需要重新计算,依此类推,后面所有区块都需要重新计算生成。
也就是说,只有重新计算被更改区块后续所有区块并且追上网络中合法区块链的进度后,把这个长的区块链分叉被提交给网络中的其它节点,才有可能被认可,只重新生成被恶意篡改的区块并提交是不会被网络上的诚实节点认可的。在当前全网巨大计算能力的背景下,一个恶意节点想重新计算多个区块并且追上全网的情况很难出现,一般认为第 6 个区块之前的所有区块就不可能被改变了。那么如果试图控制新区块的生成呢,也就是说每个新区块都是由恶意节点率先得出数学题的解得到认可,这样由于区块中包含的交易都是由节点自由决定的,恶意节点可以通过这种方式永远不让某个交易加入区块链中得到认可。理论上这种方式是可能的,如果恶意节点的计算能力比网络中所有其它节点的计算能力的总和都高,也就是恶意节点占据了全网 51%的计算能力,他就可以控制新区块的生成,这种攻击被称为 51%攻击。当然在现实当中,一个节点的计算能力超过其它所有节点的总和是非常困难的。由于篇幅所限,还有很多安全问题比如 DoS 攻击的解决方案在这里就不一一阐述了。
4、小结
现代互联网的基础是 TCP/IP 技术,基于这项技术,网络上所有节点都可以公平自由的跟其它任意节点通信,但是这个技术只解决了去中心化的通信问题,没有解决去中心化的信用问题。区块链技术的出现让我们看到了解决这个问题的希望,其在比特币上的大规模应用也让我们看到了其技术上的可行性。本文基于比特币介绍了区块链的相关技术,但是区块链技术的应用并不仅仅局限于数字货币领域,其在各个行业上的尝试都已经开始,让我们跟随最新的技术,并为其最终成熟做出自己的一份贡献。
本文作者:罗宇翔,做过 Web,搞过大数据,懂一点数据挖掘,实现过推荐系统,喜欢探索新的技术领域,注重理论与实际相结合。现就职于点融北京团队。
声明:此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网站所提供的信息,只供参考之用。