Solidity

無法辨識功能選擇器錯誤

  • May 6, 2022

我正在擴展 OpenZeppelins ERC20 以創建一個令牌,用於在另一個智能合約中進行測試。這是它的外觀:

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract TestERC20Token is ERC20 {
   constructor(uint256 initialSupply) ERC20("Test Coin", "TEST") {
       _mint(msg.sender, initialSupply * (10 ** 18));
   }
}

這是我如何使用它的另一個契約:

function deposit(uint256 amount)
       external
       checkTokenBalance(msg.sender, amount)
   {
       if (!_isClosedForDeposit()) {
           _token.transferFrom(msg.sender, address(this), amount);
           deposits[msg.sender] += amount;
           totalDeposits += amount;
           _addToDepositors(msg.sender);
       } else {
           revert DepositPeriodExpired("Depost period has expired");
       }
   }

_token在建構子中被實例化:

IERC20 private _token;
constructor(address token, uint256 duration) {
       owner = msg.sender;
       deployedAt = block.timestamp;
       _token = IERC20(token);
   }

所以我在部署我使用代幣的合約時傳遞了代幣合約的地址。

但是,當我使用 hardhat 執行這個 js 測試程式碼時:

   await deployTokenContract();

   await deployOtherContract(5);

   const amount = utils.parseUnits("5", 18);
   const token = await initTokenContract(accounts.one.privateKey);
   const approveTx = await token.approve(contractAddress, amount);
   const res = await approveTx.wait(1);
   const allowance = await token.allowance(accounts.one.address, contractAddress);

   const otherContract = await initOtherContract(accounts.one.privateKey);
   const depositTx = await otherContract.deposit(amount, {
       gasLimit: 25000
   });
   await depositTx.wait(1);

我收到以下錯誤:

Error: Transaction reverted: function selector was not recognized and there's no fallback function
   at TestERC20Token.<unrecognized-selector> (contracts/TestERC20Token.sol:6)

在我看來,當在我的另一個合約中呼叫 transferFrom 時,在 TestERC20Token 合約中沒有找到這個函式,但它應該是從 ERC20 繼承的。不知道為什麼會失敗

你能展示你的IERC20介面程式碼嗎?

因此,在兩個deployContract函式中,我將硬編碼地址附加到合約實例中,例如:

const Contract = await ethers.getContractFactory("TestERC20Token");
const contract = await Contract.deploy(initialMintAmount);
contract.attach("0x5FbDB2315678afecb367f032d93F642f64180aa3");
await contract.deployed();

將其刪除並在部署後獲取地址後,上述問題就消失了

引用自:https://ethereum.stackexchange.com/questions/127676