Деплой контракта
Как задеплоить Solidity-контракт через ethers v6: скомпилировать bytecode, отправить deploy-транзакцию и проверить адрес.
Что значит задеплоить контракт
Деплой контракта — это транзакция, которая отправляет bytecode в сеть и создаёт новый contract account.
После подтверждения транзакции у контракта появляется адрес. По этому адресу можно читать состояние и вызывать функции.
Деплоим контракт через ethers v6
Создайте проект:
mkdir deploy-contract-example
cd deploy-contract-example
npm init -y
npm pkg set type="module"
npm install ethers solc tsx
npm install --save-dev hardhat typescript @types/node
mkdir contracts scriptsСоздайте файл hardhat.config.ts:
import { defineConfig } from "hardhat/config";
export default defineConfig({
solidity: {
version: "0.8.20",
},
});Создайте файл contracts/Counter.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Counter {
uint256 public value;
constructor(uint256 initialValue) {
value = initialValue;
}
function increment() external {
value += 1;
}
}Создайте файл scripts/deploy-counter.ts:
import { ethers } from "ethers";
import solc from "solc";
import { readFileSync } from "node:fs";
const source = readFileSync("contracts/Counter.sol", "utf8");
const input = {
language: "Solidity",
sources: {
"Counter.sol": {
content: source,
},
},
settings: {
outputSelection: {
"*": {
"*": ["abi", "evm.bytecode.object"],
},
},
},
};
const output = JSON.parse(solc.compile(JSON.stringify(input)));
const contract = output.contracts["Counter.sol"].Counter;
const abi = contract.abi;
const bytecode = `0x${contract.evm.bytecode.object}`;
const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545");
// Первый тестовый аккаунт Hardhat. Не используйте этот ключ в mainnet.
const signer = new ethers.Wallet(
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
provider,
);
const factory = new ethers.ContractFactory(abi, bytecode, signer);
const counter = await factory.deploy(10);
console.log("Deploy transaction:", counter.deploymentTransaction()?.hash);
await counter.waitForDeployment();
const address = await counter.getAddress();
const value = await counter.value();
console.log("Contract address:", address);
console.log("Initial value:", value.toString());Запустите локальную сеть Hardhat в отдельном терминале:
npx hardhat nodeВо втором терминале выполните deploy-скрипт:
npx tsx scripts/deploy-counter.tsВ выводе появится hash deploy-транзакции, адрес нового контракта и стартовое значение 10.
Как это работает
solc.compile() — компилирует Solidity-код и возвращает ABI вместе с bytecode.
abi — описание функций контракта. ethers использует ABI, чтобы понимать методы value() и increment().
bytecode — EVM-код, который deploy-транзакция отправляет в сеть.
new ethers.Wallet(privateKey, provider) — создаёт signer. Именно он подписывает deploy-транзакцию и платит gas.
new ethers.ContractFactory(abi, bytecode, signer) — собирает объект, который умеет создавать новые экземпляры контракта.
factory.deploy(10) — отправляет транзакцию деплоя и передаёт 10 в constructor.
waitForDeployment() — ждёт, пока транзакция попадёт в блок и контракт действительно появится в сети.
getAddress() — возвращает адрес созданного контракта.
Что происходит в сети
Deploy-транзакция отличается от обычного вызова тем, что у неё нет поля to.
Вместо адреса получателя транзакция содержит bytecode:
to: null
data: 0x6080604052...Когда валидаторы включают транзакцию в блок, Ethereum создаёт новый contract account. Адрес контракта вычисляется из адреса деплоера и его nonce.
Частые ошибки
Забыли 0x перед bytecode → ethers ожидает hex-строку. Добавьте префикс: `0x${bytecode}`.
Не дождались деплоя → factory.deploy() возвращает объект сразу после отправки транзакции. Перед чтением адреса и вызовом функций используйте await counter.waitForDeployment().
Передали не те аргументы конструктора → порядок и типы аргументов в deploy(...) должны совпадать с constructor в Solidity.
Использовали тестовый private key в публичной сети → ключ Hardhat известен всем. Он подходит только для локального примера.
Что дальше
- Первый контракт — написать и задеплоить — собрать тот же путь через Hardhat-проект
- Что такое ABI — понять, зачем ethers нужен ABI при работе с контрактом
- Оценка газа (estimateGas) — заранее проверить стоимость deploy-транзакции