web3.eth.sign签名后sendSignedTransaction报错:未知TypedTransaction ID40
解决"TypedTransaction with ID 40 unknown"交易签名错误
报错信息
Error: TypedTransaction with ID 40 unknown
at t.TransactionFactory.fromSerializedData
你的代码
const txData = { nonce: "0x" + parseInt(nonce, 10).toString(16), from: address, to: to, gasLimit: "0x" + parseInt(gasAmount, 10).toString(16), gasPrice: "0x" + parseInt(fee, 10).toString(16), value: "0x" + parseInt(balance, 10).toString(16), }; console.log(txData) let hexObject = new ethereumjs.Tx(txData); let hexString = '0x' + hexObject.serialize().toString('hex'), encoded = { encoding: 'hex' } const rawHash = web3.utils.sha3(hexString, encoded); console.log('rawHash: ' + rawHash) let txHash = await web3.eth.sign(rawHash, address); console.log('txHash: ' + txHash) const createReceipt = await web3.eth.sendSignedTransaction(txHash, function (error, hash) { if (error) { console.log(error) } else { console.log(hash) } })
问题根源与解决方法
你的交易签名逻辑完全错误:web3.eth.sign是用来签名消息(做身份验证用)的,不是用来签名可广播交易的。你把序列化交易哈希后的签名值当成已签名交易发送,自然会触发交易类型解析失败的错误。
直接用ethereumjs-tx完成完整的交易签名流程,代码修正如下:
// 若使用新版@ethereumjs/tx,需额外导入Chain和Common来指定链 // import { Chain, Common } from '@ethereumjs/common'; // const common = new Common({ chain: Chain.Mainnet }); // 替换成你实际使用的链 const txData = { nonce: web3.utils.toHex(nonce), // 用web3工具转十六进制更简洁 to: to, gasLimit: web3.utils.toHex(gasAmount), gasPrice: web3.utils.toHex(fee), value: web3.utils.toHex(balance), }; // 初始化交易对象,新版需传入common参数 const tx = new ethereumjs.Tx(txData /*, { common } */); // 用账户私钥签名交易,私钥需先转成Buffer格式 tx.sign(Buffer.from(privateKey.replace('0x', ''), 'hex')); // 序列化已签名的交易 const serializedTx = tx.serialize(); const rawSignedTx = '0x' + serializedTx.toString('hex'); // 发送已签名交易 const createReceipt = await web3.eth.sendSignedTransaction(rawSignedTx) .on('error', (err) => console.error('发送失败:', err)) .on('transactionHash', (hash) => console.log('交易哈希:', hash)); console.log('交易回执:', createReceipt);
关键注意点
- 必须用账户私钥直接对交易对象签名,
ethereumjs-tx的sign方法会自动处理正确的交易哈希生成与签名逻辑。 - 发送的是序列化后的已签名交易,不是
web3.eth.sign返回的签名值。 - 若使用新版
@ethereumjs/tx,必须指定链信息(Common参数),否则会默认使用过时的链配置导致错误。
内容的提问来源于stack exchange,提问作者Milikoder
相关产品推荐
相关产品推荐

