5221 字
26 分钟
一笔交易是如何上链的:从钱包签名到区块确认
  1. 1区块链入门:数据可信、分布式共识与系统分层
  2. 2一笔交易是如何上链的:从钱包签名到区块确认本文
  3. 3USDT 与 USDC 是如何转账的:稳定币、代币标准与链上确认

上一篇介绍了区块链的数据层、网络层、共识层和合约层,但这些概念仍然比较抽象。一个更具体的问题是:

用户在钱包里点击“发送”之后,一笔交易究竟经历了什么,才会成为区块链上的记录?

可以把它概括成下面这条链路:

构造交易 → 私钥签名 → 广播交易 → 节点验证 → 进入交易池
→ 出块节点选择交易 → 交易写入区块 → 网络验证区块 → 状态更新与确认

这条流程适用于很多区块链,但每条链的细节并不完全相同。本文主要使用 Bitcoin 和 Ethereum 作为例子:Bitcoin 采用 UTXO 模型,Ethereum 采用账户模型;它们的交易字段、状态表示和最终确认规则都有差异。因此,文中会明确区分“区块链通常如此”和“某条链具体如此”。

一、钱包首先做了什么#

钱包不直接存储硬币#

日常所说的“钱包里有多少 Bitcoin 或 Ether”,更准确地说,是钱包掌握了能够控制链上资产的密钥材料。

钱包通常负责三件事:

  1. 管理私钥或由私钥派生出的账户密钥。
  2. 根据链的规则构造交易。
  3. 使用私钥对交易进行签名,并把签名后的交易提交给网络。

链上节点并不会读取用户手机里的钱包余额。节点读取的是账本状态,然后根据交易中的签名判断:发起者是否拥有修改相关状态的权限。

因此,“钱包丢失”通常不是链上的资产消失,而是用户失去了控制对应密钥的能力;如果没有备份或其他恢复机制,节点也无法替用户重置私钥。

Bitcoin 和 Ethereum 的余额表示不同#

Bitcoin 使用 UTXO(Unspent Transaction Output,未花费交易输出)模型。一笔交易会消耗之前交易产生的一个或多个未花费输出,再创建新的输出。可以把它理解成:交易从若干张“面额不一的数字钞票”中取出输入,并把找零作为新的输出。

Ethereum 使用账户模型。账户有地址、余额和 nonce 等状态,普通转账通常表现为:从发送者账户扣除金额和手续费,再向接收者账户增加金额。智能合约调用还可能进一步改变合约存储、创建日志或触发其他调用。

两种模型都能完成转账,但交易构造方式不同:Bitcoin 需要选择要花费的 UTXO,Ethereum 则需要使用正确的 nonce,并根据执行结果计算 gas 消耗。

二、交易不是一句“转账”,而是一份可验证的数据#

钱包需要把用户意图编码成协议规定的交易格式。以抽象形式表示,一笔交易至少要回答这些问题:

问题典型内容
谁发起输入的签名,或能恢复出发送者的公钥/地址的信息
发给谁接收地址,或者要调用的合约地址
转移多少Bitcoin 的输出金额,或 Ethereum 的 value
具体做什么普通转账,或合约调用数据
交易费用Bitcoin 的手续费,或 Ethereum 的 gas 相关字段
防止重复执行Bitcoin 的输入只能花费一次,Ethereum 使用 nonce
交易何时有效例如锁定时间、费用规则或其他协议条件

这里需要区分“交易数据”和“交易状态”。交易是对状态的一次请求;只有当交易通过验证、被纳入区块并被网络接受后,它才会影响链上状态。

Ethereum 的 nonce 为什么重要#

在 Ethereum 账户模型中,普通账户发出的交易带有 nonce。它可以帮助协议识别交易顺序,并防止同一笔交易被重复执行。

例如,一个账户当前期待 nonce 为 12 的交易。如果用户再次发送一笔 nonce 为 12、但内容不同的交易,它们通常会互相竞争;节点可能根据费用和交易池规则保留其中一笔。nonce 为 13 的交易则可能需要等待 nonce 为 12 的交易先被处理。

nonce 不是全网统一递增的区块编号,而是发送账户维度的序号。不同账户可以同时拥有相同的 nonce。

Ethereum 的 gas 是什么#

Ethereum 的交易可能只是转账,也可能执行智能合约。后者需要消耗计算、存储读写和数据处理资源。gas 是对这些执行资源的计量单位,交易需要提供相应的费用参数和 gas 上限。

