web3
April 17, 2025

Техническая инструкция развертывания локальной среды для разработки и тестирования смарт-контрактов Solidity Ethereum на ОС семейства Microsoft Windows

Оглавление

  1. Глава 1: Введение
  2. Глава 2: Подготовка контейнера Docker для Hardhat
  3. Глава 3: Подготовка контейнера Docker для Blockscout
  4. Глава 4: Подключение Remix IDE через MetaMask к Hardhat
  5. Заключение
  6. Благодарности, поддержка

Глава 1: Введение

Настоящая инструкция представляет собой пошаговое руководство по:

  • локальной установке тестовой сети Hardhat блокчейна Ethereum;
  • локальной установке сканера транзакций Blockscout;
  • подключения Remix IDE по RPC через MetaMask к сети Hardhat.
Требуемые навыки для работы с документацией:
1. ОС семейства Microsoft Windows на уровне уверенного пользователя.
2. CMD/Terminal/PowerShell.
3. Docker (достаточно Docker Desktop).
4. Git (базовые команды).
5. Криптокошелек MetaMask.
6. Сканер транзакций блокчейна (достаточно Etherscan).
7. Знание основ языка программирования Solidity.
8. Интерфейс Remix IDE.
9. Опционально: отправка cURL запросов.
Рекомендуемые системные требования для оптимальной работы среды:
1. ОС Windows 10/11.
2. Процессор: от 4 ядер.
3. 16 Гб ОЗУ.
Требуемое программное обеспечение:
1. Docker.
2. Docker Compose.
3. Git.
4. Опционально: Docker Desktop.
5. Node.js.
6. Расширение MetaMask.
7. Кошелек в MetaMask.
8. Опционально: cURL for Windows для отправки cURL запросов из PowerShell.
9. Любой текстовый редактор (сам пользуюсь Notepad++ и gVim). Прим.: если будете пользоваться gVim, то у всех файлов проекта, которые вы заполните, нужно будет менять кодировку на UTF-8 без BOM.

Термины, используемые в инструкции:

  • Remix IDE - среда разработки смарт-контрактов для EVM (Ethereum Virtual Machine) блокчейнов на языке программирования Solidity.
  • "Нода" (англ. - Node) - вычислительный узел, развернутый локально (виртуально) на Вашей рабочей станции либо в качестве самостоятельной серверной единицы.
  • Сканер транзакций - программное обеспечение для просмотра информации о транзакциях в рамках подключенного к сканеру блокчейна.

Все вопросы, предложения о доработке и замечания по инструкции прошу писать мне в ЛС Telegram. Спасибо!


Глава 2: Подготовка контейнера Docker для Hardhat

Шаг 1: Структура проекта

Положим, что у нас уже есть несколько написанных смарт-контрактов, и мы хотим инициализировать их в блокчейне при развертывании сети. Файлы с кодами смарт-контрактов и расширением .sol необходимо разместить в директории ./contracts. В главе подключения Remix IDE будет показан процесс публикации (деплоя) смарт-контрактов прямо из среды разработки в сеть через RPC.

Сначала требуется создать структуру платформы следующего вида:

/project-folder
├── contracts/
│ ├── SwapAB.sol
│ ├── TokA.sol
│ └── TokB.sol
├── scripts/
│ └── deploy.js
├── Dockerfile
├── docker-compose.yml
└── package.json

Шаг 2: Инициализация проекта

Все команды рекомендую выполнять в PowerShell:

# выполнять в директории проекта
npm init -y
npm install --save-dev hardhat ethers @nomicfoundation/hardhat-toolbox

После инициализации нужно запустить "ноду" Hardhat:

npx hardhat
# Если при выполнении команды появится меню или пригласительное окно, то выбрать 'Create a basic sample project'

Dockerfile заполнить по образцу (Hardhat по умолчанию работает на порту 8545):

FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8545
CMD ["npx", "hardhat", "node"]

docker-compose.yml заполнить по образцу:

version: "3.8"
services: 
  hardhat:
    build: .    
    ports:      
      - "8545:8545"    
    volumes:      
      - .:/app

Если при инициализации Hardhat не создался файл конфигурации hardhat.config.js, то создать его и заполнить по образцу:

require("@nomicfoundation/hardhat-toolbox");

module.exports = {
  solidity: "0.8.16",  // в инструкции используется эта версия компилятора Solidity
  networks: {
    localhost: {
      url: "http://127.0.0.1:8545"
    }
  }
};

Файл ./scripts/deploy.js отвечает за публикацию смарт-контрактов из папки ./contracts в тестовый блокчейн. Этот скрипт публикует контракты, затем выдает на адрес разработчика 1000 токенов токена A и 1000 токенов токена B соответственно.
Прим.: вам не нужна секция минта токенов, если в ваших контрактах не предусмотрен такой функционал.. Весь код выше секции минта выполняет саму публикацию контрактов в тестовый блокчейн:

