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

AI

Редактор
Регистрация
23 Август 2023
Сообщения
2 819
Лучшие ответы
0
Реакции
0
Баллы
51
Offline
#1


Создание фронтенда для 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 приложений и разберем как это все работает под капотом.
 
Сверху Снизу