VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

Hyperledger Fabric 交易流程:背书、排序,以及没有生效的更新

Three students in school uniforms work through open books at a classroom table, with textbooks and stationery nearby and study notes on the whiteboard behind them.

English version · 区块链学习导航 · 上一篇

区块链学习 · 文章 BC045

三名学生在教室桌旁一起阅读书本,身边放有课本和文具。
学习场景配图;不代表照片中的学生正在学习区块链。

在 Hyperledger Fabric 中,成功背书不会锁定提案读过的状态。交易被排序进入区块,也不保证其拟议写入会更新当前状态。节点仍需验证交易,包括适用的背书要求与读取版本检查。

这种分工解释了一个表面矛盾的结果:两个提案针对同一可用数量都模拟成功,都取得规定背书,也都出现在有序历史中,但只有其中一个改变该数量。

本篇用一个小型虚构记录系统跟踪这一过程。重点是每个阶段负责什么,以及应用宣布成功之前究竟需要哪些证据。

选择适合你的阅读路线

本篇目录

先看职责图与初始记录版本,跟踪 T、U 的模拟,再逐笔验证排好序的区块。比较反转顺序和缺少背书的变化题,最后完成练习。

本篇采用 Fabric release-2.5 文档作为明确的参考版本,并为虚构部署选择其中的 Raft 排序服务,不代表每个 Fabric 版本或排序实现。练习不涉及真实身份、证书、网络更改或交易。

所有数量都是虚构应用计数值。账本上的预留只是软件记录,不能证明真实物品存在、法律权利已经转移或实物已经交付。

返回目录 · 下一节

1. 一个流程中的四种职责

客户端表达希望执行的操作。背书节点模拟相关链码操作,并对提案响应结果签名。排序服务确定顺序,将交易打包成区块。提交节点验证交易,把有效写集应用到当前状态。

Fabric 交易流程文档把模拟与稍后的账本更新分开。其描述的流程还包括由网关或目标节点协调收集必要响应与提交交易。

这些是职责,不一定对应四个独立组织。一个节点可以同时承担背书和提交工作,一个运营者也可以控制多个组件。有用的架构图应标明每项工作由谁执行,以及执行软件由谁控制。

本例假定应用的协调路径已经正常工作,不复现 SDK 调用。重要的是:每份背书绑定相应的模拟结果,后续阶段不会把这一结果变成应用必定成功的无条件承诺。

返回目录 · 下一节

2. 身份与策略提供不同检查

通道名为 ArchiveChannel。两个虚构组织 A、B 已正确配置成员身份信息,并有获授权参与者。给定背书策略要求:A 的合资格节点与 B 的合资格节点,都对相同结果提供有效背书。

成员服务提供者文档解释配置的成员信息如何支持身份验证和组织角色。身份依据还需按相关策略解释;身份被认可,不代表可以执行所有操作。

本练习的策略全程固定,没有键级策略覆盖、私有数据集合策略、配置修改或证书状态变化。除变化题另有说明,应用授权检查也均通过。

明确这一范围很重要。“有两个签名”并不足够:两个都来自 A,就不满足 A 加 B 的要求;一个签在某份模拟结果上,另一个签在不同结果上,也不构成本题假定的匹配背书包。

返回目录 · 下一节

3. 起点的值与版本

相关公共世界状态在同一链码命名空间中有两个键。K 记录可用的课堂预约单位,H 是独立的管理计数器。

  • K 的值为5,版本为 (20,0)。
  • H 的值为10,版本为 (19,1)。

这里的版本用区块号和交易位置组成的数对表示。本练习位置从0开始。这些数对标识最后修改该键的已提交更新,不是应用数量,也不是某人尝试提交过多少提案。

例如,K=5 并不意味着其版本是5。两个键可以值相同但版本不同。一次较晚的有效写入,也可能让数值保持不变,却产生新版本。

