О нас Руководства Проекты Контакты
Админка
пожалуйста подождите

Ethereum обеспечивает работу децентрализованных приложений (dApps) с помощью smart contracts и программируемого blockchain. Web3.js предоставляет JavaScript-интерфейс для взаимодействия с узлами Ethereum. В этом руководстве рассматривается создание blockchain-приложений с точки зрения senior-разработчика.

Почему разработка под Ethereum

Ethereum предлагает уникальные возможности:

  1. Smart Contracts: самовыполняющийся код в blockchain
  2. Децентрализация: отсутствие единой точки отказа или контроля
  3. Прозрачность: все транзакции публично проверяемы
  4. Программируемые деньги: создание финансовых приложений без посредников
  5. NFT и токены: создание цифровых активов

Настройка среды разработки

Установка зависимостей

# Среда Node.js
npm init -y
npm install web3 ethers dotenv

Провайдеры инфраструктуры

Используйте провайдеров вроде Infura или Alchemy вместо запуска собственного узла:

// .env
INFURA_API_KEY=your_api_key_here
PRIVATE_KEY_1=your_private_key_here
PRIVATE_KEY_2=second_private_key_here

Локальная разработка с Ganache

Ganache предоставляет локальный blockchain Ethereum для тестирования:

# Установить Ganache CLI
npm install -g ganache
# Запустить локальный blockchain
ganache --port 8545

Основы Web3.js

Подключение к сети

import { Web3 } from 'web3';
import 'dotenv/config';
// Разработка vs. Production
const isProduction = false;
const web3 = new Web3({
provider: `https://${!isProduction ? 'sepolia' : 'mainnet'}.infura.io/v3/${process.env.INFURA_API_KEY}`,
config: {
defaultTransactionType: "0x2", // Транзакции EIP-1559
},
});
// Проверить подключение
const blockNumber = await web3.eth.getBlockNumber();
console.log('Current block:', blockNumber);

Управление аккаунтами

// Создать новый аккаунт
const newAccount = web3.eth.accounts.create();
console.log('Address:', newAccount.address);
console.log('Private Key:', newAccount.privateKey);
// Загрузить существующий аккаунт из private key
const account = web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_1);
console.log('Loaded address:', account.address);
// Получить баланс
const balance = await web3.eth.getBalance(account.address);
console.log('Balance:', web3.utils.fromWei(balance, 'ether'), 'ETH');

Выполнение транзакций

Отправка ETH

import { Web3 } from 'web3';
const isProduction = false;
const web3 = new Web3({
provider: `https://${!isProduction ? 'sepolia' : 'mainnet'}.infura.io/v3/${process.env.INFURA_API_KEY}`,
config: {
defaultTransactionType: "0x2",
},
});
// Инициализировать аккаунты
const sender = web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_1);
const receiver = web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_2);
async function sendTransaction() {
// Вывести ссылки на аккаунты для проверки
console.log(`Sender: https://${isProduction ? '' : 'sepolia.'}etherscan.io/address/${sender.address}`);
console.log(`Receiver: https://${isProduction ? '' : 'sepolia.'}etherscan.io/address/${receiver.address}`);
// Проверить баланс
const balance = await web3.eth.getBalance(sender.address);
console.log(`Sender balance: ${web3.utils.fromWei(balance, 'ether')} ETH`);
// Получить количество транзакций (nonce)
const txCount = await web3.eth.getTransactionCount(sender.address);
// Сформировать транзакцию
const txObject = {
nonce: web3.utils.toHex(txCount),
to: receiver.address,
value: web3.utils.toWei('0.001', 'ether'),
maxPriorityFeePerGas: 10_000,
maxFeePerGas: 10_000_000_000, // Максимально допустимая стоимость транзакции
};
// Подписать транзакцию
const signedTx = await sender.signTransaction(txObject);
// Отправить транзакцию
console.log(`TX: https://${isProduction ? '' : 'sepolia.'}etherscan.io/tx/${signedTx.transactionHash}`);
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
console.log('Transaction confirmed in block:', receipt.blockNumber);
// Проверить новый баланс
const newBalance = await web3.eth.getBalance(receiver.address);
console.log(`Receiver balance: ${web3.utils.fromWei(newBalance, 'ether')} ETH`);
}
sendTransaction();

Взаимодействие со smart contract

Компиляция smart contract

С использованием компилятора Solidity:

npm install solc

Простой контракт SimpleStorage.sol:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 private storedValue;
event ValueChanged(uint256 newValue);
function set(uint256 value) public {
storedValue = value;
emit ValueChanged(value);
}
function get() public view returns (uint256) {
return storedValue;
}
}

Деплой контракта

import { Web3 } from 'web3';
import fs from 'fs';
import solc from 'solc';
const web3 = new Web3('http://localhost:8545'); // Ganache
// Скомпилировать контракт
const source = fs.readFileSync('SimpleStorage.sol', 'utf8');
const input = {
language: 'Solidity',
sources: {
'SimpleStorage.sol': { content: source },
},
settings: {
outputSelection: {
'*': { '*': ['abi', 'evm.bytecode'] },
},
},
};
const compiled = JSON.parse(solc.compile(JSON.stringify(input)));
const contract = compiled.contracts['SimpleStorage.sol']['SimpleStorage'];
const abi = contract.abi;
const bytecode = contract.evm.bytecode.object;
async function deploy() {
const accounts = await web3.eth.getAccounts();
const SimpleStorage = new web3.eth.Contract(abi);
const deployed = await SimpleStorage
.deploy({ data: bytecode })
.send({
from: accounts[0],
gas: 1500000,
});
console.log('Contract deployed at:', deployed.options.address);
return deployed.options.address;
}
deploy();