gas limit 表示交易愿意提供的最大 gas 数量,而不是一定会全部消耗。若执行提前完成,未使用部分通常不会被消耗;如果执行过程中耗尽 gas,交易可能失败,但已经发生的执行成本仍需支付。具体费用字段会随 Ethereum 的交易类型和协议规则变化,不能简单地把 gas limit 当作手续费金额。

三、私钥签名证明了什么#

交易构造完成后,钱包使用私钥进行数字签名。签名的核心作用是证明:

  1. 交易由拥有相应私钥的一方生成。
  2. 交易内容在签名后没有被悄悄修改。
  3. 节点可以使用公开信息验证签名,而不需要知道私钥。

数字签名不是把交易内容“加密”起来。交易在广播后通常可以被网络节点读取,签名也不代表交易已经成功执行。签名只说明这份交易获得了对应密钥的授权,后续仍要经过格式、余额、nonce、脚本或智能合约规则等验证。

签名通常覆盖交易的规范化表示或其哈希。正因为签名绑定了交易内容,攻击者不能只修改收款地址或金额而继续使用原签名通过验证。

需要注意的是,地址并不等于身份实名。地址是协议中的标识,签名证明的是对密钥的控制权;至于现实世界中这个密钥属于谁,通常需要链外信息才能判断。

四、交易如何进入网络#

签名后的交易会被钱包提交给一个节点。这个节点可能是用户自己运行的全节点,也可能是钱包服务商、交易所或其他 RPC 服务提供的节点。

节点收到交易后,通常会先进行本地检查,例如:

  • 数据格式是否符合协议;
  • 签名是否有效;
  • 输入是否存在且尚未被花费,或者账户余额是否足够;
  • Ethereum 的 nonce 是否合理;
  • 费用字段是否满足节点和协议要求;
  • 合约调用是否能够在执行规则下通过;
  • 交易是否违反其他脚本、大小或协议限制。

如果交易通过了本地检查,节点会把它转发给相邻节点。相邻节点重复验证后再继续转发,交易就像在 P2P 网络中扩散开来。

这并不意味着“被一个节点接受”就等于“已经上链”。节点可能暂存并转发一笔交易,但交易仍可能因为费用不足、冲突交易、网络拥堵、节点策略或后续区块状态变化而无法进入区块。

五、交易池保存的是什么#

尚未被区块确认、但已经通过节点初步验证的交易,通常会进入交易池。Bitcoin Core 将其称为 mempool;Ethereum 客户端也会维护用于等待打包的交易池,但不同客户端的具体策略并不完全相同。

交易池不是区块链共识状态本身。它是节点为了等待和转发交易而维护的本地缓存,因此:

  • 不同节点的交易池内容可以不同;
  • 交易池不是永久存储,节点重启或清理策略可能导致交易被移除;
  • 交易进入交易池不代表一定会被打包;
  • 钱包显示“待处理”,通常意味着交易还没有获得区块确认。

当网络拥堵时,交易会在交易池里等待更长时间。出块节点通常会在区块大小、gas、手续费收益和自身策略之间进行选择。手续费较低的交易可能需要等待更久,也可能因为交易池容量限制而被淘汰。

六、出块节点如何选择交易#

在某个时刻,负责提出新区块的节点会从自己的候选交易集合中选择交易,并执行或验证这些交易,生成一个候选区块。

Bitcoin:验证 UTXO 并构造新区块#

Bitcoin 的出块者会选择交易,把输入指向的 UTXO 标记为将被花费,并创建新的输出。新区块还包含 coinbase 交易,用于记录协议允许的区块补贴和交易手续费收益。coinbase 交易不是普通用户发出的转账,也没有普通交易那样的输入结构。

候选区块会包含前一个区块的哈希等信息。PoW(工作量证明)要求矿工寻找满足目标条件的区块头,使得新区块可以通过网络验证。矿工找到有效结果后广播区块,其他节点会独立验证区块中的交易和工作量证明。

Ethereum:执行交易并生成状态变化#

Ethereum 的交易不仅可能转移 Ether,还可能执行智能合约。出块者需要按照协议规定的顺序执行交易,计算账户余额、nonce、合约存储和日志等状态变化,并把执行结果放入区块。

由于合约执行依赖交易顺序,同一批交易在不同顺序下可能产生不同结果。nonce、账户状态和区块规则共同约束了交易能够被接受的顺序。

Ethereum 当前使用 PoS(权益证明)共识。验证者根据协议参与区块提议和证明,而不是通过消耗大量计算力竞争出块。这里不应把“出块节点”理解为 Bitcoin 意义上的矿工;两者承担相近的区块生产职责,但参与方式不同。

