一场靠出力才能中奖的彩票
想象世界各地有成千上万的陌生人,谁也不是主管,却都想写下一本共享账本的下一页。如果他们同时动笔,结果只会是一片混乱——互相打架的页面,谁也不服谁。工作量证明用一个极其简单的想法解决了这件事:别投票,去干活。想赢得添加下一个区块的权利,你得先赢一场彩票——而买彩票的唯一方式,就是实打实地烧掉算力。谁付出了这份力气、又恰好先碰上运气,谁就赢;其余所有人都能在一瞬间核对这个结果。
跑这场比赛的人叫矿工,比赛本身就是挖矿。叫它「挖矿」是个比喻:就像挖金子一样,你付出力气却没有回报的保证,而每隔一阵子才会挖到一次。我们来看看他们究竟在挖什么。
谜题:哈希要落在目标之下
这道谜题用到密码学哈希——一种把任意数据变成定长乱码数字的函数。它有两点特别适合做彩票。第一,你无法预测输出:把输入改动一个字符,结果就会跳到一个完全不同、看起来随机的数字。第二,你无法倒着算它:没有捷径能找出一个输入,让它正好给出你想要的数字。唯一的办法就是猜、算哈希、核对、再来一遍。
要构建一个区块,矿工先把待处理的交易收集起来,再配上一个概括该区块的小小区块头。区块头里有一个字段矿工可以随意改动:随机数(nonce,意为「只用一次的数」)。矿工要做的,就是找到一个随机数,使得对整个区块头求哈希得到的数字足够小——具体来说,要小于一个叫做目标值的门槛。把获胜条件写成一道简洁的不等式,就是:
hash( block_header_with_nonce ) < target nonce = 0 -> hash = 9c4f...e1 (too big, no) nonce = 1 -> hash = 71a0...3d (too big, no) nonce = 2 -> hash = a8b2...ff (too big, no) ... nonce = 49281-> hash = 0000a3...7 (below target -> WIN!)
难找,却一秒可验
让整套系统得以运转的魔法就在这里。找到一个中奖随机数极其困难——没有巧妙的方法,只能盲目试错,所以一个矿工可能要算上万亿次哈希,才碰到一个落在目标值之下的。可一旦找到了,任何人只用一次哈希就能验证:拿过区块头和那个幸运随机数,求一次哈希,自己看看结果是不是低于目标值。产出代价高昂、验证轻而易举——这种不对称,正是工作量证明的核心。
这就是为什么谁也不必信任谁。一个中奖的区块自带它的证明:那个随机数本身,就是「有人真的烧掉了算力」的证据。你信这个矿工,不是因为他和善或有官方身份——而是因为你能自己重算一次哈希,数学对得上。
难度让节奏保持稳定
如果目标值固定不变,那么随着矿工增多或换上更快的机器,这场比赛会越跑越快——区块来得太快,又不可预测。于是网络会按既定节奏调整目标值,这套机制叫做挖矿难度。规则是自我校正的:如果最近的区块来得太快,网络就调低目标值(提高难度),要求更多前导零;如果区块来得太慢,就调高目标值(降低难度)。
最长的链获胜
有时两个矿工几乎同时中奖,网络就会短暂地分成两条互相竞争的链。没有裁判来定夺。取而代之的,是一条机械而著名的规则:诚实的矿工总是在累积工作量最多的那条链上继续构建——实际操作中,就是最长的有效链。下一个区块落在哪条分支上,哪条就胜出,较短的分支干脆被放弃。它里面的交易会退回等待池,留待以后再被收录。
这就是为什么那么多力气换来的是安全。要改写一个旧区块,攻击者得重做它的工作量,还要跑赢真链上每一个诚实矿工——一场接一场地重新中奖,速度还得超过世界上其余所有人加起来。一个区块被埋得越深,这件事就越是贵到不可能,这正是为什么一个旧区块会被当作已成定局。
这一切的猜测都靠电力运转,那份能耗是真实存在的——它就是让这条链「攻击起来很贵」的字面意义上的代价。把工作量证明讲清楚之后,下一篇会看另一台伟大的共识引擎,它用锁定的权益取代了被烧掉的电力。