javascript - 通过使用 ledger nano s,我想签署一个交易并发送它
问题描述
我正在尝试通过 Node.JS 向使用 Ledger Nano S 的人发送 ERC20 代币的以太坊交易,但我无法成功签署并发送此交易。
首先,我通过 ledgerhq API 的 signTransaction 方法对交易进行签名,然后在签名后使用 sendSignedTransaction 将其发送到主网。当我执行以下代码时,Ledger 会收到请求并显示交易的详细信息。但是,在按下 Ledger 的确认按钮后,控制台返回错误“返回错误:无效签名:加密错误(无效的 EC 签名)”。
import AppEth from "@ledgerhq/hw-app-eth";
import TransportU2F from "@ledgerhq/hw-transport-u2f";
import TransportNodeHid from "@ledgerhq/hw-transport-node-hid";
import EthereumTx from "ethereumjs-tx"
const Web3 = require('web3');
import { addHexPrefix, bufferToHex, toBuffer } from 'ethereumjs-util';
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
var destAddresses = ['0xa6acFa18468786473269Dc1521fd4ff40F6481D9'];
var amount = 1000000000000;
var i=0;
var contract = new web3.eth.Contract([token contract ABI... ], '0x74a...');
const data1 = contract.methods.transfer(destAddresses[0], amount).encodeABI();
const exParams = {
gasLimit: 6e6,
gasPrice: 3e9,
from: '0x1A...',
data : data1,
to: '0x74a...',
value: '0x00',
nonce: "0x0",
chainId: 1,
v: "0x01",
r: "0x00",
s: "0x00"
}
async function makeSign(txParams) {
const tx = new EthereumTx(txParams);
const txHex = tx.serialize().toString("hex");
const signedTransaction = '0x' + txHex;
let transport;
try {
transport = await TransportNodeHid.create();
let eth2 = new AppEth(transport);
const result = await eth2.signTransaction("m/44'/60'/0'/0", txHex).then(result => {
web3.eth.sendSignedTransaction('0x' + txHex)
.then(res => {
console.log(res);
}).catch(err => {
console.log('sendSignedTransaction');
console.log(err);
});
}).catch(err => {
console.log('signTransaction');
console.log(err);
});
txParams.r = `0x${result.r, 'hex'}`;
txParams.s = `0x${result.s, 'hex'}`;
txParams.v = `0x${result.v, 'hex'}`;
return result;
} catch (e) {
console.log(e);
}
}
makeSign(exParams).then(function () {
console.log("Promise Resolved2");
}.catch(function () {
console.log("Promise Rejected2");
});
当我只使用 signTransaction 函数时,我可以在账本设备中确认交易并在控制台上返回 txhash。但是,最终我想将交易广播到主网。你能给我任何想法吗?我想要任何反馈。此外,如果有任何使用分类帐创建和广播原始交易的示例,请通知我。
解决方案
您的代码已经将交易发送到网络。然而,仅仅等待“发送”承诺只会给你交易哈希,而不是收据。您需要将其视为事件发射器并等待“确认”事件。
const serializedTx = tx.serialize();
web3.eth.sendSignedTransaction(serializedTx.toString('hex'))
.once('transactionHash', hash => console.log('Tx hash', hash))
.on('confirmation', (confNumber, receipt) => {
console.log(`Confirmation #${confNumber}`, receipt);
})
.on('error', console.error);
如您所述,要将其发送到主网,您可以在端口 8545 上运行本地 geth 节点并使用您的代码不变,或者将 web3 指向infura或类似的。
推荐阅读
- amazon-web-services - DynamodbMapper batchSave 是一个写操作还是多个
- xamarin.forms - Xamarin 基于同一 Grid.Row 中的多个绑定属性在 Grid 内设置按钮的 IsVisible 而不编辑原始模型
- javascript - 从页脚节点 JS/EXPRESS 发布路由
- typescript - 打字稿中的数字比较
- oracle - 我们如何安排作业在 Oracle (sql developer 或 Toad) 中运行,以触发最近连接到特定数据库的邮件
- python-3.x - Facebook 营销 API 语法不正确
- reactjs - 有没有从 redux-form 迁移到 react-final-form 的指令?
- javascript - 如何检查数组的所有项目是否存在于另一个数组中
- python - 在 Python 中使用 NRC Emotion Lexicon 进行情绪分析
- c# - JPEG压缩无损编码器?