Web3 Frontend — с чего начать?

от автора

Создание фронтенда для Web3-приложений — это не только дизайн, кнопки и React. Это мост между пользователем и блокчейном. И ты, как фронтенд-разработчик — тот, кто этот мост строит.

В этой статье ты узнаешь:

  • Что такое Web3 Frontend и чем он отличается от Web2

  • Какие инструменты тебе реально нужны

  • Как начать с нуля

  • Как использовать wagmi — главный инструмент Web3-интерфейсов

Что такое Web3 Frontend?

Web3 Frontend — это интерфейс для децентрализованного приложения (dApp), который работает вместо сервера, напрямую общаясь с блокчейном и кошельком пользователя.

Если ты еще не знаешь что такое децентрализация, то обязательно прочитай об этом отдельно. Это целая концепция вокруг которой все web3 и построено.

Ты не отправляешь запросы на backend, как в Web2. Ты взаимодействуешь с сетью (Ethereum, Polygon, Base и т.п.) через смарт-контракты и подключённый кошелёк.

Что тебе нужно для старта?

1. Библиотеки Web3

Библиотека

Назначение

wagmi

Основной инструмент для Web3-интерфейса

viem

RPC-клиент для вызова контрактов (вместо ethers.js)

@rainbow-me/rainbowkit

Подключение кошельков с UI

ethers.js (опц.)

Старый, но популярный Web3-клиент

2. Базовые понятия Web3 — кратко и по делу

Чтобы комфортно работать с wagmi и любыми Web3-инструментами, нужно понимать, как устроен фундамент. Ниже представлены все ключевые термины, которые ты будешь встречать в dApp’ах снова и снова.

address → адрес кошелька или контракта

Это строка, которая представляет пользователя или контракт в сети. Она всегда начинается с 0x, содержит 40 символов.

Пример:
0x1234567890abcdef1234567890abcdef12345678

Есть два вида:

  • EOA (Externally Owned Account) — обычный кошелёк (например, MetaMask)

  • Contract Account — адрес, по которому развёрнут смарт-контракт

Чтобы отображать адрес красиво, используют ENS (например: vitalik.eth)

token → цифровой актив на балансе

ERC-20 — взаимозаменяемые (USDC, DAI):
поддерживают balanceOf, transfer, approve, decimals
Используй useBalance({ token }) в wagmi для получения баланса

ERC-721 — NFT (уникальные ID):
функции ownerOf, tokenURI, transferFrom
Через tokenURI получаешь метаданные с image, name

decimals — количество знаков после запятой:
ETH = 18, USDC = 6
Используй parseUnits / formatUnits из viem для конвертации

approve + allowance — разрешение контракту тратить токены
Обязательно для свапов, стейкинга и NFT-маркетплейсов

chainId → идентификатор сети

Показывает, к какой сети подключён пользователь. Каждый блокчейн имеет уникальный chainId.

Примеры:

  • Ethereum Mainnet → 1

  • Goerli Testnet → 5

  • Polygon → 137

  • Arbitrum → 42161

  • Optimism → 10

Ты используешь chainId, чтобы:

  • определить активную сеть

  • переключать сеть (через switchNetwork)

  • отображать правильные токены/цены

provider → канал связи с блокчейном

Это объект, через который ты читаешь данные из сети: балансы, блоки, события. Он не может подписывать транзакции.

→ В wagmi и viem провайдер создаётся через publicProvider() или RPC-провайдеры вроде Alchemy, Infura и т. д.

→ Примеры возможностей:

  • Получить текущий блок

  • Прочитать состояние контракта

  • Подписаться на события

signer → тот, кто подписывает транзакции

Это расширение provider с доступом к приватному ключу (который держит MetaMask).

С помощью signer ты можешь:

  • отправить транзакцию (sendTransaction)

  • подписать сообщение (signMessage)

  • вызывать contract.write() (например, mint())

→ В wagmi тебе не нужно напрямую работать с signer, он используется внутри хуков типа useContractWrite.

smart contract, ABI, read/write

Смарт-контракт — это программа на блокчейне.
ABI (Application Binary Interface) — это инструкция для твоего фронтенда: какие функции у контракта, какие параметры, что возвращается.

Пример ABI-функции:

{   "name": "mint",   "type": "function",   "stateMutability": "payable",   "inputs": [],   "outputs": [] } 

Есть два типа вызовов:

  • read → бесплатный, безопасный, не требует подписи (например, totalSupply(), balanceOf())

  • write → платный (gas), требует подписи (например, mint(), transfer())

gas, fee, nonce

gas → топливо, которое тратится на выполнение кода
gasPrice → цена за одну единицу газа (в Gwei)
fee = gas × gasPrice (тебе нужно заплатить в ETH или другой валюте)
nonce → счётчик количества транзакций от адреса (чтобы они шли по порядку)

