Учебник Web3-фронтенд для начинающих
Этот курс учит делать фронтенд децентрализованных приложений (dApp) — веб-интерфейсов, которые общаются с блокчейном напрямую вместо привычного бэкенда. Вы пройдёте путь от понимания архитектуры dApp до готовой страницы, которая показывает баланс токена и отправляет его.
Разберём подключение кошелька (MetaMask, EIP-1193), провайдеры и сети, три кита ethers.js (Provider, Signer, Contract), чтение и запись контрактов, безопасную работу с деньгами на bigint, события, типобезопасность, современный viem и стандарт React-dApp — wagmi с RainbowKit. Затронем токены ERC-20, NFT, подпись сообщений (SIWE), мультичейн, IPFS, The Graph, безопасность, тестирование и деплой.
Курс для фронтендеров, знакомых с JavaScript/TypeScript и React, которые хотят войти в Web3. Базовое представление о блокчейне и Solidity полезно, но не обязательно — фокус именно на фронтенде.
Курс «Web3-фронтенд: dApp на ethers.js» состоит из 8 разделов и 30 уроков: Что такое dApp и Web3-фронтенд, Архитектура, провайдеры и подключение к сети, Кошельки и подключение аккаунта, ethers.js: чтение, запись и числа, События, типобезопасность и viem, wagmi + React и UI транзакций, Токены, NFT, подпись и мультичейн и Данные, безопасность, прод и реальный пример. Уроки идут по порядку — от основ к более сложным темам, в каждом есть объяснение с примерами, а в конце — вопросы для самопроверки. К урокам привязаны задачи с автоматической проверкой: прочитали тему — сразу закрепили её кодом.
Программа курса
1 Что такое dApp и Web3-фронтенд
- Что такое dApp: фронтенд без бэкенда
Чем децентрализованное приложение отличается от обычного сайта: фронт общается со смарт-контрактом напрямую, без своего сервера и базы.
- Web2 против Web3: что меняется для фронтендера
Карта соответствий между классической клиент-серверной архитектурой и dApp: где REST заменяется контрактом, а логин — кошельком.
- Что такое dApp: фронтенд без бэкенда
2 Архитектура, провайдеры и подключение к сети
- Архитектура dApp: фронт, кошелёк, нода, контракт
Полная карта взаимодействий в dApp: чем отличаются маршруты чтения и записи и почему кошелёк нужен только для записи.
- Провайдеры и RPC: как фронт соединяется с сетью
JsonRpcProvider и BrowserProvider в ethers.js, выбор RPC-узла (Infura, Alchemy, публичные ноды) и почему для событий нужен WebSocket.
- Provider против Signer: читать или писать
Ключевое различие ethers.js: Provider только читает сеть, а Signer привязан к аккаунту и умеет подписывать транзакции и сообщения.
- Архитектура dApp: фронт, кошелёк, нода, контракт
3 Кошельки и подключение аккаунта
- window.ethereum и EIP-1193
Стандарт EIP-1193: единый объект window.ethereum, метод request и разница между eth_accounts и eth_requestAccounts.
- Подключение аккаунта и события кошелька
Кнопка «Подключить кошелёк» по правилам: eth_requestAccounts, обработка accountsChanged и chainChanged, восстановление сессии через eth_accounts.
- Смена сети: chainId, switch и add
Почему контракт привязан к сети, как проверить chainId и переключить пользователя на нужную сеть через wallet_switchEthereumChain и код 4902.
- window.ethereum и EIP-1193
4 ethers.js: чтение, запись и числа
- Три кита ethers.js: Provider, Signer, Contract
Главные классы ethers.js и их роли, как Contract создаётся из адреса/ABI/runner и ключевые отличия v5 от v6 (bigint вместо BigNumber).
- Чтение из контракта: ABI и view-функции
Что такое ABI, как фронт узнаёт функции контракта, человекочитаемый формат ABI и вызов view-функций через Provider без подписи и газа.
- Запись в контракт: транзакция, газ, подтверждение
Жизненный цикл write-транзакции в ethers.js: отправка, tx.wait(), газ и корректная обработка отказа пользователя (код 4001).
- Числа в Web3: wei, gwei, ether и bigint
Почему деньги в блокчейне — целые wei, а не float; единицы wei/gwei/ether, parseEther/formatEther и арифметика на bigint без потери точности.
- Три кита ethers.js: Provider, Signer, Contract
5 События, типобезопасность и viem
- События контракта: подписка и обновление UI
Как слушать события контракта через contract.on, читать историю логов queryFilter, роль indexed-полей и ограничение eth_getLogs по диапазону блоков.
- Типобезопасность: TypeChain и typed contracts
Почему строковый ABI опасен, как TypeChain генерирует типы контракта из ABI и как viem выводит типы через as const без кодогенерации.
- viem: современная альтернатива ethers
Почему новые dApp выбирают viem: лёгкий бандл, типы из ABI из коробки, Public/Wallet Client как аналоги Provider/Signer и сравнение с ethers.
- События контракта: подписка и обновление UI
6 wagmi + React и UI транзакций
- wagmi: хуки useAccount и useReadContract
Стандарт для React-dApp: настройка WagmiProvider, реактивный useAccount и useReadContract с кэшем, загрузкой и ошибками на базе viem и TanStack Query.
- Запись через wagmi и состояния транзакции
useWriteContract + useWaitForTransactionReceipt: две стадии записи, карта состояний pending/confirming/success/error в UI и инвалидация кэша чтения.
- RainbowKit и Web3Modal: подключение красиво
Готовые UI-библиотеки подключения кошельков: модалка с десятками кошельков, WalletConnect, ConnectButton и почему они работают поверх wagmi.
- wagmi: хуки useAccount и useReadContract
7 Токены, NFT, подпись и мультичейн
- ERC-20 на фронте: баланс, decimals, approve
Работа с токенами ERC-20: чтение баланса с учётом decimals, паттерн approve + transferFrom как две транзакции и проверка allowance.
- NFT на фронте: ERC-721 и метаданные
Показ NFT в dApp: balanceOf и tokenURI у ERC-721, структура метаданных (name/image/attributes) и превращение ipfs:// в https через шлюз.
- Подпись сообщений и вход без пароля (SIWE)
personal_sign и Sign-In with Ethereum: как доказать владение адресом без газа, зачем нужен nonce и как сервер проверяет подпись через восстановление адреса.
- Мультичейн: несколько сетей в одном dApp
Как dApp работает в нескольких сетях: карта адресов контракта на chainId, проверка поддерживаемой сети, переключение и хуки wagmi useChainId/useSwitchChain.
- ERC-20 на фронте: баланс, decimals, approve
8 Данные, безопасность, прод и реальный пример
- IPFS: где хранить картинки и метаданные
Зачем dApp нужен IPFS: адресация по содержимому (CID), доступ через шлюзы, пиннинг для надёжности и почему on-chain хранят только ссылку.
- Индексация данных: The Graph и subgraph
Почему нельзя читать историю и агрегаты прямо с ноды, как The Graph и subgraph индексируют события контракта и отдают их через GraphQL.
- Безопасность фронта: фишинг, approve, симуляция
Главные угрозы Web3-фронта (фишинг, опасные approve, слепая подпись) и защита: проверка адресов, approve на сумму, объяснение подписи и симуляция транзакций.
- Тестирование dApp: локальная сеть и тест-сети
Безопасная разработка dApp: локальный узел Hardhat/Anvil, форк mainnet для тестов против реальных контрактов и тест-сеть Sepolia перед релизом.
- Деплой dApp: IPFS или Vercel
Публикация фронта dApp как статики: привычный Vercel против децентрализованного IPFS (CID, ENS, пиннинг) и типичные грабли роутинга SPA и путей ассетов.
- UX Web3 и абстракция аккаунтов
Почему Web3-UX сложный (газ, seed-фразы, подтверждения) и как его улучшают: понятные статусы, ENS, автопереключение сети и абстракция аккаунтов ERC-4337.
- Типичные ошибки Web3-фронтенда: чек-лист
Сводный чек-лист антиграблей dApp: float для денег, необработанный reject, хардкод адресов, отсутствие проверки сети и статусов транзакции.
- Реальный пример: баланс и перевод токена
Финальный сквозной разбор страницы dApp: подключение, чтение баланса ERC-20 с decimals, отправка через wagmi с проверкой сети и состояниями транзакции.
- IPFS: где хранить картинки и метаданные