前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于链码调用请求发送到交易被打包的过程分析

关于链码调用请求发送到交易被打包的过程分析

作者头像
天地一小儒
发布2022-12-28 14:08:02
3140
发布2022-12-28 14:08:02
举报
文章被收录于专栏:信且诚心之动信且诚心之动

主题:一个链码调用请求,系统如何处理这些数据,直到被打包成交易?从交易到请求的过程中经历了哪些变化?请求大小和交易大小之间相差多少?

  1. 数据流向

1.1 生成交易的方式 整个区块链系统(Hyperledger Fabric)是通过智能合约也就是链码(Chaincode)来驱动各式各样的交易(Tx)并被打包成块(Block)的。整体上讲,链码调用只有两种形式,一种是调用(Invoke),一种是查询(Query)。前者可以被记录并通过交易改动区块链账本(Ledger),后者则不会改动账本,也就是说,即使你调用了链码中的“更新”函数,但你是用的Query,其更新,不会被刷新到区块链中。 由于链码Query是直接查询本地分类账,不会生成交易,因此,这里我们以链码Inovke过程来分析。

1.2 如何生成交易 当peer节点收到一个链码调用请求后,在对请求验证通过后,它会形成一个本地签名的提案(Proposal),此节点可称为提案节点。然后提案节点经gossip协议随机发送给若干个节点(默认是3),其他节点在收到此签名提案也会对它进行验证,通过后会对此提案添加自己的签名,这就是背书,此节点可称为背书节点。背书节点在签完名后发送给最初的那个节点——提案节点在收集到足够的签名后(比如,超过2/3节点的背书签名),将此提案和背书结果打包形成交易,签名后发送给order节点进行共识。 共识过后,众多提案背书完成的交易会被打包成块,此过程本文不予分析,因为与主题不符。

2 背书过程

2.1 生成提案 提案主要分为两个部分,Header和Payload,Header又主要分为两部分,Channel Header和Signature Header

代码语言:javascript
复制
hdr := &common.Header{
        ChannelHeader: MarshalOrPanic(
            &common.ChannelHeader{
                Type:      int32(typ),
                TxId:      txid,
                Timestamp: timestamp,
                ChannelId: chainID,
                Extension: ccHdrExtBytes,
                Epoch:     epoch,
            },
        ),
        SignatureHeader: MarshalOrPanic(
            &common.SignatureHeader{
                Nonce:   nonce,
                Creator: creator,
            },
        ),
    }

Payload主要就是链码请求。另外,交易id也是在此阶段生成。

背书主要使用的是一个签名提案的结构SignedProposal,里面只有两部分,一部分是上面提案的字节数组,另一部分则是 签名。这个结构体主要作用有四:1. 验证证书有效性 2. 验证证书是否可信(包括有收信人的CA签名以及此交易是否被许可) 3. 验证签名 4.防止重放攻击。

2.2 提案处理 节点在收到签名的提案后,会有如下过程:1. 检查并确认提案的有效性。 2. 在本地模拟提案执行,也即执行链码然后得到链码返回结果 3. 背书并生成一个提案响应的结构体。 这里需要提一下的是,它的背书响应结构体同时包含需要对账本进行修改的读写集,以及私有读写集。因此对于一个近乎是“put”(上链) 的链码方法,提案响应甚至会比实际请求要大。

2.3 发送交易 提案在收集完成后,会打包成信封发送出去,这里用到的是一个Envelope的结构&common.Envelope{Payload: paylBytes, Signature: sig},这里在把提案和背书结果(提案响应)一起封装成一个payload结构,过程曲折而复杂,我就不贴了,基本上只是增加少量的辅助字段,没有其他的一些重大的数据引入。

3 大小变化 我对批量上链做了一个测试。当请求大小是4582532时,请求变成交易的数据变化过程:

request to transaction

当请求大小是30601785,区块链报错了:CreateAndSendTransaction failed: SendTransaction failed: calling orderer 'orderer.rabbit.com:7050' failed: Orderer Server Status Code: (400) BAD_REQUEST. Description: message payload is 30601785 bytes and exceeds maximum allowed 10485760 bytes

可以看到,提案(proposal)Payload跟请求大小相比几乎一致(有点误差是因为,payload采用了压缩,而request计算没有),然后提案响应(response)Payload比请求更大,原因我也说了,主要是响应中包含对分类账以及隐私数据更新的读写集,而后数据结构基本无明显变化。 因此可以得到一些结论:

  1. 对于需要大量更新区块链的的链码调用来说,交易的大小可能是原请求的两倍甚至更高。
  2. fabric限制了交易的最大大小为10M,如果你想发送更大的交易,请提前根据链码调用方法做好请求切割。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-03-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
区块链
云链聚未来,协同无边界。腾讯云区块链作为中国领先的区块链服务平台和技术提供商,致力于构建技术、数据、价值、产业互联互通的区块链基础设施,引领区块链底层技术及行业应用创新,助力传统产业转型升级,推动实体经济与数字经济深度融合。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档