一个近期的真实案例可以帮助理解这一抽象概念。2026年初挖出的第948,000个比特币区块,其区块哈希值为00000000000000000001b01841afc366a4f999b291c8563ee0d0db956fc2db44,对应的随机数(nonce)值为2,582,463,598。这个整数与区块头中的其他信息结合后,最终生成了一个低于网络难度目标的哈希值,使该区块获得有效性并被添加到区块链中。矿工此前尝试的其他随机数都没有产生符合条件的结果。

从机制上看,这就是工作量证明(Proof of Work)的本质:矿工不断寻找一个有效的随机数,并通过持续进行哈希计算消耗电力和算力,以争夺新区块的记账权。
image.png

哈希 nonce 与账户 nonce:同一个词,不同的作用

“nonce”在加密货币领域还有另一种常见含义,这也是新手最容易混淆的地方。

比特币挖矿中的 nonce 是一个搜索变量,矿工不断修改它,以寻找符合难度目标的区块哈希;而以太坊账户中的 nonce 则是一个计数器,用于记录账户已经发送的交易数量。两者名称相同,但实际用途几乎完全不同。

“仅使用一次的数字”:nonce 一词的来源

“nonce”经常被解释为“number used once(仅使用一次的数字)”,这种说法在密码学语境下基本成立,但从词源来看并不准确。英语单词“nonce”早在密码学出现之前约750年就已经存在。“For the nonce”这一表达大约出现在13世纪的中古英语手稿中,意思是“为了这个特殊场合”。

到了1978年的Needham-Schroeder认证协议,密码学开始使用“nonce”这一术语。它真正强调的并不是随机性,而是特定范围内的唯一性。从密码学角度看,nonce可以是计数器、时间戳、随机值,也可以是三者的组合,关键要求是:在特定系统和上下文中,同一个nonce不能被重复使用。

因此,比特币、以太坊以及对称加密中的nonce虽然使用同一个词,但承担的是不同任务。

比特币挖矿nonce会不断变化,直到区块哈希低于难度目标;以太坊账户nonce是一个不断递增的交易计数器;而对称加密中的nonce则是与特定密钥配对的值,一旦重复使用,可能直接破坏加密安全性。

这个词本身含义宽泛,但具体含义高度依赖使用场景。

比特币挖矿中 nonce 的工作原理

在比特币中,随机数(nonce)位于80字节区块头中的32位字段内,其取值范围为0至4,294,967,295,也就是约43亿种可能。

矿工的目标,是在区块头中找到一个能够生成有效区块哈希的nonce。矿工将80字节的区块头输入SHA-256哈希函数两次,得到一个256位数字,然后将其与网络当前的难度目标进行比较。如果结果低于目标值,区块有效;如果高于目标值,矿工就修改nonce并重新计算。

因此,挖矿本质上是一种高速试错过程。矿工不断尝试不同的nonce,直到找到符合要求的结果。

为什么协议只给nonce分配32位空间?原因在于,nonce是矿工能够以最低成本修改的区块头字段。相比之下,区块交易发生变化后,默克尔根也会变化;修改交易意味着重新计算相关数据,而修改nonce则不需要重新构建整个区块。

但随着ASIC矿机出现,32位nonce空间已经远远不够。现代矿机能够在极短时间内耗尽全部43亿个可能值,因此矿工还需要通过调整coinbase交易中的extra nonce(额外随机数)、时间戳以及部分版本位等方式改变区块头,从而获得新的搜索空间。

其中,修改extra nonce会改变coinbase交易的交易ID(TXID),进一步导致默克尔根发生变化,最终使整个区块头改变。矿工随后又可以重新搜索32位nonce。

当矿工找到一个低于目标值的哈希时,这个结果有时会被称为“黄金随机数”。新区块随后通过点对点网络传播,其他矿工停止当前搜索并开始下一轮。

因此需要特别注意:比特币挖矿nonce只是矿工搜索过程中使用的临时数字,而以太坊账户nonce则属于账户状态的一部分。

以太坊账户 nonce 与卡住交易问题

以太坊中的每一个外部账户都有自己的nonce。该计数器从0开始,每当账户发送一笔交易并按照顺序执行后,nonce就会递增。

例如,一个账户可能依次使用nonce 0、1、2、3。网络不会允许账户直接跳过某个nonce执行后续交易。