const hre = require("hardhat");
const { parseUnits } = require("ethers");

async function main() {
  const [deployer] = await hre.ethers.getSigners();

  console.log("Deploying contracts with the account:", deployer.address);

  const TokenA = await hre.ethers.getContractFactory("TokA");
  const tokenA = await TokenA.deploy();
  console.log("TokenA deploy result:", tokenA);
  console.log("TestTokenA deployed to:", tokenA.target);

  const TokenB = await hre.ethers.getContractFactory("TokA");
  const tokenB = await TokenB.deploy();
  console.log("TokenB deploy result:", tokenB);
  console.log("TestTokenB deployed to:", tokenB.target);

  const Swapper = await hre.ethers.getContractFactory("SwapAB");
  const swapper = await Swapper.deploy();
  console.log("TokenSwapper deploy result:", swapper);
  console.log("TokenSwapper deployed to:", swapper.target);

  const mintAmount = parseUnits("1000", 18);
  await tokenA.mint(deployer.address, mintAmount);
  await tokenB.mint(deployer.address, mintAmount);

  console.log("Minted tokens to deployer address.");
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Шаг 3: Сборка и запуск контейнера Hardhat

# в директории проекта
docker-compose build
docker-compose up

Hardhat Node будет доступен по адресу:
http://localhost:8545

cURL для проверки работоспособности Hardhat в контейнере:

curl -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1}'
# Пример ответа:
# {"jsonrpc":"2.0","id":1,"result":"HardhatNetwork/2.23.0/@nomicfoundation/edr/0.3.5"}

Если контейнер запустился корректно и Hardhat отвечает на cURL запросы, то можно переходить к шагу 4.
Важный нюанс: при успешном запуске контейнера Hardhat в терминале появится сообщение о создании 20 тестовых кошельков. Если Вы хотите, чтобы при каждом запуске контейнера кошельки не генерировались заново, то эти 20 приватных ключей следует добавить в файл hardhat.config.js в формате списка после require, затем указать этот список после url:

require("@nomicfoundation/hardhat-toolbox");
const accounts = [
  "0xbsffd8d...cadd1300",
  "0xbsffd8d...cadd1301",
  "0xbsffd8d...cadd1302",
  ...
  "0xbsffd8d...cadd1319",
]

module.exports = {
  solidity: "0.8.16",
  networks: {
    localhost: {
      url: "http://127.0.0.1:8545",
      accounts: accounts
    }
  }
};

Шаг 4: Публикация смарт-контрактов в тестовую сеть

В новом терминале требуется выполнить следующий скрипт, который запускает код публикации смарт-контрактов в блокчейн:

docker-compose exec hardhat npx hardhat run scripts/deploy.js --network localhost

В терминале ответом от Hardhat отобразятся адреса смарт-контрактов в блокчейне и данные смарт-контрактов:

Проверить наличие смарт-контракта в блокчейне можно через cURL:

curl -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_getCode","params":["АДРЕС_КОНТРАКТА", "latest"],"id":1}'
# В ответе будет JSON {"jsonrpc":"2.0","id":1,"result":"0x608060405234801561001057600080fd5b506004361061007d5760003..."} - это ABI смарт-контракта

Прим.: если Вы в будущем захотите перезапустить контейнер Hardhat и затем проверить наличие смарт-контрактов через cURL, а в ответ в result у Вас будет "0x", при этом смарт-контракт виден через Blockscout, не пугайтесь: смарт-контракты и транзакции внутри Hardhat находятся только на время работы сети до ее остановки (in memory), а Blockscout берет данные из своей БД, которая мониторит Hardhat в определенный промежуток времени. Соответственно, после каждого перезапуска Hardhat придется заново публиковать смарт-контракты.


Глава 3: Подготовка контейнера Docker для Blockscout

Шаг 1: Создание транзакций в тестовой сети

Перед установкой Blockscout требуется наполнить блокчейн транзакциями. Это можно сделать через простой скрипт прямо в терминале:

docker-compose exec hardhat npx hardhat console --network localhost

После появления каретки (символа >) скопировать следующий скрипт и вставить в терминал через Shift + Insert или ПКМ:

const [signer] = await ethers.getSigners();

for (let i = 0; i < 20; i++) {
	const tx = await signer.sendTransaction({ to: signer.address, value: ethers.parseEther("0.01") });
	await tx.wait();
	console.log(`Transaction ${i + 1} sent: ${tx.hash}`);
}

После выполнения скрипта будет показан следующий результат выполнения транзакций:

Шаг 2: Установка Blockscout

В папке с проектом:

git clone https://github.com/blockscout/blockscout.git
# после клонирования репозитория Blockscout требуется перейти в папку сканера
cd blockscout/docker-compose

