Korrekte Behandlung von Anforderungs-/Assert-Fehlern in einer Node.JS-App?

Ich habe eine Getter-Funktion in meinem Smart Contract, die einen der String-Werte in einem statisch definierten String-Array zurückgibt. Beim Aufrufen der Funktion führt sie eine Begrenzungsprüfung des eingehenden Index mit durch require(). Wenn die Begrenzungsprüfung fehlschlägt, was passiert in meiner Node.JS-App, die Web3.js verwendet hat , um den Aufruf zu tätigen? Wird ein Javascript-Fehler ausgegeben? Bekomme ich NULL zurück?

Wenn jemand einen guten Artikel oder eine gute Webressource hat, die zeigt, wie Fehler aus einem Web3.JS-Aufruf richtig behandelt werden, die dazu führten, dass auf der Smart-Contract-Seite eine Assert- oder Require -Operation ausgelöst wurde, teilen Sie sie bitte mit.

Hier ist mein Smart-Contract-Code:

pragma solidity ^0.4.23;

import "github.com/OpenZeppelin/zeppelin-solidity/contracts/ownership/Ownable.sol";

contract VideoDummyData is Ownable{

    // Constructor, MUST be public.
    constructor() public {
        // Unused.
    }

    // Array of sample video IDs.
    string[3] m_aryVideoIds = 
        ["ZUSPD9zOyJs", "4nqJiBRNQuw", "PLcxE4UkJt0"];


    // Return one of the sample video IDs.
    function getVideoIdAt (uint ndx) public view returns(string)
    {
        // Bounds check on the desired index.
        require(ndx < m_aryVideoIds.length);

        return m_aryVideoIds[ndx];
    }
}
Sie erhalten nur einen Fehler von web3, aber Sie können nicht wissen, was der genaue Fehler ist.
@Andromelus - nicht bis zur nächsten Version von Solidity, wenn sie Ihnen erlauben, eine Fehlermeldung mit Assert/Revert zurückzugeben? Wenn ich damit richtig liege, wissen Sie, ob die Änderung sofort erfolgen wird, oder müssen wir warten, bis alle Knoten im Ethereum-Netzwerk die Änderung aktualisieren oder übernehmen (wie bei einem Soft Fork)?
Sie müssen nur die Transaktion abbauen. Der Knoten, mit dem Sie verbunden sind, muss also den Block kennen, in dem sich der TX befindet.
Dies ist ungefähr calleine viewFunktion, sodass keine Transaktion abgebaut werden muss.

Antworten (2)

Da Sie eine Funktion aufrufen view, wird der erste Rückruf mehr oder weniger sofort fehlschlagen.

Es ist derzeit möglich, Fehler mit zurückzugeben

require(expression, "error msg");

Die Herausforderung besteht darin, auf diese Nachricht weiter oben im Stapel in Web3 und Node zuzugreifen.

In der Zwischenzeit können Sie tryund .catch()in versprochenem Code wie einer Truffle-Contract-Abstraktion verwenden.

Sie werden den genauen Grund nicht kennen, aber Sie können ihn anhand der Vertragsanforderungen ableiten.

Ich hoffe es hilft.

Sobald Sie Methoden aufrufen/senden, werden sie aus welchem ​​Grund auch immer zurückgesetzt, Sie erhalten die folgende Antwort in Ihrem Express-/Nodejs-Code.

   {
    "data": {
        "0x926192b712005c4eab709b7f7e1718435b6f2117580360b73e7601a439feffcd": {
            "error": "revert",
            "program_counter": 383,
            "return": "0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000165468697320496420616c72656164792065786973747300000000000000000000",
            "reason": "This Id already exists"
        },
        "stack": "RuntimeError: VM Exception while processing transaction: revert This Id already exists\n    at Function.RuntimeError.fromResults (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\utils\\runtimeerror.js:94:13)\n    at BlockchainDouble.processBlock (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\blockchain_double.js:627:24)\n    at processTicksAndRejections (internal/process/task_queues.js:93:5)",
        "name": "RuntimeError"
    }
}

Hier müssen wir dem Benutzer nun eine entsprechende Nachricht zeigen, damit der Benutzer verstehen kann, dass wir den folgenden Code verwenden können. Um den Grund aus der zurückgegebenen Antwort zu erfahren. Verwenden Sie den folgenden Code im nodeJS/expressjs-Code....

try {
    await myContract.methods.foo().send();
} catch (e) {
    const data = e.data;
    const txHash = Object.keys(data)[0]; 
    const reason = data[txHash].reason;

    console.log(reason); 
}