通过Infura发送Web3已签名交易未在Etherscan交易列表显示问题咨询
问题1:代码存在的问题及修复方案
你的代码核心问题有3个:
- 硬分叉配置错误:你指定的
istanbul硬分叉是Rinkeby很早之前的版本,现在Rinkeby早已升级到London硬分叉,规则不匹配导致你签名的交易不符合当前链的要求,Infura节点接收到后直接拒收,不会向外广播,所以Etherscan查不到记录。 - 异步逻辑没有等待:
web3.eth.sendSignedTransaction是异步方法,你没有加await,也没有监听错误回调,脚本运行后可能直接提前退出,就算节点返回错误你也收不到提示,所以看起来本地没有报错。 - 冗余字段和多余格式转换:
rawTx里的from字段是多余的,签名交易不需要显式传from,签名后节点会自动从签名信息解析出发送地址;另外你传入的地址本身就是0x开头的十六进制字符串,不需要重复调用toHex转换。
修复后的核心代码示例:
const Web3 = require('web3'); const web3 = new Web3('https://rinkeby.infura.io/v3/4fa53ccf01504cc69f0dcbdfdaa38acf'); const Transaction = require('ethereumjs-tx').Transaction; async function sendTransaction() { const sendingAddress = '0x5Be6e93fE99374E506F4e3803e91EbDFe35D6A39'; const receivingAddress = '0x24620ddf8474c89C0Fc0c916acBcF4029C4eB47F'; // 构造交易去掉冗余的from字段,参数简化 const rawTx = { to : receivingAddress, value : web3.utils.toHex(web3.utils.toWei('0.0009', 'ether')), // 用toWei更直观,避免数错0 gasPrice : web3.utils.toHex(await web3.eth.getGasPrice()), // 动态获取当前网络建议GasPrice gasLimit : web3.utils.toHex(21000), // 纯ETH转账固定GasLimit data : '0x', nonce : web3.utils.toHex(await web3.eth.getTransactionCount(sendingAddress, 'latest')), // 用latest避免无效pending nonce干扰 }; const privateKey = Buffer.from('e603c35185142cc8779c47f9c88a81a52446aaa1398286abf3340178aee11c36', 'hex'); // 硬分叉改为london const tx = new Transaction(rawTx, { chain: 'rinkeby', hardfork: 'london' }); tx.sign(privateKey); const serializedTx = tx.serialize(); // 加await和错误捕获 try { const receipt = await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')); console.log('交易上链成功,收据:', receipt); } catch (err) { console.error('交易失败,错误信息:', err); } console.log('当前交易计数:', await web3.eth.getTransactionCount(sendingAddress, 'pending')); } sendTransaction();
问题2:纯ETH转账的GasPrice、GasLimit计算规则
- GasLimit:没有附加数据的普通ETH转账,GasLimit固定为21000,这是以太坊协议规定的基础转账开销,多给的部分会在交易打包后原路退回,少了会直接交易失败,不需要额外加高,你原来代码里写的210000多了10倍,属于不必要的Gas浪费。
- GasPrice:直接调用
web3.eth.getGasPrice()就能拿到当前网络的建议Gas Price,这个值是节点根据最近几个区块的平均打包价格计算的,足够让交易在正常时间内打包,不需要手动硬编码数值。如果是EIP-1559类型的交易,可以调用web3.eth.getFeeHistory获取建议的优先费和最高费用。
问题3:相同参数报Intrinsic gas too low的原因
这个问题的核心是交易类型不匹配:Metamask现在默认使用EIP-1559类型(类型2)的交易,参数里没有gasPrice,而是用maxPriorityFeePerGas和maxFeePerGas两个字段。你直接把EIP-1559交易的参数套到你代码里的legacy类型(类型0)交易里,参数结构不符合legacy交易的校验规则,就会报固有Gas过低的错误。而Metamask本身是按对应交易类型的规则处理的,所以不会报错。
另外还有一个常见原因:你把GasLimit的十进制数值转Hex的时候格式错误,或者把GasLimit和GasPrice的数值填反,也会触发这个报错。
问题4:链分叉的影响及查询方法
和分叉有关系:硬分叉会修改链的交易校验、签名、Gas计算等规则,如果你代码里指定的硬分叉版本和当前链实际运行的版本不匹配,签名出来的交易就不符合链的校验要求,节点会直接拒收,不会上链。
分叉是链的属性,和账户没有关系,不需要查单个账户的分叉版本,你只要确认你对接的Rinkeby测试网的当前生效硬分叉版本即可,目前Rinkeby最后一次升级的硬分叉为London版本,和以太坊主网规则同步。
内容的提问来源于stack exchange,提问作者Jask_Skull
相关产品推荐
相关产品推荐

