Checksum
A Bitcoin checksum is the first 4 bytes of a double SHA-256 hash, added to addresses and keys so that typing mistakes get caught. Learn how it works.
By Dimitar Zurnov · Updated 4 Nov 2026
Adapted from Learn Me a Bitcoin by Greg Walker.
A Bitcoin checksum is 4 bytes of extra data, added to a string so that a wallet can catch typing mistakes. It is the first 4 bytes of HASH256, which is SHA-256 applied twice to the data. Addresses, WIF private keys and extended keys all carry one. If the checksum does not match, the wallet can refuse the string before you send coins to the wrong place.
What does a checksum do?
A checksum lets you check that data is the same as it was when it was written. You compute a short fingerprint of the data and attach it. Later, you compute the fingerprint again. If one character changed, the two fingerprints almost certainly differ.
A checksum detects errors but does not fix them. It tells you that something is wrong, not where the mistake is.
How is a Bitcoin checksum made?
A checksum takes three steps.
- Hash the data with SHA-256.
- Hash that result with SHA-256 again. Together, the two steps are HASH256.
- Keep the first 4 bytes of the result, which is 8 hex digits.
Here is an example with 20 bytes of aa, written as 40 hex digits:
data = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
hash256(data) = 05c4de7c1069e9de703efd172e58c1919f48ae03910277a49c9afd7ded58bbeb
checksum = 05c4de7c
For the example key, the payload is a version byte, 00, followed by its 20-byte public key hash. That makes 21 bytes. Its checksum is 94686373. The full string is the payload with the checksum appended, 25 bytes in all. Base58 encoding of those 25 bytes gives the address 13uYXKWq8VoZgQApSxTXHPtYDs1m1xGi4z.
How do you verify a checksum?
To verify a checksum, split off the last 4 bytes, hash the rest again, and compare. If the two match, the data is intact. The script below creates the checksum for the example payload and then checks it.
import hashlib
def hash256(data: bytes) -> bytes:
"""Double SHA-256."""
return hashlib.sha256(hashlib.sha256(data).digest()).digest()
payload = bytes.fromhex("001fe032088d648e925f15a24a0cf6a1e80f01bf91")
checksum = hash256(payload)[:4]
print(checksum.hex()) # 94686373
def checksum_ok(data_with_checksum: bytes) -> bool:
data, stored = data_with_checksum[:-4], data_with_checksum[-4:]
return hash256(data)[:4] == stored
print(checksum_ok(payload + checksum)) # True
Now take a single typo. Change the last character of the address from z to y. The decoded checksum changes from 94686373 to 94686372. The wallet recalculates the checksum from the payload and gets 94686373, which does not match. The wallet rejects the address.
Where do Bitcoin checksums appear?
- Addresses. Every legacy address, such as P2PKH and P2SH, uses Base58Check: a payload, its checksum, then Base58 encoding.
- WIF private keys. A WIF key carries a checksum too, so an import can catch a mistyped key.
- Extended keys. The
xprvandxpubstrings for HD wallets each have their own checksum. - Network messages. Each message header between nodes holds a 4-byte checksum of its payload. Corruption or tampering shows up as a mismatch.
Bech32 addresses also contain a checksum. It is a stronger design, a BCH code that guarantees detection of any error in up to 4 characters. It is not the simple checksum described on this page.
How reliable is a 4-byte checksum?
A 4-byte checksum has 2^32 possible values, which is about 4.3 billion. A random error produces a matching checksum about once in 4.3 billion tries. That is very unlikely, but it is not impossible. So a checksum is a safety net, not a guarantee.
A full 32-byte hash would be stronger, but it would make addresses far longer. Four bytes is a compromise between safety and length.
Summary
A checksum catches typing mistakes. Addresses, WIF keys and extended keys all carry one. A wallet that verifies it can stop you before a payment goes to the wrong place. Still, check every address yourself before you pay. As a developer, always verify the checksum when you accept a string, because the check is only a few lines of code. The next page, Base58, explains the alphabet these strings are written in.
Sources: the Base58Check encoding page on the Bitcoin Wiki describes the construction, and Bitcoin Core's base58.cpp implements the decoding and checksum check.
In this section: Keys and addresses
Something look wrong? Tell us