密码学与交易生命周期

# 密码学与交易生命周期

签名证明谁同意了这笔操作,共识决定大家接受哪段历史,回执说明执行结果,最终性决定结果何时可以被业务信任。这四件事不能互相替代。

区块结构、P2P 网络、PoW 和 PoS 的展开介绍复用 区块链基础。本篇把它们串成一次真实交易,并补充开发时需要注意的边界。

# 哈希、签名、加密分别解决什么问题

技术 作用 不能保证什么
哈希 把数据变成固定长度指纹,检测内容是否变化 不能隐藏低熵原文,也不能证明是谁写的
数字签名 用私钥签名、用公钥验证消息与签名者的关系 不会自动保密,也不保证签名者理解了业务后果
加密 让没有相应密钥的人无法直接读取内容 不自动证明消息来自哪个业务身份
Merkle Tree 用树状哈希,把很多条记录汇总成一个根,并支持包含证明 包含证明不代表那条记录对应的现实事件真实

已有密码学笔记帮助理解用途,但ECDSA 签名不是 “私钥加密、公钥解密” 。它使用特定的数学签名与验证算法;钱包签名也不会把交易内容变成密文。以太坊常用的 Keccak-256 与标准 SHA3-256 也不能直接互换。

例如四条记录分别得到 A、B、C、D 四个哈希,再计算 AB、CD,最后得到根。如果要证明 A 在其中,只需给出 B 和 CD 两个相邻分支,不必下载全部记录。验证者必须事先信任或验证根的来源,否则伪造一棵树也能自洽。

# 一笔 EVM 交易经过哪些阶段

以用户调用课程合约的 purchase(courseId) 为例:

  1. 构造。客户端确定 chainId、合约地址、调用数据、金额、nonce 和费用上限。chainId 标识网络;nonce 是发送账户的交易序号,用于顺序控制与防止同一交易重复执行。
  2. 签名。钱包展示操作,用户同意后用私钥签名。拒绝签名还没有链上交易,也不会因此支付链上 Gas。
  3. 广播。RPC 节点接收签名交易。RPC 是客户端与节点交换请求的接口,不是区块链本身;一个节点接收不等于全网都已经接受。
  4. 等待打包。交易可能在节点交易池等待,也可能通过私有交易路径提交;费用不足、nonce 缺口或网络问题都会影响是否被打包。
  5. 执行。交易进入区块,节点按同样规则执行字节码,生成状态变更与 receipt(回执)。回执的 status 表示成功或失败。
  6. 确认。业务继续跟踪区块是否仍在规范链上,再根据链的最终性和业务风险决定何时交付不可逆权益。

返回交易哈希,只表示可以用它追踪交易,不是 “购买成功” 。即使调用 RPC 超时,交易也可能已广播,不能直接让用户重复付钱。

# 超时、替换和重组怎样理解

现象 实际含义 应当怎样处理
一直没有回执 未打包、被丢弃、RPC 不同步等都有可能 按哈希和发送账户 nonce 跟踪,不直接判定成功或失败
加速或取消 钱包通常用同一 nonce 的另一笔交易尝试替换 追踪最终被打包的交易;取消不保证抢在原交易之前
回执失败 执行发生 revert 或耗尽 Gas 等错误 显示原因,检查已消耗费用;不要再按成功事件发放权益
区块重组 原先看到的区块被另一条规范历史替代 撤销旧投影,从共同祖先补扫,重新确认结果

确认数与最终性不是同义词。确认数表示后续又有多少区块;以太坊 PoS 还提供 safe、finalized 等链头标签,表示不同保证。高价值业务应明确采用哪种策略,而不是统一等待几秒。L2 还可能区分排序器确认、数据提交到 L1 和结算最终性,不能照搬主网等待策略。

# 用 nonce 解释卡单、加速和取消

交易 nonce 可以理解为同一个钱包在同一条链上发出交易的递增序号。这里讨论普通以太坊钱包发出的交易,每个账户独立编号,不是全网共用一个序号;钱包通常会自动填写。

它主要解决两个问题:

  • 防止重复执行:某个序号已经被链上交易使用后,再广播同一笔签名交易,也不会让它执行第二次。例如一笔转账已经上链,别人原样重发它,不会让你再付一次钱。
  • 确定执行顺序:同一个账户的交易按 nonce 顺序执行。例如先发授权交易,再发购买交易,购买必须排在授权之后执行;但前一笔被处理,不代表它一定成功。

假设账户下一笔应执行的 nonce 是 8,却先广播了 nonce 9。后者通常要等 nonce 8 被处理后才能执行,不是给 nonce 9 增加 Gas 就一定能解决。

交易上链执行失败,也会消耗 nonce。例如 nonce 8 的授权交易上链后回滚,下一笔仍使用 9,不能重新使用 8;但授权没有生效,购买仍可能失败。只签名、只广播或仍在等待打包,则还没有在链上消耗这个序号。

