Soweit ich weiß, gibt es zwei Möglichkeiten, eine Funktion in einem anderen Vertrag aufzurufen.
1.) Verwendung der 4-Byte-Methoden-ID ----> address.call(bytes4(sha3('foo()'))
2.) Verwendung der Vertrags-ABI ---> contractInstance.foo()
Ich habe mich gefragt, ob jemand erklären könnte, warum ein Anruf mit der bytes4-Methoden-ID nur einen Gasmangel anzeigen kann, während ein Anruf mit dem ABI tatsächliche Werte zurückgeben kann. Ich vermute, es hat etwas mit dem ABI zu tun, aber ich würde gerne verstehen, was hier unter der Haube vor sich geht. Vielen Dank.
Ich bin mir nicht sicher, was Sie meinen, wenn Sie die Vertrags-ABI innerhalb eines Vertrags verwenden. Ich denke, Sie meinen, wenn wir einen Vertrag in einen anderen Vertrag importieren und auf eine Instanz davon zugreifen, indem wir einen Verweis darauf erstellen, z contractInstance = externalContract(contractAddress)
.
Letztendlich gibt es Rückgabewerte, wenn wir einen Vertrag importiert haben, weil wir bei der Kompilierung wissen, welche Art und Größe von Daten jeder Funktionsaufruf zurückgeben wird. Wir können dann die Rückgabedaten in den richtigen Variablentyp einfügen. Wenn wir jedoch eine Funktion direkt auf einer Adresse aufrufen, wissen wir nicht, welche Art und Größe die Rückgabewerte haben, da diese Details nicht in der Blockchain gespeichert werden. Die Funktion gibt nur Rohdaten zurück. Das bedeutet, dass wir nicht wissen, in welcher Art von Variable der Rückgabewert nach dem Aufruf dieser Funktion gespeichert werden soll, also ist es einfach nicht erlaubt.
Als Randnotiz können Sie seit dem Byzantium-Fork tatsächlich Rückgabewerte erhalten, address.call()
wenn Sie einige Assembler-Anweisungen direkt danach ausführen. Insbesondere die returndatacopy()
Anweisung, die im Dokument zu sehen ist . Und eine Beispielverwendung ist in einem aktualisierbaren Proxy-Vertrag zu sehen, den ich geschrieben habe (Beachten Sie, dass das Beispiel den Delegiertenruf verwendet, sich aber genauso verhalten sollte wie die Verwendung von Anruf). Dieser Ansatz gibt immer noch nur Rohdaten zurück und erstellt keine Art von Variable, in der sie leben können.
sind
sind
willjgriff