本文转载自登链社区,原网址https://learnblockchain.cn/article/3263
玩过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”