Il Blog di Shift

Pensieri e parole dal mondo dell'informatica

Vertrag überschreiben

Ein Vertrag kann höchstens eine Fallback-Funktion haben, die mit Fallback () extern [zahlbar] (ohne das Funktionsschlüsselwort) deklariert wird. Diese Funktion kann keine Argumente haben, kann nichts zurückgeben und muss über externe Sichtbarkeit verfügen. Sie wird bei einem Aufruf des Vertrags ausgeführt, wenn keine der anderen Funktionen mit der angegebenen Funktionssignatur übereinstimmt oder wenn überhaupt keine Daten angegeben wurden und keine Empfangene Ether-Funktion vorhanden ist. Die Fallback-Funktion empfängt immer Daten, aber um auch Ether zu erhalten, muss sie als zahlbar markiert werden. Vor Version 0.4.17 hat der Compiler nicht erzwungen, dass pure den Status nicht liest. Es handelt sich um eine Typprüfung zur Kompilierungszeit, die umgangen werden kann, indem ungültige explizite Konvertierungen zwischen Vertragstypen durchgeführt werden, da der Compiler überprüfen kann, ob der Typ des Vertrags keine Statusänderungsvorgänge ausführt, aber er kann nicht überprüfen, ob der Vertrag, der zur Laufzeit aufgerufen wird, tatsächlich von diesem Typ ist. Vererbung wird häufig verwendet, um die Funktionalität des übergeordneten Vertrags zu Ihrem eigenen Vertrag hinzuzufügen, aber das ist nicht alles, was es tun kann. Sie können auch ändern, wie sich einige Teile des übergeordneten Elements mit Außerkraftsetzungen verhalten. Die meisten OpenZeppelin-Verträge sollen über Erbschaft verwendet werden: Sie erben von ihnen, wenn Sie Ihre eigenen Verträge schreiben. Fügen Sie den vertragsskripthash, der im letzten Schritt in ScriptHash kopiert wurde, in ScriptHash ein, und drücken Sie die Suchtaste.

Relevante Vertragsinformationen werden automatisch angezeigt. Während externe Aufrufe an öffentliche oder externe Bibliotheksfunktionen möglich sind, wird die Aufrufkonvention für solche Aufrufe als intern in Solidity betrachtet und nicht als die gleiche, wie für den regulären Vertrag ABI angegeben. Externe Bibliotheksfunktionen unterstützen mehr Argumenttypen als externe Vertragsfunktionen, z. B. rekursive Strukturen und Speicherzeiger. Aus diesem Grund werden die Funktionssignaturen, die zum Berechnen des 4-Byte-Selektors verwendet werden, nach einem internen Benennungsschema berechnet, und Argumente von Typen, die im Vertrag ABI nicht unterstützt werden, verwenden eine interne Codierung. Genauer gesagt beginnt der Laufzeitcode einer Bibliothek immer mit einer Push-Anweisung, die zur Kompilierungszeit eine Null von 20 Bytes beträgt. Wenn der Bereitstellungscode ausgeführt wird, wird diese Konstante im Arbeitsspeicher durch die aktuelle Adresse ersetzt, und dieser geänderte Code wird im Vertrag gespeichert. Zur Laufzeit wird die Bereitstellungszeitadresse die erste Konstante sein, die auf den Stapel übertragen wird, und der Dispatchercode vergleicht die aktuelle Adresse mit dieser Konstante für jede nicht-ansichts- und nicht rein-funktion.

Im Vergleich zu Verträgen sind Bibliotheken auf folgende Weise eingeschränkt: Die Konstruktoren aller Basisverträge werden nach den unten erläuterten Linearisierungsregeln aufgerufen. Wenn die Basiskonstruktoren Argumente haben, müssen abgeleitete Verträge alle von ihnen angeben. Dies kann auf zwei Arten erfolgen: Eine Möglichkeit, Verträge programmgesteuert auf Ethereum zu erstellen, ist über die JavaScript API web3.js. Es hat eine Funktion namens web3.eth.Contract, um die Vertragserstellung zu erleichtern. Bei mehrfacher Vererbung müssen die am häufigsten abgeleiteten Basisverträge, die dieselbe Funktion definieren, nach dem Überschreibungsschlüsselwort explizit angegeben werden. Mit anderen Worten, Sie müssen alle Basisverträge angeben, die dieselbe Funktion definieren und noch nicht durch einen anderen Basisvertrag überschrieben wurden (auf einem Pfad durch das Vererbungsdiagramm). Wenn ein Vertrag dieselbe Funktion von mehreren (nicht verwandten) Basen erbt, muss er sie explizit überschreiben: Es ist möglich, Funktionen weiter oben in der Vererbungshierarchie intern aufzurufen, indem der Vertrag explizit mit ContractName.functionName() angegeben wird oder wenn Sie die Funktion eine Ebene höher in der abgeflachten Vererbungshierarchie aufrufen möchten (siehe unten).

I commenti sono chiusi

Tema di Anders Norén