淘先锋技术网

首页 1 2 3 4 5 6 7

(自己学习中的一些笔记 有参考大佬的播客)
https://blog.csdn.net/Mu_Xiaoye/article/details/104299664
1、 简介
区块链!=比特币。区块链技术是从比特币中抽象提取出来的,比特币是基于区块链这一技术的一种加密货币,并且一直在没有任何中心化机构运营和管理的情况下运行。

2、 特征
区块链的存储是一种链式存储,区块按照生成的时间顺序前后连接,区块的链接基于区块存储内容的哈希值构建。
区块生成后,会在区块链系统的各个节点中同步,各个节点(全节点)最终均保存了一份完整且一致的数据。
区块链系统会保持最终一致性,但不保证实时一致性。
比特币系统理论上不支持数据的删除与修改。(数据的删除和修改意味着其修改所在的区块的哈希值也需要修改,而区块之后的所有区块的前向链接哈希值均需要改变)

3、 密码学基础
1) cryptographic hash function(哈希)
用到的主要性质

  • a) collision resistance(抗碰撞性)
    给定x和y,且有x!=y,但给定一个哈希函数Hash(),可以得到Hash(x)=Hash(y),则称为hash碰撞。
    如果有Hash(x)!=Hash(y),必然可以得到x!=y
  • b) hiding(单向计算)
    给定x和Hash(),可以很容易得到Hash(x),但没有办法在已知Hash(x)和Hash()的情况下,反推出x的具体取值
  • c) Puzzle friendly 哈希值计算事先不可预测,仅仅根据输入很难预测出输出。
    比特币使用的是SHA-256(Secure Hash Algorithm)哈希函数。

2) 签名

  • a) 使用非对称密钥加密体系,签名时使用私钥,验证签名时使用公钥
  • b) 比特币系统一般先对一个message取一个哈希,然后再对哈希值签名
  • c) 用户注册:
    (在第三方中心化系统中,账户开通依赖于第三方。但去中心化的比特币系统中,很明显不能进行“申请账户”。)
    在比特币系统中,申请账户是用户自己来处理的,即自己创建一个公钥-私钥对
  • d)
    在发布交易时,通过自己私钥签名,其他人可以根据公钥进行验证,从而保证该交易由自己发起。也就是说,只有拥有私钥,才能将该账户中的比特币转走
    4、 比特币的数据结构
    在这里插入图片描述

1、 想要破坏区块链完整性比较困难。
2、 Header 和 body
a) BlockHeader

1)	Version(版本协议)
2)	Hash of previous block header(前一个区块的哈希值)
3)	Merkle root hash(交易列表的Merkle树根节点哈希值)
i.	保证block body内容不被篡改
4)	Time(时间戳)
5)	target(挖矿难度目标阈值)
i.	挖矿求解问题:Hash(block header)<=target
6)	nonce(随机数)
i.	挖坑是不断调整nonce值进行的,
b)	BlockBody:主要存储交易列表

1) 交易内容包括:

i.	Time(时间戳)
ii.	公钥
iii.	签名
iv.	该交易的哈希值
v.	交易金额
vi.	地址
vii.	等等等

2) 使用各个交易的哈希值构建Merkle Hash Tree,生成的Merkle root hash保存到区块块头中

3、 全节点与轻节点
(因为硬件的局限。一个区块大小为1MB,对于某些用户来说,如果存储区块的所有内容,则所需空间过大,而这是不现实的。所以轻节点只需要存储区块块头信息,全节点存储区块所有内容即可。)

	1)	全节点:保存整个区块所有内容
	2)	轻节点:仅存储区块块头信息

a) 只利用区块链进行交易,但并不参与区块链系统维护和构造
b) 全节点可以向轻节点提供交易存在证明(向轻节点证明某条交易是否被写入区块链)

4、 Merkle Tree
1) 同一个区块中的数据块,通过Merkle Tree的形式组织在一起
2) 优点:只需要记住Merkle root hash(根哈希值),便可以检测出对树中任何部位的修改。
在这里插入图片描述

5、 共识协议
1) 数字货币中经常出现的问题
a) 数字货币和纸质货币区别是可以复制,叫作双花攻击 即double spending attack

   i.	数字货币本身为带有签名的数据文件,可以进行复制。即:对用户来说,可以将同一货币花费两次。

2) 去中心化货币要解决两个问题

 a)	数字货币的发行(由谁发行,如何发行,发行多少,什么时候发行)
	i.	比特币系统中由挖矿来决定货币发行权和发行量。
b)	怎么验证交易的有效性(防止double spending sttack)
	i.	依靠区块链维护的数据结构,记录货币的是否被使用。

举例:
在这里插入图片描述

a)	假设A获得铸币权,新发布了十个比特币(铸币交易)
b)	A将10个比特币分别转给了B,C,它们各五个,并对该交易进行签名,同时需要说明所花掉的10个比特币的来源。
c)	随后,B将5个比特币分别转给C,D,它也需要对交易进行签名,并说明5个比特币的来源。

