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.
ETH ↔ Wei ↔ Gwei Converter
1.01000.01000000.01000000000.01000000000000.01000000000000000.01000000000000000000Uses 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 weigasPrice/effectiveGasPrice— phí per gas unit, tính bằng weicumulativeGasUsed— 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
-
Chia cho
1e18thay vì10n**18ntrong JS.** Float1e18đúng cho giá trị cụ thể 10¹⁸, nhưng phép tính quanh nó mất bit. Luôn dùng BigInt hoặcformatUnits. -
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ốngparseUnits("1", 18)cho 1 ETH. -
Hiển thị wei thô cho người dùng. Balance
50000000000000000wei trông vô nghĩa. LuônformatUnitstrước khi hiển thị. -
Lưu wei trong cột SQL
INTEGER. PostgreSQLINTEGERtối đa ~2.1 tỷ;BIGINT~9.2 × 10¹⁸ — vừa đủ chứa ~9 ETH. DùngNUMERIChoặc lưu dưới dạngTEXTdecimal 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.