Geth + функция смарт-контракта = плохая инструкция

Играя со смарт-контрактами Ethereum, я столкнулся со следующей проблемой. Контракт развертывается на Ropsten, а затем я пытаюсь вызвать функцию addRecipe со следующим кодом на geth:

recipes.addRecipe(300, "zupa", "zupa z trupa", {from:web3.eth.accounts[0], gas: 20000000})

Функция выглядит следующим образом:

function addRecipe(uint256 _price, string _name, string _content) public {

    recipes[recipeCount].price = _price;
    recipes[recipeCount].name = _name;
    recipes[recipeCount].content = _content;
    recipes[recipeCount].recipeOwner = msg.sender;

    recipeCount++;
}

Я получаю хэш TX, но поиск транзакции в Etherscan дает

 Warning! Error encountered during contract execution [Bad instruction] 

Вы можете проверить его здесь: https://ropsten.etherscan.io/tx/0xe5999c2d122e4871e82f5986397dfd39107cee2056a9280132abeaa460c0f66d

Добавление к функции модификатора payable или использование следующей команды не дает лучших результатов ...

recipes.addRecipe.sendTransaction(300, "zupa", "zupa z trupa", {from:web3.eth.accounts[0], gas: 200000000})

Весь контракт:

pragma solidity ^0.4.24;

contract Recipes {

    address owner;
    uint256 recipeCount = 0;

    struct Recipe {
        string name;
        string content;
        uint256 price;
        address recipeOwner;
    }

    Recipe[] public recipes;

    function () public {
        owner = msg.sender;
    }

    function kill() public {
        require (msg.sender == owner);
        selfdestruct(owner);
    }


    function addRecipe(uint256 _price, string _name, string _content) public {

        recipes[recipeCount].price = _price;
        recipes[recipeCount].name = _name;
        recipes[recipeCount].content = _content;
        recipes[recipeCount].recipeOwner = msg.sender;

        recipeCount++;
    }

    function showRecipes(uint256 _id) constant returns(string) {

        return recipes[_id].content;

    }

}

person Kamil Gorski    schedule 03.07.2018    source источник


Ответы (1)


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

function addRecipe(uint256 _price, string _name, string _content) public {
    recipes.length++;
    recipes[recipeCount].price = _price;
    recipes[recipeCount].name = _name;
    recipes[recipeCount].content = _content;
    recipes[recipeCount].recipeOwner = msg.sender;

    recipeCount++;
}

Or

function addRecipe(uint256 _price, string _name, string _content) public {
    Recipe memory r;
    r.price = _price;
    r.name = _name;
    r.content = _content;
    r.recipeOwner = msg.sender;

    recipes.push(r);

    recipeCount++;
}
person Adam Kipnis    schedule 03.07.2018
comment
Ах, ладно :), поэтому добавление еще одного элемента массива путем простого увеличения числа не даст ожидаемых результатов. Спасибо! Есть ли способ прочитать точную ошибку из geth или etherscan? Узел майнера должен возвращать ошибку при выполнении этого кода (?) Большое спасибо! - person Kamil Gorski; 03.07.2018