You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解码Hyperledger Fabric中qscc的GetBlockByTxID返回的数字结果

通过TxID获取区块编号的问题解决(Ubuntu 20.04 + Fabric 2.4.4)

问题背景

  • 环境:Ubuntu 20.04,Hyperledger Fabric 2.4.4
  • 需求:根据交易ID(TxID)查询对应的区块编号
  • 遇到的问题:调用系统链码qscc的GetBlockByTxID接口后,返回结果以十进制数字数组形式呈现(peer chaincode query全为数字,peer chaincode invoke部分为数字),直接转字符串无法解析出区块编号。

解决方法

方法1:命令行解析二进制结果(通用方案)

qscc返回的是区块的Protobuf二进制数据,被命令行工具转成了数字数组,需要转回二进制再解析:

  1. 安装依赖工具:
    sudo apt update && sudo apt install jq protobuf-compiler -y
    
  2. 获取Fabric 2.4.4的Protobuf定义文件:
    git clone https://github.com/hyperledger/fabric.git -b v2.4.4
    cd fabric/protos
    
  3. 执行查询并解析区块编号:
    # 替换<通道名>和<TxID>为实际值,执行查询并保存结果
    peer chaincode query -C <通道名> -n qscc -c '{"Args":["GetBlockByTxID", "<通道名>", "<TxID>"]}' > block_data.json
    
    # 将数字数组转为二进制文件
    jq -r '.result | map(. | tostring) | join(",")' block_data.json | xargs -I {} printf "%b" "$(echo {} | sed 's/,/\\x/g')" > block.bin
    
    # 解析二进制文件,提取区块编号
    protoc --decode=common.Block ./common/common.proto ./common/block.proto < block.bin | grep "number:"
    

方法2:使用SDK直接获取结构化数据(以Go SDK为例)

如果命令行解析繁琐,用Fabric SDK可以直接拿到结构化的区块对象,快速提取编号:

package main

import (
	"fmt"
	"github.com/golang/protobuf/proto"
	common "github.com/hyperledger/fabric-protos-go/common"
	"github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
	"github.com/hyperledger/fabric-sdk-go/pkg/core/config"
	"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
)

func main() {
	// 加载SDK配置文件(替换为你的config.yaml路径)
	sdk, err := fabsdk.New(config.FromFile("config.yaml"))
	if err != nil {
		fmt.Printf("SDK初始化失败: %v\n", err)
		return
	}
	defer sdk.Close()

	// 创建通道客户端(替换<通道名>、<用户名>、<组织名>为实际值)
	clientCtx := sdk.ChannelContext("<通道名>", fabsdk.WithUser("<用户名>"), fabsdk.WithOrg("<组织名>"))
	client, err := channel.New(clientCtx)
	if err != nil {
		fmt.Printf("通道客户端创建失败: %v\n", err)
		return
	}

	// 调用qscc查询区块
	req := channel.Request{
		ChaincodeID: "qscc",
		Fcn:         "GetBlockByTxID",
		Args:        [][]byte{[]byte("<通道名>"), []byte("<TxID>")},
	}

	resp, err := client.Query(req)
	if err != nil {
		fmt.Printf("查询失败: %v\n", err)
		return
	}

	// 反序列化区块数据
	var block common.Block
	if err := proto.Unmarshal(resp.Payload, &block); err != nil {
		fmt.Printf("区块反序列化失败: %v\n", err)
		return
	}

	// 输出区块编号
	fmt.Printf("对应区块编号: %d\n", block.Header.Number)
}

方法3:简化命令行解析(仅支持部分版本)

如果你的Fabric 2.4.4支持--output json参数,可以直接用jq提取:

peer chaincode query -C <通道名> -n qscc -c '{"Args":["GetBlockByTxID", "<通道名>", "<TxID>"]}' --output json | jq '.result.header.number'

内容的提问来源于stack exchange,提问作者hzau-cp3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 20:00:58