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
Am besten tust du:
verified = A(dc).verifyUser(userAddress);
Das A(dc)
erstellt keine neue Instanz. Es wirft die dc
Adresse in einen A
Vertrag.
Sie müssen es so machen, weil es das des Anrufs call
zurü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.success
return
revert/assert
call
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)
.