Событие смарт-контракта, показывающее «Uncaught TypeError: contract_instance.NumberIsIncreased не является функцией»

Моя функция:

function watchEvents(){
                myEvent = contract_instance.NumberIsIncreased({},{fromBlock: 'latest', toBlock: 'latest'});
                console.log(myEvent);
                myEvent.watch(function(error, result){
                    if(error){
                        console.log(error);
                    } else{
                        console.log(result);
                        document.getElementById("events").innerHTML = document.getElementById("events").innerHTML + "<br />" + JSON.stringify(result);
                    }
                });

            }

Это контракт:

event NumberIsIncreased(address indexed whoIncreased, uint256 indexed oldNumber, uint256 indexed newNumber);


function setMyNumber(uint256 myNewNumber) public {
        NumberIsIncreased(msg.sender, myNumber, myNewNumber);
        myNumber = myNewNumber;
    }

Хотя я могу получить доступ к другим функциям смарт-контракта, когда я вызываю событие, оно показывает ошибку Uncaught TypeError: contract_instance.NumberIsIncreased is not a function.

Я также могу отслеживать события в браузере Mist.

Я использую версию geth: 1.7.2-stable.

Редактировать 1:

Я использую версию web3.js:0.14.0

Другие функции, которые работают:

function getCounter(){
                contract_instance.getMyNumber(function(e,r){
                    document.getElementById("myCounter").innerText = r.toNumber();
                });
            }

function increaseCounter(){
                contract_instance.getMyNumber(function(e,r){
                    currentNumber = r;
                    currentNumber++;
                    web3.eth.getAccounts(function(e,accounts){
                        web3.personal.unlockAccount(accounts,"password", function(e,r){});
                        contract_instance.setMyNumber(currentNumber, {from:accounts[0]  , gas:200000}, function(error, result){
                            if (error){
                                console.error(error);
                            } else {
                                var txHash = result;
                                console.log(txHash);
                                callWhenMined(txHash, getCounter);
                            }
                        });
                    });
                });
            }

Мой файл контракта:

pragma solidity ^0.4.0;

contract MyContract {
    address creator;
    uint256 myNumber;

    event NumberIsIncreased(address indexed whoIncreased, uint256 indexed oldNumber, uint256 indexed newNumber);

    function MyContract() public {
        creator = msg.sender;
        myNumber = 3;
    }

    function getCreator() public constant returns (address) {
        return creator;
    }

    function getMyNumber() public constant returns (uint256) {
        return myNumber;
    }

    function setMyNumber(uint256 myNewNumber) public {
        NumberIsIncreased(msg.sender, myNumber, myNewNumber);
        myNumber = myNewNumber;
    }


    function kill() public {
        if (msg.sender == creator) {
            selfdestruct(creator);
        }
    }

}
какую версию web3js вы используете? Возможно, потребуется предоставить дополнительный код, например, другие функции смарт-контракта, к которым у вас есть доступ.
@SteveJaxon, теперь я добавил другие функции и свой файл Solidity.

Ответы (2)

События не являются функциями, которые вы можете вызывать извне из-за пределов контракта ( contract_instance.NumberIsIncreased()недействительно); они вызываются только внутри функции самого смарт-контракта. При вызове setMyNumber()эта функция вызывает событие, и событие будет зарегистрировано в объекте транзакции, который возвращается при вызове setMyNumber.

События обычно вызываются в конце функции и после изменения состояния, только после того, как вычисления в основном теле функции завершены и успешны, чтобы обеспечить регистрацию и подтверждение успешного выполнения функции.

Регистрация событий также позволяет отслеживать и отслеживать функции, вызываемые в контракте.

С другой стороны, было бы предложено соглашение об именах событий с префиксом «Журнал» (т.е. «LogNumberIsIncreased»), чтобы обеспечить более удобочитаемость кода, делая его более понятным, когда вы вызываете события. Это особенно полезно, когда ваши контракты становятся все более сложными и вы регистрируете все больше и больше событий.

Еще одна рекомендуемая передовая практика: вызов события должен происходить последним, то есть после того, как вы установите номер myNumber = myNewNumber. Вам может понадобиться временная переменная myOldNumber. В этом примере это может быть нормально, потому что, если установить номер не удастся, тогда вся функция вернется в исходное состояние и фактически не зарегистрирует событие (даже если вызов события происходит до того, как номер будет установлен). Но в соответствии с общей передовой практикой «быстрого отказа», которая снова становится более важной, когда вы пишете более сложные контракты, шаги, которые могут привести к ошибке (здесь изменение числа / изменение состояния), должны быть первыми. Если по какой-либо причине эта операция завершится неудачей, вызывая событие после операции, вам не нужно будет тратить какие-либо вычисления или выполнять ненужные шаги (событие журнала), потому что функция завершится ошибкой, прежде чем достигнет этого теперь ненужного вычисления.

После solidity.readthedocs.io/en/develop/contracts.html#events я хочу добавить часы для своего мероприятия. Метод, которому я следовал, аналогичен тому, что там присутствует. Пожалуйста, ознакомьтесь с кодом Solidity и используйте его в JavaScript API, указанном в документации. Кроме того, спасибо за предложения, я новичок, учусь везде, где могу.

Поскольку кто-то также получил эту ошибку, я отвечаю на свой вопрос.

Так что проблема здесь была решена, когда я перестроил свои контракты.

truffle migrate --reset --all

А в метамаске можно сделать сброс аккаунта.

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