【问题标题】:Failing to decode transaction's data无法解码交易数据
【发布时间】:2021-09-06 00:22:59
【问题描述】:

我正在尝试使用 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, supply, supply, addr1, MaxUint256, {
      value: supply
    });   
    const { data } = tx;

    console.log("Decoded data: ", await ICoinX.decodeFunctionData("addLiquidityETH", data));

我试过了:

  1. 函数名称:"addLiquidityETH"
  2. 函数签名:"addLiquidityETH(address,uint,uint,uint,address,uint)""addLiquidityETH(address,uint,uint,uint,address,uint) external payable returns (uint,uint,uint)"
  3. 两个签名的叹息:"0x1a3042d8""0x251511cc"
  4. 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, supply, supply, supply, addr1, MaxUint256, {
      value: supply
    });

    const { data } = tx;

    console.log("Decoded data: ", await ICoinX.decodeFunctionData("addLiquidityETH", data)); // --------> Problem

    console.log("coins after: ", formatEther(await coinX.balanceOf(addr1)));

    const pairAddress = await factory.getPair(coinX.address, wethAddr);  
    console.log(pairAddress);  

  });
});

【问题讨论】:

    标签: testing ethereum solidity ethers.js hardhat


    【解决方案1】:

    uintuint256 的别名。函数签名始终由包含字节长度的表达式生成(在您的情况下为 uint256)。

    所以你需要通过

    addLiquidityETH(address,uint256,uint256,uint256,address,uint256)
    

    而不是addLiquidityETHdecodeFunctionData() 函数。

    【讨论】:

    • 同样的错误,也尝试了完整的签名:"addLiquidityETH(address,uint256,uint256,uint256,address,uint256) external payable returns (uint256, uint256, uint256)"@Petr Hedja
    • Error: no matching function (argument="signature", value="addLiquidityETH(address,uint256,uint256,uint256,address,uint256)", code=INVALID_ARGUMENT, version=abi/5.3.1)
    【解决方案2】:

    找到解决办法:

    我在我的原始合同上导入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, supply, 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);  
    
      });
    });
    

    【讨论】:

      猜你喜欢
      • 2019-06-04
      • 1970-01-01
      • 2016-03-17
      • 2017-04-16
      • 2017-09-28
      • 1970-01-01
      • 2017-07-15
      • 2021-06-18
      • 2020-10-01
      相关资源
      最近更新 更多