Skip to content

Instantly share code, notes, and snippets.

@fabdarice
Created February 7, 2018 07:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fabdarice/180eb505d5356c2def18e984293b9c06 to your computer and use it in GitHub Desktop.
Save fabdarice/180eb505d5356c2def18e984293b9c06 to your computer and use it in GitHub Desktop.
OldContract
pragma solidity ^0.4.4;
/**
* The dispatcher is a minimal 'shim' that dispatches calls to a targeted
* contract. Calls are made using 'delegatecall', meaning all storage and value
* is kept on the dispatcher. As a result, when the target is updated, the new
* contract inherits all the stored data and value from the old contract.
*/
import './Upgradeable.sol';
contract Dispatcher is Upgradeable {
function Dispatcher(address target) {
replace(target);
}
function initialize() {
// Should only be called by on target contracts, not on the dispatcher
throw;
}
function updateContract(address target) {
replace(target);
}
function() {
bytes4 sig;
assembly { sig := calldataload(0) }
var len = _sizes[sig];
var target = _dest;
assembly {
// return _dest.delegatecall(msg.data)
calldatacopy(0x0, 0x0, calldatasize)
pop(delegatecall(sub(gas, 10000), target, 0x0, calldatasize, 0, len))
return(0, len)
}
}
}
pragma solidity ^0.4.4;
import './Upgradeable.sol';
contract Example is Upgradeable {
uint public _value;
function initialize() {
_sizes[bytes4(sha3("getUint()"))] = 32;
}
function getUint() constant returns (uint) {
return _value;
}
function setUint(uint value) {
_value = value;
}
}
pragma solidity ^0.4.4;
import './Upgradeable.sol';
contract ExampleNew is Upgradeable {
uint public _value;
uint public amount;
function initialize() {
_sizes[bytes4(sha3("getUint()"))] = 32;
_sizes[bytes4(sha3("getAmount()"))] = 32;
amount = 0;
}
function getUint() constant returns (uint) {
return _value;
}
function setUint(uint value) {
_value = value + 1000;
}
function addition(uint value) {
amount = amount + value;
}
function getAmount() constant returns (uint) {
return amount;
}
}
pragma solidity ^0.4.4;
/**
* Base contract that all upgradeable contracts should use.
*
* Contracts implementing this interface are all called using delegatecall from
* a dispatcher. As a result, the _sizes and _dest variables are shared with the
* dispatcher contract, which allows the called contract to update these at will.
*
* _sizes is a map of function signatures to return value sizes. Due to EVM
* limitations, these need to be populated by the target contract, so the
* dispatcher knows how many bytes of data to return from called functions.
* Unfortunately, this makes variable-length return values impossible.
*
* _dest is the address of the contract currently implementing all the
* functionality of the composite contract. Contracts should update this by
* calling the internal function `replace`, which updates _dest and calls
* `initialize()` on the new contract.
*
* When upgrading a contract, restrictions on permissible changes to the set of
* storage variables must be observed. New variables may be added, but existing
* ones may not be deleted or replaced. Changing variable names is acceptable.
* Structs in arrays may not be modified, but structs in maps can be, following
* the same rules described above.
*/
contract Upgradeable {
mapping(bytes4=>uint32) _sizes;
address public _dest;
/**
* This function is called using delegatecall from the dispatcher when the
* target contract is first initialized. It should use this opportunity to
* insert any return data sizes in _sizes, and perform any other upgrades
* necessary to change over from the old contract implementation (if any).
*
* Implementers of this function should either perform strictly harmless,
* idempotent operations like setting return sizes, or use some form of
* access control, to prevent outside callers.
*/
function initialize() {
}
/**
* Performs a handover to a new implementing contract.
*/
function replace(address target) internal {
_dest = target;
target.delegatecall(bytes4(sha3("initialize()")));
}
}
@srameshr
Copy link

srameshr commented Feb 7, 2018

Could you write, in what order they have to be deployed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment