Колись задумувались, як створювати додатки, що взаємодіють з блокчейном? У цьому посібнику я створю простий децентралізований додаток (DApp), який дозволяє користувачам підключити свій гаманець і взаємодіяти з смарт-контрактом в мережі Ethereum. Не хвилюйтесь, якщо ви новачок у Web3 — я розіб’ю все на прості кроки!
Що ми створимо
Ми створимо просту DApp для "Дошки оголошень", де користувачі зможуть:
- Підключити свій гаманець MetaMask
- Публікувати повідомлення в блокчейн
3.
Читати повідомлення від інших користувачів
Попередні вимоги
Перед тим як почати, переконайтесь, що у вас є:
- Встановлений Node.js на вашому комп'ютері
- Встановлений розширення MetaMask для браузера
- Базові знання JavaScript
- Трохи тестового ETH в мережі Sepolia (ми покажемо, як отримати це)
Крок 1: Налаштування середовища розробки
Спочатку створимо новий проєкт і встановимо необхідні залежності:
mkdir message-board-dapp
cd message-board-dapp
npm init -y
npm install ethers hardhat @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers
npx hardhat init
Крок 2: Створення смарт-контракту
Створіть новий файл під назвою MessageBoard.sol
у папці contracts
:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract MessageBoard {
struct Message {
address sender;
string content;
uint256 timestamp;
}
Message[] public messages;
event NewMessage(address sender, string content, uint256 timestamp);
function postMessage(string memory _content) public {
messages.push(Message(msg.sender, _content, block.timestamp));
emit NewMessage(msg.sender, _content, block.timestamp);
}
function getMessages() public view returns (Message[] memory) {
return messages;
}
}
Крок 3: Налаштування фронтенду
Створіть новий файл index.html
у кореневій папці вашого проєкту:
Blockchain Message Board
Connect Wallet
Post a Message
Post Message
Messages
``` Тепер створіть файл `app.js` для логіки нашого фронтенду: ``` import { ethers } from "https://cdnjs.cloudflare.com/ajax/libs/ethers/6.7.0/ethers.min.js"; class MessageBoardApp { constructor() { this.contract = null; this.provider = null; this.signer = null; this.contractAddress = "YOUR_CONTRACT_ADDRESS"; this.init(); } async init() { // Налаштування прослуховувачів подій (Event Listeners) document.getElementById('connectWallet').addEventListener('click', () => this.connectWallet()); document.getElementById('postMessage').addEventListener('click', () => this.postMessage()); // Перевірка чи встановлений MetaMask if (typeof window.ethereum !== 'undefined') { this.provider = new ethers.BrowserProvider(window.ethereum); await this.loadMessages(); } else { alert('Будь ласка, встановіть MetaMask для використання цього DApp!'); } } async connectWallet() { try { // Запит на доступ до акаунтів await window.ethereum.request({ method: 'eth_requestAccounts' }); this.signer = await this.provider.getSigner(); // Показати форму для повідомлення після підключення document.getElementById('messageForm').style.display = 'block'; document.getElementById('connectWallet').textContent = 'Підключено!'; } catch (error) { console.error('Помилка при підключенні гаманця:', error); } } async postMessage() { if (!this.signer) { alert('Будь ласка, спочатку підключіть свій гаманець!'); return; } const message = document.getElementById('messageInput').value; if (!message) return; try { const contract = new ethers.Contract(this.contractAddress, contractABI, this.signer); const tx = await contract.postMessage(message); await tx.wait(); // Очистити введення та перезавантажити повідомлення document.getElementById('messageInput').value = ''; await this.loadMessages(); } catch (error) {
console.error('Помилка при публікації повідомлення:', error);
}
}
async loadMessages() {
const contract = new ethers.Contract(this.contractAddress, contractABI, this.provider);
const messages = await contract.getMessages();
const messagesDiv = document.getElementById('messages');
messagesDiv.innerHTML = '';
messages.forEach(msg => {
const messageElement = document.createElement('div');
messageElement.className = 'message';
messageElement.innerHTML = `
Від кого: ${msg.sender}
${msg.content}
Опубліковано: ${new Date(msg.timestamp * 1000).toLocaleString()} `; messagesDiv.appendChild(messageElement); }); } } // Ініціалізація додатку new MessageBoardApp(); ``` ## Крок 4: Розгортання смарт-контракту 1.
Створіть скрипт розгортання в `scripts/deploy.js`:
async function main() {
const MessageBoard = await ethers.getContractFactory("MessageBoard");
const messageBoard = await MessageBoard.deploy();
await messageBoard.deployed();
console.log("MessageBoard розгорнуто за адресою:", messageBoard.address);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
```
- Налаштуйте Hardhat для мережі Sepolia в
hardhat.config.js
:
require("@nomiclabs/hardhat-waffle");
module.exports = {
solidity: "0.8.0",
networks: {
sepolia: {
url: "YOUR_SEPOLIA_RPC_URL",
accounts: ["YOUR_PRIVATE_KEY"]
}
}
};
- Розгорніть контракт:
npx hardhat run scripts/deploy.js --network sepolia
Крок 5: Тестування вашого DApp
- Отримайте тестовий ETH з Sepolia faucet
- Оновіть
contractAddress
у файліapp.js
на адресу вашого розгорнутого контракту - Запустіть фронтенд за допомогою локального сервера:
npx http-server
Загальні проблеми та їх рішення
- MetaMask не підключається
- Переконайтесь, що ви підключені до мережі Sepolia в MetaMask
- Перевірте, чи дозволяє ваш браузер спливаючі вікна
2. Транзакція не проходить
- Переконайтесь, що у вас достатньо тестового ETH для сплати комісії за газ
- Перевірте консоль для конкретних повідомлень про помилки
3. Повідомлення не завантажуються
- Перевірте, чи вірна адреса вашого контракту
- Переконайтесь, що ви підключені до правильної мережі
Подальші кроки
Тепер, коли у вас є базовий DApp, ось кілька способів його розширити:
- Додати можливість лайкати або відповідати на повідомлення
- Зберігати метадані повідомлень на IPFS
- Додати профілі користувачів
- Реалізувати категорії або теги для повідомлень
Висновок
Вітаємо! Ви створили свій перший Web3 DApp. Хоча це простий приклад, він демонструє основні концепції розробки Web3:
- Розробка смарт-контрактів
- Інтеграція гаманців
- Взаємодія користувача з блокчейном
- Інтеграція фронтенду з технологіями Web3
Не забувайте, що блокчейн незмінний, тому завжди тестуйте на тестових мережах перед розгортанням на основній мережі.
Перекладено з: Building Your First Web3 DApp: Guide to Ethereum Development