七、区块广播后,其他节点还要重新验证#

出块者广播候选区块后,其他节点不会因为“区块是知名节点发来的”就直接接受。节点会重新检查:

  • 区块结构和大小是否符合规则;
  • 前一个区块是否正确;
  • 区块头、时间和共识相关字段是否有效;
  • 出块者是否有权提出该区块;
  • 区块中的每笔交易是否有效;
  • 交易执行后的状态根或其他承诺值是否正确;
  • 区块是否违反协议规定的奖励、手续费和状态转换规则。

如果区块无效,节点应当拒绝它,即使它来自其他节点。如果两个有效区块暂时竞争同一个位置,网络还需要根据各自链的共识规则继续选择或确定最终采用的历史。

这也是“验证”与“信任”的区别:节点不是因为相信某个出块者而接受结果,而是依据公开规则重新计算和检查结果。

八、交易被写入区块后,发生了什么#

当一个有效区块被节点接受后,区块中的交易会按照确定的顺序应用到账本状态:

  • Bitcoin 中,被花费的 UTXO 被移除,新的输出加入 UTXO 集合;
  • Ethereum 中,账户余额、nonce、合约存储、合约余额和执行日志等状态可能发生变化;
  • 已经被区块包含的交易,会从等待打包的交易池中移除;
  • 与已确认交易冲突的候选交易通常会被删除或标记为不可再接受。

钱包此时可能会显示“已确认”,但确认的含义仍取决于具体链的共识规则和钱包的展示策略。

九、“确认”不等于所有链上的同一种安全性#

Bitcoin 的确认通常是区块深度#

Bitcoin 语境中的一次确认,通常表示交易所在的区块已经成为当前链的一部分。之后又产生的区块会增加它的区块深度。

区块越深,攻击者想要通过重组链来替换这笔交易,通常需要重新完成并追赶更多工作量。因此,确认数增加一般意味着交易被回滚的概率降低,但这不是绝对不可逆的数学保证。

所以,“等待 6 个确认”更多是一种风险管理约定,而不是 Bitcoin 协议规定所有交易都必须等待的固定步骤。低价值交易和高价值结算可以使用不同的风险阈值。

Ethereum 需要区分包含、证明和最终确定#

在 Ethereum 的 PoS 机制中,可以把交易状态理解为多个阶段:

  1. 交易被某个区块包含。
  2. 其他验证者对区块进行证明,区块获得越来越强的共识支持。
  3. 链达到协议定义的最终确定条件后,历史回滚的成本和条件发生质的变化。

这几个阶段不能简单地都称为“确认”。钱包或应用可能把交易进入区块称为 confirmed,也可能要等到更强的 finalized 状态才认为结算完成。开发者应根据资产价值、业务风险和所使用的客户端接口定义自己的接受条件。

最终确定性是共识属性,不是 UI 文案#

“交易成功”“已确认”“已完成”这些文字经常出现在钱包界面,但它们是产品层的表达。底层真正需要回答的是:

  • 交易是否已经进入某个有效区块?
  • 这个区块是否仍然属于节点认可的当前链?
  • 交易执行结果是否成功?
  • 该链对历史回滚提供了怎样的保证?

在 Bitcoin 中,交易进入区块并不意味着脚本执行一定按照用户预期完成;在 Ethereum 中,交易进入区块也不等于合约调用成功,交易可能包含在区块中但执行结果为失败。因此,应用不能只检查交易是否有区块高度,还需要读取交易回执、执行状态或对应链的等价信息。

十、哪些情况会让交易“看起来不见了”#

交易只到达了某个节点#

如果钱包连接的 RPC 节点没有继续传播交易,或者节点本身拒绝转发,交易可能只存在于局部网络。此时另一个区块浏览器查不到,并不一定代表签名错误,也不一定代表资产已经转移。

交易还在交易池中#

网络拥堵、费用过低、交易池容量有限,都会让交易长时间等待。不同节点的交易池并不一致,所以“我的节点看到了”与“全网都能看到”不是同一件事。

交易被替换或与其他交易冲突#

Ethereum 中,同一个账户可能存在相同 nonce 的候选交易;Bitcoin 中,也可能出现花费相同 UTXO 的冲突交易。节点的替换规则、手续费条件和矿工/验证者选择会影响最终哪一笔进入区块。

交易已经进区块,但执行失败#

