Skip to main content
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
added 2707 characters in body
Source Link
fabdarice
  • 203
  • 1
  • 7

I know that smart contracts are supposed to be immutable and that's the whole point, but to expect someone to implement a logic that never changes (no upgrade or no bugs) from day 1 is also unrealistic.
Therefore, I've been reading about several methods of working around this immutable state. A popular method seems to be using delegateCall with a Relay contract, but I'm struggling with how to actually use this method as I couldn't find any example.
Would someone be kind enough to look at that simple example I created, and tell me what I'm doing incorrectly?
https://gist.github.com/fabdarice/d513d620d9355312d085c7a68e6c6118
Relay.sol

contract Relay {
  address public currentVersion;
  address public owner;
  mapping (address => uint) user_amounts;


  modifier onlyOwner() {
    if (msg.sender != owner) {
        throw;
    }
    _;
  }

  function Relay(address initAddr) {
    currentVersion = initAddr;
    owner = msg.sender; // this owner may be another contract with multisig, not a single contract owner
  }

  function changeContract(address newVersion) public
  onlyOwner()
  {
    currentVersion = newVersion;
  }

  function() {
    if(!currentVersion.delegatecall(msg.data)) throw;
  }
}  

Donation.sol :

contract Donation {
  mapping (address => uint) user_amounts;    
  
  
  /* DOES THIS METHODS MODIFY user_amounts of the Relay contract ??? */
  function sendDonation(uint n) {
    user_amounts[msg.sender] = user_amounts[msg.sender] + n
  }
}  

DonationNew.sol :

contract DonationNew {
  mapping (address => uint) user_amounts;

  function sendDonation(uint n) {
    user_amounts[msg.sender] = user_amounts[msg.sender] + n
  }
  
  function cancelDonation() {
    user_amounts[msg.sender] = 0
  }
}  

app.js :

// First, deploying Relay, then deploying Donation and retrieve Donation contract address in 'donation_contract_address'

// Then, linking Relay to my first version of my contract Donation 
Relay.deployed().then(function(contractInstance) {
   contractInstance.changeContract(donation_contract_address);
})

// Then, I want to call sendDonation from the Donation contract
// !!!!! I DON'T KNOW WHAT IS THE CORRECT WAY TO CALL THIS !!!!!!
Relay.deployed().then(function(contractInstance) {
   contractInstance.sendDonation(5) ;
})
// OR 
Relay.deployed().then(function(contractInstance) {
   contractInstance.currentVersion.delegateCall(sendDonation(5)) ;
})

// Now I want to update the Donation contract to add the cancelDonation function
// First I deploy the new contract DonationNew and retrieve it's address in 'donation_new_contract_address'
Relay.deployed().then(function(contractInstance) {
   contractInstance.changeContract(donation_new_contract_address);
})

// are the state variables still available from the old contract to the new one?

// Then if I want to call the new function : 
Relay.deployed().then(function(contractInstance) {
   contractInstance.cancelDonation() ;
})

I know that smart contracts are supposed to be immutable and that's the whole point, but to expect someone to implement a logic that never changes (no upgrade or no bugs) from day 1 is also unrealistic.
Therefore, I've been reading about several methods of working around this immutable state. A popular method seems to be using delegateCall with a Relay contract, but I'm struggling with how to actually use this method as I couldn't find any example.
Would someone be kind enough to look at that simple example I created, and tell me what I'm doing incorrectly?
https://gist.github.com/fabdarice/d513d620d9355312d085c7a68e6c6118

I know that smart contracts are supposed to be immutable and that's the whole point, but to expect someone to implement a logic that never changes (no upgrade or no bugs) from day 1 is also unrealistic.
Therefore, I've been reading about several methods of working around this immutable state. A popular method seems to be using delegateCall with a Relay contract, but I'm struggling with how to actually use this method as I couldn't find any example.
Would someone be kind enough to look at that simple example I created, and tell me what I'm doing incorrectly?
https://gist.github.com/fabdarice/d513d620d9355312d085c7a68e6c6118
Relay.sol

contract Relay {
  address public currentVersion;
  address public owner;
  mapping (address => uint) user_amounts;


  modifier onlyOwner() {
    if (msg.sender != owner) {
        throw;
    }
    _;
  }

  function Relay(address initAddr) {
    currentVersion = initAddr;
    owner = msg.sender; // this owner may be another contract with multisig, not a single contract owner
  }

  function changeContract(address newVersion) public
  onlyOwner()
  {
    currentVersion = newVersion;
  }

  function() {
    if(!currentVersion.delegatecall(msg.data)) throw;
  }
}  

Donation.sol :

contract Donation {
  mapping (address => uint) user_amounts;    
  
  
  /* DOES THIS METHODS MODIFY user_amounts of the Relay contract ??? */
  function sendDonation(uint n) {
    user_amounts[msg.sender] = user_amounts[msg.sender] + n
  }
}  

DonationNew.sol :

contract DonationNew {
  mapping (address => uint) user_amounts;

  function sendDonation(uint n) {
    user_amounts[msg.sender] = user_amounts[msg.sender] + n
  }
  
  function cancelDonation() {
    user_amounts[msg.sender] = 0
  }
}  

app.js :

// First, deploying Relay, then deploying Donation and retrieve Donation contract address in 'donation_contract_address'

// Then, linking Relay to my first version of my contract Donation 
Relay.deployed().then(function(contractInstance) {
   contractInstance.changeContract(donation_contract_address);
})

// Then, I want to call sendDonation from the Donation contract
// !!!!! I DON'T KNOW WHAT IS THE CORRECT WAY TO CALL THIS !!!!!!
Relay.deployed().then(function(contractInstance) {
   contractInstance.sendDonation(5) ;
})
// OR 
Relay.deployed().then(function(contractInstance) {
   contractInstance.currentVersion.delegateCall(sendDonation(5)) ;
})

// Now I want to update the Donation contract to add the cancelDonation function
// First I deploy the new contract DonationNew and retrieve it's address in 'donation_new_contract_address'
Relay.deployed().then(function(contractInstance) {
   contractInstance.changeContract(donation_new_contract_address);
})

// are the state variables still available from the old contract to the new one?

// Then if I want to call the new function : 
Relay.deployed().then(function(contractInstance) {
   contractInstance.cancelDonation() ;
})
Source Link
fabdarice
  • 203
  • 1
  • 7

Smart Contract - Update implementation using a Relay with delegateCall

I know that smart contracts are supposed to be immutable and that's the whole point, but to expect someone to implement a logic that never changes (no upgrade or no bugs) from day 1 is also unrealistic.
Therefore, I've been reading about several methods of working around this immutable state. A popular method seems to be using delegateCall with a Relay contract, but I'm struggling with how to actually use this method as I couldn't find any example.
Would someone be kind enough to look at that simple example I created, and tell me what I'm doing incorrectly?
https://gist.github.com/fabdarice/d513d620d9355312d085c7a68e6c6118

P.S.: I know that this method above allow us to create an "upgradable contract" in the case we need to update our logic (functions etc..), however it doesn't allow us to modify/add our state variables structure. Is there a workaround this as well?

Thanks a lot, happy to be part of this community !

1
2