What's new
Runion

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

[?]Принцип обхода автовывода

lisa99

Heavy Weight
Депозит
$-38
Допустим, сид фраза не в одних руках.
И кто-то мониторит блокчейны на поступление транзакций на кошельки, привязанные к этой сид-фразе (=автовывод)

Как работает обход автовывода? В принципе.
Такой же мониторинг а затем, при наступлении события своп внутри блокчейна?
Что-то более быстрое. чем вывод на другой кошелек..?
 
_lain сказал(а):
флешботы, пихаешь все транзы в 1 бандл, и если кто-то пихает тот же бандл в один блок, обработается тот где больше комсы

т.е в 1 бандле должна быть транза на пополение кошелька чтоб покрыть комиссию, и уже транза на передачу токена или еще какие то взаимодействия с ним
 
и не мало важно если на кошелек пришли деньги к примеру в блоке 1 тебе нужно в блок 2 (следущий за ним) кинуть свой бандл в блок (хуево обьяснил, но думаю суть понятна)
 
_lain сказал(а):
хуево обьяснил, но думаю суть понятна

суть нее..., понятно только направление куда копать))
А если сидок несколько миллионов? хз куда прилетит. Да, отсортировать те, что с транзами.
это над ними всеми нужно чахнуть?
 
lisa99 сказал(а):
суть нее..., понятно только направление куда копать))
А если сидок несколько миллионов? хз куда прилетит. Да, отсортировать те, что с транзами.
это над ними всеми нужно чахнуть?

ты подключаешься к вебсокетам ноды сервисов или к своей ноде, следишь за транзами (мемпул) и там уже из транзы сверяешь адреса со своей базой. (не по всем сидкам проходится, а следить за транзакциями которые в мемпуле)
 
lisa99 сказал(а):
интересует только разработка. Читай заголовок!!
Коммерческих предложений много - в соответствующем Торговом разделе.

хитро, вопросов нет!
 
Крч я правильно понял что надо делать даблспенд? для обхода автовывода?
 
0xUser сказал(а):
Крч я правильно понял что надо делать даблспенд? для обхода автовывода?

Не совсем. Отправляешь 1 бандал с несколькими подписанными транзакциями и они все отправятся в 1 блоке
К примеру:
1 транзакция на пополнение кошелька с автовыводом (подписанная твоим приватным ключом)
2 транзакция на снятие токенов (подписанная приватным ключом кошелька с автовыводом)
Последнее редактирование: 20.02.2024
 
wasted1337 сказал(а):
Отправляешь 1 бандал с несколькими подписанными транзакциями и они все отправятся в 1 блоке
wasted1337 сказал(а):
К примеру:
1 транзакция на пополнение кошелька с автовыводом (подписанная твоим приватным ключом)
2 транзакция на снятие токенов (подписанная приватным ключом кошелька с автовыводом)


Пример отправки бандлы через go (c Хабра, для нескольких транзакций):

JSON:
Скопировать в буфер обмена
import (
"errors"
"fmt"

"github.com/ethereum/go-ethereum/crypto"

"github.com/metachris/flashbotsrpc"
)


rpc := flashbotsrpc.New("https://relay.flashbots.net")
// Список подписанных raw транзакций в порядке исполнения бандла
txs := []string{"0x1234...", "0x4567.."}

// Номер блока, для которого бандл будет валиден

blockNumber := 13281018

sendBundleArgs := flashbotsrpc.FlashbotsSendBundleRequest{

Txs: txs,

BlockNumber: blockNumber,

}

// Приватный ключ, который используется в качестве подписи именно запроса в FB

var privateKey, _ = crypto.GenerateKey()


result, err := rpc.FlashbotsSendBundle(privateKey, sendBundleArgs)

if err != nil {

log.Fatal(err)

}

fmt.Printf("%+v\n", result)


отправка газа и одновременно снятие, чтобы не дать вклиниться другому запросу в мемпуле ?
 
lisa99 сказал(а):
Пример отправки бандлы через go (c Хабра, для нескольких транзакций):

JSON:
Скопировать в буфер обмена
import (
"errors"
"fmt"

"github.com/ethereum/go-ethereum/crypto"


)


rpc = flashbotsrpc.New()

txs = string



blockNumber =

sendBundleArgs = flashbotsrpc.FlashbotsSendBundleRequest

Txs txs

BlockNumber blockNumber

}

// Приватный ключ, который используется в качестве подписи именно запроса в FB

var privateKey, _ = crypto.GenerateKey()


result, err := rpc.FlashbotsSendBundle(privateKey, sendBundleArgs)

if err != nil {

log.Fatal(err)

}

fmt.Printf("%+v\n", result)


отправка газа и одновременно снятие, чтобы не дать вклиниться другому запросу в мемпуле ?
Нажмите, чтобы раскрыть...

Если отправляешь через флешбот, то твою транзакцию в обычной сети не видят до её подтверждения. Но если не в одной, то автовывод сработает и придется поднимать комиссию до максимума.
 
lisa99 сказал(а):
отправка газа и одновременно снятие, чтобы не дать вклиниться другому запросу в мемпуле ?

Да. Вот готовый код на js для трансфера токена
JavaScript:
Скопировать в буфер обмена
const { ethers } = require('ethers');
const { FlashbotsBundleProvider, FlashbotsBundleResolution } = require('@flashbots/ethers-provider-bundle');
const readline = require('readline');
const { exit } = require('process');
const myrivateKey = '...' // донатер газа aka твоя приватка
const provider = new ethers.providers.JsonRpcProvider('https://rpc.ankr.com/eth');
const mywallet = new ethers.Wallet(myrivateKey, 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 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 new Promise((resolve) => {
rl.question('Продолжить? (y/n): ', (input) => resolve(input.trim().toLowerCase()));
});

if (answer === 'y') {
// Пользователь согласен, продолжаем выполнение
console.log('Продолжаем операцию...');
} else {
// Пользователь не согласен, завершаем программу
console.log('Отмена операции.');
rl.close();
process.exit();
}

const data = tokenContract.interface.encodeFunctionData("transfer", [mywallet.address, tokenBalance]);
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) => {
console.log(blockNumber);
try {
const flashbotsTransactionResponse = await flashbotsProvider.sendBundle(bundle, blockNumber + 1);
const bundleResolution = await flashbotsTransactionResponse.wait();
if (bundleResolution === FlashbotsBundleResolution.BundleIncluded) {
console.log(`Congrats, included in ${blockNumber + 1}`);
process.exit(0);
} else if (bundleResolution === FlashbotsBundleResolution.BlockPassedWithoutInclusion) {
console.log(`Not included in ${blockNumber + 1}`);
} else if (bundleResolution === FlashbotsBundleResolution.AccountNonceTooHigh) {
console.log("Nonce too high, bailing");
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(`Error sending transaction to block ${blockNumber + 1}: ${error.message}`);
}
});
rl.close();
}
main().catch((error) => {
console.error(error);
process.exit(1);
});
Последнее редактирование: 22.02.2024
 
Top