Skip to content

Instantly share code, notes, and snippets.

@pprados
Created February 23, 2017 10:57
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/2ac1e91ba0784d65b3379b1a1ab353cb to your computer and use it in GitHub Desktop.
Save pprados/2ac1e91ba0784d65b3379b1a1ab353cb to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.8;
// -- Technical contract
/**
* Database contract.
* Use to share the state between v1 and v2.
*/
contract ContractDB {
/** Generic map. */
mapping(string => uint) map;
/** Get data from map. */
function get(string key) returns(uint) {
return map[key];
}
/** Set data to map. */
function set(string key,uint val) {
map[key]=val;
}
}
/**
* The version 1 of the contract.
* The attr is initialized to 1000.
* The method doSomething() return attr + version = 1001
*/
contract ContractV1 {
uint constant private version=2;
function ContractV1()
{
db.set("attr",1000);
}
/** return attr+newAttr+version (1001). */
function doSomething() constant returns(uint) {
return db.get("attr")+version;
}
// -- Technical functions and attributs
ContractDB public db=new ContractDB();
/** kill this version. */
function replacedBy(address newVersion) {
selfdestruct(newVersion);
}
}
/**
* 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 {
uint constant private version=2;
/** return attr+newAttr+version (1102). */
function doSomething() constant returns(uint) {
return db.get("attr")+db.get("newAttr")+version;
}
/** return 42. Another method in version 2. */
function doOtherThing() constant returns(uint) {
return 42;
}
// -- Technical functions and attributs
ContractDB public db;
/**
* Propagate the states from the v1 to v2.
*/
function ContractV2(ContractV1 origin) {
db=origin.db(); // Reference the same database
db.set("newAttr",100);
origin.replacedBy(this);
}
/** kill this version. */
function replacedBy(address newVersion) {
selfdestruct(newVersion);
}
}
// -------------
/**
* 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 {
ContractV1 aContractV1;
ContractV2 aContractV2;
/**
* Initialise useContract with a ContractV1.
*/
function init() {
aContractV1=new ContractV1();
}
/**
* Invoke the method 'doSomething()', valide with a contract v1 or v2.
* The caller must be known the reference of the current version.
*/
function doSomething() constant returns(uint) {
return ((address(aContractV2) == 0)
? aContractV1.doSomething()
: aContractV2.doSomething());
}
/** Invoke a method 'doOtherThing()', only valide with a contract v2. */
function doOtherThing() constant returns(uint) {
if (address(aContractV2) == 0) throw;
return aContractV2.doOtherThing();
}
/** Change to V2. */
function changeToV2() {
aContractV2=new ContractV2(aContractV1);
delete aContractV1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment