I've read many times that you should never input an address by hand unless you want to accidentally send Ether into no-mans-land. I'd like to know what those checksums might be. Is there a way to tell a typo is occurred? how, and what are the formatting rules to it? Im asking so I can potentially create a wrapper function that checks for these things before submitting to the network.


9 Answers 9


Regular Address

EIP 55 added a "capitals-based checksum" which was implemented by Geth by May 2016. Here's Javascript code from Geth:

 * Checks if the given string is an address
 * @method isAddress
 * @param {String} address the given HEX adress
 * @return {Boolean}
var isAddress = function (address) {
    if (!/^(0x)?[0-9a-f]{40}$/i.test(address)) {
        // check if it has the basic requirements of an address
        return false;
    } else if (/^(0x)?[0-9a-f]{40}$/.test(address) || /^(0x)?[0-9A-F]{40}$/.test(address)) {
        // If it's all small caps or all all caps, return true
        return true;
    } else {
        // Otherwise check each case
        return isChecksumAddress(address);

 * Checks if the given string is a checksummed address
 * @method isChecksumAddress
 * @param {String} address the given HEX adress
 * @return {Boolean}
var isChecksumAddress = function (address) {
    // Check each case
    address = address.replace('0x','');
    var addressHash = sha3(address.toLowerCase());
    for (var i = 0; i < 40; i++ ) {
        // the nth letter should be uppercase if the nth digit of casemap is 1
        if ((parseInt(addressHash[i], 16) > 7 && address[i].toUpperCase() !== address[i]) || (parseInt(addressHash[i], 16) <= 7 && address[i].toLowerCase() !== address[i])) {
            return false;
    return true;

ICAP Address

ICAP has a checksum which can be verified. You can review Geth's icap.go and here's a snippet from it:

// https://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN
func validCheckSum(s string) error {
    s = join(s[4:], s[:4])
    expanded, err := iso13616Expand(s)
    if err != nil {
        return err
    checkSumNum, _ := new(big.Int).SetString(expanded, 10)
    if checkSumNum.Mod(checkSumNum, Big97).Cmp(Big1) != 0 {
        return ICAPChecksumError
    return nil
  • Great answer! Out of curiosity, any idea how good the checksum is? meaning with a few wrong digits, what are the chances it passes the checksum coincidentally anyway?
    – ZMitton
    Feb 15, 2016 at 11:07
  • 1
    EIP 55 compares the regular address checksum with ICAP: "On average there will be 15 check bits per address, and the net probability that a randomly generated address if mistyped will accidentally pass a check is 0.0247%. This is a ~50x improvement over ICAP, but not as good as a 4-byte check code."
    – eth
    May 8, 2016 at 6:29
  • It would be nice to be able to check for validity in Solidity as well. One way to do this would be to transfer a tiny amount of ether to any new address you create, and check for non-zero balance in Solidity. (Should that be a separate question?)
    – Paul S
    Jul 6, 2016 at 3:40
  • 1
    @PedroLobito For sha3, you can use keccak256 from a library like github.com/emn178/js-sha3 I have not been able to find the recent code that Geth uses to improve this answer.
    – eth
    Oct 17, 2017 at 8:02
  • 1
    @Alper Yes a smart contract address can be capitalized according to EIP 55, example.
    – eth
    Apr 15, 2018 at 7:01

There is an easier way now with web3:


> true

Better version

try {
  const address = web3.utils.toChecksumAddress(rawInput)
} catch(e) { 
  console.error('invalid ethereum address', e.message) 

using checkSum method is better because you will always deal with data and never have to lowerCase.

  • 1
    The isaddress() method also checks for checksum! why do we need go with checkSum method?
    – atul
    Mar 31, 2020 at 2:44
  • 1
    isAddress: Checks if a given string is a valid Ethereum address. It will also check the checksum, if the address has upper and lowercase letters. As @atul stated Nov 1, 2020 at 16:56

The standard 40 character hex addresses now have a checksum in the form of capitalization. If the address has at least one capital letter then it is checksummed and, if inputted on a site that checks the sum, it will return false if it's not a valid address.

The scheme is as follows:

convert the address to hex, but if the ith digit is a letter (ie. it's one of abcdef) print it in uppercase if the ith bit of the hash of the address (in binary form) is 1 otherwise print it in lowercase

You can read VBs full writeup here: https://github.com/ethereum/EIPs/issues/55

function validateInputAddresses(address) {
        return (/^(0x){1}[0-9a-fA-F]{40}$/i.test(address));
  • This just test plausibility, doesn't validate the checksum. It still seems to be a better way to write the plausibility test regex.
    – Simeon
    Mar 21, 2018 at 11:23

The python package 'ethereum' has a function called 'check_checksum' in the utils module:

from ethereum.utils import check_checksum
> True

I build a small project for this which i use programmatically in my apps. It has a 'micro' api:


It also has address validation for bitcoin, monero, and ripple.

You can find the documentation here: balidator.io/api-documentation


So far ether addresses have no checksum and are simply the HEX encoding of the address bytes. There is however a proposal for encoding and checksum, see: ICAP: Inter exchange Client Address Protocol.

ICAP has preliminary support merged in some Ethereum client.


Checksums are mechanisms to prevent sending funds to wrong addresses (set by mistake or by a malicious party).


You can use web3's amazing utils:


The function above works only if you have version 1.0.0 or above.


I created an online tool, check it out here: EthSum.


Another way to check is if you also have the public key of the ethereum address. The Ethereum Foundation's official eth-keys Python library can be used, and is now part of their Github repo and can be seen here and contains a suite of tools that include ways to check address validity, such as using the PublicKey().checksum_address() method (see below example).

The following method requires the uncompressed public key in bytes format, which means it would have to be only for accounts you have the public-key data for:

 >>>from eth_keys import keys
  • It should be from eth_keys import keys. I would have edited, but edits must be at least six characters.
    – Josh Davis
    Dec 7, 2021 at 18:52
  • @JoshDavis you are absolutley right! Thanks for the note I just corrected it. Dec 8, 2021 at 19:59

Or in Python (with Web3py)

from web3 import Web3


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.