Fabric 账本文档区分当前世界状态与交易历史。本练习两者都需要:历史记录哪些交易被排序并验证,当前状态则说明哪些有效写入已经反映在其中。

返回目录 · 下一节

4. 模拟两个相互竞争的预留

虚构操作 Reserve(amount) 先读取 K,检查当前值是否至少为 amount,再提议写入 K 减 amount。amount 必须是正整数,其他程序条件由题目规定为满足。

T 请求2个单位。模拟读取版本 (20,0) 的 K=5,通过检查,产生拟议写入 K=3。U 请求4个单位,独立读取同一个已提交的 K=5、版本 (20,0),也通过检查,产生拟议写入 K=1。

两次模拟都发生在任何一项更新提交之前。A、B 都为各个提案返回匹配背书。这不表示已经从5个单位中预留了6个,因为任何拟议应用写入都还没有生效。

问题不是 5−2 和 5−4 是否算对,它们都算对了。问题是:排好序的交易进入验证时,计算依赖的读取前提是否仍然成立。

返回目录 · 下一节

5. 读集记版本,写集带拟议值

T 的相关读集包含版本 (20,0) 的 K,写集包含 K=3。U 的读取依赖相同,但写集包含 K=1。

Fabric 读写集文档说明:读集记录已提交键的版本,写集记录拟议新值。验证时要考虑前面已经有效的交易,包括同一区块中位于前面的有效交易。

不要混淆读集携带的依据与模拟时使用的数值。程序读取值5来计算结果,并发检查则记录这次读取对应的版本。练习省略范围查询等其他查询语义,使单键依赖保持清楚。

这次读取是关键。我们的操作有意先读 K 再写 K。本篇不声称任何两个写入同一键的交易都会仅因涉及同一键而被自动拒绝;具体结果取决于实际读取依赖和验证规则。

返回目录 · 下一节

6. 加入一个独立提案

V 读取版本 (19,1) 的 H=10,并提议写入 H=11。它取得同样要求的 A、B 匹配背书。V 不读写 K,T、U 也不读写 H。

现在存在三个证据包:T 提议 K=3,U 提议 K=1,V 提议 H=11。主案例规定,它们的签名、身份和其他有效性要求均正确。

加入 V,可以避免把规律误记成“第二笔之后都会失败”。只要自身依赖没变,区块中较晚的交易仍然可以有效。位置本身不是失败条件。

这也把冲突与服务整体故障分开。U 的读取过时,不表示整个区块必须丢弃,也不表示无关的 H 更新必须停止。验证结果针对相应交易。

返回目录 · 下一节

7. 排序确定先后,不确定应用成功

排序服务生成区块21,其中 T 位于位置0,U 位于位置1,V 位于位置2。这是题目提供的结果,不能从哪个客户端先点击、哪个提案先到某一台服务器自行推断。

Fabric 排序服务文档区分排序与节点侧交易验证。对于普通应用交易,排序节点不会重新运行链码,判断每一项拟议更新是否仍然有效。

虚构服务采用 release-2.5 的 Raft 选项。题目明确提供崩溃故障假设,以及正常工作的必要法定多数和通信条件。这里不把 Raft 当成拜占庭容错,也不认为许可式成员管理可以省略故障假设。

本篇假定在这些条件下,区块顺序已经正确达成一致。它不声称排序节点的任意响应,或任意故障模式,都能保证交易成功送达并应用。

返回目录 · 下一节

8. 按顺序验证区块21

T 排第一。所需背书通过,K 仍为版本 (20,0),读取依赖匹配。因此 T 有效,其写入使 K=3,版本变为 (21,0)。

接着是 U。背书仍然通过,但读集期待 K 的版本为 (20,0)。前面有效的 T 已把版本推进到 (21,0),所以 U 未通过读取版本检查。拟议的 K=1 不会应用,U 也不会为 K 产生新版本。

然后是 V。H 仍为版本 (19,1),因为另外两笔没有改变它。V 通过相关检查,把 H 写为11,版本变为 (21,2)。

区块处理后,当前状态为 K=3、版本 (21,0),H=11、版本 (21,2)。逐笔结果为有效、无效、有效。虽然只有两笔应用了写入,H 的版本位置仍为2;不会为了只数成功交易而重新编号。

返回目录 · 下一节

9. 无效交易为什么仍然可见

U 仍保留在有序区块中,并附有无效的验证结果。历史上存在这笔交易,与应用状态更新成功是两回事。在区块中找到 U 的标识符,尚未证明 K 变成1。

release-2.5 排序文档对节点验证的说明支持这一区分:无效交易保留在区块历史中,但不更新账本状态。因此,历史可以解释失败尝试,而不会假装它消耗了预约单位。

应用报告应说明实际观察到哪个状态。“提案已背书”“已提交”“已进入有序区块”“已以有效状态提交到账本”是不同里程碑,前三者不能代替最后一个。

即使账本更新有效,其含义也有限:它说明配置好的系统按规则和假设接受了软件操作,不会让课堂计数器自动成为关于实物库存的独立证据。

返回目录 · 下一节

10. 反转顺序后重新计算

回到原始状态,并使用同样独立模拟得到的证据包。在一个独立变化题中,区块21先排 U,再排 T,最后排 V。这是供比较的另一种历史,不是对主案例已完成区块进行链重组。

U 现在遇到预期的 K 版本,因此应用 K=1,版本为 (21,0)。T 随后发现版本已变而无效,拟议的 K=3 不应用。V 仍有效,在 (21,2) 把 H 更新为11。

最终 K 为1,而不是3。知道选定顺序后,两种结果都可以解释。背书本身并没有决定哪一次预留最终生效。

注意,提交时不需要哪个节点暗中重新计算一个不同结果来“修复”T。证据包包含的是特定的已背书模拟结果。如果改变操作所依据的输入状态和结果,就需要新的提案流程,不能改写旧背书的含义。

返回目录 · 下一节

11. 背书要求不满足,会改变整条推演

再次回到原始状态和 T、U、V 顺序。这次假设 T 缺少 B 的必要背书,而 U、V 仍有有效的 A、B 证据包。题目假定有缺陷的 T 仍然进入了有序区块。

T 未满足适用背书要求,不更新 K。U 随后看到 K 仍为 (20,0),因此读取版本检查可以通过。在其他给定条件下,U 应用 K=1,版本为 (21,1)。V 仍在 (21,2) 应用 H=11。

这说明验证必须区分失败原因。主案例中 T 有效,使 U 的读取过时;此处 T 无效,K 保持不变,U 的旧读取依赖因此仍然对应当前版本。

Fabric 背书策略文档把背书检查列为验证职责。本例固定使用 A 加 B,避免混入真实部署可能采用的复杂策略组合。

返回目录 · 下一节

12. 重试需要新的判断

主案例完成后 K=3。如果 U 的用户仍请求4个单位,新的模拟读取3,就会不满足程序的可用数量条件。更新证据不能让3足以满足4的请求。

如果获授权用户改为提出一个新的1单位请求,新提案可以读取版本 (21,0) 的 K=3,并提议 K=2。假设取得规定背书,并在没有中间修改的情况下,成为区块22位置0的下一次有效更新,那么 K 就变为2、版本 (22,0)。

这些是不同用户决定和不同提案上下文。应用不应为了让重试成功,悄悄减少用户请求数量;也不应仅因重新发送了字节或收到接收确认,就宣布成功。

决定下一步之前,还要区分已知无效状态与超时后结果未知。缺少响应本身不能证明原操作失败。本篇不规定生产重试算法,而是解释为什么需要核对结果,并保留用户原意。

返回目录 · 下一节

13. 值相同,不表示版本相同

再看一个独立变化题:T 验证之前,有一笔有效的中间交易读取 K=5,又写入 K=5,产生较新版本。数值没变,但 T 原来的读取版本依赖已经不匹配。

