无法在超级账本结构golang中接收块级事件

问题描述 投票:0回答:1

我试图在 Golang 中监听块级事件。我根本无法接收块级事件。它只是始终显示块 0 并且不向前移动。我已经给出了示例代码。如果代码或在网络级别执行的任何其他设置有任何问题,请告诉我。 另一项观察是,如果代码是用 Nodejs 编写的,那么我能够监听块级事件,但不能用 Golang 来监听。

如果有任何解决方案,请告诉我。 我们正在使用 hyperledgr Fabric 2.4

func startBlocklevelEventListening(ctx context.Context, network client.Network) {
blockEvents, blockErr := network.BlockEvents(ctx, client.WithStartBlock(1))
if blockErr != nil {
panic(fmt.Errorf("failed to start chaincode event listening: %w", blockErr))
}
fmt.Println("\n** Start Block event listening")

go func() {
    for event := range blockEvents {
        hashBytes := event.GetHeader().GetDataHash()
        hashString := fmt.Sprintf("%x", hashBytes)
        blockNumber := event.GetHeader().GetNumber()
        fmt.Printf("\n<-- Block event received: \n   Received block number : %d \n   Received block hash - %s\n", blockNumber, hashString)
    }
}()
blockchain hyperledger-fabric hyperledger block fabric
1个回答
0
投票

我使用 Fabric v2.5 和 Fabric-gateway v1.4 进行了尝试,并且能够接收块事件。我对现有的 asset-transfer-events/application-gateway-go 示例进行了以下修改:

  1. 修改了deleteAsset函数,使其返回提交交易的区块号(类似于现有的createAsset函数)。

    func deleteAsset(contract *client.Contract) uint64 {
        fmt.Printf("\n--> Submit transaction: DeleteAsset, %s\n", assetID)
    
        _, commit, err := contract.SubmitAsync("DeleteAsset", client.WithArguments(assetID))
        if err != nil {
            panic(fmt.Errorf("failed to submit transaction: %w", err))
        }
    
        status, err := commit.Status()
        if err != nil {
            panic(fmt.Errorf("failed to get transaction commit status: %w", err))
        }
    
        if !status.Successful {
            panic(fmt.Errorf("failed to commit transaction with status code %v", status.Code))
        }
    
        fmt.Println("\n*** DeleteAsset committed successfully")
    
        return status.BlockNumber
    }
    
  2. 添加了 replayBlockEvents 函数,类似于现有的 replayChaincodeEvents 函数。

    func replayBlockEvents(ctx context.Context, network *client.Network, endBlock uint64) {
        fmt.Println("\n*** Start block event replay")
    
        events, err := network.BlockEvents(ctx, client.WithStartBlock(0))
        if err != nil {
            panic(fmt.Errorf("failed to start block event listening: %w", err))
        }
    
        for {
            select {
            case <-time.After(10 * time.Second):
                panic(errors.New("timeout waiting for event replay"))
    
            case event := <-events:
                blockNumber := event.GetHeader().GetNumber()
                fmt.Printf("\n<-- Replayed block number %d\n", blockNumber)
    
                if blockNumber == endBlock {
                    // Reached the block containing the last submitted transaction so return to stop listening for events
                    return
                }
            }
        }
    }
    
  3. 修改了main函数的最后一部分以添加块事件的重播。

    firstBlockNumber := createAsset(contract)
    updateAsset(contract)
    transferAsset(contract)
    lastBlockNumber := deleteAsset(contract)
    
    // Replay chaincode events from the block containing the first transaction
    replayChaincodeEvents(ctx, network, firstBlockNumber)
    // Replay block events up to the last committed block
    replayBlockEvents(ctx, network, lastBlockNumber)
    

运行此应用程序会产生通常的控制台输出,加上 replayBlockEvents 函数的附加输出,清楚地表明块事件正在工作:

*** Start block event replay
<-- Replayed block number 0
<-- Replayed block number 1
<-- Replayed block number 2
<-- Replayed block number 3
<-- Replayed block number 4
<-- Replayed block number 5
<-- Replayed block number 6
<-- Replayed block number 7
<-- Replayed block number 8
<-- Replayed block number 9

在 replayBlockEvents 函数中使用更简单的 for-range 循环也有效。

for event := range events {
    blockNumber := event.GetHeader().GetNumber()
    fmt.Printf("\n<-- Replayed block number %d\n", blockNumber)

    if blockNumber == endBlock {
        // Reached the block containing the last submitted transaction so return to stop listening for events
        return
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.