转自
https://yixinrock.notion.site/XRC-Public-Sale-c1a4d178fabb43dcb0535448ae0134df
管理员在 14020984 14020997 区块操作两次
setStatus管理员在 14020984 区块设置开始抢购、14020997 设置抢购结束
管理员的 setStatus 请求,被科学家打包进 bundle 执行
十个请求在 14020987 14020986 中成功执行
管理员请求在区块 index 位置,区块 456 笔请求,必须在同一个区块中才能抢到
以下账号抢到很多
请求数 14020984: 456; 14020985: 900; 14020986: 130; 14020987: 418
区块排名前 12 的,科学家从 mempool 池将 setStatus 请求和自己的请求打包成 bundle 给 flashbot
后面的这位科学家,使用的可能是鸟枪法(开始之后、不断的发请求,如果抢购结束就取消)
批量给自己的地址转 ETH,如果不调整代码中的 gas price & gas limit,给个地址 0.2E 就够了
自己去 blocknative 注册一个账号,免费账号延迟比较高(2S)
步骤 1 中的私钥填入
xrc.js70 行,格式 [’1’, ‘2’, ‘3’]步骤 2 中的私钥填入
xrc.js43 行,务必替换掉,我用的免费账号,限额很小,别卷我!process.env.PROVIDER_WSS_URL也替换成自己的 rpc运行代码 ☕️
yarn add ethers underscore bnc-sdk ws
// 提前三分钟运行
node xrc.js
// mainnet // https://etherscan.io/address/0x534d37c630b7e4d2a6c1e064f3a2632739e9ee04 // ownership // https://etherscan.io/address/0x6f8139116b64b7fa056F141d0a3F3002eeb359Bc - mempool 监听这个地址
// rinkeby // https://rinkeby.etherscan.io/address/0xe4f85223c4c81856988508d210fc62480de5352b#code
/**
监听合约的 setStatus 操作,批量下单 */
/* TODO:
10 个地址每个转 0.2
source ~/.env_main
结束后统计成功率
删除私钥 */
import { ethers } from 'ethers' import _ from 'underscore' import BlocknativeSdk from 'bnc-sdk'; import WebSocket from 'ws'; import { abi } from './abi.js';
if (process.env.PROVIDER_WSS_URL === undefined) { console.error("Please provide PROVIDER_WSS_URL env") process.exit(1) }
const contractAddress = '0x534d37c630b7e4d2a6c1e064f3a2632739e9ee04' const xrc_abi = [ 'function mint() payable', 'function balanceOf(address owner) view returns (uint256)' ]
// rinkeby // replace networkId to 1 // replace admin_address to 0x6f8139116b64b7fa056F141d0a3F3002eeb359Bc const ADMIN_ADDRESS = "0x6f8139116b64b7fa056F141d0a3F3002eeb359Bc" const options = { dappId: 'fe96be23-dee0-4b98-b2a0-b6450886588b', networkId: 1, system: 'ethereum', ws: WebSocket, transactionHandlers: [async (event) => await go(event.transaction)], onerror: (error) => {console.error('error!!! ', error)} }
// replace mint to setStatus const main = async () => { const sdk = new BlocknativeSdk(options) console.log('listening until error msg is seen...') await sdk.configuration({ scope: contractAddress, abi: abi, filters: [ { from: ADMIN_ADDRESS }, { "contractCall.methodName": "setStatus" }, { status: "confirmed" } // { status: "pending" } ], watchAddress: true }) }
const go = async (txData) => { const arr = [
]
await Promise.all(arr.map(async v => await mintByPvKey(v))) }
const mintByPvKey = async (privateKey) => { const provider = new ethers.providers.WebSocketProvider(process.env.PROVIDER_WSS_URL) const wallet = new ethers.Wallet(privateKey, provider) const account = wallet.connect(provider) const address = wallet.address
console.log(now processssssing account ${address}...)
const spacex = new ethers.Contract( contractAddress, xrc_abi, account )
const balance = async (address) => { const out = await spacex.balanceOf(address) console.log(debug: address ${address} has ${out} cnt of xrc) return out }
const mint = async () => { const gasPrice = ethers.utils.parseUnits("900", "gwei") const address = wallet.address const gasLimit = 150000 const value = ethers.utils.parseEther("0.0502") const cost = ethers.utils.formatEther(gasPrice.mul(gasLimit).add(value))
console.log(`!!!!!!! address: ${address} will spent ${cost} ETH, and gasPrice is: ${gasPrice}`)
try {
const ba = await balance(address)
if (ba > 0) {
console.log(`address ${address} already got one!!!`)
return
}
const tx = await spacex.mint({
gasPrice,
gasLimit,
value,
})
const res = await tx.wait()
if (res.status) {
console.log(`Transaction receipt : https://www.etherscan.io/tx/${res.logs[1].transactionHash}\n`);
}
} catch (e) {
console.log(e.message)
}
return
}
await mint() }
await main() // process.exit(0)