Ethereum 智能合约交易可能因为 require 条件不满足、gas 耗尽或其他执行错误而失败。它仍然可能有交易哈希和区块位置,但合约状态不会按照成功路径更新,已消耗的执行资源通常也不会退回。

应用读取到了旧状态#

钱包、浏览器和 RPC 节点可能存在缓存或同步延迟。查询余额时,要确认读取的是哪个节点、哪个区块高度以及哪种状态;否则会把展示延迟误认为链上回滚。

十一、开发者应该如何判断一笔交易的状态#

一个可靠的交易状态检查,至少要分开处理下面几层:

检查层要确认的问题
广播层节点是否接受并返回交易哈希?
交易池层节点是否仍保存这笔交易,还是已经丢弃?
包含层交易是否进入有效区块?
执行层交易执行是否成功,还是在区块中失败?
共识层区块是否获得足够的确认或达到最终确定?
业务层业务所需的资产转移、事件或状态是否确实发生?

例如,交易哈希存在只能证明某个系统曾经接收或生成过这串标识,不能单独证明交易已上链。交易有区块高度,也不能单独证明 Ethereum 合约调用成功。支付、充值、提现等高价值业务通常还需要等待额外确认,并建立重试、超时、重复通知和链重组处理机制。

十二、把整条流程串起来#

现在可以用一个抽象例子回顾完整过程:

  1. 用户在钱包中填写接收地址和金额。
  2. 钱包根据 Bitcoin 的 UTXO 或 Ethereum 的账户状态构造交易。
  3. 钱包使用私钥签名,证明这笔交易获得密钥持有者授权。
  4. 钱包把签名交易提交给节点。
  5. 节点检查格式、签名、余额、nonce、脚本或合约执行条件。
  6. 通过初步检查后,交易进入节点交易池并向邻居传播。
  7. 获得出块机会的参与者选择交易,构造候选区块。
  8. Bitcoin 通过 PoW 竞争有效区块,Ethereum 通过 PoS 的提议和证明流程推进链。
  9. 其他节点独立验证区块和状态变化。
  10. 交易被包含后,账本状态发生变化;随着后续共识支持增强,交易获得更强的确认或最终确定性。

这条链路也解释了区块链系统为什么不是“把数据写入一台服务器”:交易要经过密钥授权、P2P 传播、独立验证、确定排序和共识确认,最终才会成为多节点共同认可的状态变化。

结语#

一笔交易上链,表面上是钱包里的一个按钮,底层却同时涉及密码学、数据结构、网络传播、交易池、状态机和共识机制。

最值得记住的不是“等待几秒就成功”,而是区分以下几个概念:

  • 签名证明谁授权了交易,但不证明交易已经执行成功;
  • 交易池表示节点暂存了交易,但不证明交易已经写入区块;
  • 交易进入区块表示它被包含,但不一定意味着执行成功或永不回滚;
  • 确认数和最终确定性取决于具体区块链的共识规则;
  • Bitcoin 的 UTXO 模型和 Ethereum 的账户模型,会直接影响交易的构造与验证方式。

理解这条流程之后,再学习 Merkle Tree、UTXO 与账户模型、PoW 与 PoS、智能合约执行,就不再是孤立记忆概念,而是在解释同一个问题的不同环节。

参考资料#

本文的流程和术语参考了以下官方或协议文档;文中对 Bitcoin 与 Ethereum 的差异进行了面向入门读者的归纳,具体行为仍应以对应网络版本和客户端实现为准。

  1. Bitcoin Developer Guide: Transactions —— Bitcoin 交易、输入输出、脚本与 UTXO。
  2. Bitcoin Developer Guide: Block Chain —— Bitcoin 区块链、区块确认与工作量证明相关概念。
  3. Bitcoin Core Developer Notes: Mempool —— Bitcoin Core 交易池的策略与实现说明。
  4. Ethereum Documentation: Transactions —— Ethereum 交易结构、nonce、gas、签名和交易池相关概念。
  5. Ethereum Documentation: Accounts —— Ethereum 账户、地址、密钥和状态模型。
  6. Ethereum Documentation: Proof-of-stake consensus —— Ethereum PoS 中的验证者、区块提议、证明与最终确定性。
  7. Ethereum Yellow Paper —— Ethereum 状态转换、交易执行和协议形式化描述。
一笔交易是如何上链的:从钱包签名到区块确认
https://blog.xqcherry.top/posts/blockchain/transaction-lifecycle/
作者
xqcherry
发布于
2026-09-26
许可协议
CC BY-NC-SA 4.0