Laden Sie die öffentlichen Werte eines anderen bereitgestellten Vertrags

Pragma Solidität ^0.4.24;

Ich versuche, die Funktionen eines anderen Vertrags aufzurufen, um Werte zurückzugeben.

Ich habe das Folgende, das erfolgreich ein Wahr/Falsch zurückgibt

_childAddress.call(bytes4(keccak256("isValidChild(uint256, uint256)")), _childModule6, 6) == true)

Aber wenn ich versuche, einen tatsächlichen Wert wie folgt zurückzugeben:

uint256 tokenId = _childAddress.call(bytes4(keccak256("totalSupply()")));

Ich bekomme folgenden Fehler:

Typ bool ist nicht implizit in den erwarteten Typ uint256 konvertierbar. Token-ID

Ich kann die Syntax nirgendwo finden, um einen Wert zurückzugeben.

Jede Hilfe geschätzt.

Sie sollten den relevanten Code von jedem dieser Verträge teilen, da niemand hier erraten kann, was es ist!
fügen Sie bitte mehr Code hinzu und verwenden Sie Trüffel, da Remix nicht immer wie erwartet funktioniert

Antworten (2)

Mit Solc v0.5 wird die Signatur von callgeändert, es gibt ein Tupel zurück (bool, bytes). Der erste Parameter gibt an, ob der Aufruf erfolgreich war und der zweite Parameter ist das Ergebnis der Funktion.

    bool success;
    bytes memory result;
    uint totalSupply;

Führen Sie den Aufruf mit aus, abi.encodeWithSignatureum Parameter und Funktionssignaturen zu codieren

    (success, result) = childContract.call(abi.encodeWithSignature("totalSupply()"));
    if (success) {

Wenn der Aufruf erfolgreich war, entschlüsseln Sie das Ergebnis der Funktion

        (totalSupply) = abi.decode(result, (uint));
        return totalSupply;
    }

Mit v0.4 erstellen Sie entweder eine Schnittstelle für Ihren untergeordneten Vertrag oder verwenden assembly, um den vom Aufruf zurückgegebenen Wert abzurufen.

Die andere Antwort ist richtig und auch weit verbreitet. Wenn Sie dies jedoch tun, address.callerlaubt der Compiler nicht, die Funktion als zu markieren, viewselbst wenn Sie nur den Wert lesen. Das liegt daran, dass address.calles auch zum Schreiben des Zustands verwendet werden könnte.

wenn Sie möchten, dass eine viewFunktion mit einem Low-Level-Aufruf totalSupply()dies tut

function readTotalSupply() external view returns(uint) {
    (, bytes memory data) = childContract.staticcall(abi.encodeWithSignature("totalSupply()"));
    return abi.decode(data, (uint));
}