简介
比特币网络是中本聪作为一个实验性的网络提出来并运行的。没想到的是这一个实验性质的网络,居然成了现在虚拟货币世界的龙头老大。这个结局估计是中本聪本人都没有想到过的。
既然是一个实验性的网络,那么比特币网络中又隐藏着哪些痛点呢?快来看看吧。
攻击比特币网络
比特币网络是基于P2P架构的。在整个比特币网络中可能有成千上万的节点。
那么问题来了,这么多节点的网络,还会受到攻击吗?会受到什么类型的攻击呢?
下面讲三种攻击方式方式:
- 共识攻击(51%攻击): 如果一个人的挖矿算力,超过了全网算力的51%,就可以随意决定虚拟货币网络区块的内容,比如撤销交易或者制造虚拟交易等等,这意味着,整个虚拟货币的网络就此崩溃,所有虚拟货币的资产将掌握在这个持有51%算力的人手里。
- 自私挖矿攻击: 所谓自私挖矿,是指当一个”自私的矿池”挖到新的区块,在必须提交到网络节点之前,他们一直私下保存。该理论的依据是”自私的矿池 “保持了区块的私密性,让其余的网络算力浪费资源去挖掘,这样”自私的矿池”在挖下一个区块的时候就取得先机。
“自私的矿池”还必须监视其它矿池,预测他们什么时候发现新的区块。当”诚实的矿池”广播发现一个新块的时候,”自私的矿池”还必须发动一个Sybil Attack(女巫攻击)以抢先让他们偷挖的区块得到网络的承认。区块头当然有时间戳,”自私的矿池”还必须有足够的Sybil节点来报告是”自私的矿池”先发现区块,这样网络会接受报告并奖励”自私的矿池”。
- 服务拒绝攻击: 大量发送小额交易,拥塞网络。我们要知道比特币网络的处理能力是非常非常弱的。每10分钟出一个块,一个块的大小是1M(当然,现在搞了个隔离见证好像容量提高了),块的大小有限,最终导致块中的交易是有限的。从而就限制了比特币网络的交易处理速度。
如果这个时候网络接收到大量的小额交易,那么那些真正的大额交易就会被阻塞。
更多精彩内容且看:
- 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
- Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
- Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
- java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程
空块问题
空块的意思就是块中不包含任何交易。
那么空块是怎么产生的呢?假如我们有两个A,B矿池。
A矿池产生块后,把新块传遍全网是需要时间的。
B矿池收到A矿池新块的基本数据后,为充分利用算力,不等新块里的交易数据传完,就开始算下一个块了。
在传输交易数据的期间,B矿池有一定概率算出下一个块,这时候B矿池不知道哪些未确认交易已经被A矿池打包进前一个块,为避免打包了同一个交易,导致交易冲突,块被拒,B矿池就不会打包任何交易。
这就是空块的来历。
如果大家去查看比特币区块链的历史,可以发现(从区块364188到345469)一共18720个区块,其中只有1个交易(即coinbase交易)的有422个。
扩容问题
- 清算系统
比特币区块链是全球的、分布式的、有限容量的、代价昂贵的系统。每一笔交易的价值含量是不一样的,当块容量不够用时,我们应该保障高价值的交易进块。高价值的交易有意愿有能力支付足够高的网络手续费,从而获得足够高的优先级进块。
随着比特币的繁荣,交易数量会越来越大,有限的块容量会使得低价值的交易(例如发送1分钱)永远无法进块,因为低价值的交易不可能支付高网络手续费。
进而网络退化为清算系统,低价值含量交易被赶出,这些交易由第三方记账系统进行代替完成。
在闪电网络出现之前,第三方记账系统主要是链外钱包提供商。用户信任某第三方钱包平台,把比特币存入其中,同一平台用户之间转账仅带来账户余额变更,并不会产生比特币交易。
- 现金系统
现金系统意味着所有交易均应该进入区块,那么当块容量不够用时,则应该及时提高块体积限制,对系统进行扩容。短时间可能发生交易入块堵塞,但长期来看所有交易应该均可以入块。人人都享有比特币系统带来的巨大便利和优势。
为了解决区块链容量的问题,比特币在2017年8月24日引入了隔离见证。
- 什么是隔离见证呢?
再来回顾一下上图的比特币中区块链中交易的构造。
每个交易的的input中都包含了一个ScriptSig,这个ScriptSig主要是用来做交易验证的,只对需要验证交易的矿工来说是有意义,对于普通用户来说这个ScriptSig是完全不需要的。
而隔离见证就是把这个ScriptSig剔除到了交易之外。从而扩大了可容纳的交易数量。
同时把ScriptSig剔除到了交易之外还有一个好处就是避免了交易延展性攻击(Transaction Malleability)。
- 什么是延展性攻击呢?
延展性的意思是一个东西变形了,但其本质是不变的。对于交易来说,ScriptSig中包含的签名,其实是可以变化的。从而导致整个交易的变化,最后导致Transaction ID的变化。
因为Transaction ID是对整个交易做的一个Hash。
为什么签名是可以变化的呢?
因为对某一种签名算法来说,可能有好几种签名方式,从而多种签名方式都是正确有效的签名。但是最终会导致交易id的变化。
假设有这样一种情况。 小明在火币网发起了一笔提现交易。当这笔交易被广播到网络中,并且还没有被打包到区块中的时候。
小明监听到了这个交易,并对这个交易的签名做了微调,从而生成了一笔新的交易,发送到比特币网络中。
最终比特币网络接收了小明修改过的交易。
但是,这个时候小明可以向火币网投诉没有收到交易。火币网的客服会根据之前的交易id去查询这笔记录,当然是查不到的。最终火币网会赔偿小明一笔费用。于是,小明就攻击成功了。
区块链的膨胀问题
比特币的区块链大小是一直在增加的,其实不光是比特币,所有的区块链网络都会存在这个问题,因为每个区块链的节点都需要保存所有的链上信息。
我们看下区块链的大小,2020年,一个全节点的大小就会超过250G!
对立的社区
对于比特币而言,挖矿本身就是一种投票,原本的构想就是以CPU为单位用算力进行投票来确保系统的安全。但是随着“聪明”的技术人员们将CPU换成GPU,然后到FPGA,再到ASIC矿机,这条路已经和原来的初衷渐行渐远。
任何一个在比特币社区的人都会发现,持有比特币的人和挖矿的人成为完全不同的两个人群。比特币的矿工群体仿佛已经和社区完全割裂开来,许多矿工可能完全不了解比特币的生态,他们甚至不关心比特币的未来。
所以每年都可以看到一些奇怪的景象,持有比特币的社区不得不通过谴责和呼吁,要求某些矿池把算力降下来,以免严重影响比特币的发展。
而这些矿池也会表示自己是基于道德和觉悟来降低自己的份额。任何一个持有比特币的人,难道不对这种景象感到怪异么,比特币的命运竟然是掌握在并不一定关心比特币命运的人手上。
这似乎有点类似于,一个公司的命运并不是那些持有公司股份的股东来决定的,而是那些有可能根本不拥有股份,而只要有钱的人来决定的,也就是金融世界中的那些“门口的野蛮人”。那些持有比特币的人完全无法对比特币的未来做出自己的决定。我们仿佛从中本聪设定的一CPU一票的文明世界,一下子沦为纯粹是靠蛮力,看谁力气更大的原始社会。
失效的进化机制
比特币在发展初期主要是依靠以中本聪为核心的技术团队制定相关技术标准和研发比特币钱包。但是随着中本聪退出比特币界,这方面的任务就逐渐转移到比特币基金会。
比特币基金会是一个负责协调比特币发展的非营利机构。他们除了负责开发比特币钱包之外,还参与推广比特币理念和应用、教育市场以及和政府沟通等事项。由于基金会本身是非营利机构,只能依靠捐款来运作。但是比特币世界上大量的资金都投入到矿机中,而开发者很难从比特币发展中获利。
开发者往往面临一个两难的困境,由于比特币已经在全世界获得一定程度的认可,它的客户端被全球几百万人在使用,但是它的早期核心开发者已经不知所踪,让后续的开发者不敢改动核心代码,只能在外围做一些修补。因为一旦修改核心代码,任何的小问题都可能引起全球比特币网络的瘫痪(这在比特币发展过程中已经出现过),而没有太多的开发者愿意承担这样的风险。但是如果能够改动成功并且稳定运作,开发者除了获得社区的掌声之外,并不能获得任何实际上的利益。
并且是否使用新版本客户端的决定权在比特币矿工的手上,所以任何对矿工不利的修改都不可能通过,即使比特币基金会也无能为力,所以也导致开发者没有足够的热情去修改。在这种情况下,比特币客户端在发展了多年之后还是停留在非常原始的状态,不仅不适合普通人使用,而且完全不像一个互联网时代的软件。中本聪原本设想的社区众多开发者不断修改系统,出现像Linux一样,通过社区合力来推动系统顺应时代发展的情况并没有出现。
解决问题
那么对于区块扩容的问题,其实现在已经有了两个比较好的解决办法。
第一个就是闪电网络:
闪电网络可以看做是一个临时记账系统,比如说A和B直接有很多的交易,那么他们可以先在区块链中构建一个通道。
后面所有的交易都在这个通道中进行(可以通过智能合约的形式),只有通道关闭的时候,两者的交易才会正式更新到比特币网络中。
这样就为A和B节约了不少的交易费用。
还有一个叫做侧链技术
侧链技术实际上是在比特币网络之外又构建了一个链。比特币网络只做清算使用。
当然,为了解决比特币的问题,第二代甚至是第三代区块链技术平台都出现了。感兴趣的朋友可以继续关注我后续的更新。
总结
本文介绍了区块链网络中的困境和一些解决办法,希望大家能够喜欢。
本文作者:flydean程序那些事本文链接:http://www.flydean.com/bitcoin-in-trouble/
本文来源:flydean的博客
欢迎关注我的公众号:程序那些事,更多精彩等着您!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。