使 msg.sender 可用于外部合同

Making msg.sender available for external contract

我正在尝试制作一个从 dAPP 中获取所有奖励的函数。

function harvest(uint256 pid,address to)...{
     UserInfo storage user = userInfo[pid][msg.sender];
     .............
     token.safeTransfer(to, value)
}
function myFunction(address _user) ...{
.....
for(i < maxPid){
   IMasterchef(masterchef).harvest(i, _user); 
}
....
}

如您所见,每当我调用 .harvest() 函数时,它都会检查 msg.sender,在我的例子中是 MyContractToHarvestAll。这是一个错误,因为 harvest() 函数永远不会找到任何关于真实 msg.sender(MyContractToHarvestAll 的调用者)的信息。

如果我尝试:

 contract.delegateCall(abi...(harvest...))  

由于存储上下文,它不起作用


我的问题是:

(bool success, bytes memory data) = IMasterchef(masterchef).delegatecall(abi.encodeWithSignature("harvest(uint256,address)",i,_user));

there is a possibilty to make a delegateCall using interfaces

目前 (v0.8) 无法在接口上使用。您需要使用 address 类型

的(低级)delegatecall 成员
(bool success, bytes memory data) =  masterchef.delegatecall(
    abi.encodeWithSignature("harvest(uint256,address)", i, _user)
);

Do you know any tips to make msg.sender = the caller of MyContractHarvestAll?

通过使用delegatecall。但是随后 EVM 使用代理 (MyContractToHarvestAll) 的存储 - 而不是目标 (Contract to harvest) 的存储。

设计上不可能让 msg.sender 的原始调用者通过代理传递,并同时使用目标的存储。

注意:原始调用者存储在已弃用的 tx.origin 全局变量中。但是除非您能够修改 Contract to harvest(使用 tx.origin 而不是 msg.sender),否则无法绕过此逻辑。