02 交易流程
Fabric 中的一次交易主要分为6个环节,分别是发起交易提案、背书节点验证签名并执行交易、检查提案响应、将背书结果封装进交易、验证与提交交易、账本更新。
2.1 总览
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LNsb70wj-1619445082184)(http://blog.mdecade.site/images/Fabric/%E4%BA%A4%E6%98%93%E6%B5%81%E7%A8%8B.jpg)]
- 客户端(CLI或SDK)构造并提交提案请求
- Peer节点响应,模拟执行交易,并对结果进行签名
- 客户端根据相应结果,构建交易请求,提交至Orderer节点
- Orderer对交易进行排序,并创建区块
- Orderer将打包好的区块广播给组织中的Leader节点
- Leader节点将接收到区块广播给其他Peer节点
2.2 详细分析
- 发起交易提案
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vaoU777p-1619445082187)(http://blog.mdecade.site/images/Fabric/step1.png)]-
客户端发起交易请求。交易请求会根据一定的背书策略到达某些或全部的Peer节点进行背书
-
构建交易提案。应用程序根据所支持的SDK中的API生成一个交易提案。提案是带有确定输入参数的调用链码方法的请求,该请求的作用是读取或者更新账本。交易提案包括以下要素
- channelID:通道信息
- chaincodeID:需要调用的链码的信息
- timestamp:时间戳
- sign:客户端签名
- txPayload:提交的事务本身包含的内容,包括:
- operation:调用链码的函数以及相应参数
- metadata:调用的相关属性(查询数据?)
- 交易提案的结构如下图所示
-
在上述过程中,SDK将交易提案打包成合适的格式以及根据用户的秘钥对交易提案生成签名
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0bNdjAN2-1619445082190)(http://blog.mdecade.site/images/Fabric/交易提案.jpg)]
-
- 背书节点验证签名并执行交易
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vI4AYDFP-1619445082191)(http://blog.mdecade.site/images/Fabric/step2.png)]- 背书节点验证
- 交易提案的格式完整
- 且验证该交易提案之前没有被提交过(重放攻击保护)
- 验证客户端签名是否有效(使用 MSP)
- 验证交易提案的请求者是否在该通道中拥有相关权限
- 验证通过后使用交易提案中的参数调用链码函数,模拟执行,生成交易结果包括响应值、读集和写集(即表示要创建或更新的资产的键值对)。
- 此时,并没有对账本进行更新,仅仅是模拟执行。交易结构会和背书节点的签名一起作为提案响应,返回到SDK,由SDK解析给客户端。提案响应的结构如下图所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-99o3Fm3L-1619445082193)(http://blog.mdecade.site/images/Fabric/提案响应.jpg)]
- 背书节点验证
- 检查提案响应
- 应用程序验证背书节点的签名,并比较这些提案响应,以确定其是否相同。
- 如果链码只查询账本,应用程序将检查查询响应,并且通常不会将交易提交给排序服务。
- 如果客户端应用程序的请求是更新账本,则应用程序在提交之前需确定是否已满足指定的背书策略,然后将事务提交给Orderer节点以继续下一步操作。
- 即使应用程序选择不检查响应或以其他方式转发未背书的交易,节点仍会执行背书策略,并在提交验证阶段遵守该策略。
- 客户端将背书结果封装进交易
- 交易请求被提交到Orderer节点,交易会包含读写集、背书节点的签名和通道 ID。
- Orderer节点不需要为了执行其操作而检查交易的整个内容,它只是从网络中的所有通道接收交易,将它们按时间按通道排序,并将每个通道的交易打包成区块。
- 交易区块被创建之后会有Orderer节点广播给同一通道内的所有组织的 Leader 节点,并由 Leader 节点广播给同组织的其他 Peer 节点。
- 验证和提交交易
- Peer 节点接收到交易区块之后,会对区块内的交易进行验证,以确保满足背书策略
- 确保自交易执行生成读集以来,读集中变量的账本状态没有变化
- 将块中的交易标记为有效或无效
- 账本更新
- 每个 Peer 节点都将区块追加到通道的链上
- 对于每个有效的交易,写集都提交到当前状态数据库
- 系统会发出一个事件,通知客户端应用程序本次交易(调用)已被不可更改地附加到链上,同时还会通知交易验证结果是有效还是无效。