我正在使用Web3库。我希望从Web3事务中提取一个签名哈希,将其发送到外部硬件设备,在那里签名,然后使用从那里获得的签名在Ropsten上广播我的事务。
在他们的GitHub页面上,我找到了一个测试示例:
在第26-37行中,我检查了它是如何签名的:
const tx = {
chainId: '0x11',
data: '0x',
gas: '0x7530',
gasPrice: '0x3b9aca00',
nonce: '0x3',
to: '0xb414031Aa4838A69e27Cb2AE31E709Bcd674F0Cb',
value: '0x64'
};
await expect(
transactionSigner.sign(tx, '3a0ce9a362c73439adb38c595e739539be1e34d19c5e9f04962c101c86bd7616')显然,transactionSigner签了名:
在这一类中,在第62-63行:
const ethTx = new EthereumTx(transaction);
ethTx.sign(Buffer.from(privateKey, 'hex'));因此,他们实际上正在使用另一个库ehtereumjs:
https://github.com/ethereumjs/ethereumjs-tx/blob/master/src/transaction.ts
在第269-270行,我们发现:
const msgHash = this.hash(false)
const sig = ecsign(msgHash, privateKey)这就是我想要的,"msgHash“变量。我怎么才能达到它,而不需要宰杀一半的图书馆,并重写它手动?或者有一种简单的方法让我自己来构建它,如果是的话,如何准确地构建它?
例如,在bitcoinlib-js中,有一个SignerAsync对象,您可以自己构造它,只需将它的“符号(散列:缓冲区)”属性分配给您自己的自定义签名函数。Bitcoinlib自动将我需要的“哈希”东西放入符号(散列:缓冲区),然后简单地将它传递给外部硬件设备。在Web3中有类似的地方吗?
发布于 2019-09-06 21:16:11
原来的诀窍是不要调用Web3's transactionSigner(),它的级别太高了。直接调用ethereumjs库:
// Regular ethereum tx object
const txData = {
chainId: '0x11',
data: '0x',
gas: '0x7530',
gasPrice: '0x3b9aca00',
nonce: '0x3',
to: '0xb414031Aa4838A69e27Cb2AE31E709Bcd674F0Cb',
value: '0x64'
};
const ethTX = new Transaction(txData, {
chain: ETH_ROPSTEN_CHAINID // Ropsten testnet chainID = 3
});
// Hash the ethereumjs-tx Transaction object
const transactionHashToSign = ethTX.hash(false);
// Now send this to your external hardware device
const signature: string = hardwareDevice.sign(transactionHashToSign);然后,您必须自己从该签名中提取R、S和V六弦,并将它们设置为ethTX对象,因为现在您还没有使用Web3's或ethTX为您处理此问题的“符号”函数。
对我来说,我用硬件设备制作了一个数字签名。提取R和S是有充分记录的,但取决于您的硬件设备,V并不总是签名的一部分。您必须自己计算它(我使用了C++'s僵尸库)。您可以从签名中提取公钥,并将其与您签名的公钥进行比较(参见https://crypto.stackexchange.com/questions/98316/possible-to-directly-calculate-the-recovery-id-from-a-msg-signature-and-public)。基本上,唯一的方法是尝试提取不同v值的公钥,并查看哪些结果与您的公钥匹配,然后才是正确的v值。
完成之后,将它们设置为"ethTX“对象:
ethTX.r = Buffer.from(r, 'hex');
ethTX.s = Buffer.from(s, 'hex');
ethTX.v = Buffer.from(v, 'hex');那你就可以
const rawTx: string = '0x' + ethTX.serialize().toString('hex');然后广播这个原始交易。
https://ethereum.stackexchange.com/questions/74433
复制相似问题