用户给 nonce 8 的交易加速时,会尝试广播另一笔同 nonce、满足节点替换要求的交易,因此交易哈希可能变化。所谓取消通常也是竞争替换,不是从全网删除原交易;原交易如果先被打包,取消就没能阻止它。

后台跟踪应把一次业务操作与相关交易尝试分开保存,记录 chainId、发送者、nonce 和哈希。发现替换后核对新交易的目标、value 和 data:同 nonce 的新交易可能是支付加速,也可能是不再支付的取消交易,不能一律认定原业务成功。

交易 nonce 和登录 nonce 有什么区别

  • 交易 nonce 是链上校验的递增序号:用于交易防重放和执行顺序控制。
  • 登录 nonce 是后端生成的一次性随机验证码:用户把它包含在登录消息中签名,后端验证后将它标记为已使用,防止同一份登录签名反复登录。具体流程见 SIWE 钱包签名登录。

两者都用于防重放,但登录签名不会消耗钱包的链上交易 nonce,也不需要发送链上交易。

# 回执失败和短重组为什么是两件事

回执失败表示这次执行进入了区块,但业务调用没有成功;重组则表示原来承载结果的区块不再属于当前规范链。即使先前回执是 success,所在区块离开规范链后,也不能继续据此发放最终权益。

为什么会发生:新区块和验证者的投票需要通过网络传播,各节点收到它们的时间并不一致。消息延迟时,不同节点可能暂时认为不同的分支才是主链;后续收到更多信息,再按共识规则选择分支。节点如果切换到另一条分支,原先跟随的部分区块就会被替换,这就是重组。以太坊 PoS 的分支选择与验证者的投票权重等规则有关,不是平台可以任意修改交易记录。

什么时候可能发生:主要是在链尾区块还没有最终确定时,区块传播较慢、投票消息延迟或短暂网络故障都可能造成分歧。因此短重组不一定来自攻击,也不是每笔交易都会遇到;单纯交易排队、Gas 不足则不等于重组。

“短” 指影响的区块数量少,不是交易耗时短。等待后续确认可以降低风险,但确认数不等于以太坊的 finalized(已最终确定)状态;已最终确定的区块不会因为这种普通网络分歧被正常替换。

例如先观察到区块 100-A 中购买成功,随后规范链在高度 100 变成 100-B。应标记 A 分支的事件失效,再核查购买交易是否被重新纳入后续区块。高度 100 这个数字没变,不代表同一个区块;所以索引必须保存 blockHash。

如果 100-B 及其后续区块还没有这笔购买交易,就不能继续按原来的成功回执认定已付款。它可能重新被打包,也可能仍在等待;重组不等于付款必定失败,而是原来的到账依据需要重新核实。

确认策略应按业务分层:界面可以快速提示已执行,高价值发货或提现则等待更强保证。具体补扫与投影恢复见 链上索引,不能只在 UI 多等几秒就声称解决了重组。

# 共识不替代业务判断

节点可以验证签名、余额、nonce 和执行规则,却无法知道用户是否被钓鱼、报价是否公平。预言机提交的价格也需要合约检查时效与异常值。 “大家都执行了同一段错误规则” 不会让规则变正确。

# 面试时可以这样回答

交易 nonce 有什么用,和登录 nonce 有什么区别?

建议回答:交易 nonce 是同一钱包在同一条链上的递增交易序号,主要防止同一笔交易重复执行,并保证交易按序处理。比如授权用 8,购买用 9,购买要等 8 先被处理;即使 8 上链后执行失败,也会消耗这个序号。登录 nonce 则是后端发的一次性随机验证码,用来防止重复使用登录签名,不会消耗链上的交易序号。

拿到交易哈希,为什么不能直接给用户发放权益?

建议回答:哈希只用于追踪交易,交易可能没打包,也可能执行失败。后端要核对目标链、合约、成功回执和业务事件,再按照确认策略更新权益。对重组和重复扫描还要支持回滚与幂等,不能只相信前端上报的哈希。

区块链数据为什么不能随便修改?

建议回答:哈希把区块和历史内容关联起来,修改会被检测到;共识规则决定网络接受哪条历史,让替换历史需要付出很高代价。不是某个文件物理上不能改,而是改完很难让其他节点按规则接受。具体安全性还取决于共识机制、参与者分布和最终性状态。

用户点了加速,原交易一直查不到回执,怎么办?

建议回答:加速可能产生同 nonce 的替换交易,原哈希就未必再有回执。我会按链、发送者和 nonce 追踪最终打包的交易,再核对它是否仍执行原业务。取消交易也可能占用同一 nonce,所以不能发现替换就直接标记支付成功;等待超时则保留待确认状态,不诱导重复付款。

# 官方参考

上次更新时间: 2026年10月10日 06:39:50