Не удалось оценить газ в Remix

Не могу использовать функцию передачи, как она написана. Предполагается, что владелец использует его. Таким образом, была создана новая функция для функции «чеканки» для использования сборщиком. Не знаю, почему сообщение компилятора такое загадочное.

totalSupply_ = totalSupply_.add(_amount);
balances[_to] = balances[_to].add(_amount);
emit Mint(_to, _amount);
emit Transfer(address(0), _to, _amount);

Пытаюсь создать Faucet для моего токена ERC-20 и получаю сообщение «Ошибка оценки газа» при запуске моей dripTokenфункции, которая выглядит следующим образом (ОБНОВЛЕНО):

function dripToken() public {
  require(faucetStatus);
  if(!checkStatus(msg.sender)) revert();
  tokenInstance.updateSupply(oneToken);
  updateStatus(msg.sender, oneMinute);
  tokenInstance.transfer(msg.sender, oneToken);
}

Я сузил его до строки с вызовом передачи, которая вызывает ошибку. Теперь я развертываю свой токен ERC-20 и передаю его в контракт крана следующим образом:

constructor(string _fname, address _tokenInstance) public {
  tokenInstance = MyToken(_tokenInstance);
  faucetName = _fname;
  faucetStatus = true;

  emit FaucetOn(faucetStatus);
}

Моя функция передачи токена взята из https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/StandardToken.sol . Я только что заметил, что получаю предупреждение компилятора о функции передачи, которая намекает на проблему. , но я не понимаю, почему (пока). Вот предупреждение:

Требование к газу функции StandardToken.transfer(address,uint256) высокое: бесконечно. Если потребность в газе для функции выше, чем лимит газа в блоке, она не может быть выполнена. Пожалуйста, избегайте циклов в ваших функциях или действиях, которые изменяют большие области хранилища (включая очистку или копирование массивов в хранилище).

function transfer(address _to, uint256 _value) public returns (bool) {
  require(_value <= balances[msg.sender]);
  require(_to != address(0));

  balances[msg.sender] = balances[msg.sender].sub(_value);
  balances[_to] = balances[_to].add(_value);
  emit Transfer(msg.sender, _to, _value);
  return true;
}

Я создаю свой токен следующим образом. Теперь я инициализирую его с небольшим запасом.

contract MyToken is StandardToken {
  string public name;                   
  uint8 public decimals;                
  string public symbol;  

  constructor() public {  
    StandardToken.balances[msg.sender] = 1000000000000000000;
    StandardToken.totalSupply_ = 1000000000000000000;                        
    name = "My Token";                             
    decimals = 18; 
    symbol = "MY";      
  }
}

Разместил мой код на диске Google: https://drive.google.com/open?id=1EvKEVhD8bR2oKS2W1XNRQpTqVbieUcmC

Трудно понять, не видя реализации transfer, но я предполагаю, что это не сработает, если сам контракт не имеет достаточно высокого баланса. Вы можете просто хотеть totalSupply_ += oneToken; balanceOf[msg.sender] += oneToken; emit Transfer(0, msg.sender, oneToken);.
Я попытался поменять местами строки, как вы предложили. Все еще получаю ту же ошибку. Что делает emit Transfer? Это другая передаточная функция? Я также удалил свое наследство и теперь передаю контракт токена в сборщик. Я обновил исходный пост с большим количеством кода.
Transfer— это событие, которое должно генерироваться вашим токеном каждый раз, когда токен передается. (По соглашению генерируется событие, показывающее перевод с адреса 0, когда чеканятся новые токены.)
Заметил, что я получаю предупреждение о передаточной функции, о высоком газе. Не уверен, что вызывает это (пока). Вставил предупреждение в мой op.
Если вы поделитесь достаточным количеством кода, чтобы воспроизвести проблему, я буду рад попробовать ее. Просто строить догадки немного утомительно.
Спасибо за предложение. Добавил ссылку на гугл диск. Я заметил, что запускаю ремикс с внедренным web3. Я вернулся к JVM, и у меня больше нет ошибки газа, но функция передачи все еще не работает. Он жалуется, что конструктор не помечен как подлежащий оплате. Я думал, что ключевое слово Payable используется только при переводе ETH? Моя первоначальная ошибка могла быть связана с моими настройками лимита газа. Все еще отлаживаю.
Упоминание о том, что конструктор оплачивается, является отвлекающим маневром. Я думаю, что это в этом сообщении об ошибке, потому что это была/была частая причина возврата транзакций, но это не связано с вашей проблемой.

Ответы (2)

См. ответ в верхней части ОП. Я думаю, что это был блок require, который не удался. Не уверен, почему компилятор так загадочен в этом.

Необходимо указать адрес, с которого осуществляется перевод. Например, если вы пытаетесь передать токен ERC20, код будет следующим:

ERC20TokenAddress.transfer(msg.sender, oneToken);

Без ведущего адреса EVM не знает, что передается.

Как получить адрес? В настоящее время я определяю контракт сборщика следующим образом: контракт Faucet — это ERC20Token. Было бы лучше развернуть контракт ERC20Token, а затем передать адрес контракту Faucet через конструктор и просто удалить наследование?
Да, вы можете это сделать. Другой вариант - иметь setAddress()функцию. Это будет выглядеть какfunction setAddress(address tokenAddress) onlyOwner { ERC20TokenAddress = tokenAddress; }
Нет ничего плохого в том, что один и тот же контракт является токеном ERC20 и имеет функцию dripToken().
Заметил, что я получаю предупреждение о передаточной функции, о высоком газе. Не уверен, что вызывает это (пока). Вставил предупреждение в мой op.