如何解决无法解码交易数据
我正在尝试使用 Ethers.js 文档中的说明对智能合约测试中的交易数据进行解码,但我一直发现第一个参数(片段)无效:
Ethers.js
interface.decodefunctionData( fragment,data ) ⇒ Result
Returns the decoded values from transaction data for fragment (see Specifying Fragments) for the given data.
ABI
:
const abi = require('../artifacts/contracts/CoinX.sol/CoinX.json').abi;
Interface
:
let ICoinX = new ethers.utils.Interface(abi);
AddLiquidityETH function on UniswapV2Router02.sol
:
function addLiquidityETH(
address token,uint amountTokenDesired,uint amountTokenMin,uint amountETHMin,address to,uint deadline
) external payable returns (uint amountToken,uint amountETH,uint liquidity);
Main snippet on my test
:
const tx = await router.addLiquidityETH(coinX.address,supply,addr1,MaxUint256,{
value: supply
});
const { data } = tx;
console.log("Decoded data: ",await ICoinX.decodefunctionData("addLiquidityETH",data));
我尝试过:
- 函数名称:
"addLiquidityETH"
。 - 函数签名:
"addLiquidityETH(address,uint,address,uint)"
和"addLiquidityETH(address,uint) external payable returns (uint,uint)"
- 两个签名的 sighash:
"0x1a3042d8"
和"0x251511cc"
interface.decodefunctionResult( fragment,data )
...但错误仍然出现。
Error
:
Error: no matching function (argument="name",value="addLiquidityETH",code=INVALID_ARGUMENT,version=abi/5.3.1)
感谢您的帮助!
Full test
:
const { parseEther,formatEther } = ethers.utils;
const { MaxUint256 } = ethers.constants;
const abi = require('../artifacts/contracts/CoinX.sol/CoinX.json').abi;
const routeraddress = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D";
const factoryAddress = "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f";
describe("Uniswap",function() {
let router,coinX,ICoinX,factory;
const supply = parseEther('100');
before(async () => {
router = await ethers.getContractAt("IUniswapV2Router02",routeraddress);
factory = await ethers.getContractAt("IUniswapV2Factory",factoryAddress);
const CoinX = await ethers.getContractFactory('CoinX');
coinX = await CoinX.deploy(supply);
await coinX.deployed();
ICoinX = new ethers.utils.Interface(abi);
});
it("should allow Trades",async function() {
const wethAddr = await router.WETH();
const [addr1] = await ethers.provider.listAccounts();
console.log("coins before: ",formatEther(await coinX.balanceOf(addr1)));
await coinX.approve(routeraddress,MaxUint256);
const tx = await router.addLiquidityETH(coinX.address,{
value: supply
});
const { data } = tx;
console.log("Decoded data: ",data)); // --------> Problem
console.log("coins after: ",formatEther(await coinX.balanceOf(addr1)));
const pairAddress = await factory.getPair(coinX.address,wethAddr);
console.log(pairAddress);
});
});
解决方法
uint
是 uint256
的别名。函数签名始终由包含字节长度的表达式生成(在您的情况下为 uint256
)。
所以你需要通过
addLiquidityETH(address,uint256,address,uint256)
代替 addLiquidityETH
到 decodeFunctionData()
函数。
找到解决办法:
我在我的原始合约中导入 IUniswapV2Router02
认为我在测试中需要的接口是我的合约的接口:
pragma solidity ^0.8.0;
//routers interface
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol';
contract CoinX is ERC20 {
constructor(uint256 initialSupply) ERC20("CoinX","CNX") {
_mint(msg.sender,initialSupply);
}
}
...实际上我需要在我的测试中直接要求 IUniswapV2Router02
而不是我的合约界面。
一旦我这样做了,decodeFunctionData
就可以通过使用 addLiquidityETH
完美地工作。
Full test (fixed):
const { parseEther,formatEther } = ethers.utils;
const { MaxUint256 } = ethers.constants;
//router's ABI
const abiRouter = require('../artifacts/@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol/IUniswapV2Router02.json').abi;
const routerAddress = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D";
const factoryAddress = "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f";
describe("Uniswap",function() {
let router,coinX,myIUniswapV2Router02,factory;
const supply = parseEther('100');
before(async () => {
router = await ethers.getContractAt("IUniswapV2Router02",routerAddress);
factory = await ethers.getContractAt("IUniswapV2Factory",factoryAddress);
const CoinX = await ethers.getContractFactory('CoinX');
coinX = await CoinX.deploy(supply);
await coinX.deployed();
//router's interface on my test
myIUniswapV2Router02 = new ethers.utils.Interface(abiRouter);
});
it("should allow trades",async function() {
const wethAddr = await router.WETH();
const [addr1] = await ethers.provider.listAccounts();
console.log("coins before: ",formatEther(await coinX.balanceOf(addr1)));
await coinX.approve(routerAddress,MaxUint256);
const tx = await router.addLiquidityETH(coinX.address,supply,addr1,MaxUint256,{
value: supply
});
const { data } = tx;
//works as expected
console.log("Decoded data: ",await myIUniswapV2Router02.decodeFunctionData("addLiquidityETH",data));
console.log("coins after: ",formatEther(await coinX.balanceOf(addr1)));
const pairAddress = await factory.getPair(coinX.address,wethAddr);
console.log(pairAddress);
});
});
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。