如何在ethers.js中正确使用swapExactETHForTokens方法完成兑换交易
问题原因
- 你调用的
swapExactETHForTokens是带payable修饰的Solidity合约方法,这类方法接收的原生代币(ETH/BSC链上的BNB等)就是合约里读取的msg.value,这个参数不需要写在方法的入参列表里,在ethers.js中是通过调用方法时的交易覆写配置对象来传递的。 - 你当前代码存在两个错误:
- 填写的ABI参数错误:标准的
swapExactETHForTokens方法不存在第一个amountIn入参,入参第一个位置就是amountOutMin,多出来的入参会导致合约调用参数不匹配 - 交易覆写对象里没有添加
value字段传递你要发送的原生代币数量
- 填写的ABI参数错误:标准的
修复方案
- 先修正合约的ABI定义,删除多余的
amountIn参数 - 调用方法时在最后一个配置对象中添加
value字段,值为你要发送的原生代币数量,单位必须是wei
修正后的代码示例
const WBNBHERORouterContract = new ethers.Contract( router, [ `function getAmountsOut(uint amountIn, address[] memory path) public view returns (uint[] memory amounts)`, // 修正后的swapExactETHForTokens ABI,删除了多余的第一个amountIn参数 `function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts)` ], signer ); // 你要发送的BNB/ETH数量,单位为wei,比如要发0.1BNB就用ethers.utils.parseEther("0.1") const sendNativeAmount = wbnbAmount; const tx = await WBNBHERORouterContract.swapExactETHForTokens( minAmountToBuy, // 第一个参数是amountOutMin [WBNB, HERO], wallet.address, Date.now() + 1000 * 60, { gasLimit: 251234, value: sendNativeAmount // 在这里传入msg.value对应的数值,单位wei } ) receipt = await tx.wait();
注意事项
- 如果你手里的原生代币数量是十进制的可读值(比如0.1ETH),需要先用
ethers.utils.parseEther("0.1")转换成wei单位的BigNumber类型再赋值给value - 保证你的signer地址里有足够的原生代币支付发送的value+gas费用
内容的提问来源于stack exchange,提问作者sossnowski
相关产品推荐
相关产品推荐

