Типичные ошибки Web3-фронтенда: чек-лист
Собираем грабли из всего курса в один чек-лист: ошибки, которые в Web3 стоят денег и доверия.
Чек-лист антиграблей — сводка самых частых и дорогих ошибок Web3-фронтенда, проверяемых перед релизом.
В Web3 ошибки наказываются жёстче, чем в обычном вебе: пользователь теряет деньги, а откатить нельзя. Соберём в одном месте всё, что мы разбирали, как финальный чек-лист код-ревью.
1. Float для денег
Любая сумма во float (тип number) рано или поздно даст ошибку округления. Деньги — только в целых wei на bigint; конвертация через parseUnits/formatUnits с правильными decimals.
// НЕПРАВИЛЬНО: float
const amount = 0.1 + 0.2; // 0.30000000000000004
// ПРАВИЛЬНО: bigint в минимальных единицах
const wei = 100000000000000000n + 200000000000000000n; // 0.3 в wei, точно
console.log(amount);
console.log(wei.toString());Вывод:
0.30000000000000004 300000000000000000
2. Не обработан reject
Пользователь нажимает «Reject» в кошельке постоянно — это норма. Не ловите это как ошибку приложения. Различайте код 4001/ACTION_REJECTED и реальные сбои.
3. Хардкод адресов
Адрес контракта зависит от сети. Хардкод одного адреса — баг в мультичейне и после передеплоя. Держите карту chainId → адрес в конфиге.
4. Нет проверки сети
Пользователь может быть в другой сети, чем ваш контракт. Перед записью проверяйте chainId и предлагайте переключение; иначе транзакция уйдёт «в пустоту» и сожжёт газ.
5. UI не отражает состояние транзакции
Без статусов pending/confirming/success/error пользователь не понимает, что происходит, и кликает повторно. Блокируйте кнопку, дожидайтесь tx.wait()/receipt, обновляйте данные после успеха.
6. Игнор decimals и сырых чисел
Показ balanceOf «как есть» — в миллион раз неверно. Всегда форматируйте с decimals токена.
7. Не отписаны слушатели событий
В React подписки на события и кошелёк копятся при ремоунте. Чистите их в cleanup-функции useEffect (или используйте wagmi, который делает это сам).
Сводная таблица
| Ошибка | Чем грозит | Как избежать |
| Float для денег | Потеря точности сумм | bigint + parseUnits/formatUnits |
| Reject как ошибка | Пугает пользователя | ловить код 4001 отдельно |
| Хардкод адреса | Битый мультичейн | карта chainId→адрес |
| Нет проверки сети | Газ впустую | проверять chainId, switch |
| Нет статусов tx | Двойные транзакции | pending/confirming/success |
Как работает под капотом
Все эти грабли — следствие одной особенности: в Web3 фронт напрямую распоряжается деньгами и необратимыми действиями, чего в Web2 не было. Там худшее — неверно показанные данные; тут — потерянные средства. Поэтому привычные «мелочи» (округление, обработка отмены, состояние загрузки) перестают быть косметикой и становятся вопросами безопасности и денег.
Итоги
- Деньги — только bigint/wei, никогда float.
- Reject — норма; адреса — из конфига по сети; сеть — проверять.
- Состояние транзакции и decimals — обязательны; слушатели — чистить.