Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example of separated storage and logic
contract Database{
mapping(uint => uint) public _data;
mapping(address => bool) _owners;
function Database(address[] owners){ //Called once at creation, pass in initial owners
for(uint i; i<owners.length; i++){
_owners[owners[i]]=true;
}
}
function setData(uint id, uint data) public returns (bool){
if(_owners[msg.sender]){
_data[id] = data;
return true;
}
return false;
}
function changeOwners(address owner, bool permission) public returns(bool){
if(_owners[msg.sender]){
_owners[owner] = permission;
return true;
}
return false;
}
}
var owners = [eth.accounts[0]];/* Initial owners*/ ;
/* First time - initialize the database */
var databaseContract = web3.eth.contract([{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"_data","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"data","type":"uint256"}],"name":"setData","outputs":[{"name":"","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"owner","type":"address"},{"name":"permission","type":"bool"}],"name":"changeOwners","outputs":[{"name":"","type":"bool"}],"type":"function"},{"inputs":[{"name":"owners","type":"address[]"}],"type":"constructor"}]);
var database = databaseContract.new(
owners,
{
from: web3.eth.accounts[0],
data: '606060405260405161015b38038061015b8339810160405280510160005b81518110156075576001600160005060008484815181101560025790602001906020020151600160a060020a0316815260200190815260200160002060006101000a81548160ff02191690830217905550600101601d565b505060d7806100846000396000f3606060405260e060020a600035046303a7f8258114602e5780634848b1a5146045578063f9b30d03146085575b005b60cd60043560006020819052908152604090205481565b60cd600435602435600160a060020a03331660009081526001602052604081205460ff1615607f5782815260208190526040902081905560015b92915050565b60cd600435602435600160a060020a03331660009081526001602052604081205460ff1615607f57600160a060020a038316815260409020805460ff1916821790556001607f565b6060908152602090f3',
gas: 1000000
}
)
/* --------------- To add logic contracts ----------------- */
var data = database.address; /* Address of database */ ;
var logicContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"newContract","type":"address"}],"name":"update","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"example","outputs":[],"type":"function"},{"inputs":[{"name":"data","type":"address"}],"type":"constructor"}]);
var logic = logicContract.new(
data, // This is where the address gets passed in
{
from: web3.eth.accounts[0],
data: '60606040526040516020806101dd83395060806040525160008054600160a060020a03191682179055506101a6806100376000396000f3606060405260e060020a60003504631c1b8772811461002657806354353f2f146100d0575b005b6100246004356000805460e060020a63f9b30d03026060908152600160a060020a0384811660645260016084529091169163f9b30d039160a491602091906044908290876161da5a03f1156100025750604080516000805460e060020a63f9b30d0302835230600160a060020a03908116600485015260248401839052935193169450604482810193602093909290839003909101908290876161da5a03f1156100025750505050565b610024600080547f03a7f825000000000000000000000000000000000000000000000000000000006060908152610539606452600160a060020a03909116906303a7f8259060849060209060248187876161da5a03f11561000257505060408051805184547f4848b1a500000000000000000000000000000000000000000000000000000000835261053960048401526104d2602484015292519094600160a060020a03939093169350634848b1a5926044808401936020939290839003909101908290876161da5a03f115610002575050505056',
gas: 1000000
})
// To update the permissions in the database (first wait for logic to be mined)
database.changeOwners(logic.address, true,{from:eth.accounts[0],gas:100000});
//Or if there already is a logic contract
oldLogic.update(logic.address, {from:eth.accounts[0],gas:100000});
contract Database{
function _data(uint id) public constant returns (uint data);
function setData(uint id, uint data) public returns (bool);
function changeOwners(address owner, bool permission) public returns(bool);
}
contract Logic{
Database database;
function Logic (address data){
database = Database(data);
}
// Logic here
function update(address newContract) public {
database.changeOwners(newContract,true); // Give new contract write permissions
database.changeOwners(this,false); // Revokes it's own permissions
}
function example(){
uint foo = database._data(1337); // get data
database.setData(1337,1234); // set data
}
}
@tjade273

This comment has been minimized.

Copy link
Owner Author

commented Sep 16, 2015

Using string arguments as mapping keys doesn't seem to work, so the DB now uses unique IDs instead of names. In real life, using a (uint => data) mapping where data is a custom struct would probably make the most sense.

@tjade273

This comment has been minimized.

Copy link
Owner Author

commented Sep 16, 2015

The database contract is created only once, then the address is passed as an argument to the constructor of each new logic contract. Make sure to properly change the permissions, or you will lose access to the DB and will have to copy all the data to a new one :(

@sekharkumarroy

This comment has been minimized.

Copy link

commented Sep 16, 2015

There is an issue with web3 RPC to use string as key. One workaround I found is -
mapping(bytes32 => int) private mymapping;
mymapping[sha3(#inputstring)]

so instead of string use sha3(string) as key. Hope that helps.

@5chdn

This comment has been minimized.

Copy link

commented Jan 28, 2016

I am wondering, what's the difference between the two Database contracts, and why do you define it twice?

edit, nevermind, rereading everything sometimes help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.