1
votes

I am started to studying how to write an Ethereum smart contract with Remix IDE and configured Ganache & Truffle in localhost.

I practicing follow this article (Upgradable Proxy Contracts). Therefore, I will have the files as following:

Registry.sol (Main Contract)

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 (For storage purpose)

pragma solidity ^0.6.12;

contract Storage {
    uint public val;
}

LogicOne.sol (First logic contract)

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 (Second logic contract)

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;
    }
}

I able to deploy the contract successfully via truffle console. However, when switch to Remix IDE, I able to deploy all the contract but the main contract is not link with the logic1 contract and unable to switch to logic2 contract.

I failed to simulate the following code in Remix IDE.

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

Everytime I click "At Address" button, a new main contract is deployed. The expected result is main contract should remain the same but contract logic is switch from LogicOne to LogicTwo.

enter image description here

The scenario I tried as below:

Scenario 1:

  1. Deploy all contracts
  2. Call main contract setLogicContract() function to set the logic contract address
  3. Called setVal() function but "val" is not update in main contract

Scenario 2:

  1. Deploy LogicOne contract
  2. Input LogicOne contract address in "At Address" and clicked the button to deploy main contract
  3. Called setVal() function and "Val" is updated in main contract
  4. Tried to input LogicTwo contract address in "At Address" and clicked the button to deploy second main contract
  5. However, this will create another new main contract.

Is there anyone can share the experience for the step to deploy the contract ? Any opinion is appreciate !

1

1 Answers

1
votes

To call a "proxied" function you set the address to the proxy contract but use the ABI of the underlying contract being proxied.

In this case you want to use the address of Registry.sol and the ABI of LogicOne.sol or LogicTwo.sol. Not sure if it is possible to do this with Remix.

Based on the article you linked, you want to be doing this

  1. We use LogicOne ABI to modify the “val” storage in Registry contract. LogicOne.at(Registry.address).setVal(2)

And to get back your value, you probably want LogicOne.at(Registry.address).val()