Все write-функции тратят gas, даже если они не срабатывают (например, revert’ятся)

network, chain, L2

network = chain = блокчейн-среда, в которой работает dApp
L1 → основной уровень (Ethereum Mainnet)
L2 → надстройка над L1 для ускорения и удешевления транзакций

Ты должен всегда:

  • проверять, в какой сети находится пользователь

  • уметь предлагать переключение сети (например, с mainnet на L2)

  • работать с несколькими chainId через wagmi-конфигурацию

tokens, decimals, balance

На блокчейне балансы измеряются в целых числах, без запятой
— ETH имеет 18 знаков после запятой
— USDC — 6

В wagmi ты используешь useBalance({ address }) — и получаешь уже отформатированное значение

Краткая таблица для повторения

Термин

Пояснение

address

Адрес пользователя или контракта (0x...)

chainId

ID блокчейна

provider

Канал к блокчейну (чтение)

signer

Подписант транзакций (MetaMask и т.д.)

contract

Программа на блокчейне

ABI

Описание функций контракта

gas

Стоимость исполнения

read

Чтение без газа

write

Транзакции с подписью и оплатой

nonce

Счётчик транзакций

signMessage

Подпись строки через кошелёк

SIWE

Авторизация без пароля через Ethereum

token

цифровой актив

wagmi — must-have для Web3 Frontend

Библиотека wagmi — это набор React-хуков, которые позволяют:

  • Подключать кошелёк

  • читать/записывать в смарт-контракт

  • Получать баланс, ENS, chain info

  • Подписывать сообщения и транзакции

🧪 Пример: минимальный dApp с wagmi

1. Установка:

npm install wagmi viem @rainbow-me/rainbowkit

2. Настройка WagmiConfig

// main.tsx import { WagmiConfig, createConfig, configureChains } from 'wagmi' import { publicProvider } from 'wagmi/providers/public' import { mainnet, polygon, optimism } from 'wagmi/chains' import { QueryClient, QueryClientProvider } from '@tanstack/react-query'  const { publicClient, webSocketPublicClient } = configureChains(   [mainnet, polygon, optimism],   [publicProvider()] )  const config = createConfig({   autoConnect: true,   publicClient,   webSocketPublicClient, })  const queryClient = new QueryClient()  export function Web3Provider({ children }) {   return (     <WagmiConfig config={config}>       <QueryClientProvider client={queryClient}>         {children}       </QueryClientProvider>     </WagmiConfig>   ) } 

3. Подключение кошелька

// ConnectWallet.tsx import { useAccount, useConnect, useDisconnect } from 'wagmi' import { InjectedConnector } from 'wagmi/connectors/injected'  export function ConnectWallet() {   const { connect } = useConnect({     connector: new InjectedConnector(),   })   const { disconnect } = useDisconnect()   const { isConnected, address } = useAccount()    return isConnected ? (     <div>       <p>Вы подключены: {address}</p>       <button onClick={() => disconnect()}>Отключиться</button>     </div>   ) : (     <button onClick={() => connect()}>Подключить MetaMask</button>   ) } 

4. Чтение баланса

// Balance.tsx import { useBalance, useAccount } from 'wagmi'  export function Balance() {   const { address } = useAccount()   const { data, isLoading } = useBalance({ address })    if (isLoading) return <p>Загрузка...</p>    return <p>Баланс: {data?.formatted} {data?.symbol}</p> } 

5. Вызов функции смарт-контракта

// MintNFT.tsx import { usePrepareContractWrite, useContractWrite } from 'wagmi' import { parseEther } from 'viem'  const contractAddress = '0x123...' // твой контракт const abi = [   {     name: 'mint',     type: 'function',     stateMutability: 'payable',     inputs: [],     outputs: [],   }, ]  export function MintNFT() {   const { config } = usePrepareContractWrite({     address: contractAddress,     abi,     functionName: 'mint',     value: parseEther('0.01'),   })    const { write, isLoading, isSuccess } = useContractWrite(config)    return (     <button disabled={!write || isLoading} onClick={() => write?.()}>       {isLoading ? 'Минтим...' : 'Минт NFT'}       {isSuccess && <p>Успех!</p>}     </button>   ) } 

Что по итогу?

Web3 Frontend — это не сложно, если начать с правильных инструментов.
Твоя цель — не перепридумать backend, а создать безопасный, быстрый и дружелюбный интерфейс поверх блокчейна. И в этом тебе максимально помогает wagmi.

В следующих частях мы остановимся более подробно на живых примерах dapp приложений и разберем как это все работает под капотом.


ссылка на оригинал статьи https://habr.com/ru/articles/931352/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *