synlestidae / ethereum-tx-sign

MIT License
41 stars 36 forks source link

hash of signed transaction #90

Open brandonm78 opened 1 month ago

brandonm78 commented 1 month ago

In my script I have:

let hash = new_transaction.hash()

after I sign the transaction but am not getting the same hash on etherscan. How do I generate the correct transaction hash? It seems like the transaction hash I am getting is perhaps from pre-signing and its not updating.

synlestidae commented 1 month ago

Thanks for raising this. Could you reply with a complete Rust snippet that I can run, to re-create the problem?

I'm not familar with etherscan but if you could also show the result there that would be handy. Or anything to compare the result from this library.

If there is a bug with the library I will want to fix it immediately

brandonm78 commented 1 month ago

Etherscan.io http://etherscan.io/ is the ethereum network explorer where you can search transactions, see blocks, etc. I noticed that when I do a transaction that the hash generated is different than what i get from the RPC server and what shows up on the blockchain.

My code is pretty much exactly as you show in your examples. I don’t want to share a working piece of code as I would be required to provide my private key. So I hope this helps.

CODE EXAMPLE OF WHAT I AM USING

use ethereum_tx_sign::LegacyTransaction;

let new_transaction = LegacyTransaction { chain: 1, nonce: 0, to: Some([0; 20]), value: 1675538, gas_price: 250, gas: 21000, data: vec![/ contract code or other data /], }

let ecdsa = new_transaction.ecdsa(&private_key_32_bytes); let transaction_bytes = new_transaction.sign(&ecdsa); let hash = new_transaction.hash();

ENDS HERE.

The hash in this case that is generated at the end is incorrect. I have actually figured out to how to resolve this and get the correct hash if that helps.
To do so, I have added the following to my rust code:

use sha3::{Keccak256};

let mut hasher = Keccak256::new(); hasher.update(transaction_bytes.clone()); let hash = hasher.finalize();

With the following added, I am now able to get the correct hash from the transaction_bytes above. But perhaps there is a better way to do it without adding another crate since your using tiny keccak. I notice your example README that you do not have the transaction hash as part of it, but it is a function at:

https://docs.rs/ethereum-tx-sign/6.1.3/ethereum_tx_sign/struct.LegacyTransaction.html

Yet, the function doesn’t work as I think it should since it does not allow me to input the transaction bytes to generate the correct hash.

On May 30, 2024, at 11:33 PM, synlestidae @.***> wrote:

Thanks for raising this. Could you reply with a complete Rust snippet that I can run, to re-create the problem?

I'm not familar with etherscan but if you could also show the result there that would be handy. Or anything to compare the result from this library.

If there is a bug with the library I will want to fix it immediately

— Reply to this email directly, view it on GitHub https://github.com/synlestidae/ethereum-tx-sign/issues/90#issuecomment-2141320299, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXFBXUJWNDQMVOWCYOP4ZV3ZFAKSDAVCNFSM6AAAAABIRI2WV2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNBRGMZDAMRZHE. You are receiving this because you authored the thread.

synlestidae commented 1 month ago

Thank you, that is helpful. I am surprised the hash is coming out wrong. Aiming to fix soon

synlestidae commented 1 month ago

I have tried out sha3's hasher, as you showed in your example. I noticed that the tests still pass, indicating we are getting the same result 🤔

synlestidae commented 1 month ago

The hash() is 100% the pre-signed hash though - maybe the library needs an update as it being confused with the signed transaction hash. e.g. separate unsigned_hash() and signed_hash() to make it less confusing

brandonm78 commented 2 weeks ago

That would work, as long as there is a way to get the signed_hash() for us users of the crate whether thats the default or simply a library function.
I can’t see any reason why anyone would ever need the unsigned_hash().


As another suggestion for a feature request, my most recent use is taking a mempool transaction, the transaction data provided and generating the “raw transaction” from it using the v r and s values (not having a primary key). I was able to do this in python, but it would be much speedier if it could be done in rust.

It would be great if this was a feature..

let new_transaction = LegacyTransaction { chain: 1, nonce: 0, to: Some([0; 20]), value: 1675538, gas_price: 250, gas: 21000, data: vec![/ contract code or other data /], }

and then encoding it using the v r and s values to generate the raw transaction. This might be something your already doing in your tests. If so perhaps you could make this a library. Or provide how to do it as part of your examples.

On Jun 4, 2024, at 1:30 AM, synlestidae @.***> wrote:

The hash() is 100% the pre-signed hash though - maybe the library needs an update as it being confused with the signed transaction hash. e.g. separate unsigned_hash() and signed_hash() to make it less confusing

— Reply to this email directly, view it on GitHub https://github.com/synlestidae/ethereum-tx-sign/issues/90#issuecomment-2146922977, or unsubscribe https://github.com/notifications/unsubscribe-auth/AXFBXUJFMS6UDJCIB4DBYTDZFV3IXAVCNFSM6AAAAABIRI2WV2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNBWHEZDEOJXG4. You are receiving this because you authored the thread.