Wie ein Ergebnis wiederhergestellt wird, das durch Aufrufen einer Funktion eines anderen Vertrags zurückgegeben wird

Ich möchte ein Ergebnis wiederherstellen, das von einem Aufruf an eine Funktion eines anderen Vertrags in meinem Vertrag zurückgegeben wird. Mein Soliditätscode ist unten, ich habe

contract A {
    function verifyUser(address userAddress) public returns(bool) {
        bool verified = false;
        uint id = userId[userAddress];
        if (id != 0) {
            verified = true;
        }
        return verified;
    }
}

Ich habe den Assemblercode verwendet, um den zurückgegebenen Wert der Methode verifyUser von Vertrag A abzurufen

 contract B {
function verifAtt(uint idRequiredData, uint P, address userAddress) public returns (bool answer){
    answer=false;
    if(P==1) {
                bytes4 sig = bytes4(keccak256("verifyUser(address)"));
                assembly {
                    // move pointer to free memory spot
                    let ptr := mload(0x40)
                    // put function sig at memory spot
                    mstore(ptr,sig)
                    // append argument after function sig
                    mstore(add(ptr,0x04), userAddress)

                    let result := call(
                      15000, // gas limit
                      sload(dc), // to addr. append var to _slot to access storage variable
                      0, // not transfer any ether
                      ptr, // Inputs are stored at location ptr
                      0x24, // Inputs are 36 bytes long
                      ptr,  //Store output over input
                      0x20) //Outputs are 32 bytes long
                    if eq(result, 0) {
                       revert(0, 0)
                    }
                    answer := mload(ptr) // Assign output to answer var
                    mstore(0x40,add(ptr,0x24)) // Set storage pointer to new space
                }
            }
        }
return answer
}

Ich habe die Funktion verifyUser von Vertrag B getestet und das Ergebnis ist immer wahr, auch wenn das Ergebnis falsch sein muss. Ich möchte sicher sein, dass der Assembler-Code richtig ist.

Ich arbeite mit Remix und Solidity 0.4.16

Antworten (1)

Am besten tust du:


verified = A(dc).verifyUser(userAddress);

Das A(dc)erstellt keine neue Instanz. Es wirft die dcAdresse in einen AVertrag.

Sie müssen es so machen, weil es das des Anrufs callzurückgibt , zB ob es mit einem oder einem endete . Sie können die Rückgabedaten erhalten, wenn Sie eine ausführen , aber es erfordert die Verwendung von Solidity Assembly.successreturnrevert/assertcall


Außerdem sollte man sich gut überlegen, was man mit dem macht for. Das ist sehr gefährlich. Ihre Transaktion kann nicht mehr Gas als das Blockgaslimit verbrauchen. Wenn Ihr Array also zu groß ist, schlägt der Funktionsaufruf immer fehl.

Als allgemeine Regel sollten alle Ihre Funktionen in O(1).