当前位置: 首页 > 工具软件 > mempool > 使用案例 >

以太坊内存池mempool

幸乐湛
2023-12-01

本文转载自登链社区,原网址https://learnblockchain.cn/article/3263

一、以太坊内存池是什么

  1. 我们知道以太坊是目前最大的公链,它是一个去中心化的数据库,与传统数据库有一个很大的区别是,以太坊的数据并没有一个主动写入的过程。所谓数据上链,其实是用户发起一笔交易,并携带相关信息。这些相关信息可以是调用智能合约某些函数和相关参数。然后这笔交易会广播到全网节点,其他节点收到之后会将他保存到自己的内存池中(mempool,其实翻译成交易池更合适)。如果节点开启了挖矿功能,我们把它叫做矿工节点。矿工节点会根据内存池中所有交易的gasPrice从大到小排序,打包进区块。当然每一笔交易只能被一个矿工打包,这个通过共识决定。一旦发现某一笔交易已经上链,就将其从内存池中删除。

二、科学家和抢跑机器人

玩过DeFi的小伙伴可能遇到过这样的情况,当你要买入一个商品的时候,有人在你之前抢先成交了。其实这些都是机器人发起的交易。我们把这类机器人叫抢跑机器人,开发这些机器人的人叫 “科学家”。抢跑机器的基本原理就是通过监听内存池中的交易,分析交易内容,然后发起一笔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
}

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”

 类似资料: