微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法解码交易数据

如何解决无法解码交易数据

我正在尝试使用 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));

我尝试过:

  1. 函数名称"addLiquidityETH"
  2. 函数签名:"addLiquidityETH(address,uint,address,uint)""addLiquidityETH(address,uint) external payable returns (uint,uint)"
  3. 两个签名的 sighash:"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,{
      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);  

  });
});

解决方法

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

所以你需要通过

addLiquidityETH(address,uint256,address,uint256)

代替 addLiquidityETHdecodeFunctionData() 函数。

,

找到解决办法:

我在我的原始合约中导入 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?