#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, но он не выдает ошибок и работает нормально