首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何提取或创建带有web3.js的消息,以便与外部硬件设备签名?

如何提取或创建带有web3.js的消息,以便与外部硬件设备签名?
EN

Ethereum用户
提问于 2019-08-30 17:04:59
回答 1查看 868关注 0票数 0

我正在使用Web3库。我希望从Web3事务中提取一个签名哈希,将其发送到外部硬件设备,在那里签名,然后使用从那里获得的签名在Ropsten上广播我的事务。

在他们的GitHub页面上,我找到了一个测试示例:

https://github.com/ethereum/web3.js/blob/2.x/packages/web3-eth/tests/src/signers/TransactionSignerTest.js

在第26-37行中,我检查了它是如何签名的:

代码语言:javascript
复制
    const tx = {
        chainId: '0x11',
        data: '0x',
        gas: '0x7530',
        gasPrice: '0x3b9aca00',
        nonce: '0x3',
        to: '0xb414031Aa4838A69e27Cb2AE31E709Bcd674F0Cb',
        value: '0x64'
    };

    await expect(
        transactionSigner.sign(tx, '3a0ce9a362c73439adb38c595e739539be1e34d19c5e9f04962c101c86bd7616')

显然,transactionSigner签了名:

https://github.com/ethereum/web3.js/blob/aaf26c8806bc9fb60cf6dcb6658104963c6c7fc7/packages/web3-eth/src/signers/TransactionSigner.js

在这一类中,在第62-63行:

代码语言:javascript
复制
    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行,我们发现:

代码语言:javascript
复制
const msgHash = this.hash(false)
const sig = ecsign(msgHash, privateKey)

这就是我想要的,"msgHash“变量。我怎么才能达到它,而不需要宰杀一半的图书馆,并重写它手动?或者有一种简单的方法让我自己来构建它,如果是的话,如何准确地构建它?

例如,在bitcoinlib-js中,有一个SignerAsync对象,您可以自己构造它,只需将它的“符号(散列:缓冲区)”属性分配给您自己的自定义签名函数。Bitcoinlib自动将我需要的“哈希”东西放入符号(散列:缓冲区),然后简单地将它传递给外部硬件设备。在Web3中有类似的地方吗?

EN

回答 1

Ethereum用户

回答已采纳

发布于 2019-09-06 21:16:11

原来的诀窍是不要调用Web3's transactionSigner(),它的级别太高了。直接调用ethereumjs库:

代码语言:javascript
复制
// 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“对象:

代码语言:javascript
复制
  ethTX.r = Buffer.from(r, 'hex');
  ethTX.s = Buffer.from(s, 'hex');
  ethTX.v = Buffer.from(v, 'hex');

那你就可以

代码语言:javascript
复制
const rawTx: string = '0x' + ethTX.serialize().toString('hex');

然后广播这个原始交易。

票数 1
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/74433

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档