# How can I check if an Ethereum address is valid?

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.

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
*
* @return {Boolean}
*/
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 '16 at 11:07 • 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 '16 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 '16 at 3:40 • @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 '17 at 8:02 • @Alper Yes a smart contract address can be capitalized according to EIP 55, example. – eth Apr 15 '18 at 7:01 There is an easier way now with web3: web3.utils.isAddress('0xc1912fee45d61c87cc5ea59dae31190fffff232d'); > true  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. • The isaddress() method also checks for checksum! why do we need go with checkSum method? – atul Mar 31 '20 at 2:44 • 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 – I.G. Pascual Nov 1 '20 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 '18 at 11:23

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

from ethereum.utils import check_checksum
check_checksum('0xc1912fee45d61c87cc5ea59dae31190fffff232d')
> True


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

https://balidator.io/api/ethereum/0xea0258D0E745620e77B0A389e3A656EFdb7Cf821


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).

### Programmatically

You can use web3's amazing utils:

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

### Web

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

>>>keys.PublicKey(b'\x98\xbb\xfa\xdd\xbc\xc7\xab\x14\xa3\x9c\xb4\x84\xbf\x94MO\xf5\x91^G\xc1\xc2\x0b\xe77t\xc3\xd0\x05\x12|Z\xf5\x17PZ\x97\xe2\\IR\xc1\xbd\x10\xa3\xa3\xdf\xbf0\xaf;7\xc0z\xbc\xc7\x0b\x9c\xbd<FY\x98').to_checksum_address()

'0x28f4961F8b06F7361A1efD5E700DE717b1db5292'
`