比特币的一些实现细节

一、UTXO

比特币的区块链是基于交易的账本(transaction-based ledger),区块内记录着所有交易信息。

根据区块链账本可以计算出所有未花费的交易,也就是UTXO(Unspent Transaction Output),全节点的内存中维护着UTXO数据结构,记录所有未花费的交易输出,如果一笔交易输出被花费了,那么就从UTXO中删除。

UTXO可用于验证新交易是否合法,如果新交易的来源在UTXO中搜索不到,那么该交易是无效的,不会被加入到区块中。

值得注意的是,如果某笔输出不花费出去,那么该输出将永久保存在UTXO中。

二、交易费(transaction fee)

一笔交易可能会有多个输入和多个输出,如果总输入大于总输出,差额作为交易费付给记账节点的账户,这样记账节点将更有动力将这笔交易打包进区块。公式如下所示:
t o t a l i n p u t s t o t a l o u t p u t s t r a n s a c t i o n f e e = t o t a l i n p u t s t o t a l o u t p u t s total inputs ≥ total outputs\\ transaction fee = total inputs - total outputs

三、区块头(block header)代码解析

变量类型 变量名称 注释
int32_t nVersion 比特币版本协议
uint256 hashPrevBlock 前一个区块的哈希
uint256 hashMerkleRoot Merkle root 哈希,由于nNonce值的空间有限,如果尝试了所有nonce值,仍不满足target阈值,则可通过改变coinbase域前8个字节来使hashMerkleRoot变化,从而可以继续尝试nonce值,最终将获得符合要求的nonce值
int32_t nTime 区块产生时间
int32_t nBits 挖矿的目标阈值,编码后的target
int32_t nNonce 最多2^32个取值,全部尝试后仍不满足就修改coinbase域

一个完整的区块包括区块头和区块体,一般在1M字节以内。

四、挖矿过程的无记忆性

伯努利试验(Bernoulli trial):
具有两种结果的随机试验(a random experiment with binary outcome)。
每次尝试nonce值,都是一个伯努利实验。

伯努利过程(Bernoulli process):
一系列独立的伯努利试验(a sequence of independent Bernoulli trials)
伯努利过程具有无记忆性(memoryless),前面的试验结果对后面没有影响。

泊松过程(Poisson process):
试验次数很多,每次试验成功概率都很小。出块时间服从指数分布(exponential distribution),如下图所示:
在这里插入图片描述
平均挖矿时间是10min,就算已经尝试了很长时间的nonce值仍不符合要求,接下来成功找到nonce值的平均时间仍然是10min。无记忆性可保证挖矿公平,否则算力强的节点随着时间流逝会产生更强的优势,超出了算力比例的优势。

五、挖矿奖励变化与总量

挖矿奖励减半时间:
比特币规定每21万个区块奖励减半,每个区块的出块时间大约是10分钟,因此大约每隔4年出块奖励减半,推导过程如下:
21 × 10 60 × 24 × 365 4 \frac{21万个区块×10分钟}{60分钟×24小时×365天}≈4年
比特币总量:
比特币的发行依靠区块的奖励,比特币总量也就是奖励总量。最一开始的奖励是50BTC,逐渐减半,可计算出比特币总量为2100万个,推导过程如下:
21 × 50 B T C + 21 × 25 B T C + 21 × 12.5 B T C + . . . . . . = 21 × 50 B T C × ( 1 + 1 2 + 1 4 + . . . . . . ) = 21 × 50 B T C × ( 1 1 1 2 ) = 2100 B T C \begin{aligned} &21万×50BTC+21万×25BTC+21万×12.5BTC+......\\ &=21万×50BTC×(1+\frac{1}{2}+\frac{1}{4}+......)\\ &=21万×50BTC×(\frac{1}{1-\frac{1}{2}})\\ &=2100万BTC \end{aligned}

六、挖矿保证比特币的安全性(Bitcoin is secured by mining)

6次确认

用户A转账给B,B需要等待6个区块的确认,才能保证转账给自己的比特币生效;
如果没有足够区块的确认,A可以发起一笔转账给自己账户A’的交易,然后重新挖矿,产生区块,在这个区块后面继续挖矿产生区块,努力让分叉成为最长合法链,使得之前A转给B的交易将会失效,B也得不到该笔资金。
如下图所示,如果B能够看到该笔交易后面已经有6个区块了,那么这条链将大概率成为最长合法链,攻击者的分叉也很难追上这条链了,B基本确保拿到了该笔资金。
在这里插入图片描述

零次确认(zero confirmation)

由于等待6次确认需要大约60分钟,有时可能还要长于这个时间,在某些情况下,我们无需等待区块产生或者6个区块的产生:

  1. 大部分节点为诚实节点,且诚实节点默认接收最一开始的交易,即使作恶的人又发起了一笔转给自己的交易,第二笔交易一般被认为是无效的,不会被放入区块。
  2. 如果是网上购物,发货本身也需要一定的时间,如果发现转账被分叉了,再撤销物流也不迟。

自私挖矿(selfish mining)

自私挖矿指的是如果挖到区块之后,不立马发布出去,而是自己接着再挖下一个区块,这时会少一些竞争,如果顺利挖到的话,一下子全部发布出去,这样自己能够获得两个区块的奖励。但是这样存在一个风险,不发布挖到的区块,别人随时可能挖到区块并发布,如果生效的话,那么自己保留的区块将会失效,也就得不到任何奖励。
所以自私挖矿需要算力足够强,才更有可能连续发布两个区块,而不至于得不到任何奖励。

发布了7 篇原创文章 · 获赞 0 · 访问量 1466

猜你喜欢

转载自blog.csdn.net/ice_fire_x/article/details/104158009
今日推荐