密码学与交易生命周期
# 密码学与交易生命周期
签名证明谁同意了这笔操作,共识决定大家接受哪段历史,回执说明执行结果,最终性决定结果何时可以被业务信任。这四件事不能互相替代。
区块结构、P2P 网络、PoW 和 PoS 的展开介绍复用 区块链基础。本篇把它们串成一次真实交易,并补充开发时需要注意的边界。
# 哈希、签名、加密分别解决什么问题
| 技术 | 作用 | 不能保证什么 |
|---|---|---|
| 哈希 | 把数据变成固定长度指纹,检测内容是否变化 | 不能隐藏低熵原文,也不能证明是谁写的 |
| 数字签名 | 用私钥签名、用公钥验证消息与签名者的关系 | 不会自动保密,也不保证签名者理解了业务后果 |
| 加密 | 让没有相应密钥的人无法直接读取内容 | 不自动证明消息来自哪个业务身份 |
| Merkle Tree | 用树状哈希,把很多条记录汇总成一个根,并支持包含证明 | 包含证明不代表那条记录对应的现实事件真实 |
已有密码学笔记帮助理解用途,但ECDSA 签名不是 “私钥加密、公钥解密” 。它使用特定的数学签名与验证算法;钱包签名也不会把交易内容变成密文。以太坊常用的 Keccak-256 与标准 SHA3-256 也不能直接互换。
例如四条记录分别得到 A、B、C、D 四个哈希,再计算 AB、CD,最后得到根。如果要证明 A 在其中,只需给出 B 和 CD 两个相邻分支,不必下载全部记录。验证者必须事先信任或验证根的来源,否则伪造一棵树也能自洽。
# 一笔 EVM 交易经过哪些阶段
以用户调用课程合约的 purchase(courseId) 为例:
- 构造。客户端确定 chainId、合约地址、调用数据、金额、nonce 和费用上限。chainId 标识网络;nonce 是发送账户的交易序号,用于顺序控制与防止同一交易重复执行。
- 签名。钱包展示操作,用户同意后用私钥签名。拒绝签名还没有链上交易,也不会因此支付链上 Gas。
- 广播。RPC 节点接收签名交易。RPC 是客户端与节点交换请求的接口,不是区块链本身;一个节点接收不等于全网都已经接受。
- 等待打包。交易可能在节点交易池等待,也可能通过私有交易路径提交;费用不足、nonce 缺口或网络问题都会影响是否被打包。
- 执行。交易进入区块,节点按同样规则执行字节码,生成状态变更与 receipt(回执)。回执的
status表示成功或失败。 - 确认。业务继续跟踪区块是否仍在规范链上,再根据链的最终性和业务风险决定何时交付不可逆权益。
返回交易哈希,只表示可以用它追踪交易,不是 “购买成功” 。即使调用 RPC 超时,交易也可能已广播,不能直接让用户重复付钱。
# 超时、替换和重组怎样理解
| 现象 | 实际含义 | 应当怎样处理 |
|---|---|---|
| 一直没有回执 | 未打包、被丢弃、RPC 不同步等都有可能 | 按哈希和发送账户 nonce 跟踪,不直接判定成功或失败 |
| 加速或取消 | 钱包通常用同一 nonce 的另一笔交易尝试替换 | 追踪最终被打包的交易;取消不保证抢在原交易之前 |
| 回执失败 | 执行发生 revert 或耗尽 Gas 等错误 | 显示原因,检查已消耗费用;不要再按成功事件发放权益 |
| 区块重组 | 原先看到的区块被另一条规范历史替代 | 撤销旧投影,从共同祖先补扫,重新确认结果 |
确认数与最终性不是同义词。确认数表示后续又有多少区块;以太坊 PoS 还提供 safe、finalized 等链头标签,表示不同保证。高价值业务应明确采用哪种策略,而不是统一等待几秒。L2 还可能区分排序器确认、数据提交到 L1 和结算最终性,不能照搬主网等待策略。
# 用 nonce 解释卡单、加速和取消
假设账户下一笔应执行的 nonce 是 8,却先广播了 nonce 9。后者通常要等 nonce 8 被处理后才能执行,不是给 nonce 9 增加 Gas 就一定能解决。
用户给 nonce 8 的交易加速时,会尝试广播另一笔同 nonce、满足节点替换要求的交易,因此交易哈希可能变化。所谓取消通常也是竞争替换,不是从全网删除原交易;原交易如果先被打包,取消就没能阻止它。
后台跟踪应把一次业务操作与相关交易尝试分开保存,记录 chainId、发送者、nonce 和哈希。发现替换后核对新交易的目标、value 和 data:同 nonce 的新交易可能是支付加速,也可能是不再支付的取消交易,不能一律认定原业务成功。
# 回执失败和短重组为什么是两件事
回执失败表示这次执行进入了区块,但业务调用没有成功;重组则表示原来承载结果的区块不再属于当前规范链。即使先前回执是 success,所在区块离开规范链后,也不能继续据此发放最终权益。
例如先观察到区块 100-A 中购买成功,随后规范链在高度 100 变成 100-B。应标记 A 分支的事件失效,再核查购买交易是否被重新纳入后续区块。高度 100 这个数字没变,不代表同一个区块;所以索引必须保存 blockHash。
确认策略应按业务分层:界面可以快速提示已执行,高价值发货或提现则等待更强保证。具体补扫与投影恢复见 链上索引,不能只在 UI 多等几秒就声称解决了重组。
# 共识不替代业务判断
节点可以验证签名、余额、nonce 和执行规则,却无法知道用户是否被钓鱼、报价是否公平。预言机提交的价格也需要合约检查时效与异常值。 “大家都执行了同一段错误规则” 不会让规则变正确。
# 面试时可以这样回答
拿到交易哈希,为什么不能直接给用户发放权益?参考答案
哈希只用于追踪交易,交易可能没打包,也可能执行失败。后端要核对目标链、合约、成功回执和业务事件,再按照确认策略更新权益。对重组和重复扫描还要支持回滚与幂等,不能只相信前端上报的哈希。
区块链数据为什么不能随便修改?参考答案
哈希把区块和历史内容关联起来,修改会被检测到;共识规则决定网络接受哪条历史,让替换历史需要付出很高代价。不是某个文件物理上不能改,而是改完很难让其他节点按规则接受。具体安全性还取决于共识机制、参与者分布和最终性状态。
用户点了加速,原交易一直查不到回执,怎么办?参考答案
加速可能产生同 nonce 的替换交易,原哈希就未必再有回执。我会按链、发送者和 nonce 追踪最终打包的交易,再核对它是否仍执行原业务。取消交易也可能占用同一 nonce,所以不能发现替换就直接标记支付成功;等待超时则保留待确认状态,不诱导重复付款。