Smart Contract-Ereignis, das „Uncaught TypeError: contract_instance.NumberIsIncreased is not a function“ anzeigt

Meine Funktion ist:

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);
                    }
                });

            }

Das ist der Vertrag:

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


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

Obwohl ich auf andere Funktionen im Smart Contract zugreifen kann, wird beim Aufrufen des Ereignisses der Fehler angezeigt Uncaught TypeError: contract_instance.NumberIsIncreased is not a function.

Ich kann Ereignisse auch im Mist-Browser verfolgen.

Ich verwende die Geth-Version: 1.7.2-stable.

Bearbeiten 1:

Ich verwende die web3.js-Version:0.14.0

Andere funktionierende Funktionen:

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);
                            }
                        });
                    });
                });
            }

Meine Vertragsdatei:

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);
        }
    }

}
Welche Version von web3js verwendest du? Es kann erforderlich sein, etwas mehr Code bereitzustellen, z. B. die anderen Funktionen des Smart Contracts, auf die Sie zugreifen können.
@SteveJaxon, ich habe jetzt die anderen Funktionen und meine Solidity-Datei hinzugefügt.

Antworten (2)

Ereignisse sind keine Funktionen, die Sie außerhalb des Vertrages aufrufen können ( contract_instance.NumberIsIncreased()ist ungültig); Sie werden nur innerhalb einer Funktion im Smart Contract selbst aufgerufen. Wenn Sie aufrufen setMyNumber(), ruft diese Funktion das Ereignis auf, und das Ereignis wird im Transaktionsobjekt protokolliert, das durch den Aufruf zurückgegeben wird setMyNumber.

Ereignisse werden normalerweise am Ende der Funktion und nach Zustandsänderungen aufgerufen, erst wenn die Berechnungen im Hauptteil der Funktion abgeschlossen und erfolgreich sind, um eine Protokollierung und Bestätigung zu ermöglichen, dass die Funktion erfolgreich war.

Das Protokollieren von Ereignissen ermöglicht auch das Überwachen und Beobachten von Funktionen, die für einen Vertrag aufgerufen werden.

Als Nebenbemerkung würde ich eine Namenskonvention vorschlagen, bei der Ereignissen das Präfix „Log“ (dh „LogNumberIsIncreased“) vorangestellt wird, um eine einfachere Lesbarkeit des Codes zu ermöglichen und es klarer zu machen, wenn Sie Ereignisse aufrufen. Dies ist besonders hilfreich, wenn Ihre Verträge komplexer werden und Sie immer mehr Ereignisse protokollieren.

Eine weitere empfohlene bewährte Methode: Das Aufrufen des Ereignisses sollte zuletzt erfolgen, dh nachdem Sie die Nummer festgelegt haben myNumber = myNewNumber. Möglicherweise benötigen Sie eine temporäre Variable myOldNumber. In diesem Beispiel könnte es in Ordnung sein, denn wenn das Festlegen der Nummer fehlschlägt, würde die gesamte Funktion zurückgesetzt und das Ereignis nicht tatsächlich protokolliert (obwohl der Ereignisaufruf kommt, bevor die Nummer festgelegt wird). Aber als allgemeine Best Practice von „fail fast“, die wieder wichtiger wird, wenn Sie komplexere Verträge schreiben, sollten Schritte, die fehlschlagen könnten (hier Ändern der Nummer / Ändern des Status), an erster Stelle stehen. Wenn diese Operation aus irgendeinem Grund fehlschlägt, müssen Sie durch Aufrufen des Ereignisses nach der Operation keine Berechnung verschwenden oder unnötige Schritte ausführen (Ereignis protokollieren), da die Funktion fehlschlagen würde, bevor diese jetzt unnötige Berechnung erreicht wird.

Nach solidity.readthedocs.io/en/develop/contracts.html#events möchte ich eine Überwachung für mein Ereignis hinzufügen. Die Methode, der ich gefolgt bin, ähnelt der, die dort vorhanden ist. Bitte werfen Sie einen Blick auf den Solidity-Code und verwenden Sie die in der Dokumentation angegebene JavaScript-API. Auch danke für die Vorschläge, ich bin ein Neuling und lerne von überall, wo ich kann.

Da jemand diesen Fehler auch bekommen hat, beantworte ich meine eigene Frage.

Das Problem hier wurde also gelöst, als ich meine Verträge neu erstellte.

truffle migrate --reset --all

Und in der Metamaske können Sie das Konto zurücksetzen.

Danach bekam ich die Ereignisprotokolle. Sie sollten Ihre Ereignisse in Ihrer Vertragsinstanz auch in der Truffle-Konsole sehen können.