Skip to main content

Type a word from a question or an article title.

2 · Practice

Hash commitment: fixing a deal's terms without revealing them

How a keccak256 hash records a contract's fingerprint on the blockchain without publishing the text, and why swapping the document becomes impossible.

5 min readUpdated:
In this article

Imagine you sealed a contract in an envelope and put an unforgeable seal on it. Nobody sees the contents, but anyone can check whether the envelope was opened and whether it is the same document. A hash commitment is the cryptographic analogue of such an envelope.

What a hash is

A hash function turns any data - a word, a paragraph, a 100-megabyte file - into a string of fixed length. Ethereum uses keccak256: the output is always 32 bytes, written as 66 characters like 0x7f3a9c2e…4b8d1a.

Three properties make a hash fit for fixing terms:

  1. Determinism. The same data always gives the same hash.
  2. The avalanche effect. Changing one character changes the hash beyond recognition. "Payment 1000" and "Payment 1001" give completely different fingerprints.
  3. One-wayness. From the hash you cannot recover the original text and, importantly, cannot find another document with the same hash.

How it works in a deal

  1. The sides agree the terms - anywhere: in a messenger, by email, by voice.
  2. They compose a terms document.
  3. The service computes its hash in your browser - the document itself is sent nowhere.
  4. The hash is recorded on the blockchain with the deal. The document does not reach the network: the content of the deal stays private.
  5. The contract requires the other side to pass the very same hash when accepting. If they see a different document, their hash will differ and the transaction will revert.
  6. In a dispute either side hands the document to the guarantor, who computes the hash and compares it with the one recorded in the deal. A match means the document is authentic.

The last point is the mechanism's main value: neither side can swap the terms after the fact. Even a hacked interface will not show the buyer and seller different texts and push the deal through: the accepting side signs exactly the hash they see.

Text normalisation: why the "same" text gives a different hash

To a computer "Hello" and "Hello␠" (with a trailing space) are different data. So text copied from Word and text typed by hand can give different hashes though they look the same. There are several sources of mismatch:

  • Line breaks. Windows uses CRLF, Linux and macOS LF.
  • Non-breaking spaces. Word and messengers love to insert special spaces that look ordinary.
  • Trailing spaces at line ends.
  • Unicode forms. A letter such as "é" can be one character or two ("e" plus an accent). They look identical.

To make everything match, text is brought to a canonical form before hashing:

  1. Unicode is converted to NFC.
  2. All line breaks become \n.
  3. Non-breaking and exotic spaces are replaced with an ordinary one.
  4. Spaces at the end of every line are removed.
  5. Empty lines at the start and end are dropped.

The normalised text is then encoded as UTF-8 bytes and keccak256 is computed over them. These rules must match for the buyer, seller, guarantor and any service checking the hash - otherwise the comparison fails. That is why they are pinned in test vectors.

And if it is a file

For a file - a PDF, an image, an archive - no normalisation is applied. The file's bytes are hashed as they are. Any "improvement" of the file (re-saving, compressing, adding metadata) changes the bytes and breaks the check. Pass the file unchanged.

What a hash does not give

It is important to understand the limits.

It does not prove the terms are fair or fulfilled. The hash confirms only the identity of the document: whether the sides fixed this very text. Who is right in a dispute is decided by the guarantor.

It does not hide short, predictable texts. A hash cannot be "unrolled", but variants can be brute-forced. If the terms are "Will buy an iPhone for 500 USDT" and nothing more, an attacker can try similar texts, comparing hashes, and guess the contents. For long unique contracts it is unrealistic, but for short phrases it is worth adding a random string - a "salt".

It does not store the document itself. A lost file cannot be restored from the hash. The service keeps only the fingerprint, and the document is with you and the other side. Download and save it at once. Without the document the guarantor cannot help you.

Time is fixed as well

The hash is recorded on the blockchain with the block's timestamp. It means that by the moment the deal was created the document already existed - you prove not only the content but also "no later than when" it was there.

Where else this is used

The same idea underlies many technologies: file integrity checks on download, signatures in Git commits, the Merkle tree in a blockchain, commit-reveal in votes and auctions. If you are a developer, how this looks at the byte level is in the article on data encoding in ABI.

Practical tips

  • Describe the terms concretely: what, in what form, by when, by what signs it counts as done.
  • Do not change the file after computing the hash: even one comma changes the fingerprint.
  • Download the document from the service and keep a copy.
  • Send the other side both the document and the fingerprint - they will check before accepting.
  • For short texts add a random string.

A hash fixes the text, but you also need to be able to write the text: how to write deal terms. Then look at worked examples: a freelance project, physical goods, a domain and digital goods. For those ready to look under the hood - multisig and timelock and then Ethereum accounts.

Mentioned in

Ready to try it?

Create your first deal in a couple of minutes. The money is locked in a smart contract and paid out by rules you can see in advance.