Skip to content
Go to file
* Changes reference to `sha3` to `keccak256`.

Ethereum doesn't use `sha3` anywhere, and later in the document it explicitly states that this is actually `keccak256`.  To avoid people implementing SHA3 only to find out it doesn't work (like I did), I'm fixing this to be `keccak256`.

* Use eth-utils for eip-55 example code

Replace the pyethereum code, because it's deprecated, and because it
uses the name "sha3" for the hashing function, rather than the clearer

Co-authored-by: Jason Carver <>
13 contributors

Users who have contributed to this file

@cdetrio @Arachnid @carver @yuzushioh @pipermerriam @Nilang-Decentral @MicahZoltu @ligi @dcousens @garciaw @alexvansande @almindor
152 lines (118 sloc) 6.66 KB
eip title author type category status created
Mixed-case checksum address encoding
Vitalik Buterin <>, Alex Van de Sande <>
Standards Track



import eth_utils

def checksum_encode(addr): # Takes a 20-byte binary address as input
    hex_addr = addr.hex()
    checksummed_buffer = ""

    # Treat the hex address as ascii/utf-8 for keccak256 hashing
    hashed_address = eth_utils.keccak(text=hex_addr).hex()

    # Iterate over each character in the hex address
    for nibble_index, character in enumerate(hex_addr):

        if character in "0123456789":
            # We can't upper-case the decimal digits
            checksummed_buffer += character
        elif character in "abcdef":
            # Check if the corresponding hex digit (nibble) in the hash is 8 or higher
            hashed_address_nibble = int(hashed_address[nibble_index], 16)
            if hashed_address_nibble > 7:
                checksummed_buffer += character.upper()
                checksummed_buffer += character
            raise eth_utils.ValidationError(
                f"Unrecognized hex character {character!r} at position {nibble_index}"

    return "0x" + checksummed_buffer

def test(addr_str):
    addr_bytes = eth_utils.to_bytes(hexstr=addr_str)
    checksum_encoded = checksum_encode(addr_bytes)
    assert checksum_encoded == addr_str, f"{checksum_encoded} != expected {addr_str}"


In English, 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 4*ith bit of the hash of the lowercase hexadecimal address is 1 otherwise print it in lowercase.



  • Backwards compatible with many hex parsers that accept mixed case, allowing it to be easily introduced over time
  • Keeps the length at 40 characters
  • 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.


In javascript:

const createKeccakHash = require('keccak')

function toChecksumAddress (address) {
  address = address.toLowerCase().replace('0x', '')
  var hash = createKeccakHash('keccak256').update(address).digest('hex')
  var ret = '0x'

  for (var i = 0; i < address.length; i++) {
    if (parseInt(hash[i], 16) >= 8) {
      ret += address[i].toUpperCase()
    } else {
      ret += address[i]

  return ret
> toChecksumAddress('0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359')

Note that the input to the Keccak256 hash is the lowercase hexadecimal string (i.e. the hex address encoded as ASCII):

    var hash = createKeccakHash('keccak256').update(Buffer.from(address.toLowerCase(), 'ascii')).digest()

Test Cases

# All caps
# All Lower
# Normal


Wallet displays checksummed addresses rejects invalid mixed-case rejects too short rejects too long
Etherwall 2.0.1 Yes Yes Yes Yes
Jaxx 1.2.17 No Yes Yes Yes
MetaMask 3.7.8 Yes Yes Yes Yes
Mist 0.8.10 Yes Yes Yes Yes
MyEtherWallet v3.9.4 Yes Yes Yes Yes
Parity 1.6.6-beta (UI) Yes Yes Yes Yes
Jaxx Liberty 2.0.0 Yes Yes Yes Yes
Coinomi 1.10 Yes Yes Yes Yes
Trust Wallet Yes Yes Yes Yes

Exchange support for mixed-case address checksums, as of 2017-05-27:

Exchange displays checksummed deposit addresses rejects invalid mixed-case rejects too short rejects too long
Bitfinex No Yes Yes Yes
Coinbase Yes No Yes Yes
GDAX Yes Yes Yes Yes
Kraken No No Yes Yes
Poloniex No No Yes Yes
Shapeshift No No Yes Yes


  1. EIP 55 issue and discussion
  2. Python example by @Recmo
  3. Python implementation in ethereum-utils
  4. Ethereumjs-util implementation
  5. Swift implementation in EthereumKit
  6. Kotlin implementation in KEthereum
You can’t perform that action at this time.