我正在尝试制作一个从dAPP获取所有奖励的函数。
- 收获合同:
function harvest(uint256 pid,address to)...{
UserInfo storage user = userInfo[pid][msg.sender];
.............
token.safeTransfer(to, value)
}
- MyContractToHarvestAll:
function myFunction(address _user) ...{
.....
for(i < maxPid){
IMasterchef(masterchef).harvest(i, _user);
}
....
}
正如您所看到的,每当我调用。harvest()函数时,它都会检查msg。sender,在我的例子中是MyContractToHarvestAll。这是一个错误,因为harvest()函数永远不会找到关于真实msg的任何信息。sender (MyContractToHarvestAll的调用者).
如果我尝试:
contract.delegateCall(abi...(harvest...))
由于存储上下文
,它不起作用我的问题是:
- 是否有可能使用接口创建一个delegateCall ?像这样:
(bool success, bytes memory data) = IMasterchef(masterchef).delegatecall(abi.encodeWithSignature("harvest(uint256,address)",i,_user));
- 你知道制作味精的技巧吗?sender = MyContractHarvestAll的调用者?
可以使用接口
创建一个delegateCall
当前(v0.8)不支持在接口上。您需要使用address
类型
delegatecall
成员(bool success, bytes memory data) = masterchef.delegatecall(
abi.encodeWithSignature("harvest(uint256,address)", i, _user)
);
你知道什么制作味精的技巧吗?sender = MyContractHarvestAll的调用者?
通过使用delegatecall
。但是EVM使用代理(MyContractToHarvestAll
)的存储——而不是目标(Contract to harvest
)的存储。
在设计上不可能让原始调用者作为msg.sender
通过代理传递,同时使用目标的存储空间。
注意:原始调用者存储在已弃用的tx.origin
全局变量中。但是,除非您能够修改Contract to harvest
(使用tx.origin
而不是msg.sender
),否则无法绕过此逻辑。