Chuyển đổi ETH ↔ Wei ↔ Gwei

Chuyển giữa các đơn vị Ethereum (wei, gwei, ether, v.v.). BigInt math, không mất độ chính xác.

web3

ETH ↔ Wei ↔ Gwei Converter

ETH (ether)1.0
finney (10⁻³)1000.0
szabo (10⁻⁶)1000000.0
gwei (10⁻⁹)1000000000.0
mwei (10⁻¹²)1000000000000.0
kwei (10⁻¹⁵)1000000000000000.0
wei (smallest)1000000000000000000

Uses ethers.parseUnits / formatUnits (BigInt math — no floating-point loss).

Runs entirely in your browser. Your input never leaves your device.

What next?

How it works

Hệ thống đơn vị ETH

Ether (ETH) có thể chia đến 18 chữ số thập phân. Đơn vị nhỏ nhất là wei — đặt theo tên Wei Dai, nhà mật mã học đề xuất b-money. Toàn bộ hệ thống:

| Đơn vị | Giá trị wei | Dùng khi nào | |--------|-------------|-------------| | wei | 1 | Toán học nội bộ smart contract | | kwei (babbage) | 10³ | Hiếm dùng | | mwei (lovelace) | 10⁶ | Hiếm dùng | | gwei (shannon) | 10⁹ | Gas price | | microether (szabo) | 10¹² | Đôi khi trong DeFi | | milliether (finney) | 10¹⁵ | Hiếm dùng | | ether | 10¹⁸ | Hiển thị balance cho người dùng |

Trong thực tế, bạn làm việc với ba đơn vị gần như duy nhất: wei cho arithmetic trong contract, gwei cho gas pricing, và ether để hiển thị balance. Các đơn vị trung gian (kwei, mwei, szabo, finney) chủ yếu xuất hiện trong tài liệu cũ và EIP cũ.

Tại sao wei tồn tại và tại sao quan trọng

Solidity và EVM hoạt động hoàn toàn bằng số nguyên — không có kiểu dữ liệu floating-point. Mọi value transfer xảy ra trong wei. Nếu contract nhận 1 ETH, EVM thấy số nguyên 1000000000000000000 (10¹⁸). Thiết kế này loại bỏ rounding error trong financial logic với chi phí là mọi developer phải suy nghĩ về số nguyên rất lớn.

Hệ quả rất thực tế: lỗi sai một chữ số thập phân không mất vài xu — nó có thể mất 10× hoặc 100× số tiền dự định. Function nhận wei nhưng nhận được gwei sẽ đọc 1 gwei (10⁹ wei) như 0.000000001 ETH, không phải 1 ETH mà người gọi muốn.

Bẫy precision của JavaScript Number

Number trong JavaScript là 64-bit IEEE 754 double. Nó chỉ biểu diễn chính xác số nguyên đến 2⁵³ − 1 = 9,007,199,254,740,991. Một ether trong wei là 1,000,000,000,000,000,000 (10¹⁸) — lớn hơn giới hạn đó. Phép tính trên giá trị wei dùng Number thông thường sẽ silently mất precision:

// SAI — mất precision ngầm
const oneEther = 1e18;          // 1000000000000000000 ✓ (đúng, may mắn)
const weirdAmt = 1.5e18 + 1;    // 1500000000000000001? Không:
console.log(1500000000000000001) // → 1500000000000000000 ✗ (mất +1)

Cách sửa là dùng BigInt (native trong mọi JS/TS hiện đại) hoặc thư viện bọc nó:

// ĐÚNG — dùng BigInt
const oneEther = 1_000_000_000_000_000_000n;
const result = oneEther + 1n;  // 1000000000000000001n ✓

Tool này dùng ethers.js v6 bên trong, biểu diễn mọi amount như BigInt. Kết quả conversion được format dưới dạng decimal string, không phải float — nên hiển thị là chính xác.

parseUnits và formatUnits của ethers.js

Hai function bạn dùng hàng ngày trong bất kỳ Ethereum dapp nào:

import { parseUnits, formatUnits } from "ethers";

// Người dùng nhập "1.5" ETH → BigInt trong wei
const weiAmount = parseUnits("1.5", "ether");
// → 1500000000000000000n

// Contract trả BigInt wei → hiển thị cho người dùng
const display = formatUnits(weiAmount, "ether");
// → "1.5"

// Gas price: gwei ↔ wei
const gasPrice = parseUnits("20", "gwei");      // → 20000000000n
const gasPriceGwei = formatUnits(gasPrice, "gwei"); // → "20.0"

Argument thứ hai nhận tên đơn vị ("ether", "gwei", "wei") hoặc số decimal dưới dạng integer. Cách này tổng quát cho ERC-20 token: parseUnits("100", 6) cho USDC (6 decimals), parseUnits("100", 18) cho hầu hết token khác.

Tính toán gas cost

Chi phí ETH của một transaction là:

gas cost (ETH) = gas used × gas price (gwei) × 10⁻⁹

Hoặc trong wei:

gas cost (wei) = gas used × gas price (wei)

Một ETH transfer tiêu chuẩn dùng 21,000 gas. Ở gas price 20 gwei:

cost = 21,000 × 20 × 10⁻⁹ ETH = 0.00042 ETH = 420,000,000,000,000 wei

DeFi swap phức tạp có thể dùng 150,000–500,000 gas. Dùng converter này để kiểm tra cost ở gas price hiện tại mà không cần tính nhẩm.

EIP-1559: base fee + priority fee

Kể từ London hard fork (tháng 8/2021), Ethereum dùng mô hình hai thành phần:

  • Base fee — được protocol đặt theo thuật toán mỗi block, bị đốt (không trả cho validator). Tính bằng gwei.
  • Priority fee (tip) — trả thẳng cho validator như khuyến khích. Tính bằng gwei. Thường: 0.1–2 gwei lúc bình thường, lên đến 10+ gwei khi tắc nghẽn.

Wallet của bạn đặt max fee per gas (mức tối đa bạn trả) và max priority fee. Phí thực tế là:

actual fee per gas = min(max_fee, base_fee + priority_fee)

Khi debug transaction receipt, field effectiveGasPrice là phí thực tế per gas tính bằng wei. Dùng converter này để chuyển về gwei so sánh với base fee hiện tại.

Debug transaction receipt

Khi inspect raw transaction receipt từ eth_getTransactionReceipt, nhiều field tính bằng wei:

  • value — ETH được chuyển, tính bằng wei
  • gasPrice / effectiveGasPrice — phí per gas unit, tính bằng wei
  • cumulativeGasUsed — gas tích lũy trong block đến tx này

Chuyển effectiveGasPrice sang gwei để so sánh với block explorer. Nhân effectiveGasPrice × gasUsed để tính tổng phí tính bằng wei, rồi chuyển sang ETH để kiểm tra chi phí bằng tiền thật.

Lỗi developer phổ biến

  1. Chia cho 1e18 thay vì 10n**18n trong JS.** Float 1e18 đúng cho giá trị cụ thể 10¹⁸, nhưng phép tính quanh nó mất bit. Luôn dùng BigInt hoặc formatUnits.

  2. Nhầm ERC-20 token decimals với ETH decimals. USDC dùng 6 decimals; DAI dùng 18; một số token dùng 8. parseUnits("1", 6) cho 1 USDC không giống parseUnits("1", 18) cho 1 ETH.

  3. Hiển thị wei thô cho người dùng. Balance 50000000000000000 wei trông vô nghĩa. Luôn formatUnits trước khi hiển thị.

  4. Lưu wei trong cột SQL INTEGER. PostgreSQL INTEGER tối đa ~2.1 tỷ; BIGINT ~9.2 × 10¹⁸ — vừa đủ chứa ~9 ETH. Dùng NUMERIC hoặc lưu dưới dạng TEXT decimal string.

Quyền riêng tư

