Während der Vertragsausführung aufgetretener Fehler [Ungültiges Sprungziel]

Beim Aufruf zur start()Funktion in einem Smart Contract schlägt die Transaktion mit dieser Meldung fehl:

Warnung! Während der Vertragsausführung aufgetretener Fehler [Ungültiges Sprungziel]

Laut Error While Token Contract Execution ... generiert ein ungültiger Array-Index definitiv diese Meldung. Also habe ich darüber nachgedacht und versucht herauszufinden, wann mein Code einen ungültigen Index verwendet, aber ich kann ihn nicht finden.

Dies ist die angeforderte Methode:

function start(address seller, address thirdParty) returns (uint escrowId) {
    escrowId = numEscrows;
    numEscrows++;
    escrow e;
    e.thirdParty = thirdParty;
    e.seller = seller;
    e.buyer = msg.sender;
    e.amount = msg.value;
    e.recipient = seller;
    e.status = 1; // started

    escrows[escrowId] = e;

    return escrowId;
}

Das einzige Array dort ist escrows[]als deklariertmapping (uint => escrow) escrows;

Nachdem ich verschiedene Dinge ausprobiert hatte, kam ich zu dem Schluss, dass das Problem sicherlich in der letzten Zeile liegt:escrows[escrowId] = e;

Ist eine solche Zuordnung nicht möglich escrows[0] = e;? Warum nicht?

Was mache ich falsch? Wie kann ich es debuggen?

Antworten (1)

start(...)und start1(...)es gibt zwei Möglichkeiten, wie Sie Ihre Funktion so umschreiben können, dass sie wie erwartet funktioniert:

pragma solidity ^0.4.0;
contract Ballot {
    struct Escrow {
        address thirdParty;
        address seller;
        address buyer;
        uint amount;
        address recipient;
        uint status;
    }
    uint numEscrows;
    mapping (uint => Escrow) escrows;

    function start(address seller, address thirdParty) returns (uint escrowId) {
        escrowId = numEscrows;
        numEscrows++;
        Escrow memory e;
        e.thirdParty = thirdParty;
        e.seller = seller;
        e.buyer = msg.sender;
        e.amount = msg.value;
        e.recipient = seller;
        e.status = 1; // started

        escrows[escrowId] = e;

        return escrowId;
    }

    function start1(address seller, address thirdParty) returns (uint escrowId) {
        escrows[numEscrows].thirdParty = thirdParty;
        escrows[numEscrows].seller = seller;
        escrows[numEscrows].buyer = msg.sender;
        escrows[numEscrows].amount = msg.value;
        escrows[numEscrows].recipient = seller;
        escrows[numEscrows].status = 1; // started
        numEscrows++;
        return numEscrows;
    }
}

Und hier ist der Echtzeit-Compiler und der Runtime-Bildschirm von Solidity, der zeigt, dass sowohl start(...)als auch start1(...)ausgeführt werden, ohne eine Ausnahme auszulösen:

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass es start1(...)weniger Benzin kostet als start(...).

In start(...)habe ich das Schlüsselwort „ Memory “ hinzugefügt – siehe Was ist das Schlüsselwort „Memory“? Was tut es? , Unterschied zwischen Arbeitsspeicher und Speicher? und Was macht das Schlüsselwort "Memory" genau? Für weitere Informationen.

In Ihrer Frage erwähnten Sie "Das einzige Array, das escrows [] gibt, das als mapping (uint => escrow) escrows; deklariert ist". Beachten Sie, dass sich Arrays von Mappings unterscheiden – siehe Arrays vs. Mappings und Store data in mapping vs. array .

Der Merkerspeicher scheint alle meine Probleme gelöst zu haben. Danke!