Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ethereum transaction hash: how to get in advance?

Please tell me how can I get transactionHash in avance?

// I have these tx opts:
var txOpts = {
  "to":"0x345cA3e014Aaf5dcA488057592ee47305D9B3e10",
  "nonce":"0x8",
  "gasPrice":1,
  "gas":250000,
  "value":"0xde0b6b3a7640000",
  "data":"0xd0e30db0"
}

// I create and sign tx:
var tx = new ethereumjs.Tx(txOpts);
tx.sign(new ethereumjs.Buffer.Buffer("c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", "hex"));

// I've got raw tx:
var rawTx = tx.serialize().toString('hex');
"f86c08018303d09094345ca3e014aaf5dca488057592ee47305d9b3e10880de0b6b3a764000084d0e30db01ca0625e358100f4aacb9a65e6e054d963138565e3ceafb20eae4c9c8aaa583a29eea01d8f74faba33ab577ec36ac383dd5bd5298216bcf69fe2c09bba2d3003ecd008"

When I send this tx to ganache-cli, I receive this logs:

eth_sendRawTransaction
   > {
   >   "jsonrpc": "2.0",
   >   "id": 7,
   >   "method": "eth_sendRawTransaction",
   >   "params": [
   >     "0xf86c08018303d09094345ca3e014aaf5dca488057592ee47305d9b3e10880de0b6b3a764000084d0e30db01ca0625e358100f4aacb9a65e6e054d963138565e3ceafb20eae4c9c8aaa583a29eea01d8f74faba33ab577ec36ac383dd5bd5298216bcf69fe2c09bba2d3003ecd008"
   >   ],
   >   "external": true
   > }

  Transaction: 0x73d419e3a9a63aab7ee4f3be43c0df0175f4395615945d395c827bffb3bbfecc
  Gas usage: 29634
  Block Number: 9
  Block Time: Fri Jan 12 2018 23:21:22 GMT-0700

Transaction hash is 0x73d419e3a9a63aab7ee4f3be43c0df0175f4395615945d395c827bffb3bbfecc How to get it in advance?

// use ethereumjs.hash function (is that rlp-hash?):
var hash = tx.hash().toString('hex')
"**71ef26c4c1c1b01a5f87525e8e9b3ca7ffe5c9ae30ee1e70b353bf9b14db96be**"

This is not equal to 73d419e3a9a63aab7ee4f3be43c0df0175f4395615945d395c827bffb3bbfecc!

Is there any possibility to calculat CORRECT transaction hash in advance before mining? Please tell me what functions should I use.

Thanks a lot!

like image 261
Alexa Avatar asked Mar 07 '23 03:03

Alexa


2 Answers

I digged a little bit to get the answer.

Instead of just call tx.hash().toString('hex'), you need to call like this tx.hash(true).toString('hex'), in which true stands for includeSignature when computing the hash.

In case you're curious, this is the method(https://github.com/ethereumjs/ethereumjs-tx/blob/9a6324f64f4da1cb550a3eec4eaef95da4ab441b/src/transaction.ts#L177).

And you could also get the same result from rawTx like this:

import * as ethUtil from 'ethereumjs-util';
const rawTx = `0x${signedTx.serialize().toString('hex')}`;    // 0x is important
const res1 = `0x${ethUtil.keccak(rawTx).toString('hex')}`;
const res2 = `0x${signedTx.hash(true).toString('hex')}`;
res1 === res2; // true

I hope this will help.

like image 90
alphacat2018 Avatar answered Mar 24 '23 09:03

alphacat2018


This is just an issue with ganache. queueRawTransaction uses a FakeTransaction, which ignores the actual signature on your transaction and instead fakes it. I'm not entirely sure why it works this way, but I believe your code will do the right thing for a transaction submitted to an actual Ethereum network.

If you want to get the same transaction hash ganache is computing, this does the trick, but it won't be the transaction hash you get from Ethereum proper:

const EthereumTx = require('ethereumjs-tx');
const FakeTx = require('ethereumjs-tx/fake.js');

var txOpts = {
  "to":"0x345cA3e014Aaf5dcA488057592ee47305D9B3e10",
  "nonce":"0x8",
  "gasPrice":1,
  "gas":250000,
  "value":"0xde0b6b3a7640000",
  "data":"0xd0e30db0"
}

var tx = new EthereumTx(txOpts);
tx.sign(Buffer.from("c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", "hex"));

const raw = tx.serialize().toString('hex');
const fake = new FakeTx(raw);
fake.from = tx.getSenderAddress();

console.log(fake.hash(true).toString('hex'));

// Output:
// 71ef26c4c1c1b01a5f87525e8e9b3ca7ffe5c9ae30ee1e70b353bf9b14db96be
like image 31
user94559 Avatar answered Mar 24 '23 10:03

user94559