比特币相关知识学习
密码学(Hash算法和椭圆曲线签名算法)
区块链中主要用到的密码学相关的是:1.哈希函数 2.签名(非对称加密)
哈希函数是一种从任何一种数据中创建小的数字“指纹”的方法。 散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。
比特币中哈希函数的三个特征为:1.collision resistence(抗碰撞性)2.hiding(不可逆向推导)3.puzzle friendly(比特币中的挖矿)。比特币中用的hash函数为SHA-256
比特币系统中首先对Message取哈希,然后再对哈希值签名
ECC(Elliptic Curve Cryptography,椭圆曲线加密)
被公认为在指定密钥长度下最安全的加密算法,比特币中的公私钥生成以及签名算法ECSDA
都是基于ECC的.私钥用来生成签名,公钥验证签名,可以有效的防篡改。
https://blog.csdn.net/weixin_42117918/article/details/103221756(这个理解椭圆曲线加密运算还是不错的)
在椭圆曲线加密利用了“椭圆曲线上的离散对数问题”,已知:
- 椭圆曲线E
- 椭圆曲线E上一点G(基点)
- 椭圆曲线E上一点xG(x倍的G)
求解x
给定椭圆曲线E,基点G和点xG,我们称xG为公钥,x值为私钥,根据椭圆曲线性质,“已知点xG求x的问题”则非常困难,因为只能遍历每一个x做运算。即已知私钥求公钥很简单,而已知公钥求公钥几乎不可能。
区块的基本结构
-
区块(用哈希指针代替了普通指针,没有环路的情况下都可以使用哈希指针,否则造成循环依赖)
区块主要包含区块头和区块体,区块头中主要包含的内容如下:版本号,前一个区块头的Hash,Merkle树根的Hash(对所有区块中的交易创建一颗Merkle树,并计算出树根的hash),时间戳(区块的创建时间),难度目标target(区块的工作量证明难度目标),Nonce(用户工作量证明算法的一个扰动输入函数)等。
-
Merkle Tree(用哈希指针代替了普通指针)
Merkle Tree的一个用途时用来提供Merkle proof
(黄色交易所在叶节点到Merkel root路径中用到的哈希值)
SPV(Simple Payment Verification,简单支付验证)借助Merkle Proof机制,只需要保存最长区块链的所有块头的情况下,就能够验证对一笔支付交易是否在存在。相比较于全节点,实现SPV的客户端称为轻节点(Light Node)。轻节点收到Merkle proof之后从下往上只能验证交易所在的分支的哈希值(会不会有问题? 人为制造哈希碰撞使向上反馈的总哈希值不变x 不可行,因为有collision resistence的保证)是否正确即可。
什么是UTXO?
区块链是一个去中心化的账本
,比特币是基于交易模式
的,其全节点要维护一个UTXO(Unspent Transaction Output,未花费的交易输出)
集合,UTXO的总体的设计是基于这样一种思路,如果A要花费一笔钱比如100元,这笔钱不会凭空产生,那么必然由B先花费了100元,被A赚到这100元,然后A才能继续花费这一笔钱。这个链条的源头就是先产生这笔钱,在比特币中这被称为铸币(coinbase)
。然后会产生这样一个链条,铸币->B->A->?整个过程从铸币开始,一直可以追溯到当前的状态,当接收到一个UTXO输入的时候,可以基于这个模型判断这笔钱有没有被在别的地方花费过。
UTXO集合中每个元素要给出产生这个输出的交易的哈希值,以及其在交易中是第几个输出。通过这两个信息,便可以定位到UTXO中的输出.
为什么要维护这样一个数据结构?为了防范“双花攻击”,判断一个交易是否合法,要查一下想要花掉的BTC是否在该集合中,只有在集合中的才是合法的。如果想要花掉的BTC不在UTXO中,那么说明这个BTC要么不存在,要么已经被花过,所以全节点需要在内存中维护一个UTXO从而便于快速检测双花攻击。
PoW共识的基本原理
PoW(Proof of Work,工作量证明)应用于比特币中,算力越高收益越高,依赖数学运算来获取记账权,去中心化程度高,资源消耗高,出块时间长,51%算力攻击
工作方式:第一个找到合适的nonce的节点获得记账权。节点生成新区块后广播给其他节点,其他节点对此区块进行验证,若通过验证则接受该区块,完成本轮共识,否则拒绝该区块,继续寻找合适的nonce。
此外简单扩展几种常见的共识:
- PoS(Proof of Stake,权益证明)
应用于以太坊中,权益(代币)越高收益越高,节点记账权获取难易程度和持有的权益成反比(也需要挖矿),减少PoW共识的资源消耗
工作方式:每个节点在每一轮共识中只需要计算一次Hash,当拥有的权益越多,满足Hash目标的机会越大,获得记账权的机会越大。可以说,PoS是一个资源节省的共识协议。PeerCoin定义的权益除了与代币数量有关,引入了币龄(Coin Age)
,100个代币持有两天,币龄为200,因此持有的代币数量越多,时间越长,获得记账权的机会越大。 - DPoS(Delegate Proof of Work,委托权益证明机制)
应用于EOS中,由PoS演化而来,性能高,持币者通过抵押代币获得选票选举出若干节点(超级节点)作为区块生产者(类似董事会选举),去中心化程度低
工作方式:用户投票最多的若干节点成为出块节点。在每一轮共识中,轮流选出一个出块节点产生区块,并广播给其他的出块节点进行验证。若节点在规定时间内无完成出块,或产生无效区块,会被取消资格,取而代之的是重新投票选取新的出块节点。 - PoA(Proof of Authority,权威证明)
应用于以太坊联盟链,性能高(不需要挖矿),去中心程度低(几个权威节点组成一个中心),权威节点出块验证,防止双花
工作方式:首先选举权威节点统计各节点状态,当有交易时,各节点不在互相发,而是统一发到Authority中,由权威节点来验证交易,PoA网络中的Validator验证人就是节点选举出来的Authority,Validator验证并签署交易之后,普通节点都从它那同步数据。(晶格链中选取PoA共识是每个节点都会打包,节点按顺序打包) - PBFT(Practical Byzantine Fault Tolerance,实用拜占庭容错)
应用于超级账本,性能高,去中心化程度低,最大容错作恶节点数f=(n-1)/3
工作方式:客户端节点发送交易请求给Primary主节点,主节点(负责将交易打包成区块和共识,每轮共识过程中有且仅有一个Primary节点)广播本次请求给其他Replica副本节点,副本节点执行三阶段共识流程之后返回消息给客户端,客户端收到来自f+1节点的相同消息之后表明共识过程已经完成。
https://www.cnblogs.com/zmk-c/p/14535734.html(这个简单理解PBFT还是不错的)
- Raft
应用于超级账本2.0后的版本/私链,选举领导、同步数据,只能容纳故障节点不容纳作恶节点
工作方式:选举一位Leader节点,该Leader将处理客户端请求并将数据复制到所有节点,如果节点异常或网络异常,Leader节点会一直重试直到所有日志都会正确复制到所有节点。
https://www.cnblogs.com/zmk-c/p/14535679.html(这个理解Raft共识机制还是不错的)
常见共识算法的“不可能三角”视图(去中心化,安全性,可扩展性)现在流行混合共识去优化解决
最后,展示一下现有共识机制及其发展的分支
区块链网络基本实现方式
比特币工作于网络应用层,其底层(网络层)是一个P2P Overlay network(P2P覆盖网络)
比特币系统中所有节点完全平等,不像一些其他网络存在超级节点。要加入网络,至少需要知道一个种子节点,通过种子节点告知自己它所知道的节点。节点之间的通信采用了TCP协议,便于穿透防火墙。当节点离开时,只需要自行退出即可,其他节点在一定时间后仍然没有收到该节点消息,便会将其删掉。
每个节点维护一个邻居节点集合,消息传播在网络中采用洪泛法,某个节点在收到一条消息会将其发送给所有邻居节点并标记,下次再收到便不会再发送该消息。邻居节点选取随机,未考虑网络底层拓扑结构,也与现实世界物理地址无关。该网络具有极强鲁棒性,但牺牲了网络效率。
比特币网络传播属于Best effort尽力而为
,不能保证一定传输成功。一个交易发布到网络上,未必所有节点都能收到,也未必所有节点收到交易顺序都一致。
思考问题
PoW为什么可以保证区块链的一致性?
比特币区块链上有一个共识——始终以最长连为主链(有效链),也即 “最长链规则”,这个规则对于工作量证明来说,主链必然是广大矿工消耗最多经济资本创造出来的链。所有不合法、不在主链上的区块,最终都会被丢弃,以此维护一个权威的公共账本,由此保证区块链的一致性。
分叉是如何产生的?是如何解决的?
分叉在区块链中指原来的一条链分成了两条链,分叉形成的原因主要有三种:
- state fork:对比特币系统当前状态产生分歧导致的分叉(例如挖矿时两个节点同时发布区
- forking attack:分叉攻击,人为故意造成的
- protocal fork:比特币协议改变,但不能保证所有节点同时升级,如果存在少数节点未升级,也会导致分叉产生
其中protocal fork又分为硬分叉
和软分叉
两种:
-
硬分叉:对比特币协议新增协议,扩展新功能,未升级的旧节点会不认可这些修改,这也就对比特币协议内容产生了分歧,从而导致分叉,一个典型的例子就是对比特币区块大小的修改(1M->4M),即如果比特币中半数以上的节点更新了,新旧节点形成的链不同,成为两条平行的链。其特点是必须系统中所有节点更新软件,系统才不会产生永久性分叉。
-
软分叉:如果对BTC协议添加限制,使得原本合法交易在新交易中不合法,便会形成软分叉。(1M->0.5M)
只要系统中拥有半数以上算力节点更新软件,系统就不会产生永久性分叉。因为旧节点挖出的区块一直被抛弃,无法得到出块奖励(不在最长合法链上)。这就倒逼旧节点升级软件,最终会实现区块链上的所有矿工共同认可新协议,实现软件协议的升级
比特币的安全性体现在哪些方面?
- 首先恶意节点并不能将其他账户上的比特币转给自己,因为转账需要签名,恶意节点无法伪造其他人的签名,并且大多数诚实节点不承认其的合法性,以致该区块成为orphan block孤儿区块,对攻击者来说不仅不能偷盗其他人的比特币而且还会得不到出块奖励,浪费了挖矿成本。
- UTXO避免了double spending双花问题
- 椭圆曲线加密算法签名保证了几乎是无法伪造的,哈希函数两个特征1.collision resistence(抗碰撞性)2.hiding(不可逆向推导)
为什么要调整挖矿难度?以及如何调整挖矿难度?
挖矿的本质就是不断调整block header中的nonce值,使整个block header的哈希值小于等于给定的目标阈值,即H(block header) <= target
(target越小目标难度越大)对于挖矿难度的调整,可以视为调整目标空间在整个输出空间中所占比例大小。
因为系统的总算力是越来越强的,如果不调整挖矿难度,则出块时间越来越短(出块时间越来越短是好事吗?)
出块时间缩短,那么交易可以很快被写入区块链,并提高了系统的响应时间,增加了区块链系统的效率。但是,出块时间并不是越短越好,首先,区块链在网络传播上具有时延,假如出块时间为1秒,但网络传播需要10秒,则会使得系统中节点经常性处于不一致的状态,增加了系统不稳定性,且系统经常性位于分叉状态(不仅二分叉,乃至多分叉)。分叉过多,则不利于系统达成共识,且会造成算力分散,使得黑客攻击成本大大降低(不再需要整个系统51%的算力)。
比特币中的主链选择协议是采用最长链规则
,以太坊主采用的是Ghost协议(Greedy Heaviest-Observed Sub-Tree protocl,贪婪子树协议)
(后续以太坊中详细介绍)
在BTC协议中规定,每隔2016个区块
需要调整一次难度,根据10min产生一个新区块可以得到,大概需要14天的时间。具体调整公式如下:
这里目标阈值的上调和下调都是有4倍
的限制。