Remix执行Polygon合约函数遇Internal JSON-RPC错误及回滚问题排查
问题原因及解决方案
核心问题分析
- 原生MATIC与WMATIC混淆:Polygon上的原生MATIC并非ERC20代币,你代码中使用的
0x0000000000000000000000000000000000001010是WMATIC(包装后的MATIC)地址。处理原生MATIC时,不能用ERC20的transferFrom方法,需通过payable函数接收,并调用Router对应的原生代币兑换方法。 - Router接口定义错误:你自定义的
Router接口未适配原生MATIC的兑换逻辑。Polygon上的UniswapV2风格Router(如QuickSwap)针对原生代币的兑换方法是swapExactETHForTokens(而非swapExactTokensForTokens),且该函数必须标记为payable才能接收原生MATIC。 - 兑换逻辑不匹配:使用原生MATIC兑换USDC时,无需手动处理WMATIC的转账与授权,Router会自动将原生MATIC转换为WMATIC完成兑换;同时路径参数需以WMATIC地址开头。
- 授权校验缺失:若使用WMATIC兑换,用户需先给合约授权WMATIC权限,原代码未做相关校验,会直接导致交易回滚。
修正后的合约代码
// SPDX-License-Identifier: MIT pragma solidity 0.8.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; // 适配UniswapV2风格Router的核心接口 interface IUniswapV2Router { function swapExactETHForTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable returns (uint[] memory amounts); function WETH() external pure returns (address); } contract Swapper { // Polygon QuickSwap Router地址(与你原代码一致) IUniswapV2Router public router = IUniswapV2Router(0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff); // Polygon USDC合约地址 IERC20 public USDC_token = IERC20(0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174); // 原生MATIC兑换USDC,函数需标记payable以接收MATIC function swapMATICToUSDC(uint amountOutMin) external payable { require(msg.value > 0, "No MATIC sent"); address[] memory path = new address[](2); path[0] = router.WETH(); // 自动获取WMATIC地址,避免硬编码错误 path[1] = address(USDC_token); // 调用Router的原生代币兑换函数,传入msg.value的MATIC router.swapExactETHForTokens{value: msg.value}( amountOutMin, path, msg.sender, block.timestamp ); } // (可选)WMATIC兑换USDC的版本 function swapWMATICToUSDC(uint amountIn, uint amountOutMin) external { address[] memory path = new address[](2); path[0] = router.WETH(); path[1] = address(USDC_token); // 转用户WMATIC到合约并授权Router使用 IERC20(router.WETH()).transferFrom(msg.sender, address(this), amountIn); IERC20(router.WETH()).approve(address(router), amountIn); router.swapExactTokensForTokens( amountIn, amountOutMin, path, msg.sender, block.timestamp ); } }
额外注意事项
- Gas估算恢复:修正逻辑后,Gas估算错误问题会自动解决。
- 最小输出量设置:不要将
amountOutMin设为0,建议通过Router的getAmountsOut方法预估合理值,避免三明治攻击。 - 用户操作说明:调用
swapMATICToUSDC时,需在Remix的「Value」栏填写要兑换的MATIC数量;调用swapWMATICToUSDC前,需先给合约授权WMATIC权限。
内容的提问来源于stack exchange,提问作者Julio Sarda
相关产品推荐
相关产品推荐

