Как добавить функцию указания количества токенов для отправки?
JavaScript:
const { ethers } = require('ethers');
const { FlashbotsBundleProvider, FlashbotsBundleResolution } = require('@flashbots/ethers-provider-bundle');
const readline = require('readline');
const { exit } = require('process');
const myPrivateKey = '...' // Приватный ключ донатера газа (замените на свой)
const provider = new ethers.providers.JsonRpcProvider('https://rpc.ankr.com/eth');
const myWallet = new ethers.Wallet(myPrivateKey, provider);
let flashbotsProvider;
async function setupFlashbotsProvider() {
flashbotsProvider = await FlashbotsBundleProvider.create(provider, myWallet);
// Дополнительный код, зависящий от flashbotsProvider
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// Функция для запроса ввода от пользователя
function askQuestion(question) {
return new Promise((resolve) => {
rl.question(question, (input) => resolve(input.trim()));
});
}
async function main() {
await setupFlashbotsProvider();
const privateKey = await askQuestion("Введите приватный ключ отправителя токена: ");
const wallet = new ethers.Wallet(privateKey, provider);
console.log("Адрес отправителя:", wallet.address);
const tokenAddressInput = await askQuestion("Введите адрес контракта токена: ");
const tokenAddress = ethers.utils.getAddress(tokenAddressInput);
const ERC20_ABI = [
"function balanceOf(address owner) view returns (uint256)",
"function transfer(address to, uint amount) returns (bool)"
];
const tokenContract = new ethers.Contract(tokenAddress, ERC20_ABI, provider);
const tokenBalance = await tokenContract.balanceOf(wallet.address);
console.log(`Баланс токена: ${tokenBalance} wei`);
const tokensToTransferInput = await askQuestion("Введите количество токенов для перевода (в wei): ");
const tokensToTransfer = ethers.BigNumber.from(tokensToTransferInput);
if (tokensToTransfer.gt(tokenBalance)) {
console.log("Ошибка: количество токенов для перевода превышает баланс.");
process.exit(1);
}
const gasLimitInput = await askQuestion("Введите gas limit для токена: ");
const gasLimit = Number(gasLimitInput) || 65000;
const gasPrice = await provider.getGasPrice();
const gasPriceWithIncrease = gasPrice.add(gasPrice.div(10));
const totalCostEth = ethers.utils.formatEther(gasPriceWithIncrease.mul(gasLimit));
console.log(`Текущая стоимость транзакции: ${totalCostEth} ETH`);
const answer = await askQuestion('Продолжить? (y/n): ');
if (answer.toLowerCase() !== 'y') {
console.log('Отмена операции.');
rl.close();
process.exit(0);
}
const data = tokenContract.interface.encodeFunctionData("transfer", [myWallet.address, tokensToTransfer]);
const bundle = [
{
transaction: {
chainId: 1,
to: wallet.address,
value: gasPriceWithIncrease.mul(gasLimit),
type: 1,
gasPrice: gasPriceWithIncrease,
gasLimit: 21000,
},
signer: myWallet
},
{
transaction: {
chainId: 1,
to: tokenAddress,
type: 1,
data: data,
gasPrice: gasPriceWithIncrease,
gasLimit: gasLimit,
},
signer: wallet
}
];
provider.on('block', async (blockNumber) => {
try {
const flashbotsTransactionResponse = await flashbotsProvider.sendBundle(bundle, blockNumber + 1);
const bundleResolution = await flashbotsTransactionResponse.wait();
if (bundleResolution === FlashbotsBundleResolution.BundleIncluded) {
console.log(`Успешно включено в блок ${blockNumber + 1}`);
process.exit(0);
} else if (bundleResolution === FlashbotsBundleResolution.BlockPassedWithoutInclusion) {
console.log(`Не включено в блок ${blockNumber + 1}`);
} else if (bundleResolution === FlashbotsBundleResolution.AccountNonceTooHigh) {
console.log("Nonce слишком высокий, завершаем");
process.exit(0);
}
if ('error' in flashbotsTransactionResponse) {
console.warn(flashbotsTransactionResponse.error.message);
return;
}
const simulate = await flashbotsTransactionResponse.simulate();
if (simulate.firstRevert === undefined) {
console.log("Транзакция будет успешно выполнена. Ожидайте.");
} else {
console.log(simulate.firstRevert);
// exit()
}
} catch (error) {
console.warn(`Ошибка при отправке транзакции в блок ${blockNumber + 1}: ${error.message}`);
}
});
rl.close();
}
main().catch((error) => {
console.error(error);
process.exit(1);
});