冷兔复盘

转自

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

  • 后面的这位科学家,使用的可能是鸟枪法(开始之后、不断的发请求,如果抢购结束就取消)

步骤

  1. 批量给自己的地址转 ETH,如果不调整代码中的 gas price & gas limit,给个地址 0.2E 就够了

  2. 自己去 blocknative 注册一个账号,免费账号延迟比较高(2S)

    1. https://docs.blocknative.com/webhook-api/rate-limits

  3. 步骤 1 中的私钥填入 xrc.js 70 行,格式 [’1’, ‘2’, ‘3’]

  4. 步骤 2 中的私钥填入 xrc.js 43 行,务必替换掉,我用的免费账号,限额很小,别卷我!

  5. process.env.PROVIDER_WSS_URL 也替换成自己的 rpc

  6. 运行代码 ☕️

如何运行

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)

export const abi = [{"inputs":[{"internalType":"string","name":"initBaseURI","type":"string"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"uint256","name":"_maxBatchSize","type":"uint256"},{"internalType":"uint256","name":"_collectionSize","type":"uint256"},{"internalType":"uint256","name":"_reserveAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"newBaseURI","type":"string"}],"name":"BaseURIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReservedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"SignerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum XRC.Status","name":"status","type":"uint8"}],"name":"StatusChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceWithdrawn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getOwnershipData","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"}],"internalType":"struct ERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextOwnerToExplicitlySet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"salt","type":"string"},{"internalType":"bytes","name":"token","type":"bytes"}],"name":"presaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"publicMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"reserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"setOwnersExplicit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum XRC.Status","name":"_status","type":"uint8"}],"name":"setStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"status","outputs":[{"internalType":"enum XRC.Status","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]