区块链的内部结构
Double Spending Attack 双花攻击
重复花费现有的某些货币。
在区块链中,为了避免这种攻击,需要指出每次交易时,货币的来源,以验证交易的合法性。
每笔交易包括输入和输出两个部分:
- 输入:说明币的来源和转账方的公钥
- 输出:给出接受方公钥的哈希值(可以避免有人冒名顶替)
区块内部(全节点)
全节点主要参与区块链的构造与维护
Block header
version
hash of previous block header
Merkle root hash(保证body中的list不被篡改)
target
nonce
puzzle:$H(block header)\le target$
Block body
- trasaction list
其中,list中保存的交易要求在各个块之间达成一致,引出分布式的共识问题
Distributed consensus 分布式中的共识
分布式系统中的相关结论
FLP impossibility result:在一个异步的系统中(asynchronous异步,指网络传输时延没有上限),即使只有一个成员是错误的(faulty),也不可能取得共识
CAP Theorem:包括Consistency,Availability 和 Partition tolerance,三者最多只能做到两种
分布式重要协议:Paxos
- 保证 Consistency 一致性:如果系统内达成了共识,那么这个共识一定是一致的
- 在某些情况下,这个协议可能一直无法达成共识
Consensus in Bitcoin 比特币中的共识
假设系统中大部分节点是好的,有恶意的只是小部分。
联盟链 Hyperledger Fabric (超级账本)企业级许可制分布式账本技术
如何达成共识?直接投票?可能会发生:
女巫攻击 Sybil attack:如果一个有恶意的实体模仿了多个身份,他就可以控制系统的很大一部分,破坏了系统的冗余策略。我们把这种模仿多个身份的攻击定义为女巫攻击 (Sybil Attack)
POW(proof of work)
每个节点都可以在本地组装出一个候选区块,将它认为合法的交易放入区块中,然后开始尝试各种 nonce 值,当满足公式 $H(block header) \le target$ 时,达成目标,则这个节点获得了记账权(即在比特币这个去中心化的账本中写入下一个区块的权利),就发布下一个区块(块中一定含有一个铸币交易)。其他节点收到区块后,验证区块的合法性(例如验证block header中的nonce,nBits是否符合要求,验证block body中的交易是否合法等等),如果不符合要求,则不能被接收
分叉攻击 Forking Attack
通过向区块链中插入一个分支来回滚一个已经发生了的交易
比特币中规定,接收的区块,应该是对最长合法链(longest valid chain)的扩展
虽然块的内容是合法的,但是不在最长合法链上,可能会造成如图所示情况:A将自己的钱转给B后,A再将这笔钱转给自己,转给自己的这笔交易由于不在最长合法链上,就无法进行正确的验证
两个节点同时发布合法区块
如果在正常情况下发生了分叉,就是两个节点同时获得了记账权,发布了合法区块,但其他的节点接收的时间不同,只会接受最早听到的那一个区块,这时就出现了两个等长的分叉。这两个都是最长合法链。
当接受这个区块后,就会沿着这个区块向后继续拓展。因此这种两个最长合法链的情况会维持一段时间,最终会有一个分支胜出,成为唯一的最长合法链,另外一条较短的就叫做 orphan block,之后被丢弃掉。
block reward 出块奖励
获得记账权的节点在发布的区块里,可以有一个特殊的交易:铸币交易(coinbase transaction),可以发布一定数量的比特币,即出块奖励的数量。这是发行新的比特币的唯一方法。
比特币刚上线时,每一个发布的区块可以产生50个比特币(50BTC),即出块奖励。协议规定,21万个区块以后,出块奖励减半,以此类推。
如果一个恶意节点获得了记账权?
双花攻击
如图所示,M将一笔钱转给了A,获得了商品后,M成功挖到了矿,此时在交易之前插入一个区块,再将这笔钱转给自己,造成双花攻击。
避免方式:在6个区块之后,确认某笔交易。此时这笔交易就是不可篡改的
如果转账交易已经发生,但是还没有被写到区块链中,叫做 zero confirmation。
Boycott
矿工不喜欢帐户A,当含有帐户A的交易的区块发布后,立马用一个块插入到之前的位置上形成分叉,使得帐户A无法进行交易