I'm trying to store transactions in a database and want to generate a unique identifier from the transaction data. It must not change My data source is api.etherscan.io, and I am currently making an id from the transaction blockHash + hash, eg:

Given this transaction (with hashes are shortened for clarity):

{ blockNumber: '6564583',
     timeStamp: '1540241421',
     nonce: '34',
     transactionIndex: '141',
     from: '0x83b2d2289f1a666659a0261f4e0cd046386d586f',
     to: '0x164013dfdfbf67b0dfca341ff12c4a616fb2a44a',

My database id would be something like 0xf59dc77_0x19f51a3.

Is this enough to guarantee uniqueness, or is there more?

  • The transaction hash itself (not shortened) is enough to guarantee uniqueness. – user19510 Jul 3 '19 at 18:15
  • So there's only ever 1 transaction per hash? – iampomo Jul 4 '19 at 10:23
  • Yes. Per the answer below, it's pretty much impossible for these hashes to collide. – user19510 Jul 4 '19 at 14:45

Transaction hashes are unique until there is a hash collision.

A hash collision occurs if two different inputs produce the same hash output. The transaction hash is 64 hexadecimal characters = 32 bytes = 32 * 8 bits = 216 bits. Ethereum blockchain has some 500 million transactions currently. Each of those has a possibility to cause a transaction hash collision.

We can calculate the probability of a transaction hash collision with a calculator: http://davidjohnstone.net/pages/hash-collision-probability . If you enter the aforementioned numbers you get a probability of 1.186945×10-48 which is rather..small.

So, for all practical purposes, you will not get a hash collision.

However if you only store a part of the hash the odds of getting a collision increase exponentially. If you are using 16 characters that means 128 bits. Given the same calculator the chance is 3.673419×10-22. That's a lot more than the previous one but still very very small, so you should be ok. So the (partial) hashes will most likely stay unique.

  • A tx hash has 64 hexadecimal digits so 4 bits per digit, 64 * 4 = 256 bits per hash. – Ismael Jul 3 '19 at 17:06
  • It depends on the characters but "normal" characters take 1-2 bytes in UTF-8. And at least according to onlineutf8tools.com/convert-utf8-to-binary one tx hash takes 512 bits / 64 bytes. – Lauri Peltonen Jul 3 '19 at 17:25
  • Transaction hashes on Ethereum are the output of keccak256 which is 256 bits. I never mentioned characters because of the ambiguity but digits instead. – Ismael Jul 3 '19 at 17:53
  • Transaction hashes are indeed 32 bytes (256 bits). – user19510 Jul 3 '19 at 18:14
  • I was sure I had some conversion mistake there. Mistook "64 hex chars" to be the same as "64 chars". Fixed now. Thanks all for the comments. – Lauri Peltonen Jul 3 '19 at 18:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.