Web3发送EIP-1559交易成功后出现invalid remainder错误的问题咨询
问题修复方案
1. 错误根因与修复方法
Error: invalid remainder 错误由两方面原因导致:一是 @ethereumjs/tx 和 @ethereumjs/common 依赖版本不匹配,内部序列化逻辑冲突;二是你已经使用了自带签名能力的 HDWalletProvider,额外调用 @ethereumjs/tx 手动签名的冗余逻辑触发了校验错误。
修复步骤:
- 首先保证
@ethereumjs/tx和@ethereumjs/common大版本号完全一致,比如同时升级到v6版本 - 优先直接用HDWalletProvider的内置签名能力,删除冗余的手动签名逻辑,优化后的代码如下:
// EIP-1559 交易优化版代码 const fs = require( 'fs' ).promises; const Web3 = require( 'web3' ); const HDWalletProvider = require( '@truffle/hdwallet-provider' ); async function main () { // Infura Rinkeby节点地址 const infuraRinkeby = "https://rinkeby.infura.io/v3/4fa53ccf01504cc69f0dcbdfdaa38acf"; // 读取助记词 const mnemonic = ( JSON.parse( await fs.readFile( "./private/mnemonic.json" , "utf8" ) ) ).mnemonic; // 初始化provider const provider = new HDWalletProvider( mnemonic , infuraRinkeby ); const web3 = new Web3( provider ); // 获取发送地址和余额 const sendingAddress = ( await web3.eth.getAccounts() )[0]; let sendingAddressBalance = await web3.eth.getBalance( sendingAddress ); console.log( " " ); console.log( Array( 75 ).join( "=" ) ); console.log( "交易前状态" ); console.log( "地址: " + sendingAddress ); console.log( "余额: " + sendingAddressBalance ); // 接收地址 const receivingAddress = "0x24620ddf8474c89C0Fc0c916acBcF4029C4eB47F"; // 构造交易参数,provider会自动完成签名 const txParams = { from: sendingAddress, to: receivingAddress, gas: 210000, maxFeePerGas: web3.utils.toWei('1.5', 'gwei'), maxPriorityFeePerGas: web3.utils.toWei('1.5', 'gwei'), value: web3.utils.toWei('0.1', 'ether'), data: web3.utils.toHex('This is my example') }; // 发送交易获取回执 const receipt = await web3.eth.sendTransaction(txParams); console.log("交易哈希: " + receipt.transactionHash); // 打印交易后状态 console.log( '交易后状态' ); sendingAddressBalance = await web3.eth.getBalance( sendingAddress ); console.log( "地址: " + sendingAddress ); console.log( "余额: " + sendingAddressBalance ); console.log( Array( 75 ).join( "=" ) ); console.log( " " ); // 停止provider引擎避免程序 hang 住 provider.engine.stop(); };
如果一定要保留手动签名的逻辑,删除rawTx中的from字段即可,EIP1559交易的from字段会通过签名公钥自动恢复,手动传入会导致序列化校验失败。
2. 错误捕获方案
之前try catch失效是因为没有兜底处理异步Promise的全局抛出,添加两处配置即可完全避免程序崩溃:
- 给main函数调用添加catch捕获
main().catch(e => { console.error("程序运行错误:", e); process.exit(1); });
- 添加全局未处理拒绝监听,兜底捕获所有异步错误
process.on('unhandledRejection', (reason, promise) => { console.error('未捕获的异步错误:', reason); });
3. 替代依赖方案
可以直接用ethers.js替代当前的web3 + truffle-hdwallet-provider + ethereumjs 组合,对EIP-1559的原生支持更好,没有版本冲突问题,代码更简洁:
const { ethers, Wallet } = require("ethers"); const fs = require('fs').promises; async function main() { const infuraRinkeby = "https://rinkeby.infura.io/v3/4fa53ccf01504cc69f0dcbdfdaa38acf"; const mnemonic = ( JSON.parse( await fs.readFile( "./private/mnemonic.json" , "utf8" ) ) ).mnemonic; const provider = new ethers.providers.JsonRpcProvider(infuraRinkeby); const wallet = Wallet.fromMnemonic(mnemonic).connect(provider); // 发送交易逻辑 const tx = await wallet.sendTransaction({ to: "0x24620ddf8474c89C0Fc0c916acBcF4029C4eB47F", value: ethers.utils.parseEther("0.1"), gasLimit: 210000, maxFeePerGas: ethers.utils.parseUnits("1.5", "gwei"), maxPriorityFeePerGas: ethers.utils.parseUnits("1.5", "gwei"), data: ethers.utils.toUtf8Bytes("This is my example") }); await tx.wait(); console.log("交易哈希:", tx.hash); }
内容的提问来源于stack exchange,提问作者Jask_Skull
相关产品推荐
相关产品推荐

