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?
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:
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 .
Juan Ignacio Pérez Sakristán