注:本文为翻译,略微改动,原文:https://blog.goodaudience.com/how-a-miner-adds-transactions-to-the-blockchain-in-seven-steps-856053271476 你曾经好奇在挖矿在区块链上是怎样进行的吗?
想知道一笔交易是如何确认并且添加到区块链上的吗?
我也有过这样的疑问。我找了没有找到对这些过程的处理一步步清晰的描述,所以我决定自己把这些理解写出来。下面我将分为七个步骤来讲述在区块链上一个交易如何被处理并记录上链的。
一、交易签名交易者用钱包客户端对一笔交易进行签名,目的是发送特定的数字货币或者 token 令牌给其他的交易者
二、广播交易这笔交易由钱包客户端广播给区块链上正在挖矿的矿工,在没有矿工记录这笔交易前,交易被保存在 “待确认交易池” 中。”待确认交易池“ 是保留在网络上等待被处理交易的集合。这种池子通常不是一个巨大的池子,而是以小的细分的本地池的形式存在。
三、选取交易网络上的矿工(通常被称为是节点,但并不十分准确)在这些 ”待确认交易池“ 中选取一部分交易形成一个区块。区块通常是多个交易的集合(这时交易还未被确认),再加上一些额外的元数据。每个矿工生成自己的区块。其他的矿工也可以把这些相同的交易写进他们自己的区块中。
举个例子:
矿工 A 和矿工 B 可以同时把交易 X 记录到他们的区块当中。每一个区块都有它的最大容量。在比特币中,一个区块的最大容量是 1MB 的数据。在把交易记录进他们的区块之前,矿工需要根据区块链上记录的历史交易来确定当前交易是否合法。 如果比特币的拥有者,想要让他的交易更快的被确认,他可以选择提供更高的支付奖励。矿工想获取更高的报酬,所以会优先选择记录 ”待确认交易池“ 中奖励更高的交易。
四、计算签名
选择好了待确认的交易,矿工们各自创建一个区块,把交易记录在区块上。接下来就是是把这个区块添加到区块链上(这意味着区块链上的所有节点都记录这个区块),为了达到这个目的,这个区块首先需要一个签名(通常被称为是工作量证明)。 对于一个区块来说,签名是由进行唯一的(不与其他区块相同)同等难度的非常复杂的数学计算来产生。每个区块进行的数学计算是不同的,所以每个矿工需要针对他们的区块进行一个唯一的不同于其他区块的数学计算。这些数学计算都是同等难度的。解决这个数学计算的问题,需要大量的计算能力(也就意味着需要大量的电力消耗)。 对比在计算器上计算来说,这些计算量要大的多,所以通常需要在计算机上进行。这个大量算力消耗进行计算的过程被称为 ”挖矿“ 。如果您想进一步了解这些数学计算的工作原理(实际上并不那么复杂),请继续阅读以下内容;否则,想保持一个更简单的理解,请直接跳至步骤5。
挖矿又叫做 hash 计算(工作量证明的共识算法)
每个矿工想要在区块链上添加一个区块,需要解决的数学计算问题就是:给该区块中的数据计算出一个 以确定的 0 的个数开头的 hashcode(又称签名)。这听起来很复杂?但实际上并不是很复杂。
简单来说,首先,了解 hash 函数是什么很重要(译者说:这里直接描述 hash 函数是不准确的,hash 函数有很多种,原作者这里描述的应该是特指比特币区块计算的 hash 函数,下面不再强调说明)。这个 hash 函数需要是一种计算非常难,但是验证起来很简单的 hash 函数。
hash 函数是一种接收任意长度的字符串和数字组合,然后输出一个 32 个字符(比特币的 hash 算法用的是双重的 SHA256,输出应该是 256bit 的数据即 32 个字节,一般处理为 16 进制字符来输出,应该是有 64 个字符,这里原作者用 32 个字符不恰当)的数字和字母的随机组合字符串。如果输入中有任何字符改动,输出也将产生随机的改动,但是相同的输入经过 hash 函数计算出的结果总是相同的。(关于 hash 函数想要有更多的了解可以参考我的那篇 《白话讲 hash》)
现在想这样一个问题,一个区块上记录的交易数据是确定的, hash 函数对于相同的输入计算出的输出总是相同的,而且要想记录在比特币的区块链上,又要求这个 hash 输出的前面确定的位数是 0 。 这时候如果区块记录的交易数据计算出的 hash 输出不满足要求怎么办?比特币的做法是,矿工可以在区块中数据中添加一个随机数,然后再进行 hash 计算 。每次计算都改变这个随机数,由于随机数改变,hash 计算输出也会改变。
矿工无限期的重复改变随机数计算 hash,直到撞上满足输出结果前面是指定数量的 0,比如说 7 个 0。实际上前面 0 的数量取决于区块链的计算难度。区块的结构稍微复杂一些,下面是区块结构图:
这就是矿工要记录一个区块需要大量算力计算出数学问题的原因。猜测许多不同的随机数会耗费大量的算力。当大量的算力加入到区块链计算中,数学计算的难度也会增加(要求 hashcode 前面 0 的位数增多),同时将导致更多的电力消耗。 关于计算难度和电力消耗更多的信息请参考:https://blog.goodaudience.com/blockchain-the-mystery-of-mining-difficulty-and-block-time-f07f0ee64fd0
注意:这个处理过程实际上不应该定位为数学问题,而是一件确定性的事情-计算机对数字执行预定的操作,以查看输出是否满足要求
五、区块广播
矿工找到一个合法的签名(上过程计算出的 hashcode),将签名和区块一起广播给所有其他矿工
六、区块合法性检测
其他矿工检测收到广播的区块和签名的合法性,计算这个区块上的交易数据和随机数是否满足输出的hashcode 前面有指定数量的 0(还记得前面说的吗?计算十分困难,验证比较简单)。 如果它是合法的,其他矿工将承认该区块的合法性,并将这个区块添加到区块链上(他们达成共识,基于共同的共识算法)。这就是工作量证明定义的由来。这个签名就是工作量的保证(计算出符合规则的签名消耗了大量算力)。 这个区块现在可以被添加到区块链上,并且广播给网络上的每一个矿工。只要区块内的交易根据之前区块的历史记录计算出来是合法的,其他的节点就会接受并且保存这个区块。
七、区块确认
当一个区块被添加到链上,在它后面添加的区块都将被看做是它的确认。例如,我在编号为 502 的区块记录了一笔交易,当前区块链长度为 507 ,这就意味着,我 502 记录的这笔交易被确认了 5 次(507-502 = 5)。 之所以称之为确认,是因为,在当前添加区块后面添加的区块,都将确认对整个交易和记录交易的区块达成共识。你可以说你的交易被区块链确认了 5 次。越多的确认次数(也就是说 区块嵌入区块链内越深)区块越难被攻击。 如果你想了解确认次数和被攻击相关的知识,可以参考:https://medium.com/coinmonks/what-is-a-51-attack-or-double-spend-attack-aa108db63474 当区块被添加到区块链中之后,矿工又开始重复步骤三中的工作:创建一个新的区块。矿工在解决以下两个问题前不能继续挖矿(其实可以,不再本文讨论范围之内)
如果这个区块中与当前区块链上最后一个区块有相同的交易(所有矿工都在挖矿,选择交易记录),则这个区块的所有交易被认为是不合法的。因为,交易者的钱可能已经不够支付。
每个区块需要添加前一个区块的签名到自己的元数据里。这是区块组成区块链的必要条件。如果一个矿工对已经在区块链上的区块进行挖矿,其它矿工将会注意到它的元数据和区块链上的最后一个区块签名不一致,将拒接添加该区块到区块链上。