这种严格的顺序机制也是以太坊防止交易重放的重要组成部分。已签名交易绑定特定nonce,同时在EIP-155之后还绑定特定的chain ID,因此旧交易不能简单地重新广播成一笔新的有效交易。

但这种机制也会产生一个常见问题:交易卡住。

如果一笔交易的手续费不足以吸引验证者及时打包,它可能长期停留在内存池中。而同一个地址之后提交的交易会获得更高的nonce。在前一笔交易被确认或替换之前,后续交易可能无法正常执行,从而造成整个交易队列停滞。

解决方式通常是通过“费用替换”(Replace-by-Fee)重新提交一笔具有相同nonce、但手续费更高的新交易,以替换原来的交易。

如果用户希望取消一笔卡住的交易,也可以在相同nonce下发送一笔新的交易,让新的交易竞争原来的交易槽位。交易一旦成功被确认,后续nonce对应的交易就能够继续处理。

账户抽象化则进一步改变了这一机制。ERC-4337智能账户可以使用二维nonce,将交易序列拆分为不同的并行流,使一个交易流发生阻塞时,不一定会影响其他交易流。

需要注意的是,以太坊在2022年9月完成“合并”并转向权益证明(Proof of Stake)后,账户nonce并没有消失。发生变化的是共识机制以及区块头中的挖矿nonce。验证者不再依靠传统的哈希谜题竞争区块,而是按照权益证明机制参与区块生产。

加密中的 nonce:重复一次就可能造成灾难

离开区块链之后,nonce在密码学中的作用同样重要,而且一旦使用错误,后果可能更加严重。

现代认证加密算法通常要求将密钥与每条消息的nonce进行配对。例如,AES-GCM和ChaCha20-Poly1305都使用96位nonce。其核心规则非常简单:

同一个密钥下,nonce不能重复使用。

对于AES-GCM而言,如果相同密钥和nonce被重复使用,攻击者可能通过比较不同密文获取有关底层明文的信息,而且还可能进一步破坏消息认证安全。

类似问题也曾真实发生。2010年索尼PS3的安全漏洞就是因为ECDSA签名中的随机值k被重复使用,攻击者最终可以利用多个签名恢复私钥。这个案例说明,在密码学中,一个看似普通的随机数错误,可能直接导致整个密钥体系失效。

2013年的RFC 6979则提供了一种确定性ECDSA方案,通过消息和私钥计算签名所需的k值,从而减少对外部随机数生成器的依赖。

这里还需要区分不同密码算法的规则。

对于AES-GCM、ChaCha20-Poly1305等AEAD算法而言,nonce可以是可预测的,例如使用递增计数器,只要确保在同一个密钥下绝不重复即可。

但对于ECDSA和Schnorr签名而言,签名随机数的要求更加严格。签名nonce不仅需要唯一,还必须避免泄露,否则可能导致私钥被恢复。

因此,不能简单地把“随机”理解为“必须不可预测”。不同密码系统对nonce的要求并不相同。

Salt、Nonce与IV并不是一回事

在安全领域,Salt(盐)、Nonce(随机数)和IV(初始化向量)有时会被混在一起,但三者并非完全等同。

Salt主要用于密码哈希。它通常是为每个用户生成的随机值,与密码共同参与哈希计算,以阻止攻击者直接使用预计算的彩虹表。Salt通常可以公开保存,并不需要保密。

Nonce则更多用于消息加密、认证以及数字签名。它通常与密钥和消息处理过程相关。在AES-GCM等AEAD算法中,nonce可以公开,但必须确保同一密钥下不重复;在ECDSA等签名算法中,nonce的安全要求则更加严格。

**IV(Initialization Vector)**则是许多传统加密模式中使用的术语,尤其常见于CBC、CTR等模式。现代AEAD标准更多使用“nonce”这一术语,但二者在具体协议中的定义和安全要求仍需结合算法本身判断。

如果只记住一条规则,可以这样理解:

Salt主要用于保护密码哈希;Nonce主要用于保证消息或签名过程中的唯一性;而IV则是许多加密模式中用于初始化加密状态的参数。

同一个“nonce”术语,可以出现在比特币挖矿、以太坊账户和现代密码学中,但它们解决的是完全不同的问题。理解这一点,是进一步理解工作量证明、交易排序以及密码学安全机制的基础。