注:
a)	这里有两种哈希指针,一种指向前面的区块,使得各个区块形成链。第二张是为了说明比特币的来源,说明比特币的来源并非凭空捏造,可以防止双花攻击
b)	交易时,需要付款人的签名和收款人的地址(收款人的公钥的哈希)。
c)	收款方需知道付款方的公钥,从而来验证付款方的签名是否有效(实际上其他节点都需要知道付款方公钥,验证交易合法性)
d)	在该图中,一个区块仅含有一个交易,实际中一个区块中包含多个交易,交易通过Markle Tree组织起来,在区块中存储。

3) 比特币共识协议
各个节点独立打包交易,形成区块链,必然无法避免区块链内容不一致。从分布式系统角度来说,账本内容需要取得分布式共识,从而保证区块链内容在不同节点上的一致性。
背景:假设系统中存在部分节点有恶意,但存在比例较小。大多数节点为“好”的节点,在这种情况下进行共识协议设置。

    想法1:直接投票
    某个节点打包交易到区块,将其发给其他节点,其他节点检查该候选区块,检查若正确投赞成票,若票数过半数,加入区块链。
存在的问题1——恶意节点不断打包不合法区块,导致一直无法达成共识,时间全花费在投票上。
存在的问题2——无强迫投票手段,某些节点不投票(行政不作为)。
存在的问题3——网络延迟事先未知,投票需要等多久?效率上会产生问题。
   更大的一个问题——membership。如果是联盟链,对加入成员有要求,可以基于投票。但比特币系统,任何人都可以加入,且创建账户及其简单,只需要本地产生公私钥对即可。只有转账(交易)时候,比特币系统才能知道该账户的存在。这样,黑客可以使用计算机专门生成大量公私钥对,当其产生大量公私钥对超过系统中一半数目,就可以获得支配地位(女巫攻击)。所以,这种简单的投票方案也是不可行的。

比特币账户巧妙的解决了这个问题,不是按照账户数目投票,而是按照计算力(算力可以用每秒能试多少nonce数值表示)来投票。每个节点都可以在本地组装出一个候选区块,把它认为合法的交易放在里面,然后开始尝试各种nonce值(占4 byte),看哪一个能满足不等式H(block header)≤target的要求。如果某个节点找到了符合要求的nonce,它就获得了记账权。
所谓的记账权,就是往比特币账本里写入下一个区块的权利。只有找到这个nonce,获得记账权的节点才有权利发布下一个区块。其他节点收到这个区块之后,要验证这个区块的合法性。
比如括号里block header的内容填的对不对;block header里面有一个域,叫nBits域,实际上它是目标阈值的一个编码。检查一下nBits域设置的是不是符合比特币协议中规定的难度要求;该不等式是否成立。假设都符合要求,然后检查block body 里面的交易列表,验证一下每个交易都是合法的:①要有合法的签名②以前没有被花过。如果有一项不符合要求,这个区块就是不能被接受的。如果所有条件都符合,也不一定接受。

A.合法的区块会被拒绝吗?
如图所示。发生分叉的情况下,暂时保存分叉情况,但区块链只承认最长合法链,随着时间推移,必然存在某一条链变成最长合法链。这样,也就会导致合法区块被拒绝。
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201024183530647.png#pic_center)

B.分叉攻击
如图所示,A用户对上面的A转账给B的记录回滚,从而非法获取利益。在两条链上,发现交易都合法。这是一个典型的双花攻击。A给B转账后,用分叉攻击将钱又转回来,覆盖掉原来的记录。
  在比特币系统中,这种情况实际上很难发生。因为大多数矿工认可的是最长的合法链,会沿着上面的链继续挖下去。而A这个攻击者要想回退记录,就必须使得下面的链变得比上面的链还长。理论上来说,攻击者需要达到整个系统中51%的计算力,才能使得这种攻击成功。

在这里插入图片描述

此外,区块链正常运行场景下,也可能会发生分叉。当两个节点同时获得记账权时,会有两个等长的合法链。在缺省情况下,节点接收最先听到的区块,该节点会沿着该区块继续延续。但随着时间延续,必然有一个链胜出,由此保证了区块链的一致性。(被扔掉的区块称为“孤儿区块”)
4) 比特币激励机制
为什么系统中节点要竞争记账权?需要提供计算力和电力成本,节点为什么要去做?

比特币系统设计之初便考虑到了这个问题,那就是引入激励机制。比特币通过设置区块奖励来解决该问题,一个获得合法区块的节点,可以在区块中加入一个特殊交易(铸币交易)。事实上,这种方式也是唯一一个产生新比特币的途径。

