上篇文章我们介绍了比特币区块链的存储模型,介绍完存储模型后肯定会有很多问题,这些问题的答案大部分在写流程里可以找到,今天就来写入流程。
本文预计阅读时间 5 分钟。
在比特币系统中,中本聪的官方写入流程介绍如下:(后面会有解释)
0)用户提交交易(个人补充):A 是一个真实的人,他想给 B 转账,A 需要使用比特币的客户端,选择转账的金额和 B 的钱包 ID,点击发送。比特币客户端可以获得 A 的地址,也就是 A 的钱包ID和电子签名。于是,一笔交易所需要的信息除了上一个交易的输出就都具备了。
1)节点广播交易:这笔交易通过比特币客户端发给比特币的一个系统节点 N1。N1 接收到这笔交易信息后就广播给其他节点,这是异步的,不用等其他节点回复,其他节点接收到新的交易信息后也会做广播。
2)节点打包交易:这里假设系统的每个节点都有向区块链上写入数据的能力(其实某个节点往区块链里写数据就是往本地磁盘写)。每个节点将自己收到的有效交易信息放入一个区块里,存到本地,我们称为候选区块。
3)挖矿:(proof-of-work) 挖矿这个词很火。我们之前提到每个区块头部有一个 nonce,挖矿的本质是使用计算机的计算能力找到一个合适的 nonce,使得这个区块的所有信息 hash 后的小数足够小,比如前70位都是0。因为 nonce 的改变会影响整个 hash 值,所以改变这个 nonce 值就可以改变 hash 后的值。由于这个阈值足够小,需要大量的计算,一般10分钟才会挖到这个 nonce,而挖到 nonce 的节点就有资格向本地区块链上写入这个候选区块了,即证明了工作量。这个挖矿的节点就可以叫做矿工。
为什么这些矿工不合作呢,每人分一段范围的数挖?这是不可行的,由于每个矿工都本地的候选区块都不一样,因此每个候选区块适用的 nonce 值也不一样,可能你分到了一个根本挖不到矿的范围,所以每个矿工只能自己挖。
为什么会有人想当矿工呢?人们不会干费力不讨好的事,因为矿工挖到矿会收获比特币。这笔钱会以一个账单的形式记录在每个区块的开头。所以,其实各个矿工需要的就是CPU的计算能力和电,谁的计算能力越高,谁能挖到矿的概率越大,谁就越有钱,谁就能继续增加计算能力。
这样看,矿被挖到的时间会越来越短,因为计算机的计算能力是逐年升高的。这里,中本聪又设计了可以动态调整挖矿难度,也就是 hash 之后的值需要小于的那个阈值是可调整的。你挖的快了就调低一点,挖的慢了就调高一点。使整个区块链稳定在每10分钟增加一个区块这个水平。
因此,挖矿这个过程总结一下就是:挖属于自己候选区块的矿,并将这个候选区块写入本地区块链。
4)广播区块:当写入这个区块 B 后,矿工需要广播 B 给其他节点。
5)验证区块并写入:节点接收到一个区块 B 时,会验证 B 是否满足要求,且交易合法,交易合法的意思是没有重复消费比特币。如果不满足要求则不承认 B。如果满足要求,就把 B 写到本地区块链的末尾。
6)继续写:第 5)步只将这个区块写到了本地,那如何告诉别人我承认这个区块了?方法如下:如果产生新的区块就追加到 B 的末尾,继续广播新的区块。也就表明这个节点是相信 B 的有效性的,原意往 B 后边加数据。
理想的运行方式
一种理想的工作模式是:严格按照每10分钟有一个节点挖到矿,且一个区块在10分钟之内可以到达所有节点。
举个例子:比特币节点有几千个,1点有一个节点挖到矿了,可以向区块链中写入区块,并在 1点10分之前将这个区块广播给所有其他节点,而其他节点也都验证过了这个区块,并把这个区块加到本地链上。此时所有节点数据都一致了。1点10分又有一个节点挖到矿了,继续这个循环。
这样整个分布式系统中的数据总是一致的,不一致的时间不超过10分钟,由于严格控制了写入速度,使系统没有冲突。系统就这样幸福快乐地永远运行下去了。
但是,现实并不是这么美丽,可能10分钟有两个节点挖到矿了,链会出现冲突,即数据不一致了。我们下节介绍冲突解决和双重支付问题。
总结
理解系统的写入流程是很重要的,写入流程就是系统的基本运转方式,就像人类社会的运转方式,需要用各种规则约束。任何一点流程中的瑕疵在系统中都可能被放大最终导致整个系统挂掉。可以打个比喻,一个稳定运行的系统就像是一个精致的水晶城堡,这就是系统的艺术。
致谢:DPer。研究信息安全,有兴趣可以关注公众号《差分隐私》
领取专属 10元无门槛券
私享最新 技术干货