Cómo recuperar un resultado devuelto llamando a una función de otro contrato

Quiero recuperar un resultado devuelto por una llamada a una función de otro contrato en mi contrato. Mi código de solidez está abajo, tengo

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

Utilicé el código ensamblador para obtener el valor devuelto por el método de verificación del usuario del contrato A.

 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
}

Probé la función verificar usuario del contrato B y el resultado siempre es verdadero, incluso si el resultado debe ser falso. Quiero estar seguro de que el código ensamblador es correcto.

trabajo con remix y solidity 0.4.16

Respuestas (1)

Sería mejor que hicieras:


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

El A(dc)no está creando una nueva instancia. Es arrojar la dcdirección a un Acontrato.

Tienes que hacerlo así porque calldevolverá el successde la llamada, por ejemplo, si terminó con un returno un revert/assert. Puede obtener los datos de retorno si hace un call, pero requiere el uso de un ensamblaje de solidez.


Además de eso, debe pensar dos veces sobre lo que está haciendo con el archivo for. Esto es algo muy peligroso de hacer. Su transacción no puede usar más gas que el límite de gas del bloque. Entonces, si su matriz es demasiado grande, la llamada a la función siempre fallará.

Como regla general, todas sus funciones deben completarse en O(1).