我正在尝试制作一个中继智能合约,它可以在另一个已部署的智能合约的函数调用中传递
msg.value
和 msg.sender
。
背景:目标是通过一个主要智能合约铸造/借用多个 DeFi 协议(部署且不属于我的合约),从而只需要一个钱包来处理。这意味着资金 (
msg.value
?) 和所有者 (msg.sender
?) 在调用交易的函数内转移到 DeFi 智能合约。
EOA = 带有一点 ETH 用来支付费用的钱包
Relay = 中继智能合约,必须从 DeFi 智能合约接收资金(= 作为
msg.sender
?)
proxyDeFi = 代理智能合约,允许在一笔交易中向一个或多个 DeFi 智能合约发送多个请求
在我看来,
delegatecall
允许在执行另一个智能合约的函数时传递msg.sender
和msg.value
,所以我到目前为止所做的:
代理 DeFi 在被 EOA 调用时按预期工作,但代理 DeFi 是查询的 DeFi 智能合约的
msg.sender
,而不是 EOA。
我们需要几个可以经常更新的代理合约,所以我尝试做一个简单的中继:
contract Relay {
address public proxyDeFi;
address owner = msg.sender;
modifier isOwner() {
require(msg.sender == owner, "Forbidden");
_;
}
function update(address newAddress) isOwner public {
proxyDeFi = newAddress;
}
fallback() isOwner external payable {
proxyDeFi.delegatecall(msg.data);
}
}
我尝试将 proxyDeFi 的功能调用到 Relay(带有 EOA),但交易在
deletegateCall
上被系统还原。我尝试在 proxyDefi 端添加调试,但没有任何输出,我是 Solidity 新手,所以肯定有一些我不明白的地方。
粗略地说,我希望 proxyDeFi 只被视为中继的库,但 proxyDeFi 将是部署的另一个智能合约,以便我们可以修改它而无需重新部署中继。我有一种感觉,我想要实现的目标实际上比这更复杂,或者我的方法可能不是正确/最好的。我非常感谢您的建议。
当您调用合约到合约交互时,
msg.sender
是调用合约,如果您希望它获取初始化交易的人的地址,您可以使用tx.origin
。
小心,使用委托调用,如果使用不当,会存在一些漏洞,因为它调用函数并更新存储在调用合约上的数据。
您应该参考 OpenZeppelin 的代理合约(https://docs.openzeppelin.com/contracts/5.x/api/proxy)以确保其安全正确地工作。 在部署到主网之前请仔细检查。