Ethereum Address Checksum Tool (EIP-55)

Validate an Ethereum address and convert it to its EIP-55 checksummed form. Mixed-case checksums catch typos before you send funds, and the breakdown below shows which character failed and why.

All one case, so there is no checksum to verify. Here is the checksummed form.
Checksummed address (EIP-55)
0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed
Checksum, character by character
5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed
d385650ce8fdc6db7ee3a091d34814dbc4ce1821

Bottom row is the Keccak-256 hash of the lowercase address, one hex nibble per character. Cyan means the nibble is 8 or greater, which is what uppercases the letter above it.

Official EIP-55 test vectors, click to load
All caps
All lower
Normal

Why address checksums matter

An Ethereum address is the last 20 bytes of the Keccak-256 hash of a public key, written as 40 hex characters. Nothing in that format carries error detection: any 40-character hex string is a syntactically valid address, and the network will happily move funds to one that nobody controls. EIP-55, proposed by Vitalik Buterin and Alex Van de Sande on 14 January 2016 and now Final, fixes this without changing the format at all. It uses the capitalization of the letters a to f to carry a Keccak-256 checksum, so the address still looks the same and still works the same, but software can flag a single mistyped character.

The specification estimates about 15 check bits per address, which puts the chance that a randomly generated address survives a typo and still passes the check at 0.0247%, roughly fifty times better than the older ICAP scheme it replaced. That is worth restating plainly: a passing checksum means the string was not garbled in transit, not that the address belongs to the person you think it does.

The algorithm, step by step

Strip the 0x prefix and lowercase the remaining 40 characters. Hash that ASCII string with Keccak-256, the same hash Ethereum uses for selectors and storage slots, which you can reproduce with the Keccak-256 calculator. Walk the address and the hash in parallel, one hex character against one hex nibble. Where the character is a letter and the nibble is 8 or greater, print it uppercase; otherwise leave it as it is. Digits 0 to 9 have no case, so they pass through untouched and contribute nothing to the checksum, which is why an address made mostly of digits protects you less than one full of letters. The two rows in the tool above are exactly these two strings, aligned.

Verification runs the same way round. Lowercase the address you were given, recompute the checksummed form, and compare it to what you were given character for character. Anything that differs is either a typo or an address that was never checksummed under plain EIP-55. Note the asymmetry: an all-lowercase or all-uppercase address cannot fail, since it never claimed a checksum in the first place. Only mixed-case input is a claim that can be checked, which is the reason the tool reports those two situations differently.

Checksumming in ethers.js, web3.js and beyond

Every serious Ethereum library ships this, and you should reach for it rather than hand-rolling the loop. On BLAZED.sh, ethers.js and web3.js are pre-installed in the script editor, so these run without any setup.

// ethers.js v6
import { getAddress, isAddress } from "ethers";

getAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed");
// -> "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"
getAddress("0x5aAeb6053f3E94C9b9A09f33669435E7Ef1BeAed");
// -> throws: bad address checksum
isAddress("0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"); // true

// web3.js
import { utils } from "web3";

utils.toChecksumAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed");
utils.isAddress("0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"); // true

// viem
import { getAddress } from "viem";
getAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed");
# Python, eth-utils
from eth_utils import to_checksum_address, is_checksum_address

to_checksum_address("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed")
is_checksum_address("0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed")  # True
// Go, go-ethereum
import "github.com/ethereum/go-ethereum/common"

addr := common.HexToAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed")
addr.Hex() // "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"

Two traps worth knowing. Go's common.HexToAddress parses without validating, so it will silently accept a broken checksum and only Hex() gives you the correct casing back. And Solidity has no notion of this at all: an address is 20 raw bytes at runtime, so casing is a purely off-chain, human-facing concern. Do the check where the string is still a string, in your frontend or your bot, before the transaction is ever built.

EIP-1191 and other chains

EIP-1191 is the one variation you are likely to meet. It hashes the chain ID concatenated with the lowercase address instead of the address alone, so the same account renders with different capitalization on different networks and an address pasted from the wrong chain fails the check loudly. RSK adopted it for chain IDs 30 and 31. Ethereum mainnet did not, and neither did the EVM chains that follow mainnet conventions, so plain EIP-55 remains the interoperable default and is what this tool implements. If an address that you trust reports a mismatch here, an EIP-1191 origin is the first thing to rule out.

When you are about to send, the checksum is only half the check. Confirm the recipient from a second source, and if you want to know what the transfer will cost before you sign it, the gas fee calculator prices it against live mainnet conditions. If your own service validates addresses at scale, doing it next to the node rather than over a remote API is the whole point of running your code on BLAZED.sh.

Frequently asked questions

What is an EIP-55 checksum address?

EIP-55 encodes a checksum into the capitalization of an address's hex letters. Wallets can then detect a mistyped address without changing its length or adding characters. It was proposed by Vitalik Buterin and Alex Van de Sande in January 2016 and is now Final.

How is the checksum computed?

Take the lowercase address without the 0x prefix, hash it with Keccak-256, and for each of the 40 characters look at the matching hex nibble of the hash. Where that nibble is 8 or greater and the character is a letter a to f, print the letter uppercase; otherwise leave it lowercase. Digits are never changed. The result is the checksummed address.

My address failed validation, what does that mean?

A mixed-case address that does not match its checksum usually means a typo, a character dropped during copy and paste, or an address that was checksummed for a different chain under EIP-1191. Compare the characters flagged in the breakdown against your source before sending funds, since the checksum exists to catch exactly this.

Is an all-lowercase address valid?

Yes, an all-lowercase or all-uppercase address is accepted everywhere because it carries no checksum to verify. Ethereum addresses are case insensitive on chain; the casing only ever exists for humans and software to check. Convert it here to the safer checksummed form.

How reliable is an EIP-55 checksum at catching typos?

The specification puts it at roughly 15 check bits per address, giving a 0.0247% chance that a randomly generated address, if mistyped, still passes the check. That is about a fifty-fold improvement over the older ICAP scheme, but it is error detection, not proof that the address is the one you meant.

Does a valid checksum mean the address exists or is safe?

No. The checksum only proves the string was not garbled. Every 20-byte value is a valid Ethereum address whether or not anyone holds its private key, and funds sent to an address nobody controls are unrecoverable. A checksum is a spell check, not a payee verification.

How do I validate an EIP-55 checksum in ethers.js or web3.js?

In ethers.js call getAddress(address), which returns the checksummed form and throws when a mixed-case input fails the check, or isAddress(address) for a boolean. In web3.js call web3.utils.toChecksumAddress(address) to convert and web3.utils.isAddress(address) to validate. Both libraries are pre-installed on BLAZED.sh scripts.

What is EIP-1191 and how does it differ?

EIP-1191 extends EIP-55 by prefixing the chain ID to the string that gets hashed, so an address checksummed for one network fails the check on another. RSK mainnet and testnet, chain IDs 30 and 31, adopted it. Ethereum mainnet does not, so this tool implements plain EIP-55; an RSK-style address will show as a mismatch here.

Are checksummed addresses the same across EVM chains?

For every chain that follows plain EIP-55, yes. The checksum depends only on the address itself, so the same account renders as the same mixed-case string on Ethereum mainnet and on EVM chains that reuse the scheme. Only chains that opted into EIP-1191 produce a different capitalization.

Does this tool send my address anywhere?

No. The Keccak-256 hashing runs locally in your browser with the js-sha3 library. Nothing is uploaded, logged or stored, and the page works offline once loaded.

Building on Ethereum?

Run your code on the node itself. No rate limits, no compute units, predictable per-request credits, sub-10ms RPC.