Skip to content

Instantly share code, notes, and snippets.

@pprados
Created February 23, 2017 10:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pprados/aab3d3b29a11d31305a16af65d1b599d to your computer and use it in GitHub Desktop.
Save pprados/aab3d3b29a11d31305a16af65d1b599d to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.8;
/**
* Interface shared by Proxy, ContractV1 and ContractV2.
*/
contract Interface {
/** return uint, depend of the current version. */
function doSomething() constant returns(uint);
}
/**
* The version 1 of the contract.
* The attr is initialized to 1000.
* The method doSomething() return attr + version = 1001
*/
contract ContractV1 is Interface {
uint constant private version=1;
uint public attr=1000;
/** return attr+newAttr+version (1001). */
function doSomething() constant returns(uint) {
return attr+version;
}
}
/**
* The version 2 of the contract.
* To preserve all the attributs from the v1 version, this version IS a ContractV1.
* All methods can be rewrite, new one can be added and some attributs can be added.
*
* The newAttr is initialized to 100.
* The method doSomething() return attr + newAtttr + version = 1102
*/
contract ContractV2 is Interface {
uint constant private version=2;
uint attr;
uint newAttr=100;
/** return attr+newAttr+version (1102). */
function doSomething() constant returns(uint) {
return attr+newAttr+version;
}
/** return 42. Another method in version 2. */
function doOtherThing() constant returns(uint) {
return 42;
}
// -- Technical functions and attributs
/**
* Propagate the states from the v1 to v2.
*/
function ContractV2(ContractV1 contractV1) {
attr=contractV1.attr();
}
}
// -- Technical contract
/**
* A proxy to delegate method to the current version.
*/
contract Proxy is Interface {
/** The current version. */
Interface public currentVersion;
/** Create a proxy with a specific version. */
function Proxy(Interface _currentVersion) {
currentVersion=_currentVersion;
}
/** Delegate to the current version. */
function doSomething() constant returns(uint) {
return currentVersion.doSomething();
}
/** Change to the current version. */
function changeVersion(Interface _currentVersion) {
currentVersion=_currentVersion;
}
}
// -------------
/**
* Unit test.
*
* After created an instance,
* - call 'init()'
* - call 'doSomething()' return 1001
* - call 'changeToV2'
* - call 'doSomething()' return 1102
* - call 'doOtherthing()' return 42
*/
contract A_UnitTest {
/** Current proxy. */
Interface aContract;
function init() {
aContract=Interface(new Proxy(new ContractV1()));
}
/** Invoke the method 'doSomething()', valide with a contract v1 or v2. */
function doSomething() constant returns(uint) {
return aContract.doSomething();
}
/** Invoke a method 'doOtherThing()', only valide with a contract v2. */
function doOtherThing() constant returns(uint) {
throw; // Not implemented
}
/** Change to V2. */
function changeToV2() {
ContractV1 contractV1=ContractV1(Proxy(aContract).currentVersion());
Proxy(aContract).changeVersion(new ContractV2(contractV1));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment