主页 > imtoken安卓下载 > 如何监控以太坊内存池(附源码)
如何监控以太坊内存池(附源码)
我们知道以太坊是目前最大的公链。 它是一个去中心化的数据库。 与传统数据库有很大的不同,以太坊数据没有主动写入过程。
什么是以太坊内存池?
我们知道以太坊是目前最大的公链。 它是一个去中心化的数据库。 与传统数据库有很大的不同,以太坊数据没有主动写入过程。 所谓数据上链,其实就是用户发起交易,携带相关信息。 这些相关信息可以是调用智能合约的某些函数和相关参数。 那么这笔交易就会广播给全网的节点,其他节点收到后会保存在自己的内存池中(mempool,其实翻译成交易池更合适)。 如果节点开启了挖矿功能,我们称它为矿工节点。 矿工节点会将内存池中所有交易的gasPrice从大到小排序,打包成块。 当然以太坊内存,每笔交易只能由一个矿工打包,这是共识决定的。 一旦发现交易已经上传到链上,就会从内存池中删除。
科学家和抢夺机器人
玩过 DeFi 的朋友可能遇到过这样的情况。 当你想买一个产品时以太坊内存,有人比你先卖了它。 其实这些都是机器人发起的交易。 我们称这类机器人为失控机器人,研发这些机器人的人被称为“科学家”。 rush machine的基本原理是监听内存池中的交易,分析交易内容,然后发起一个gasPrice较高的交易强行跳入队列。 上面我们说过,矿工根据gasPrice的大小来决定先打包哪笔交易。
如何监控内存池?
监控内存池需要全节点,可以自己部署,也可以第三方节点部署。 比如我们这里使用infura.io,先去上面申请一个key,拿到接口地址。 以太坊官方代码已经实现了go客户端,可以直接使用,代码如下
package main
import (
"context"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient/gethclient"
"github.com/ethereum/go-ethereum/rpc"
"log"
"os"
"os/signal"
"syscall"
)
const (
url = "https://mainnet.infura.io/v3/b4c05366e4c14e8a8304f0690aeae0e8"
wss = "wss://mainnet.infura.io/ws/v3/b4c05366e4c14e8a8304f0690aeae0e8"
)
func watch() {
backend, err := ethclient.Dial(url)
if err != nil {
log.Printf("failed to dial: %v", err)
return
}
rpcCli, err := rpc.Dial(wss)
if err != nil {
log.Printf("failed to dial: %v", err)
return
}
gcli := gethclient.New(rpcCli)
txch := make(chan common.Hash, 100)
_, err = gcli.SubscribePendingTransactions(context.Background(), txch)
if err != nil {
log.Printf("failed to SubscribePendingTransactions: %v", err)
return
}
for {
select {
case txhash := <-txch:
tx, _, err := backend.TransactionByHash(context.Background(), txhash)
if err != nil {
continue
}
data, _ := tx.MarshalJSON()
log.Printf("tx: %v", string(data))
}
}
}
func main() {
go watch()
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
<-signalChan
}
本文参与登联社区写作激励计划,好文章好收益,欢迎正在阅读的你加入。