китаев.tech

Отправка ETH

Как отправить ETH через ethers v6: собрать транзакцию, подписать её кошельком и дождаться подтверждения в блоке.

Что значит отправить ETH

Отправка ETH — это транзакция, которая переводит value с одного EOA на другой адрес.

Она меняет State Ethereum, поэтому её должен подписать кошелёк, а отправитель платит gas.


Отправляем ETH в локальной сети

Запустите локальную сеть Hardhat в отдельном терминале:

bash
npx hardhat node

Затем выполните TypeScript-код:

typescript
import { ethers } from "ethers";

const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545");

// Первый тестовый аккаунт Hardhat. Не используйте этот ключ в mainnet.
const sender = new ethers.Wallet(
  "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
  provider,
);

// Второй тестовый аккаунт Hardhat.
const recipient = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8";

const senderBalanceBefore = await provider.getBalance(sender.address);
const recipientBalanceBefore = await provider.getBalance(recipient);

console.log("Sender:", sender.address);
console.log("Recipient:", recipient);
console.log("Sender before:", ethers.formatEther(senderBalanceBefore), "ETH");
console.log("Recipient before:", ethers.formatEther(recipientBalanceBefore), "ETH");

const tx = await sender.sendTransaction({
  to: recipient,
  value: ethers.parseEther("0.1"),
});

console.log("Transaction hash:", tx.hash);

const receipt = await tx.wait();

if (!receipt || receipt.status !== 1) {
  throw new Error("Транзакция не была успешно выполнена");
}

const senderBalanceAfter = await provider.getBalance(sender.address);
const recipientBalanceAfter = await provider.getBalance(recipient);
const fee = receipt.gasUsed * receipt.gasPrice;

console.log("Block:", receipt.blockNumber);
console.log("Gas used:", receipt.gasUsed.toString());
console.log("Fee:", ethers.formatEther(fee), "ETH");
console.log("Sender after:", ethers.formatEther(senderBalanceAfter), "ETH");
console.log("Recipient after:", ethers.formatEther(recipientBalanceAfter), "ETH");

Код отправляет 0.1 ETH между двумя тестовыми аккаунтами Hardhat и ждёт, пока транзакция попадёт в блок.


Как это работает

new ethers.JsonRpcProvider("http://127.0.0.1:8545") — подключается к локальной Ethereum-сети.

new ethers.Wallet(privateKey, provider) — создаёт signer: объект, который умеет подписывать и отправлять транзакции.

sender.sendTransaction({ to, value }) — создаёт, подписывает и отправляет транзакцию через RPC.

ethers.parseEther("0.1") — переводит человекочитаемое значение ETH в wei.

tx.hash — идентификатор отправленной транзакции. По нему можно искать транзакцию в RPC или explorer.

tx.wait() — ждёт, пока транзакцию включат в блок, и возвращает receipt.

receipt.status — показывает результат выполнения: 1 означает success, 0 означает failed.

receipt.gasUsed * receipt.gasPrice — считает фактическую комиссию за транзакцию.


Что меняется после отправки

Баланс получателя увеличится ровно на 0.1 ETH.

Баланс отправителя уменьшится на сумму перевода и комиссию:

text
senderAfter = senderBefore - value - fee
recipientAfter = recipientBefore + value

Даже простой перевод ETH стоит gas, потому что сеть проверяет подпись, nonce, баланс отправителя и записывает новый State.


Частые ошибки

Передавать ETH как число 0.1 → используйте ethers.parseEther("0.1"). В транзакции value должен быть в wei.

Не ждать tx.wait() → hash означает только отправку в RPC. State меняется после включения транзакции в блок.

Использовать тестовый private key в публичной сети → ключи Hardhat известны всем. Они подходят только для локальной сети.


Что дальше

Материалы китаev.tech публикуются в образовательных целях и не являются инвестиционной рекомендацией. Примеры кода и описания протоколов — для обучения; использование в продакшне на ваш собственный риск. Дисклеймер и политика конфиденциальности.