Solidity does not support txHash variable yet, but it has been requested at EIP 901 https://github.com/ethereum/EIPs/issues/901 . Meanwhile how could I calculate the txHash of a transaction using Solidity code in the Smart Contract? I guess txHash is built upon some keccak hashing of the msg.sender and probably the nonce of the request, right? Is there a canonical formula for the Ethereum txHash calculation? Thx!
3 Answers
Short answer
It cannot be done.
Longer answer
The txhash is keccak256(signedTransaction)
.
This keccak256 function is available as a solidity function http://solidity.readthedocs.io/en/v0.4.21/units-and-global-variables.html
So you would need to construct signedTransaction
since this value is not exposed to solidity, cf. https://stackoverflow.com/questions/49803424/how-can-we-access-rlp-encoded-signed-raw-transaction-in-solidity
The constituents of signedTransaction
are
- nonce
- gas price
- gas limit
- to
- value in wei
- data
- ecdsaV
- ecdsaR
- ecdsaS
Value 3 is not directly available but you can get the current remaining gas at any point in your code execution and calculate from this, how much was available once the execution started. Values 1, 7, 8, and 9 (the nonce and the signature values) are not available using solidity, nor are they available using assembly code (which can be written inline in solidity source code files). So your problem can unfortunately not be solved.
See also: do the contracts of ethereum have the access to the nonce of the blocks?
According to geth source code (file core/types/transactions
) and this medium post the hash of a transaction is given by the keccak 256-bit hashing of the rlp encoding of all fields of a transaction, as showed in this image 1.
Therefore in order to calculate the transaction function, you need to be able to:
- Calculate the KEC256 bit hash of an arbitrary number of bytes
- Access/Calculate an RLP encoding of a transaction
- Access all fields of a transaction:
By looking the EVM specification (Yellow Paper, Appendix H), you can see that the first point is very easy, indeed it corresponds to the SHA3 (0x20)
instruction.
Neither the RLP encoding of all fields of a transaction is given nor an RLP encode instruction in the EVM instruction set, but it is possible to calculate it (Yellow Paper, Appendix B), provided that the sender has enough gas at its disposal.
Finally, there aren't instruction to access all fields. In particular I cannot find the EVM instructions to access:
- the nonce of the transaction: It corresponds to the number of transactions sent by the sender (I cannot find a function to retrieve neither this number)
- the signature information
v
andr
- the transaction gas limit
I think you can pre-determine the remaining parameters that are not available on-chain (v, r, s, nounce). Then calling the function you want using the remaining args as parameters, generating the tx.hash
using keccak256 and making it available on the contract for use.
If you want to handle customers, you can provide a signature to verify the parameters using ECDSA.recover
.
In theory it is possible. I'm doing this right now to dominate the Ethscriptions
marketplaces and the future of light-nfts
. Will post the solution here, follow me for more. Cheers !