Sometimes, you find beauty in the simplest thing. Let’s consider how Vitalik Buterin and Alex Van de Sande introduced a checksum in Ethereum addresses.

First, let’s remember that, unlike Bitcoin, Ethereum addresses do not incorporate a checksum. It was considered unnecessary. With ICAP support, and Ethereum Name Service, humans were not supposed to interact with raw hexadecimal strings. These two techniques (ICAP, a convention compatible with IBAN and ENS), are far better than the Base58 + checksum approach used in Blockchain, nevertheless, the transitional checksum method introduced by Buterin is brilliant.

In a typical hexadecimal representation of an address, we will have an average of 15 letters.

Let’s consider this address:


It contains 20 letters. Old wallets are case insensitive. 8da is not different from 8DA. That’s important, because, it will allow us to modify the address to introduce a checksum without breaking these wallets.

First, we will take the Keccak256 hash from the lowercased address without the 0x prefix.

>>> keccak_256(b'8da82fcc73cbf2fb1a8c627ec2f0e3fcc3f06748').digest().hex()[:40] # We only need the first 20 bytes of the hash

Now, we put the original address and the Keccak hash together, and whenever we found a letter in the address, we check the corresponding character in the hash. If it happens to greater than 8, we capitalize the letter, otherwise, we keep the lowercase.


For instance, the second and the third character in our original address are letters, and the corresponding characters in the hash are both greater than 8, which means that we should uppercase these two characters. 8DA…. The final checksum encoded address would be:


Detecting Errors

Let us now introduce a tiny mistake to simulate a misread. For instance, the 6th character right to left in the checksum encoded version of our address is F, easy to confuse with, let’s say, E.

Fortunately, our wallet is EIP-55 complaint and seeing that the address contains both, lower and uppercase chars, it will create the checksum to compare. Because the hash function is highly sensitive to changes in the input, the hash itself is completely different (we changed only one bit, E and F are one bit apart)


And the checksum produced is all wrong:


You can take a look at a simple python implementation here