Создание экземпляра контракта внутри другого контракта и вызов его методов приводит к возникновению исключения.

У меня есть 2 основных контракта: один на токен, а второй на продажу.

Контракт токена:

contract MyToken is StandardToken, Ownable {

    string public constant name = "My Sample Token";

    string public constant symbol = "MST";

    uint32 public constant decimals = 18;

    function MyToken(uint _totalSupply) {
       require (_totalSupply > 0);
       totalSupply = _totalSupply;
       balances[msg.sender] = totalSupply;
    }
}

Договор купли-продажи

contract Sale {
    address owner;

    address public founderAddress;
    uint256 public constant foundersAmount = 50;

    MyToken public token = new MyToken(1000);


    uint256 public issuedTokensAmount = 0;

    function Sale() {
        owner = msg.sender;
        founderAddress = 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c;
        token.transfer(founderAddress, foundersAmount);
    }

    function() external payable {
        token.transfer(msg.sender, 1);
        owner.transfer(msg.value);
    }   
}

StandardToken и Ownable являются стандартными реализациями из репозитория OpenZeppelin. Полный текст контракта доступен здесь.

Итак, в основном в своем контракте на продажу я создаю экземпляр своего контракта на токены с фиксированной поставкой и назначаю все токены вызывающей стороне. Затем я перевожу некоторое количество токенов на адрес учредителя. Когда я пытаюсь отправить некоторое количество эфириума в контракт на продажу, я пытаюсь передать некоторые из моих токенов отправителю (запуская весь код в браузере Remix, я создаю экземпляр контракта на продажу и вызываю «запасной» метод с указанием некоторого количества эфира). Однако это не удается с «Исключением во время выполнения. (Недопустимый код операции). Пожалуйста, отладьте транзакцию для получения дополнительной информации». сообщение. Все, что я вижу при отладке, - это то, что код не работает в оплачиваемом методе в строке:

 token.transfer(msg.sender, 1);

Я не вижу точной причины этого, поскольку я не могу войти в этот метод и посмотреть, что происходит внутри.

Интересно то, что когда я удаляю вызов метода передачи в экземпляре токена в конструкторе контракта на продажу, код, кажется, работает нормально без каких-либо исключений.

Что мне не хватает?


person slash686    schedule 06.09.2017    source источник
comment
Являются ли функция MyToken (uint _totalSupply) и функция Sale () конструкторами для этих двух контрактов? Разрешен ли этот синтаксис? Мне нужно вкратце прочитать документы (docs.soliditylang.org/en/v0. 5.3 / contract.html), и я не могу найти место, где конструктор можно было бы заменить функцией с тем же именем, что и контракт. Можете ли вы заменить эти две функции конструкторами, как определено на странице, на которую я ссылаюсь, а затем попробуйте еще раз, чтобы узнать, есть ли у вас эта ошибка или нет.   -  person falopsy    schedule 20.07.2021


Ответы (2)


Я отлаживал контракт с помощью remix, и неверный код операции выбрасывается:

290 DUP8
291 DUP1
292 EXTCODESIZE
293 ISZERO
294 ISZERO
295 PUSH2 012f
298 JUMPI
299 PUSH1 00
301 DUP1
302 INVALID

Остальное я пропустил, но по сути он загружает адрес контракта токена и вызывает EXTCODESIZE, который извлекает размер кода контракта и проверяет, не равен ли он 0 (контракт токена существует), к сожалению, он равен 0. На На данный момент я не уверен, является ли это ограничением ремикса или я неправильно понял настройку.

Я попробовал аналогичную настройку контракта на truffle + testrpc, и он развернулся, успешно принял валюту. Однако обратите внимание, что testrpc указал:

Gas usage: 59137

Это означает, что это превышает значение sendTransaction по умолчанию без данных по умолчанию (21000 единиц газа). Это означает, что в реальной среде убедитесь, что вы проинформировали пользователей о необходимости добавить дополнительный газ, в противном случае функция отката, вероятно, не сработает из-за ошибок OOG.

person Yao Sun    schedule 08.09.2017

Причина в том, что вы используете резервную функцию. Попробуйте использовать обычную функцию, и это должно произойти.

person Abhimanyu Sareen    schedule 11.03.2021