I can verify transactions ids with version 1 using the normal Keccak256 hash just fine. I seem to be having trouble with version 2.

For example, this transaction: https://explorer.xmr.my/tx/be9d2cf9b473dbbb2c59ffb07b5d812516f94d64121d87ad61956386a4bc3843/1

I've calculated Keccak256 on the entire transaction which yields: 190c94b59a9d90e8e6ec4ed69092161e82413c121ae0db84f3e859d2eccb9a80

Obviously, this is not be9d2cf9b473dbbb2c59ffb07b5d812516f94d64121d87ad61956386a4bc3843

The TransactionPrefix portion is correctly hashed by Keccak256 to be 1bbfda600fa6affc80dae05b1124bf05ed0e20890aa42601441dbe0f6fa81f4b

I noticed that rctOps.cpp has its own cn_fast_hash which seems to be maybe different than crypto/crypto-ops.cpp's cn_fast_hash. What's the difference if that's what I'm missing?

1 Answer 1


It turns out that for version 2, the hash is computed by combining 3 other hashes and then computing the hash of the aggregate.

To be specific, the tx hash turns out to be:

H(H(prefix) || H(RingCTBase) || H(RingCTPrunable))

Where H is the Keccak256 hashing function, prefix is the Transaction Prefix serialized, RingCTBase is the RingCTBase serialized and RingCTPrunable is the RingCTPrunable serialized.

The details can be found in src/cryptonote_basic/cryptonote_format_utils.cpp's calculate_transaction_hash.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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