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

如何在Golang中解码Tendermint的Base64编码交易(适配go-ethereum)

问题描述

调用Tendermint的/unconfirmed_txs接口获取待处理交易数据,得到如下Base64编码的交易列表:

CsQECpAECh8vZXRoZXJtaW50LmV2bS52MS5Nc2dFdGhlcmV1bVR4EuwDCqUDChovZXRoZX
JtaW50LmV2bS52MS5MZWdhY3lUeBKGAwgCEg01MDc3OTQ2NTQxMzY0GPbZDCIqMHgxNDU4
NjNFYjQyQ2Y2Mjg0N0E2Q2E3ODRlNjQxNkMxNjgyYjFiMkFlKhU0MDAwMDAwMDAwMDAwMD
AwMDAwMDAy5AF/82q1AAAAAAAAAAAAAAAAAAAAAAAAAAAAfvEOe1XqTQ9Ynq8AAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAK5tNYq1CNfuvRh/6NqF6Z
zkg6PtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMd7WUoAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAFx/ilcNV47YTmP9+nse5y3q4a4jAAAAAA
AAAAAAAAAA3XPeoQq8K/+ZxgiC7FsrgbsdxbI6AVZCIBX0RwQW5LaC1LZG0W5mHid2Dsx/
8FQn0r9IhHrWBAVxSiBLOhtk5OAdcCGBHaLUHK8rKEpL1bgtBRYxG/if+UesIxpCMHhlZG
RjOWMxMWVkY2Q1NTY4YWZlOWM0Y2ZmYWNjMmU4ZjBhMGNlNjFiMDczMDE4OTQ1NzEyZDMw
NTU3ZDBjMTUw+j8uCiwvZXRoZXJtaW50LmV2bS52MS5FeHRlbnNpb25PcHRpb25zRXRoZX
JldW1UeBImEiQKHgoHYmFzZWNybxITMTA1NjgxMjA3ODI5NTU5Mjk1MhD22Qw=

请问如何在Golang中解码这些交易,获取完整交易数据(最好能转换为go-ethereum的Transaction结构体)?

经调研得知需要使用编解码器并注册相关函数,但未找到适配该场景的示例代码,也不清楚具体实现逻辑。

尝试使用github.com/calvinlauyh/cosmosutils库解码交易,却遇到错误:

unable to resolve type URL /ethermint.evm.v1.MsgEthereumTx: tx parse error


解决方案

错误原因

报错是因为cosmosutils库未注册ethermint.evm.v1.MsgEthereumTx这个Protobuf类型,编解码器无法识别该交易类型。这类交易是兼容EVM的Cosmos链(如Evmos)上的以太坊格式交易,必须用Ethermint官方的Protobuf定义和编解码器处理。

步骤1:引入依赖

在Go项目的go.mod中添加必要依赖(版本需匹配目标链的实际版本):

require (
    github.com/cosmos/cosmos-sdk v0.47.0
    github.com/evmos/ethermint v0.20.0
    github.com/ethereum/go-ethereum v1.10.26
    google.golang.org/protobuf v1.28.1
)

步骤2:解码Base64交易为Cosmos Tx结构体

先将Base64字符串解码为字节流,再用注册了Ethermint类型的Cosmos编解码器解码:

package main

import (
    "encoding/base64"
    "fmt"

    "github.com/cosmos/cosmos-sdk/codec"
    "github.com/cosmos/cosmos-sdk/codec/types"
    "github.com/evmos/ethermint/x/evm/types"
)

func main() {
    // 移除原Base64字符串中的换行符
    base64Tx := "CsQECpAECh8vZXRoZXJtaW50LmV2bS52MS5Nc2dFdGhlcmV1bVR4EuwDCqUDChovZXRoZXJtaW50LmV2bS52MS5MZWdhY3lUeBKGAwgCEg01MDc3OTQ2NTQxMzY0GPbZDCIqMHgxNDU4NjNFYjQyQ2Y2Mjg0N0E2Q2E3ODRlNjQxNkMxNjgyYjFiMkFlKhU0MDAwMDAwMDAwMDAwMDAwMDAwMDAy5AF/82q1AAAAAAAAAAAAAAAAAAAAAAAAAAAAfvEOe1XqTQ9Ynq8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAK5tNYq1CNfuvRh/6NqF6Zzkg6PtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMd7WUoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAFx/ilcNV47YTmP9+nse5y3q4a4jAAAAAAAAAAAAAAAAAAAAAA3XPeoQq8K/+ZxgiC7FsrgbsdxbI6AVZCIBX0RwQW5LaC1LZG0W5mHid2Dsx/8FQn0r9IhHrWBAVxSiBLOhtk5OAdcCGBHaLUHK8rKEpL1bgtBRYxG/if+UesIxpCMHhlZGRjOWMxMWVkY2Q1NTY4YWZlOWM0Y2ZmYWNjMmU4ZjBhMGNlNjFiMDczMDE4OTQ1NzEyZDMwNTU3ZDBjMTUw+j8uCiwvZXRoZXJtaW50LmV2bS52MS5FeHRlbnNpb25PcHRpb25zRXRoZXJldW1UeBImEiQKHgoHYmFzZWNybxITMTA1NjgxMjA3ODI5NTU5Mjk1MhD22Qw="

    // 1. Base64解码为字节
    txBytes, err := base64.StdEncoding.DecodeString(base64Tx)
    if err != nil {
        panic(err)
    }

    // 2. 创建编解码器并注册Ethermint的EVM消息类型
    interfaceRegistry := types.NewInterfaceRegistry()
    types.RegisterInterfaces(interfaceRegistry)
    cdc := codec.NewProtoCodec(interfaceRegistry)

    // 3. 解码为Cosmos SDK标准Tx结构体
    var tx codec.Tx
    err = cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx)
    if err != nil {
        panic(err)
    }

    // 4. 断言为MsgEthereumTx类型(EVM交易通常仅包含该类型消息)
    msgTx, ok := tx.GetMsgs()[0].(*types.MsgEthereumTx)
    if !ok {
        panic("交易不是MsgEthereumTx类型")
    }

    fmt.Printf("解码后的EVM交易消息: %+v\n", msgTx)
}

步骤3:转换为go-ethereum的Transaction结构体

MsgEthereumTx的Data字段是RLP编码的以太坊原生交易,直接解码即可得到go-ethereum的Transaction结构体:

import (
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/rlp"
)

// 在步骤2解码得到msgTx后执行以下代码
var ethTx types.Transaction
err = rlp.DecodeBytes(msgTx.Data, &ethTx)
if err != nil {
    panic(err)
}

fmt.Printf("转换后的以太坊交易: %+v\n", ethTx)
fmt.Printf("交易哈希: %s\n", ethTx.Hash().Hex())
fmt.Printf("发送方地址: %s\n", ethTx.From().Hex())

注意事项

  • 依赖版本必须与目标链版本一致,否则会出现类型不兼容问题。
  • 若交易包含多个消息,需遍历tx.GetMsgs()逐个处理,但EVM交易通常仅包含一个MsgEthereumTx。
  • 部分链会对交易做额外封装(如签名信息),此时需先解码外层的AuthInfo和TxBody,再处理内部消息。

内容的提问来源于stack exchange,提问作者Alexis Moret

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:45:30