比特币系统设计规定,起初每个区块可以获得50个比特币,但之后每隔21万个区块,奖励减半。
为了避免节点只想发布区块而不想打包交易,中本聪在设计该系统时,引入了交易费。在一个区块中,其输入>=输出,差值便是给区块所属节点的手续费
6、 系统实现
区块链是一个去中心化的账本,比特币采用了基于交易的账本模式。系统中并没有显示记录账户包含的比特币数,实际上它需要通过交易记录进行推算。

  1. 在比特币系统中,全节点需要维护一个名为 UTXO(Unspent Transaction Output尚未被花掉的交易输出) 的数据结构。
    如图,A转给B 5个BTC,转给C 3个BTC,B将5个BTC花掉,则该交易记录不保存在UTXO中,C没有花掉,则该交易记录保存在UTXO中
    在这里插入图片描述

UTXO集合中每个元素要给出产生这个输出的交易的哈希值,以及其在交易中是第几个输出。通过这两个信息,便可以定位到UTXO中的输出.
为什么要维护这样一个数据结构???
为了防范“双花攻击”,判断一个交易是否合法,要查一下想要花掉的BTC是否在该集合中,只有在集合中才是合法的。如果想要花掉的BTC不在UTXO中,那么说明这个BTC要么根本不存在,要么已经被花过。所以,全节点需要在内存中维护一个UTXO,从而便于快速检测double spending(双花攻击)。
2)BTC系统中具体的区块信息
在这里插入图片描述

7、 挖坑算法和难度调整
比特币争夺记账权的过程叫作挖矿(mining)
1)block header的代码中实现的数据结构
在这里插入图片描述

可以看到,nonce是一个32位的无符号整型数据,在挖矿时候是通过不断调整nonce进行的,但可以看到,nonce的取值最多为2^32 (2的32次方)种。但并非将这些nonce全部遍历一遍,就一定能找到符合要求的nonce。由于近年来,挖矿人员越来越多,挖矿难度已经调整的比较大了,而2^32这一搜索空间太小,所以仅调整nonce很大可能找不到正确的结果。
挖矿时只改随机数不够,还可以更改根哈希值。
在这里插入图片描述

铸币交易没有输入,它有一个coinbase,可以写入任何的内容。也可以把digital commitment里的commit的哈希值写入里面。也可以把第一节讲到的预测股市的内容写入里面,coinbase的内容是没有人会检查的,甚至可以写你的心情。
对应的是最后一个block header里的根哈希值对应的merkle tree,左下角的交易是coinbase,把它的域改了之后,其上的哈希值就发生了变化,然后沿着merkle tree的结构往上传递。最后导致block header里的根哈希值发生变化(merkle root是block header的一部分)。块头里4个字节的nonce不够用,还有其他字节可以用,比如coinbase域的前八个字节当做extra nonce来用,这样子搜索空间就增大到了2的96次方。
在这里插入图片描述

所以真正挖矿的时候只有两层循环,外层循环调整coinbase域的extra nonce。算出block header里的根哈希值之后,内层循环再调整header里的nonce。
2)挖矿难度调整
区块链的出块时间保持平均在10min左右,随着挖矿人数的增加,系统总算力不断增强,挖矿难度绝对不能一成不变。
如果调整挖矿难度?
在比特币系统开发过程中,中本聪便考虑到了这个问题,并设计了一个相应的调整难度的算法。
挖矿本质上就是不断调整block header中的nonce值,使整个block header的哈希值小于等于给定的目标阈值。即:H(block header)<=target.(target便是目标阈值,target越小,目标难度就越大)
在BTC协议中规定,每隔2016个区块需要调整一次难度,根据10min产生一个新区块可以得到,大概需要14天的时间。具体调整公式如下:
在这里插入图片描述

可见,如果实际出块时间比较长,target会比较大,相应的挖矿难度会降低;如果实际出块时间比较短,target会比较小,相应的挖矿难度会增大。
3)全节点和轻节点
之前提到,由于硬件限制,BTC系统中分为轻节点和全节点,下表阐述了全节点和轻节点的区别
在这里插入图片描述

挖矿:

1. 决定沿着哪条链挖下去。
2. 当出现等长分叉,选择哪一个分叉	只能检测哪个是最长链,不知道哪个是最长合法链
在比特币网络中,大多数节点都是轻节点。如果只是想进行转账操作,不需要挖矿,就无需运行一个全节点。在挖矿过程中,如果监听到别人已经挖出区块延伸了最长合法链,此时应该立刻放弃当前区块,在本地重新组装一个指向最后这个新合法区块的候选区块,重新开始挖矿。

8、 比特币网络工作原理
比特币系统的底层(网络层)是一个P2P Overlay network(P2P覆盖网络)。比特币系统中所有节点完全平等,不像一些其他网络存在超级节点(super node)。
每个节点维护一个邻居节点集合,消息传播在网络中采用洪泛法,某个节点在收到一条消息会将其发送给所有邻居节点并标记,下次再收到便不会再发送该消息。(邻居节点选取随机,未考虑网络底层拓扑结构,也与现实世界物理地址无关。该网络具有极强鲁棒性,但牺牲了网络效率。)