如何在Go语言go-ethereum中订阅以太坊pending交易
go-ethereum 订阅pending待处理交易正确方案
你遇到的方法不存在报错,是因为标准库ethclient.Client没有直接封装SubscribePendingTransactions方法,不需要额外引入其他客户端包,直接调用客户端底层的通用订阅接口即可实现,和web3.js的pendingTransactions订阅能力完全对应。
前置要求
- 节点必须使用WebSocket(ws/wss)或者IPC协议连接,HTTP协议不支持服务端主动推送,无法实现订阅功能
- 你连接的以太坊节点需要开启pending交易订阅权限,部分第三方节点服务默认会关闭该接口,需要提前确认
- 不要使用
types.Log类型通道接收数据,该类型是合约日志订阅专用,和pending交易返回结构不匹配
基础实现(仅获取交易哈希,和web3.js默认行为一致)
package main import ( "context" "log" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" ) func main() { // 替换为你的节点ws地址 client, err := ethclient.Dial("wss://your-eth-node-ws-endpoint") if err != nil { log.Fatalf("节点连接失败: %v", err) } defer client.Close() // 通道用于接收pending交易哈希 txHashChan := make(chan common.Hash) // 调用通用订阅接口,订阅newPendingTransactions事件 sub, err := client.Subscribe(context.Background(), "eth", txHashChan, "newPendingTransactions") if err != nil { log.Fatalf("订阅发起失败: %v", err) } defer sub.Unsubscribe() // 循环接收推送 for { select { case subErr := <-sub.Err(): log.Fatalf("订阅连接异常: %v", subErr) case txHash := <-txHashChan: log.Printf("收到pending交易,哈希: %s", txHash.Hex()) // 如需完整交易内容,可在此处调用 client.TransactionByHash(context.Background(), txHash) 获取 } } }
进阶实现(直接获取完整交易内容)
如果不想拿到哈希后再单独发请求拉取交易详情,可以在订阅时传入最后一个参数true,节点会直接返回完整的交易结构体,只需要把接收通道类型改成*types.Transaction即可:
import "github.com/ethereum/go-ethereum/core/types" // ... 省略节点连接逻辑 txChan := make(chan *types.Transaction) // 最后一个参数传true,要求节点返回完整交易 sub, err := client.Subscribe(context.Background(), "eth", txChan, "newPendingTransactions", true) if err != nil { log.Fatalf("订阅发起失败: %v", err) } // 接收逻辑 for { select { case subErr := <-sub.Err(): log.Fatalf("订阅连接异常: %v", subErr) case tx := <-txChan: log.Printf("收到pending交易,哈希: %s", tx.Hash().Hex()) // 可自行从tx对象中提取nonce、gasPrice、to地址、转账金额、input数据等交易字段 } }
注意事项
- 如果订阅一直收不到数据,先确认节点是否同步完成,是否开启了
--ws.api eth权限,以及节点是否配置了交易池广播pending交易的相关参数 - 公链上pending交易吞吐量很高,订阅该接口会产生大量数据推送,注意做好消费端的流控,避免通道阻塞导致程序卡死
内容的提问来源于stack exchange,提问作者Nicholas E. Harding
相关产品推荐
相关产品推荐

