0

I want to recuperate a result returned by a call to a function of another contract in my contract. My solidity code is bellow, I have

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

I used the assembly code to get the returned value of the verifyUser method of contract 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
}

I tested the function verifyUser of contract B and the result is always true even if the result must be false. I want to be sure that the assembly code is right.

I work with remix and solidity 0.4.16

1 Answer 1

2

You would be better off doing:


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

The A(dc) is not creating a new instance. It casting the dc address to an A contract.

You have to do it like this because call will return the success of the call, e.g. whether it ended with a return or a revert/assert. You can get the return data if you do a call, but it requires using solidity assembly.


Beside that, you should think twice about what you are doing with the for. This is a very dangerous thing to do. Your transaction cannot use more gas than the block gas limit. So if your array is too big then the function call will always fail.

As a general rule, all your functions should complete in O(1).

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.