使 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)
}
- 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...))
由于存储上下文,它不起作用
我的问题是:
- 是否可以使用接口进行委托调用?类似的东西:
(bool success, bytes memory data) = IMasterchef(masterchef).delegatecall(abi.encodeWithSignature("harvest(uint256,address)",i,_user));
- 你知道任何让 msg.sender = MyContractHarvestAll 的调用者的技巧吗?
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
),否则无法绕过此逻辑。
我正在尝试制作一个从 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...))
由于存储上下文,它不起作用
我的问题是:
- 是否可以使用接口进行委托调用?类似的东西:
(bool success, bytes memory data) = IMasterchef(masterchef).delegatecall(abi.encodeWithSignature("harvest(uint256,address)",i,_user));
- 你知道任何让 msg.sender = MyContractHarvestAll 的调用者的技巧吗?
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
),否则无法绕过此逻辑。