...by Daniel Szego
quote
"Simplicity is the ultimate sophistication."
Leonardo da Vinci

Monday, December 25, 2017

Solidity and Truffle Tips and Tricks - updatable smart contract


Ethereum Smart Contracts are immutable by design, meaning that if you deployed them, there is no way to update. However, with some tricks there is the possibility to make updates at least to a certain level.  

- client side: one way might be to handle everything on the client side, like deploying a new contract and simply forgetting the old one in a way that all client references are set to the new one. Certainly, it is not a very reliable or professional way of doing things.

- selfdestruct: one way of doing it is to implement selfdestruct into the contract, destroy the contract and develop a new one. Certainly, it a highly centralized way of doing things, hence you should probably provide a provable way to migrate the data of the old contract to the new one.   

- data dependent execution: another way might be if you explicitly implement several execution logic into the smart contract and the execution is dependent on an internal variable. Certainly, the disadvantage in this scenario that you have to prepare to every possible execution path:

contract DataDependenExec{

  uint _execPath = 0;

  function execute() public {
    if (_execPath == 0) {
       // ... execution path one
    } else {
       // ... execution path two
    }
  }

  // .. some functionality to set _execPath 
}

- multiply smart contracts: a further solution might be that the contracts are organized in a master - slave style and cooperation via a certain interface is realized. If the slave contract is updated, the master calls the new functionality. Certainly, the interface have to be designed very carefully, in a way that no change happen in the fingertip of the function and of course security has to be taken pretty seriously as well. 

contract Master{

  address _slaveAddress;

  function changeSlave (_newAddress) public {
    _slaveAddress = _newAddress;
  }

  function callSlave () public {
     Slave slave = Slave (_slaveAddress);
     slave.callSlaveFunction();
  }
}

contract Slave{

  function callSlaveFunction(){
    ...
  }
}