1. 交易的传播和验证
交易包含两部分:n个输入个m个输出,其中n>=0,m>0
输入=要花费的UTXO+解锁脚本
输出=UTXO(币的数量+锁定脚本)钱包生成交易,并向邻近节点传播。节点对收到的交易进行验证,并丢弃不合法的交易。节点对交易的验证主要包括以下几方面:
交易的size要小于区块的size的上限
交易输入UTXO是存在的
交易输入UTXO没有被其它交易引用-防止双花(Double Spending)
输入总金额>输出总金额(多出来的钱是给旷工的小费)
解锁脚本验证成功
验证合格后将交易加入到本地的Transaction数据库中,并转给邻近节点,邻近节点再做一遍验证然后再转给邻近的节点。
2.区块的生成与验证
区块是区块链的基本结构单元,由区块头和区块主体构成。区块体包括交易数量和交易详情。
- 挖矿之前需要先构造区块,首先将coinbase交易打包进区块 ,然后将交易池中高优先级的交易打包进区块。
- 优先级=交易额度*UTXO深度/交易size(防止粉尘攻击),粉尘攻击是大量低额度、低交易费的交易以至网络拥堵。从理论上说一个交易如果交易费为零,随着UTXO深度的增加,优先级也会变高,但事实上很多旷工会直接拒绝零交易费的交易。
- 创建区块的头部,区块头包括版本号 、父区块哈希(实际上是父区块的区块头哈希值,用来回溯父区块和保证父区块不被篡改)、Merkle树根、时间戳、难度目标值、Nonce。
- 挖矿成功后,将计算出来的随机数Nonce填入区块头部,向邻近节点传播。
相邻区块收到新区快后,立即做以下验证:
验证POW的nonce值是否符合难度值
检查时间戳是否小于当前时间2小时
检查Merkle树根是否正确
检查区块size是否小于区块size的上限
第一个交易必须是coinbase交易
验证每个交易
时间戳
- 矿工们在挖矿的过程中,对收集到的交易记录加盖数字时间戳,并将其打包到区块中。而时间又不能从某个中心服务器获取,这样会违背去中心化思想。其实方法也很简单,还是利用“多数人的正义”,时间来自于连接的其他节点时间的中位数(比平均值更不受极端数字影响),要求连接的节点数量至少为5,中位数和本地系统时间差别不超过70分钟,否则会提醒你更新本机的时间。
Merkle树
这里Merkle树其实就是一颗二叉树,首先对交易进行两次SHA256运算得到相应的哈希值,然后对哈希值两两组队再进行两次SHA256运算,如果交易数量为奇数,则对最后一个哈希值进行复制然后再做哈希运算。比如上图如果再有个交易9,Hash9 = SHA256(SHA256(Transaction9)),Hash99 = SHA256(SHA256(Hash9 + Hash9))。以此类推最后会得到一个Merkle root存入区块头中。这样任何一个交易被篡改,Merkle root必然发生改变,区块头哈希值也就随之改变,之后所有的区块都将是无效区块。因此Merkle树能够校验数据完整性,防止数据被篡改。
通过对一个区块头的所有信息进行哈希运算得出一个哈希值,此哈希值可以唯一并且准确标识这个区块,只要其哈希值不发生变化,就代表区块中的信息没有被篡改。每个区块头都包含上一个区块的区块头哈希值,这使得每一个区块都能找到前一个区块,这样一直倒推就能形成一条完整的区块链。
3.挖矿
为什么要挖矿?
当用户发布交易后,需要有人将交易进行确认,写到区块链中,形成新的区块。在一个互相不信任的系统中,有谁来完成这件事情呢?怎么保证这个记账的人不作恶呢?什么是挖矿?
就是对区块头进行哈希运算,通过不断改变区块头中的nonce值来得出不同的哈希值,如果哈希值小于系统给定的难度目标值,就算挖矿成功,就能获得记账权,同时也能获得奖励和这个区块内的所有交易费。因此如果这个节点作恶,那么别的节点将不会认可这个区块,这个区块将会是白挖了,而且还白白浪费了大量的算力。因此通过挖矿来保证节点不作恶。比特币系统规定每挖21万个区块奖励减半,到2140年比特币将全部被挖出,矿工挖矿将没有奖励,完全靠手续费为生。有没有可能找不到对应的nonce值
nonce占4个字节,就是32位,如果遍历整个2^32后还没算出来,可以通过改变交易的顺序来改变Merkle root,再重新遍历nonce。难度调整
比特币平均每隔10分钟出一个区块,而算力是不断增大的。比特币系统会每隔2016个区块调整一次难度,新目标 = 当前目标值*过去2016个区块用时分钟 / 2016分钟,难度值越大,目标值越小,挖矿也就越难。矿池
由于全网算力越来越大,挖矿难度也越来越大,单个旷工挖出矿的概率越来越小,因此收入就非常不稳定。现在已经很少有个人矿工了,而是很多矿工一起组成矿池。矿池管理员维护全节点,负责打包区块,并将任务分段,给矿工布置挖矿任务。比如A矿工负责0到10万的nonce值的哈希运算,B负责10万到20万,这样挖矿速度就会大大提升。同时矿池内部也会有一个难度值,通过计算每个矿工找到符合矿池难度值得数量来衡量矿工的算力。
比如矿池一天挖出100个比特币,A矿工有10次nonce值计算的哈希值小于矿池难度目标值,而矿池所有矿工共有1000次符合的nonce值,则A矿工提供的算力占矿池的百分之一,应获得1个比特币。至于交易费,不同的矿池有不同的分发。