首页 > 解决方案 > Remix IDE 如何通过“At Address”正确部署代理合约?

问题描述

我开始研究如何使用 Remix IDE 编写以太坊智能合约并在 localhost 中配置 Ganache & Truffle。

我练习遵循这篇文章(可升级代理合同)。因此,我将拥有以下文件:

Registry.sol(主合约)

pragma solidity ^0.6.12;

import './Storage.sol';

contract Registry is Storage {

address public logic_contract;

function setLogicContract(address _c) public returns (bool success){
    logic_contract = _c;
    return true;
}

fallback () payable external {
    address target = logic_contract;
    assembly {
        let ptr := mload(0x40)
        calldatacopy(ptr, 0, calldatasize())
        let result := delegatecall(gas(), target, ptr, calldatasize(), 0, 0)
        let size := returndatasize()
        returndatacopy(ptr, 0, size)
        switch result
        case 0 { revert(ptr, size) }
        case 1 { return(ptr, size) }
    }
}

Storage.sol(用于存储目的)

pragma solidity ^0.6.12;

contract Storage {
    uint public val;
}

LogicOne.sol(第一个逻辑合约)

pragma solidity ^0.6.12;

import './Storage.sol';

contract LogicOne is Storage {
    function setVal(uint _val) public returns (bool success) {
        val = 2 * _val;
        return true;
    }
}

LogicTwo.sol(第二个逻辑合约)

pragma solidity ^0.6.12;

import './Storage.sol';

contract LogicTwo is Storage {
    function setVal(uint _val) public returns (bool success) {
        val = 1000 * _val;
        return true;
    }
}

我能够通过松露控制台成功部署合同。但是,当切换到 Remix IDE 时,我可以部署所有合约,但主合约没有与 logic1 合约链接,无法切换到 logic2 合约。

我未能在 Remix IDE 中模拟以下代码。

Registry.at(Registry.address).setLogicContract(LogicOne.address)
Registry.at(Registry.address).setLogicContract(LogicTwo.address)

每次我单击“地址”按钮时,都会部署一个新的主合约。预期结果是主合约应该保持不变,但合约逻辑从 LogicOne 切换到 LogicTwo。

在此处输入图像描述

我尝试的场景如下:

场景一:

  1. 部署所有合约
  2. 调用主合约 setLogicContract() 函数设置逻辑合约地址
  3. 调用 setVal() 函数但“val”未在主合约中更新

场景二:

  1. 部署 LogicOne 合约
  2. 在“地址”输入LogicOne合约地址,点击按钮部署主合约
  3. 调用 setVal() 函数并在主合约中更新“Val”
  4. 尝试在“At Address”中输入LogicTwo合约地址并点击按钮部署第二个主合约
  5. 但是,这将创建另一个新的主合约。

有没有人可以分享部署合同步骤的经验?任何意见表示赞赏!

标签: ethereumsmartcontractsremix

解决方案


要调用“代理”函数,您将地址设置为代理合约,但使用被代理的基础合约的 ABI。

在这种情况下,您要使用 Registry.sol 的地址和 LogicOne.sol 或 LogicTwo.sol 的 ABI。不确定 Remix 是否可以做到这一点。

根据您链接的文章,您希望这样做

  1. 我们使用 LogicOne ABI 来修改 Registry 合约中的“val”存储。LogicOne.at(Registry.address).setVal(2)

为了找回你的价值,你可能想要 LogicOne.at(Registry.address).val()


推荐阅读