在给定版本检查规则下,即使重新读取界面仍显示5,T 也可能失败。检查针对模拟时观察到的已提交版本,不只是比较新旧数字。

这不是算术错误,而是所采用并发控制依据的结果。如果诊断写成“数字仍是五,所以没有变化”,就漏掉了中间那次有效更新。

调查过时提案时,应把版本和区块上下文与数值一起保留。只显示一个数字的最新状态界面,不足以重建提案实际使用的依赖。

返回目录 · 下一节

14. 练习:报告真正发生的事情

除明确指出变化题外,使用主案例。所有未特别说明的有效性条件均满足。

  1. 排序前,T、U 都取得 A、B 背书,K 是否已经减少?
  2. 主案例区块21处理后,K 当前值与版本是什么?
  3. 为什么 V 使用版本 (21,2),而不是 (21,1)?
  4. 缺少 B 背书的变化题中,U 为什么可能有效?
  5. 在主案例区块中找到旧 U 证据包,应用能否报告成功预留4个单位?
  6. 主案例后发起新请求,原来的4单位意图能否仅靠取得新背书而成功?
  7. 若中间有效更新把 K 再写成5,但版本变新,值相等是否保留 T 的旧读取依赖?

答案与推理

  1. 没有。背书模拟产出带签名的拟议结果,还没有把写入应用到当前状态。在有效更新提交之前,K 仍为5及给定初始版本。

2. K=3,版本 (21,0)。T 生效;U 无效,没有应用拟议的 K=1。H 则独立变为11,版本 (21,2)。

3. V 在有序区块中位于位置2。无效的 U 仍占位置1。版本使用提交交易的位置,不使用压缩后的成功更新序号。

4. T 的背书验证无效,使它不改变 K。因此 U 期待的版本 (20,0) 仍匹配,在给定条件下可于位置1应用。

5. 不能。必须把 U 在区块中存在这一事实,与其无效状态一起阅读。它记录了尝试,不代表写集成功应用。

6. 不能。新模拟只看到3个可用单位,指定程序拒绝请求4个。改变请求数量,需要新的获授权意图。

7. 不能。虽然值相同,版本已经改变,旧读取版本依赖按给定规则已过时。

返回目录 · 下一节

15. 常见问题

提交节点是否只要在最新状态上重新运行每个提案?

这不是本篇教授的流程模型。节点验证已背书结果及其依赖,再应用有效写集。原结果不再适用,不会让过时的已背书结果自动变成另一项操作。

许可式成员管理能保证参与者诚实吗?

不能。它按配置规则识别参与者。部署仍需明确策略、故障假设和管理控制。本例选择的 Raft 排序模型容忍的是崩溃故障,不是对恶意排序节点的全面保证。

无效交易会让整个区块被抹掉吗?

本例不会。U 得到无效交易状态,不更新世界状态;区块历史保留它,有效的 T、V 仍应用写入。

返回目录 · 下一节

资料来源与后续阅读

以下一手资料核对于2026年10月12日,新加坡时间,采用 Fabric release-2.5 文档路径:

  • 交易流程:提案模拟、背书与后续提交的职责。
  • 读写集语义:读取版本、拟议写入值,以及针对前面有效更新的验证。本题使用直接键读取,不使用范围或富查询。
  • 排序服务:排序与节点验证分工、无效交易保留,以及本例选择的 Raft 崩溃故障模型。本篇不依赖宽泛比较或无条件最终性表述。
  • 背书策略:适用背书要求及其验证。本例策略固定,没有覆盖策略。
  • 成员服务提供者:配置的身份与组织成员概念。
  • 账本:当前世界状态与交易历史是不同视图。

如果对身份、策略或状态报告不熟悉,可回看之前的信任模型和交易证据课程。下一篇将按执行、数据、最终性及退出权限所在位置比较附属链设计,而不是把某个类别名称当成安全保证。

返回目录