原创: 张祥利 Pallet 6月14日
张祥利,PalletOne高级核心开发工程师,9年c/c++开发经验。熟悉加解密算法,熟悉比特币,对数据结构和算法有较深入的了解。
Bitcoin入门
区块“链”
奖励发行与总量恒定
产块的第一笔交易,即CoinBase交易,是奖励发行新的Bitcoin
每21万块(4年) 奖励减半,从而总量恒定
https://github.com/bitcoinbook/bitcoinbook/blob/develop/code/max_money.py
产块间隔与难度调整
10分钟一个块
每2016个块(两周)调整一次难度
New Difficulty = Old Difficulty * (ActualTimeofLast2016Blocks/20160 minutes)
难度是基于概率的计算,哈希结果小于某个值
即调整的是Hash起始0的个数
UTXO(unspend transaction output)
交易验证
每个节点在校验每一笔交易时,都需要对照一个长长的标准列表。
如果交易被验证有效,该节点将会将这笔交易传播到这个节点所连接的其他节点,而每一个相邻节点又会将交易发送到三至四个与它们相邻的节点。
这将确保只有有效的交易才会在网络中传播,而无效的交易将会在第一个节点处被废弃。
在收到交易后,每一个节点都会在全网广播前对这些交易进行校验,并以接收时的相应顺序,为有效的新交易建立一个池(交易池)。
区块验证
当一个节点接收到一个新的区块,它将对照一个长长的标准清单对该区块进行验证,若没有通过验证,这个区块将被拒绝。这些标准可以在比特币核心客户端的CheckBlock函数和CheckBlockHead函数中获得,它包括:
▷ 区块的数据结构语法上有效
▷ 区块头的哈希值小于目标难度(确认包含足够的工作量证明)
▷ 区块时间戳早于验证时刻未来两个小时(允许时间错误)
▷ 区块大小在长度限制之内
▷ 第一个交易(且只有第一个)是coinbase交易
▷ 使用检查清单验证区块内的交易并确保它们的有效性,
▷ “交易的独立校验”一节已经讨论过这个清单
区块打包
验证交易后,比特币节点会将这些交易添加到自己的内存池中。
节点在收到新区块并验证后,会移除已经在新区块中出现过的交易记录,确保任何留在内存池中的交易都是未确认的,等待被记录到新区块中。
创建Coinbase交易(coinbase奖励和计算全部交易矿工费的总和),计算Merkel根。
构造区块头,区块头完成全部的字段填充后,开始挖矿: 改变nonce值以满足难度。
交易块龄,优先级
UTXO的“块龄”是自该UTXO被记录到区块链为止所经历过的区块数,即这个UTXO在区块链中的深度。
交易的优先级是通过输入值和输入的“块龄”乘积之和除以交易的总长度得到
Priority = Sum (Value of input * Input Age) / Transaction Size
比特币网络
全节点
轻节点:简易支付验证 (SPV)节点
SPV节点只需下载区块头,而不用下载包含在每个区块中的交易信息。SPV节点会通过请求merkle路径证明以及验证区块链中的工作量证明,来证实交易的存在性。
矿工
矿机
矿池
网友评论