Delegatecall can be used in either solidity or assembly.
In solidity, I can get it working with the following code:
bytes memory payload = abi.encodeWithSignature ("get_value(uint16,uint16)", var1, var2);
bool success;
bytes memory result;
(success, result) = my_contract.delegatecall (payload);
The above code calls my_contract.get_value(var1, var2)
.
How can I do the same thing in assembly? The function is defined like this:
delegatecall (gas, address, in, insize, out, outsize)
If I am in an assembly block, assuming address
is supposed to be the address of the contract that contains the function being called, how would it ever know which function I intend to call? When I do it using solidity, it knows this from the encoded payload data that I pass into it. But the assembly function only takes an address. And it always returns 0.
I have not been able to find any good documentation for EVM assembly anywhere on the Internet.
EDIT: Below is one of the attempts I made, using an example from the Internet.
let freememstart := mload (0x40)
calldatacopy (freememstart, 0, calldatasize ())
success := delegatecall (not (0), my_contract, freememstart, calldatasize (), freememstart, 32)
EDIT 2: Another attempt I made, not using calldatacopy.
bytes memory payload = abi.encodeWithSignature ("get_value(uint16,uint16)", var1, var2);
uint payload_size = payload.length * 8;
assembly
{
let freememstart := mload (0x40)
mstore (0x40, add (freememstart, payload_size))
mstore (freememstart, payload)
let output := mload (0x40)
mstore (0x40, add (output, 0x20))
success := delegatecall (not (0), contract_addr, freememstart, payload_size, output, 0x20)
}