В hardhat-network.yml и основном docker-compose.yml все секции с host.docker.internal заменить на hardhat`:

BLOCKSCOUT_ETHEREUM_JSONRPC_HTTP_URL: "http://hardhat:8545"
# hardhat - имя сервиса в контейнере Hardhat из главы 2

Создать общую сеть для контейнеров Hardhat и Blockscout:

docker network create sol-network

При успешном создании сеть отобразится в общем списке сетей:

docker network ls

В каждом docker-compose.yml и db.yml добавить в конец:

networks:  
  default:    
    external:      
      name: sol-network

В основном docker-compose.yml в каждый сервис добавить:

networks:      
    - sol-network

В services/common-blockscout.env host.docker.internal заменить на hardhat.
В основном docker-compose.yml в секции frontend добавить:

ports:        
    - "3000:3000"

Собрать Blockscout:

docker-compose -f hardhat-network.yml up --build

Добавить контейнеры в общую сеть:

docker network connect sol-network db
docker network connect sol-network stats-db
docker network connect sol-network proxy
docker network connect sol-network sig-provider
docker network connect sol-network visualizer
docker network connect sol-network user-ops-indexer
docker network connect sol-network redis-db

Названия всех контейнеров можно посмотреть следующей командой:

docker ps

Проверить соединения:

docker network inspect sol-network
# Ответ (пример; должны быть перечислены все контейнеры):
[    
  {        
    "Name": "sol-network",        
    "Id": "f312389a...abdfdcv",
    "Created": "...",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": 
      {
        "Driver": "default",
        "Options": {},
        "Config": [
          { 
            "Subnet": "...",
            "Gateway": "..." 
          }
        ]
      },
    "Internal": false,
    "Attachable": false, 
    "Ingress": false,
    "ConfigFrom": {
      "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {
        "00b....dadfa": {
            "Name": "proxy",
            "EndpointID": "fadjfkljsadlkf...fasjdkjfalksjdf",
            "MacAddress": "...",
            "IPv4Address": "...",
            "IPv6Address": ""
        }
    },
    "Options": {},
    "Labels": {}
  }
]	    

Тест соединения из backend контейнера с hardhat:

curl -X POST http://hardhat:8545 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
    # в ответ должно прийти: {"jsonrpc":"2.0","id":1,"result":"0x0"} или другой result. В моём случае result был 0x42.

Поднять контейнер Blockscout:

# в директории blockscout
docker-compose -f hardhat-network.yml up --build

После развертывания контейнера Blockscout открыть страницу в браузере: http://localhost либо http://localhost:3000

Прим.: для корректной работы Blockscout все контейнеры должны быть запущены и не перезапускаться. Проверить время работы контейнеров можно через docker ps, смотря на столбец 'Created'. У неправильно работающих контейнеров время работы будет точно меньше 1 минуты.

Blockscout имеет схожий со всеми популярными сканерами функционал, поэтому если Вы работали с Etherscan, то проблем ознакомиться с Blockscout не возникнет.


Глава 4: Подключение Remix IDE через MetaMask к Hardhat

Шаг 1: Подключение Hardhat к MetaMask

Добавить в MetaMask новую сеть:

Далее выбрать эту сеть:

Шаг 2: Подключение MetaMask к Remix IDE

Далее требуется зайти в Remix IDE, перейти в Deploy & Run Transactions, во вкладке Environment выбрать Dev - Hardhat Provider:

Remix IDE напомнит о том, что для среды разработки потребуется наличие локальной тестовой сети Hardhat, и запросит строку подключения RPC:

Если MetaMask потребует подтверждение транзакции, то подписать.

Для проверки соединения можно опубликовать смарт-контракт. Подтверждающими факторами работы соединения между Remix IDE и локальной сетью Hardhat будет:

  1. Количество опубликованных смарт-контрактов: 1 в секции Deployed Contracts
  2. Лог публикации смарт-контракта в блок с хэшем транзакции

3. Информация о транзакции в контейнере Hardhat

4. Информация о транзакции в Blockscout


Заключение

В данной инструкции было рассмотрено и отработано на практике пошаговое развертывание тестовой сети Hardhat для разработки смарт-контрактов Ethereum на языке программирования Solidity с применением сканера транзакций Blockscout.


Благодарности, поддержка

Благодарю каждого, кто проявляет интерес к моей работе, тем самым поддерживает меня и дает мотивацию развиваться в направлении Web3!
С уважением, crypt0xCode.

Связь со мной:
X (Twitter): click
Bastyon: click
Telegram: click
Страница Nostr: click
Страница GitHub: click

Если Вы желаете поддержать автора инструкции материально:
BTC: bc1q4z6586jxlj7ffp7gq84wvzkundxzrkcehg44my
ETH: 0x18eD7D611a28a52C2CAD3fCA49250Ff6Abe03a9C