[Ethereum] Solidity assembly function call parameter alignment

assemblysolidity

I am trying to call a function using assembly. The called
function has address parameters. How to use address in assembly call?

Called function example:

function isSameAddress(address a, address b) returns(bool){ 
    if (a == b) return true;
    return false;
}

Best Answer

Couldn't find an answer so ran following example in remix. while reusing code from here. And conclusion is, address should be padded to 32 bytes.

pragma solidity 0.4.18;


contract TestAddress {

    function isSameAddress(address a, address b) returns(bool){  //Simply add the two arguments and return
        if (a == b) return true;
        return false;
    }

    function() public {  //If the function signature doesn't check out, return -1
        revert();
    }
}

contract TestAllignment {
    TestAddress test;

    function TestAllignment(){  //Constructor function
        test = new TestAddress();
    }

    function testAsem() public view returns (bool same) {
        address contractAddr = address(test);  
        bytes4 sig = bytes4(keccak256("isSameAddress(address,address)")); //Function signature
        address a = msg.sender;

        assembly {
            let x := mload(0x40)   //Find empty storage location using "free memory pointer"
            mstore(x,sig) //Place signature at begining of empty storage 
            mstore(add(x,0x04),a) // first address parameter. just after signature
            mstore(add(x,0x24),a) // 2nd address parameter - first padded. add 32 bytes (not 20 bytes)
            mstore(0x40,add(x,0x64)) // this is missing in other examples. Set free pointer before function call. so it is used by called function.
             // new free pointer position after the output values of the called function.

            let success := call(      
                            5000, //5k gas
                            contractAddr, //To addr
                            0,    //No wei passed
                            x,    // Inputs are at location x
                            0x44, //Inputs size two padded, so 68 bytes
                            x,    //Store output over input
                            0x20) //Output is 32 bytes long

            same := mload(x)       //Assign output value
            mstore(0x40,add(x,0x20)) // Set storage pointer to empty space
        }

        return same;
    }

    function testSol() public view returns(bool same){ //Make sure the Test1 function works properly
        address add = msg.sender;

        same = test.isSameAddress(add,add); 
    }
}

Thanks to Tjaden for the code example.

Related Topic