Storage
為什麼這個對 DSProxy 的呼叫會失敗?
以這兩個合約為例,它們都部署在 Kovan 上並驗證了原始碼:
並採取此交易:
哪個已恢復,我不明白為什麼。
我想呼叫
execute(address,bytes)
函式DSProxy
並傳入以下參數:
- 0xE3CD2e7a628b57d3e50c5f7B921182f676721bDF
- 0xb081b4eb(“wrapEth”函式的簽名)
- 還發送一些 ETH
有效地呼叫wrapEth中定義的應付函式
TargetContract
,但通過DELEGATECALLDSProxy
功能。在 ethers.js 的幫助下,我為這個多合約呼叫生成了 calldata,它看起來像這樣:
0x1cff79cd000000000000000000000000e3cd2e7a628b57d3e50c5f7b921182f676721bdf00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004b081b4eb00000000000000000000000000000000000000000000000000000000
不幸的是,當我通過 MetaMask、MyCrypto 或任何其他錢包將此呼叫數據轉發到 Kovan 測試網時,我收到了還原的交易。雖然我覺得上面的 calldata 是正確的,但我嘗試調整字節的最後一部分(函式簽名)以防 Ethers 中存在錯誤,但沒有運氣。
你能看到這裡的錯誤嗎?
DSProxy 使用delegatecall 呼叫目標合約,因此
wrapEth
您在內部訪問的是DSProxy 儲存而不是TargetContract。您正在
weth
從錯誤的儲存中讀取並使用其他東西作為地址。
weth
一種可能的解決方案是作為參數傳遞。contract TargetContract { constructor() {} function wrapEth(WethInterface weth) public payable { weth.deposit{ value: msg.value }(); } }
另一種解決方案是讓 TargetContract 從 DSProxy 繼承並使用函式來初始化 we.
contract TargetContract is DSProxy { WethInterface public weth; function initialize(WethInterface _weth) public { weth = _weth; } function wrapEth() public payable { weth.deposit{ value: msg.value }(); } }