the txHash of a transaction should be the sha3(raw_transaction_string

this is the case on any ethereum node, except testrpc

I created a sample. in this example, testrpc has been launched with

testrpc --port 8544 --network-id 256 --gasLimit 0x5F5E100 --account="0x29469148b567bb0142b4e33c518d833c77ef36b3894b56c7291bed448c943a03,100000000000000000000000000"

on there is a testnet which runs geth

when executed this code yields to rows on the console, the first one says that the hashes are NOT equal while the second confirms that they are

let Web3 = require('web3')
let EthereumTx = require('ethereumjs-tx')

let txObj = {
  from: "0x855e89aee346d780aa5912838d0fd16b4fcf12a3",
  to: "0x3532727c1126ddad9a6e9f935b74e41e7b1d4025"

let web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8544/'))
submitTx().then(() => {
  web3 = new Web3(new Web3.providers.HttpProvider(''))
  return submitTx()

function submitTx() {
  return web3.eth.getTransactionCount(txObj.from, 'pending')
    .then(nonce => {
      txObj.nonce = nonce
      txObj.gasLimit = web3.utils.toHex(22000)
      txObj.gasPrice = web3.utils.toHex(2)
      txObj.value = web3.utils.toHex(1e18)
      const tx = new EthereumTx(txObj)
      tx.sign(Buffer.from("29469148b567bb0142b4e33c518d833c77ef36b3894b56c7291bed448c943a03", 'hex'))
      let signedTxHexString = tx.serialize().toString('hex')
      txObj.txHash = "0x" + tx.hash().toString('hex')
      return web3.eth.sendSignedTransaction("0x" + signedTxHexString, (err, txHash) => {
        if(txHash === txObj.txHash) {
          console.log("computed and returned are the same", txHash, txObj.txHash)
        } else {
          console.log("computed and returned are NOT the same", txHash, txObj.txHash)

is this normal behaviour for testrpc?

For more info on the state of this issue have a look at the github https://github.com/trufflesuite/ganache-cli/issues/387

  • You should report this issue to their github repository. In my experience testrpc is very good for fast development, but for validation it has some bugs that are not present in a full client like geth or parity.
    – Ismael
    Sep 9, 2017 at 14:38

1 Answer 1


Correct transaction hash calculation requires transactions that are signed with the caller's private key. Ganache/TestRPC include features like forking, which makes it possible to impersonate accounts for which you do not hold the private key.

If this were possible with a true Ethereum client this would obviously be horrible - how would ETH hold any value?? However it's important to remember that Ganache & friends are test/simulation tools meant to aid in development of distributed applications. This means that we sometimes break the rules a bit in order to allow things to happen which would otherwise be impossible on the real network. As a result, protocol development is decidedly out of scope for these tools.

That said, we do have an issue open on this one (I think you raised it?) and when we close that, we'll be doing our best to calculate the hashes correctly in the cases where we do have private keys, but I'm still sorting out how to do this without breaking the forking feature (it might not be possible), so it might take some time.

Your Answer

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

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