Взаимодействие с контрактом

const contractAddress = '0x...'; // Адрес деплоя
const contract = new web3.eth.Contract(abi, contractAddress);
// Прочитать значение (бесплатно, без gas)
async function getValue() {
const value = await contract.methods.get().call();
console.log('Stored value:', value);
}
// Записать значение (требует gas)
async function setValue(newValue) {
const accounts = await web3.eth.getAccounts();
const receipt = await contract.methods
.set(newValue)
.send({
from: accounts[0],
gas: 100000,
});
console.log('Transaction hash:', receipt.transactionHash);
}
// Слушать events
contract.events.ValueChanged({
fromBlock: 'latest',
})
.on('data', (event) => {
console.log('Value changed to:', event.returnValues.newValue);
})
.on('error', console.error);

Использование альтернативы Ethers.js

Ethers.js — ещё одна популярная библиотека с более чистым API:

import { ethers } from 'ethers';
// Подключиться к провайдеру
const provider = new ethers.JsonRpcProvider(
`https://sepolia.infura.io/v3/${process.env.INFURA_API_KEY}`
);
// Создать кошелёк
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
// Отправить транзакцию
async function sendEther() {
const tx = await wallet.sendTransaction({
to: '0xRecipientAddress',
value: ethers.parseEther('0.01'),
});
console.log('TX Hash:', tx.hash);
const receipt = await tx.wait();
console.log('Confirmed in block:', receipt.blockNumber);
}
// Взаимодействие с контрактом
const contract = new ethers.Contract(contractAddress, abi, wallet);
await contract.set(42);
const value = await contract.get();

Взаимодействие с токеном ERC-20

const tokenABI = [
'function balanceOf(address owner) view returns (uint256)',
'function transfer(address to, uint256 amount) returns (bool)',
'function decimals() view returns (uint8)',
'function symbol() view returns (string)',
];
const tokenContract = new web3.eth.Contract(tokenABI, tokenAddress);
// Получить информацию о токене
const symbol = await tokenContract.methods.symbol().call();
const decimals = await tokenContract.methods.decimals().call();
const balance = await tokenContract.methods.balanceOf(walletAddress).call();
console.log(`Balance: ${balance / 10 ** decimals} ${symbol}`);
// Перевести токены
const amount = BigInt(100) * BigInt(10 ** decimals); // 100 токенов
await tokenContract.methods
.transfer(recipientAddress, amount.toString())
.send({ from: senderAddress, gas: 100000 });

Среда тестирования

Использование тестовой сети Sepolia

  1. Получите тестовый ETH из faucet: https://www.alchemy.com/faucets/ethereum-sepolia
  2. Переключитесь на testnet в вашем коде:
const isProduction = process.env.NODE_ENV === 'production';
const network = isProduction ? 'mainnet' : 'sepolia';
const provider = `https://${network}.infura.io/v3/${process.env.INFURA_API_KEY}`;

Hardhat для разработки

npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
npx hardhat init

Настройте hardhat.config.js:

require("@nomicfoundation/hardhat-toolbox");
module.exports = {
solidity: "0.8.19",
networks: {
sepolia: {
url: `https://sepolia.infura.io/v3/${process.env.INFURA_API_KEY}`,
accounts: [process.env.PRIVATE_KEY],
},
},
};

Запуск тестов:

npx hardhat test
npx hardhat run scripts/deploy.js --network sepolia

Полезные инструменты разработки

  • Remix IDE: браузерный редактор Solidity — https://remix.ethereum.org
  • Etherscan: block explorer — https://etherscan.io
  • Ganache: локальный blockchain — https://github.com/trufflesuite/ganache-ui
  • Infura: инфраструктура узлов — https://www.infura.io
  • Alchemy: расширенный API — https://www.alchemy.com

Соображения по безопасности

  1. Никогда не раскрывайте private keys: используйте переменные окружения
  2. Валидируйте все входные данные: smart contracts нельзя изменить после деплоя
  3. Тщательно тестируйте: ошибки стоят реальных денег
  4. Используйте проверенные (audited) контракты: не изобретайте велосипед для токенов
  5. Понимайте gas: оптимизируйте, чтобы экономить деньги пользователей
  6. Обрабатывайте сбои: транзакции могут завершаться неудачей по многим причинам

Ключевые выводы

  1. Сначала используйте testnet: всегда тестируйте в Sepolia перед mainnet
  2. Понимайте gas: каждая операция стоит денег
  3. Events для обновления UI: слушайте events контракта для обновлений в реальном времени
  4. BigInt для сумм: в Ethereum используется 18 знаков после запятой, используйте BigInt
  5. Безопасное управление ключами: для production используйте аппаратные кошельки
  6. Проверяйте в Etherscan: публикуйте исходный код для прозрачности

Разработка под blockchain требует внимательного отношения к безопасности и тестированию — ошибки необратимы и потенциально дорого обходятся. Начинайте с testnet и небольших сумм, пока не будете уверены.

 
 
 
Языки
Темы
Copyright © 1999 — 2026
Зетка Интерактив