Toàn bộ conversion chạy locally trong browser qua ethers.js. Không có giá trị nào được gửi đến server.

FAQ

Wei là gì và tại sao Ethereum dùng nó?

Wei là đơn vị nhỏ nhất không thể chia của ether — 1 ETH bằng 10¹⁸ wei. EVM không có arithmetic floating-point, nên mọi value transfer on-chain là số nguyên wei. Dùng đơn vị nhỏ nhất cho toán học nội bộ loại bỏ rounding error trong financial logic. Tên đặt theo Wei Dai, nhà mật mã học mô tả b-money, tiền thân khái niệm của Bitcoin.

Tại sao không dùng JavaScript Number cho giá trị wei?

Number trong JavaScript là 64-bit IEEE 754 double, chỉ biểu diễn chính xác số nguyên đến 2⁵³ − 1 (khoảng 9 × 10¹⁵). Một ETH tính bằng wei là 10¹⁸ — lớn hơn giới hạn đó. Phép tính wei dùng Number thông thường silently mất precision với bất kỳ amount nào trên ~9 ETH. Luôn dùng BigInt hoặc thư viện như ethers.js bọc BigInt bên trong.

Gwei là gì và khi nào dùng?

Gwei (gigawei) bằng 10⁹ wei. Đây là đơn vị tiêu chuẩn cho gas price vì nó ở quy mô dễ đọc cho người — gas price Ethereum hiện tại dao động từ vài digit đến vài trăm gwei. Khi wallet hiển thị "gas price: 15 gwei", đó là 15,000,000,000 wei per unit gas tiêu thụ.

Tính tổng phí của một transaction thế nào?

Nhân gas used với effective gas price: fee (wei) = gasUsed × effectiveGasPrice. Cả hai giá trị xuất hiện trong transaction receipt. Chuyển kết quả từ wei sang ETH dùng tool này để có cost dễ đọc. Với ETH transfer tiêu chuẩn (21,000 gas) ở 20 gwei, phí là 0.00042 ETH.

EIP-1559 thay đổi gì?

EIP-1559 (London fork, tháng 8/2021) thay thế đấu giá gas price đơn bằng mô hình base fee cộng priority fee. Base fee bị đốt và được điều chỉnh theo thuật toán mỗi block; priority fee (tip) đến validator. Bạn đặt max fee per gas như mức trần. Phí thực tế là min(maxFee, baseFee + priorityFee). Điều này khiến estimate phí dự đoán được hơn và giảm overpayment.

Converter này có hoạt động với ERC-20 token không?

Một phần. ERC-20 token dùng cùng pattern wei/unit nhưng với số decimal riêng — USDC có 6 decimal, hầu hết token có 18, một số wrapped asset có 8. Mode "custom decimals" của converter nhận bất kỳ số decimal nào để bạn convert amount ERC-20 bất kỳ. Tên đơn vị (wei, gwei, ether) ở phía ETH chỉ là label cho lũy thừa của 10 — cùng toán học áp dụng.

Nên lưu giá trị wei trong database thế nào?

Không dùng cột SQL INTEGER hay BIGINT — PostgreSQL BIGINT tối đa ~9.2 × 10¹⁸, chỉ chứa ~9 ETH trước khi overflow. Dùng NUMERIC (arbitrary precision) hoặc lưu amount dưới dạng TEXT decimal string. Khi đọc lại, parse với BigInt() hoặc ethers.parseUnits trước khi làm arithmetic.

Tại sao smart contract của tôi nhận sai amount?

Hầu như luôn là unit mismatch. Nếu frontend gửi parseUnits("1", "gwei") (= 10⁹ wei) nhưng contract mong đợi amount tính bằng wei và nghĩ đó là 1 ETH, bạn đã gửi 10⁻⁹ ETH thay vì 1 ETH. Quyết định nhất quán ở mọi layer xem bạn đang làm việc bằng wei hay ether, thêm unit suffix vào tên biến (amountWei, priceGwei), và validate bằng converter này trước khi deploy.