Web3 — Разрабатываем магазин без базы данных
- суббота, 31 января 2026 г. в 00:00:04
Для начала определимся, что мы хотим получить.
Авторизация с кошельком через metamask extension.
Магазин внутри-игровых предметов. При покупке, осуществляется перевод средств на адрес магазина и записывается адрес покупателя и id предмета в контракт. Можно запросить купленные предметы.


Во-первых, понадобятся инструменты для сборки, тестирования, отладки и публикации смарт-контрактов. Современные решения: foundry и hardhat3. Я использовал foundry.
Для разработки также потребуется тестнет. Можно использовать стороннее решение, или воспользоваться тестнетом представляемым фреймворком. Я использовал anvil из foundry.
anvil запускается и работает из консоли. Функционал стандартный, тестнет создает аккаунты со средствами на счетах и предоставляет RPC точку(вида, http://127.0.0.1:8545) для работы. По этому адресу нужно подключить metamask extension. А также туда публикуется собранный контракт.


Контракт будет написан на solidity. Нам понадобятся две функции:
1. Покупка предмета. Покупка будет передавать средства на кошелек магазина и записывать покупателю id купленного предмета.
function purchaseItem(uint8 _itemId) external payable {
uint256 itemCost = 2 gwei; // 0.0012 USD / 0.18 RUB;
// Forward the funds to the seller
(bool success, ) = STORE_ADDRESS.call{value: itemCost}("");
require(success, "Transfer failed");
boughtItems[msg.sender].push(_itemId);
}2. Просмотр купленных предметов.
function getBoughtItems() external view returns (uint8[] memory) {
return boughtItems[msg.sender];
}Также запишем адрес кошелька магазина при инициализации контракта.
constructor(address _store) {
STORE_ADDRESS = _store;
}Для сборки, тестирования и публикации я использовал forge из фреймворка foundry. Тесты для дураков приводить здесь не буду. После успешного тестирования и сборки, публикуем контракт:
forge create ./src/Store.sol:Store \
--private-key <PRIVATE_KEY> \
--rpc-url <RPC_URL> \
--broadcast \
--constructor-args <STORE_PUBLIC_KEY>После публикации, нам предоставляют адрес смарт-контракта. Строка "Deployed to". Его будем использовать в следующей части при подключении интерфейса.

Понадобится библиотека для взаимодействия с metamask и блокчейном. Я использовал ethers v6, она показалась мне наиболее хорошо документированной.
Подключаемся к кошельку через metamask extension.
import { ethers } from "ethers";
const provider = new ethers.BrowserProvider(window.ethereum); Запросим баланс, чтобы убедится в корректной работе.
const signerObj = await provider.getSigner();
const balance = await provider.getBalance(signerObj.address);
const balanceFormatted = ethers.formatEther(balance);1. Нам нужен abi собранного контракта. Это строка с описанием методов смарт-контракта, его можно написать самостоятельно или взять в артефакте после сборки.
import ContractArtifact from "***/Store.json";
const abi = ContractArtifact.abi;2. Создаем экземпляр Contract, передаем туда адрес смарт-контракта, который выдали после сборки, abi и объект полученный при авторизации.
const contract = new ethers.Contract(CONTRACT_ADDRESS, abi, signerObj);3. Теперь можно вызывать функции смарт-контракта.
// покупка предмета
contract.purchaseItem(itemId, {
value: ethers.parseUnits("2", "gwei")
});
// получение списка покупок
const userItems = await contract.getBoughtItems();По завершении работ, можно залить магазин и контракт в настоящую сеть. Для публикации потребуется небольшое количество эфира.

Всем спасибо за внимание!