How to stream pending blockchain transactions with geth(Go-Ethereum)
Tags: geth, go, ethereum, blockchain
Published: 2023-07-23 23:44:25


> >As the EVM network handles thousands of transactions every minute, developers often require real-time monitoring of pending transactions for various purposes, such as building transaction monitoring systems, auditing smart contracts, tracking network activity or even front-running.








In this technical article, 

let's explore how Golang can connect to an EVM node using the WebSocket-based RPC client and subscribes to pending transactions. 

We will demonstrate how to effectively monitor real-time pending transactions on the mem-pool, providing you with a solid foundation to build more sophisticated tools tailored to your specific needs.




**Why Golang?**

Go, commonly known as Golang, is a programming language designed by Google that has gained immense popularity for various reasons. When it comes to real-time Ethereum transaction monitoring, Go offers several key advantages that make it an excellent choice for this particular task.

**1. Concurrency and Goroutines:**

Go is renowned for its built-in concurrency features, particularly Goroutines. Goroutines allow developers to execute lightweight, concurrent functions concurrently, making it easy to handle multiple tasks simultaneously. In the context of monitoring pending transactions, Goroutines can efficiently manage incoming transactions, ensuring real-time responsiveness and scalability.

**2. High Performance:**

Go's compilation model and runtime optimizations make it a high-performance language. This is crucial for real-time applications like transaction monitoring, where low latency and responsiveness are essential. Go's efficient execution ensures that the transaction monitoring system can handle a high volume of transactions without performance bottlenecks.

**3. Easy-to-Use and Simple Syntax:**

Go's syntax is simple, clean, and easy to read, making it approachable for developers of varying experience levels. Its minimalistic design eliminates unnecessary complexity, making it easier to focus on building the core functionality of the monitoring application. This simplicity also leads to more maintainable and less error-prone code.




### __Prerequisites

Before we delve into the code, ensure you have the following prerequisites in place:

1. Golang installed on your system, you can install Golang from [here](https://go.dev/doc/install)

2. A basic understanding of Ethereum and its transaction lifecycle

3.An IDE (Visual studio code)



**Getting Started**

    Create a file called main.go and then run 

`go mod init main`

This will create a file called go.mod like below

![created go.mod](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z6p654mdzk0g977xdeac.png)

Now create a file called main.go in the same directory as the go.mod file we created earlier.

At this point, we can now install the go-ethereum package.

   To do this run the command below 

`go get github.com/ethereum/go-ethereum/`

it will now appear in our go.mod file and a file named go.sum will also be automatically created carrying all the dependencies.

You should now have something like this:


![Rename file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t4ieuy63df97qsvyomaw.png)



_Great , we are now set _ ✅

**1. Importing Required Packages**

The initial part of the code is concerned with importing the necessary packages that enable interaction with Ethereum networks and WebSockets. Notably, we import the following:

```
import (
	"context"
	"fmt"
	"log"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient/gethclient"
	"github.com/ethereum/go-ethereum/rpc"
)

```

_let's talk about these a bit_


- "context" package is essential for handling the context of the application.

- "fmt" package allows us to format and print output messages.

- "log" package provides error logging functionalities.

- "github.com/ethereum/go-ethereum/common" offers Ethereum common data structures.

- "github.com/ethereum/go-ethereum/ethclient/gethclient" provides access to the Ethereum client.

- "github.com/ethereum/go-ethereum/rpc" enables communication with Ethereum nodes via RPC.



**2. Connecting to an Ethereum Node**

To interact with the Ethereum network, we need a connection to a node. In this case, i am connecting using the WebSocket-based RPC client from Infura, a popular Ethereum node provider. The node URL is specified as:

```
client, err := rpc.Dial("wss://polygon-mumbai.infura.io/ws/v3/b2ea..................")
if err != nil {
    log.Fatal(err)
}

```
Now it is good to note that you will need to use the Infura wss for this to work properly.

So create an [Infura](https://app.infura.io/) account and then switch to websocket RPCs like in the image below 


![Infura website image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hgro33lyu7vf8gctbail.png)


Do not forget to replace the Infura URL with your preferred Ethereum node's WebSocket endpoint.




**3. Subscribing to Pending Transactions**

Once we have established a connection to the Ethereum node, we can subscribe to pending transactions using the gethclient.New method:

```
ctx := context.Background()

pendingTxSub := make(chan common.Hash)
sub, err := gethclient.New(client).SubscribePendingTransactions(ctx, pendingTxSub)
if err != nil {
    log.Fatal(err)
}
defer sub.Unsubscribe()

```


We create a channel pendingTxSub to receive incoming pending transaction hashes. The SubscribePendingTransactions method helps us subscribe to these pending transactions in real-time. Don't forget to unsubscribe from the subscription once you are done with it, hence the defer sub.Unsubscribe().




**4. Processing Incoming Pending Transactions**

Furthermore, we set up a loop to process incoming pending transactions:

```
for {
    select {
    case err := <-sub.Err():
        log.Fatal(err)
    case txs := <-pendingTxSub:
        fmt.Printf("Pending Transaction Hash: %s\n", txs.Hex())
    }
}

```
Here, 
we use a select statement to listen for two types of channels: sub.Err() to handle errors and pendingTxSub to process incoming pending transaction hashes. When a new pending transaction is detected, the hash is printed to the console.





**Complete code**

```
package main

import (
	"context"
	"fmt"
	"log"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient/gethclient"
	"github.com/ethereum/go-ethereum/rpc"
)

func main() {
	// Connect to an Ethereum node using an HTTP-based RPC client
	client, err := rpc.Dial("<RPC HERE>")
	if err != nil {
		log.Fatal(err)
	}

	// Create a context to handle the subscription
	ctx := context.Background()

	// Subscribe to pending transactions
	 pendingTxSub := make(chan common.Hash)
	sub, err := gethclient.New(client).SubscribePendingTransactions(ctx,pendingTxSub)
	if err != nil {
		log.Fatal(err)
	}
	defer sub.Unsubscribe()

	// Start processing incoming pending transactions
	for {
		select {
		case err := <-sub.Err():
			log.Fatal(err)
		case txs := <-pendingTxSub:
			fmt.Printf("Pending Transaction Hash: %s\n", txs.Hex())
			
		}
	}
}

```



Congratulations! 🚀

You have now successfully built a simple Golang application that connects to an Ethereum node, subscribes to pending transactions, and processes them in real-time. This forms the foundation for creating more sophisticated transaction monitoring systems, dApp analytics tools, and auditing solutions.

Feel free to expand on this code and integrate additional features, such as storing transaction data in a database or analyzing the gas fees associated with transactions.

> Remember to ensure that your Ethereum node provider supports WebSocket connections, as some providers may offer only HTTP-based RPC access.

If you learned something, please don't forget to react to this post and drop a star on this repo on [github](https://github.com/Ayoseun/Listen-to-pending-transactions-using-Geth).

Happy coding!💯

## References

- [Golang](https://go.dev/)

- [Ethereum](https://ethereum.org/en/)

- [Web3go](https://github.com/MariusVanDerWijden/web3go/blob/master/gethclient.go)

- [Go-Ethereum](https://geth.ethereum.org/docs/)

{% embed https://github.com/Ayoseun/Listen-to-pending-transactions-using-Geth %}