首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何创建TransparentUpgradeableProxy工厂?

如何创建TransparentUpgradeableProxy工厂?
EN

Ethereum用户
提问于 2022-11-19 06:50:46
回答 4查看 520关注 0票数 2

下面是工厂的代码,该工厂创建可升级的契约实例。我知道,为了实现这一点,我有一个选择是使用TransparentUpgradeableProxy (实际上,当我第一次使用Hardhat -and部署时,它起了作用--这就是它在引擎盖下所做的):

SmartWalletFactory.sol

代码语言:javascript
复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;

import "../multiwrap/SmartWallet.sol";
import "../proxy/SmartWalletProxy.sol";

contract SmartWalletFactory {
    mapping(uint256 => address) private smartWallets;
    SmartWalletProxy immutable proxy;

    constructor(address _initialImpl) {
        proxy = new SmartWalletProxy(_initialImpl);
    }

    function createSmartWallet(
        uint256 _smartWalletId,
        address _defaultAdmin,
        string memory _name,
        string memory _symbol,
        string memory _contractURI,
        address[] memory _trustedForwarders,
        address _royaltyRecipient,
        uint256 _royaltyBps
      ) public {
        TransparentUpgradeableProxy smartWallet = new TransparentUpgradeableProxy(address(proxy), address(0), abi.encodeWithSelector(SmartWallet(payable(address(0))).initialize.selector, _defaultAdmin, _name, _symbol, _contractURI, _trustedForwarders, _royaltyRecipient, _royaltyBps));
        smartWallets[_smartWalletId] = address(smartWallet);
    }
} 

这是代理的代码:

SmartWalletProxy.sol

代码语言:javascript
复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;

import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";

contract SmartWalletProxy is Ownable {
    TransparentUpgradeableProxy immutable proxy;
    address public smartWalletImplementation;

    constructor(address _initialImpl) {
        proxy = new TransparentUpgradeableProxy(_initialImpl, address(0), "0x");
        smartWalletImplementation = _initialImpl;
        transferOwnership(tx.origin);
    }

    function upgrade(address _newImpl) public onlyOwner {
        proxy.upgradeTo(_newImpl);
        smartWalletImplementation = _newImpl;
    }

}

因此,我首先部署SmartWallet作为我的实现契约,然后使用SmartWallet的地址作为输入来部署SmartWalletFactory

我遇到的问题是,我得到了以下错误(使用Remix):

代码语言:javascript
复制
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
Internal JSON-RPC error.
{
"code": 3,
"message": "execution reverted: Address: low-level delegate call failed",
"data": "0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000027416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c656400000000000000000000000000000000000000000000000000"
}

有人知道这个错误可能是什么吗?

EN

回答 4

Ethereum用户

回答已采纳

发布于 2022-12-12 12:11:46

我知道这可能不是您想要的答案,但我强烈建议您考虑使用UUPS设计模式来实现可升级的智能合同。它与transparent proxy pattern类似,只不过升级是通过逻辑契约而不是从代理契约触发的。

UUPS代理模式教程

好处有很多。例如,不存在solidity function collision或基于此的任何攻击的可能性。此外,Hardhat && OpenZepplein都为其提供了完整的库支持。

在我个人看来,TransparentUpgradeableProxy已经过时了。UUPS & Dimond模式是唯一值得考虑的两种模式。

票数 0
EN

Ethereum用户

发布于 2022-12-13 22:28:23

第二参数 of TransparentUpgradeableProxy设置代理管理地址。当在proxy的构造函数的第一行初始化SmartWalletProxy.sol时,您将指定零地址作为代理的管理员。也许可以尝试使用address(this)而不是address(0)

票数 3
EN

Ethereum用户

发布于 2022-12-12 11:41:37

为了使用透明的代理模式,您必须使用proxyAdmin操作代理。当与代理合同进行任何交互时,代理将调用委托给您提供代理的任何合同。

因此,这里的线索是错误线"message": "execution reverted: Address: low-level delegate call failed"。在阅读这篇文章时,我会假设您还没有设置您的proxyAdmin,或者您正在从一个非管理地址调用合同。

这里读取docs OpenZeppelin

票数 1
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/139655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档