简体   繁体   English

以太坊交易哈希:如何提前获得?

[英]Ethereum transaction hash: how to get in advance?

Please tell me how can I get transactionHash in avance? 请告诉我如何才能获得transactionHash?

// 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: 当我将此tx发送到ganache-cli时,我会收到以下日志:

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? 事务哈希值是0x73d419e3a9a63aab7ee4f3be43c0df0175f4395615945d395c827bffb3bbfecc如何提前获取?

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

This is not equal to 73d419e3a9a63aab7ee4f3be43c0df0175f4395615945d395c827bffb3bbfecc! 这不等于73d419e3a9a63aab7ee4f3be43c0df0175f4395615945d395c827bffb3bbfecc!

Is there any possibility to calculat CORRECT transaction hash in advance before mining? 在挖掘之前是否有可能提前计算CORRECT事务哈希? Please tell me what functions should I use. 请告诉我应该使用哪些功能。

Thanks a lot! 非常感谢!

This is just an issue with ganache . 这只是ganache一个问题。 queueRawTransaction uses a FakeTransaction , which ignores the actual signature on your transaction and instead fakes it. queueRawTransaction使用FakeTransaction ,它忽略了事务上的实际签名,而是伪造它。 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: 如果你想获得相同的事务哈希ganache是计算,这可以解决问题,但它不是你从以太坊本身得到的事务哈希:

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

The actual tx hash we've got from ganache is: 我们从ganache得到的实际tx哈希是:

0x73d419e3a9a63aab7ee4f3be43c0df0175f4395615945d395c827bffb3bbfecc 0x73d419e3a9a63aab7ee4f3be43c0df0175f4395615945d395c827bffb3bbfecc

Both FakeTx and ethereumjs-tx returns the same hash for signed transaction: FakeTx和ethereumjs-tx都为签名事务返回相同的哈希值:

71ef26c4c1c1b01a5f87525e8e9b3ca7ffe5c9ae30ee1e70b353bf9b14db96be 71ef26c4c1c1b01a5f87525e8e9b3ca7ffe5c9ae30ee1e70b353bf9b14db96be

However if thransaction is not signed "tx.hash().toString('hex')" returns exactly the same value as ganache cli. 但是如果thransaction没有签名“tx.hash()。toString('hex')”返回与ganache cli完全相同的值。 Even without adding 'from' to txOpts. 即使没有将'from'添加到txOpts。

It is not possible to get transaction hash in advance, you can only get transaction hash just after performing transaction. 事先无法获得事务哈希,只能在执行事务后获取事务哈希。

But whenever transaction not pick by any miner this transaction hash will temporary, there is possibility that if you send very less fees with your transaction then your transaction might be not picked by any miner. 但是,无论何时交易都没有被任何矿工选择,这个交易哈希将是暂时的,如果您在交易中收取的费用很少,那么任何矿工都可能不会选择您的交易。

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. 你需要调用tx.hash(true).toString('hex') ,而不是只调用tx.hash().toString('hex') ,其中true代表计算哈希时的includeSignature

In case you're curious, this is the method( https://github.com/ethereumjs/ethereumjs-tx/blob/9a6324f64f4da1cb550a3eec4eaef95da4ab441b/src/transaction.ts#L177 ). 如果你很好奇,这就是方法( https://github.com/ethereumjs/ethereumjs-tx/blob/9a6324f64f4da1cb550a3eec4eaef95da4ab441b/src/transaction.ts#L177 )。

And you could also get the same result from rawTx like this: 你也可以从rawTx得到相同的结果:

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. 我希望这将有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM