Не удается вывести токены ERC-20 из контракта с краном

#solidity #truffle #erc20 #ganache #openzeppelin

Вопрос:

Недавно я опубликовал токен ERC-20 в mainnet, и все работает хорошо. Сейчас я пытаюсь написать смарт-контракт на кран, чтобы раздавать монеты тому, кто их попросит. Обратите внимание, что это будет не кран, который чеканит новые токены непосредственно из контракта на токены, а тот, который я могу предварительно загрузить токенами (отправив на кран из своего кошелька).

Я собрал смарт-контракт для крана из разных источников, и все работает нормально, за исключением функции «вывод». Я получаю следующую ошибку:

 truffle(development)gt; FaucetDeployed.withdraw() Uncaught Error: Returned error: VM Exception while processing transaction: revert  at evalmachine.lt;anonymousgt;:0:16  at sigintHandlersWrap (vm.js:273:12)  at Script.runInContext (vm.js:142:14)  at runScript (C:UsersJonathanAppDataRoamingnpmnode_modulestrufflebuildwebpack:packagescorelibconsole.js:364:1)  at Console.interpret (C:UsersJonathanAppDataRoamingnpmnode_modulestrufflebuildwebpack:packagescorelibconsole.js:379:1)  at bound (domain.js:421:15)  at REPLServer.runBound [as eval] (domain.js:432:12)  at REPLServer.onLine (repl.js:909:10)  at REPLServer.emit (events.js:400:28)  at REPLServer.emit (domain.js:475:12)  at REPLServer.Interface._onLine (readline.js:434:10)  at REPLServer.Interface._normalWrite (readline.js:588:12)  at Socket.ondata (readline.js:246:10)  at Socket.emit (events.js:400:28) {  data: {  '0xf08ce8522dce0fb4c19ac791e5a7960055e1ad0e106761efa8f411c1cc9e23c9': { error: 'revert', program_counter: 677, return: '0x' },  stack: 'c: VM Exception while processing transaction: revertn'    ' at Function.c.fromResults (C:\Users\Jonathan\AppData\Roaming\npm\node_modules\ganache-cli\build\ganache-core.node.cli.js:4:192416)n'    ' at w.processBlock (C:\Users\Jonathan\AppData\Roaming\npm\node_modules\ganache-cli\build\ganache-core.node.cli.js:42:50915)n'    ' at runMicrotasks (lt;anonymousgt;)n'    ' at processTicksAndRejections (internal/process/task_queues.js:95:5)',  name: 'c'  

Вот мой код смарт-контракта на кран:

 // SPDX-License-Identifier: MIT  pragma solidity ^0.8.0;  import "@openzeppelin/contracts/token/ERC20/IERC20.sol";  contract Faucet {  address payable owner;  IERC20 private _token;  uint256 public withdrawalAmount = 50 * (10 ** 18);   event Withdrawal(address indexed to, uint amount);  event Deposit(address indexed from, uint amount);   constructor (IERC20 token) {  _token = token;  owner = payable(msg.sender);  }   // Accept any incoming amount  receive() external payable {  emit Deposit(msg.sender, msg.value);  }   // Give out ether to anyone who asks  function withdraw() public {  // Limit withdrawal amount to 1,000 tokens  require(  withdrawalAmount lt;= 1000 * (10 ** 18),  "Request exceeds maximum withdrawal amount of 1000 ICHC"  );   require(  _token.balanceOf(address(this)) gt;= withdrawalAmount,  "Insufficient balance in faucet for withdrawal request"  );   require(  msg.sender != address(0),  "Request must not originate from a zero account"  );   // Send the amount to the address that requested it  _token.transfer(msg.sender, withdrawalAmount);  }   // setter for withdrawl amount  function setWithdrawalAmount(uint256 amount) public onlyOwner {  // Limit max withdrawal amount to 10,000 tokens  require(amount lt;= 10000 * (10 ** 18));  withdrawalAmount = amount * (10 ** 18);  }   // Contract destructor  function destroy() public onlyOwner {  selfdestruct(owner);  }   // Access control modifier  modifier onlyOwner {  require(msg.sender == owner, "Only the contract owner can call this function");  _;  } }  

Я развертываю его, а также токен ERC20 в локальном блокчейне ganache с помощью «миграции трюфелей». Затем я тестирую его, используя следующие команды в консоли трюфеля:

Установка:

 Faucet.deployed().then(i=gt;{FaucetDeployed = i}); MyToken.deployed().then(s=gt;{ token = s });  

Загрузите кран с токенами:

 token.transfer("0x55b9bCF39F78ef22E452d54957366cCBFffaF85E","300000000000000000000")  

Проверьте баланс крана:

 token.balanceOf("0x55b9bCF39F78ef22E452d54957366cCBFffaF85E").then((b)=gt; { balf = b }) balf.toString() // shows "300000000000000000000"  

Попытка вывода средств из крана:

 FaucetDeployed.withdraw()  

Это приводит к ошибке в верхней части этого поста. Я попытался удалить все инструкции require, но результат тот же. Я уверен, что упускаю из виду что-то действительно глупое. Кто-нибудь может определить, что я делаю не так? Я ценю любой совет — спасибо!

  • Джонатан

Комментарии:

1. Как вы устроились token constructor ?! Попробуйте этот код: constructor (address tokenAddress) и следующая строка: _token = IERC20(tokenAddress)

2. Спасибо, Ахмад. Аргумент «токен» в конструкторе наследует свой тип из импортированного контракта IERC20. Я передаю адрес токена при развертывании контракта на кран.

3. Ахмад — Я только что попробовал ваш подход, но, к сожалению, получил ту же ошибку. Спасибо за предложение.

4. Не могли бы вы, пожалуйста, развернуть как токен, так и контракт на кран в тестовой сети rinkeby, чтобы посмотреть, какую ошибку он выдает?! Я не знаком с трюфелями.

5. Я попробовал простой токен и ваш контракт на кран в тестовой сети Rinkeby, но он не выдает ошибок и работает нормально