Inside view
method it's not possible to do delegatecall
due to compilation errors. Is there any way to delegate view calls?
1 Answer
UPDATE: Check out my new answer with 2 different solutions to the similar issue here: https://ethereum.stackexchange.com/a/142712/3032
Yep, but it is tricky:
pragma solidity ^0.5.0;
contract D {
function g(uint256 a) public view returns(uint256) {
return a*2;
}
}
contract A {
D public impl;
constructor() public {
impl = new D();
}
function() external {
require(msg.sender == address(this));
(bool success, bytes memory data) = address(impl).delegatecall(msg.data);
assembly {
switch success
// delegatecall returns 0 on error.
case 0 { revert(add(data, 32), returndatasize) }
default { return(add(data, 32), returndatasize) }
}
}
function f(uint256 a)
public
view
returns(uint256)
{
(bool success, bytes memory data) = address(this).staticcall(
abi.encodeWithSelector(
impl.g.selector,
10
)
);
assembly {
switch success
// delegatecall returns 0 on error.
case 0 { revert(add(data, 32), returndatasize) }
default { return(add(data, 32), returndatasize) }
}
}
}
-
1A static call is different from a delegate call, for example delegate doesn't change msg.sender and static call does change it.– Ismael ♦Commented Apr 10, 2020 at 17:05
-
Ismael's point is a good one. This pattern works as long as the delegatecall isn't invoking a method where calling context (msg.sender, msg.value, etc.) matters. Otherwise that context will be lost when the staticcall happens. Commented May 26, 2022 at 23:29