I am trying to call a library function using assembly and the delegatecall opcode. The library function accepts two parameters, the state object storage pointer and an address, it returns a single uint.
I can tell if the op fails because the data at in_pos is untouched, however when it does work it always returns zero even if the function being called simply returns a 0x01 value.
state
is a struct that is shared by the calling contract and the library, its position is 0
address t = 0xTargetLibraryAddress; address a = 0xAccount; bytes32 result; assembly { let in_pos := mload(0x40) mstore(in_pos, 0x12345678) //a valid func sig within the library mstore(add(in_pos, 0x04), state) mstore(add(in_pos, 0x24), a) let success := delegatecall(sub(gas, 10000), t, in_pos, 0x44, in_pos, 0x20) result := mload(in_pos) mstore(0x40, add(in_pos, 0x44)) }
Any suggestions?
Best Answer
From what I can gather
mstore()
will write in 32 byte chunks, thereforemstore(in_pos, 0x04)
is still in the same space as in_pos and will overwrite the 4 bytes function signature.What I ended up doing is writing the 4 bytes in the first 32 bytes, the 1st arg in the 2nd 32 bytes and the 2nd arg in the 3rd 32 bytes, then called delegatecall pointing to the start of the 4 byte signature by using a 28 byte offset.
delegatecall(sub(gas, 1000), t, add(in_pos, 28), 0x44, in_pos, 0x20)