Update MemberIdentity.sol

Update MemberIdentity.sol

pragma solidity ^0.4.2;
/*
We are starting from a simple identity contract supporting KYC using hashes computed off chain, e.g.

sha-1(NAME/GIVENNAMES/DATEOFBIRTH/PLACEOFBIRTH/NATIONALIY/EMAIL/ADDRESS1/ADDRESS2/ADDRESS3/RANDOM)

Specific factors to be hashed in identity hash for RChain is TBD. No identity factors are exposed on the blockchain.

For rchain membership we will need claimed and verified mappings and may want to use encrypted rather than hashed credentials.

Use case using hashes:
1. a membership request is made off chain by supplying rhain with their identity factors kept off chain.
   Google form triggers email for activation, sms, postcard with codes of 6 charactes of the hash.
   The hashed identity (appended form fields) (with a random string at the end?), contract address is sent to the user by email,
   contract address and code for verifying a cliam.
2. user activates account with their hash sent by email associating the email addresses with the member hash and ethereum address.
   A small amount of eth is charged to prevent spam and cover costs.
3. Then they they invoke a claim method in the contract which adds the code as a claim
   for the member associated with the ethereum address. A small amount of eth is charged to prevent spam and cover costs.
4. The contract owner (rchain) monitors the log for claims and can add, verify or revoke claims and verifications.
   Claim verification may reward the claiment in rhoc. todo
5. A member can add or replace an eth address associated with their hash. todo
6. Anyone can determin if claims have been verified by rchain associated with the hash id of an ethereum account.
*/
// work in progress, simple proof of concept, comment and suggest edits.
// TODO make Owned? integrate with uPort?
contract MemberIdentityRegistry {
    // TODO bring up to standards (amp/rhoc/divvy bounties, work claimed in comments)
    //   http://solidity.readthedocs.io/en/develop/layout-of-source-files.html
    //   http://solidity.readthedocs.io/en/develop/style-guide.html
    //   http://solidity.readthedocs.io/en/develop/structure-of-a-contract.html
    //   http://solidity.readthedocs.io/en/develop/common-patterns.html
    //   http://solidity.readthedocs.io/en/develop/security-considerations.html
    // TODO test and debug
    address public owner = msg.sender; //TODO add methods to change owner
    address public wallet; // wallet to hold rhoc rewards and eth commected.
    uint256 public price = .001 ether; // prevent spam, cover costs.
    mapping(address => mapping(bytes32 => uint256)) public verified;
    mapping(address => mapping(bytes32 => bytes32)) public code;
    mapping(address => mapping(bytes32 => uint256)) claimed;  // TOIDO use data structure for hash and code?
    mapping(address => address) uPortAddress; // future use

    event ClaimedEvent(uint256 hash, bytes32 factor, bytes32 code);
    event VerifiedEvent(uint256 hash);

    function setPrice(uint256 value) {
        if(owner != msg.sender) throw;
        price = value;
    }

    function setWallet(address addr) {
        if(owner != msg.sender) throw;
        wallet = addr;
    }
    function activate(uint256 hash) payable { // hash sent to email verifies email
        // receive eth fee
	    if(msg.value != price) throw;
	    if ( ! wallet.send(msg.value) ) throw;
        claimed[msg.sender]["email"] = hash;
        ClaimedEvent(hash, "email", "");
    }
    function claimIFactor(bytes32 factor, bytes32 code) payable {
         uint256 hash = claimed[msg.sender]["email"]
        // receive eth fee
	    if(msg.value != price) throw;
	    if ( ! wallet.send(msg.value) ) throw;
        claimed[msg.sender][factor] = hash;
	code[msg.sender][factor] = code;
        ClaimedEvent(hash, factor, code);
    }

    function bringuPort(address uPortId) {   // for future
        // TODO verify address belongs to uPortId?
        uPortAddress[msg.sender] = uPortId;
    }

    function getVerifiedHashID(address who, bytes32 factor) returns (uint256) {
        return verified[who][factor];
    }

    function revoke(bytes32 factor,address who) {
        if(owner != msg.sender) throw;
        delete verified[who][factor];
    }
    function revokeMyId(bytes32 factor) {
       delete verified[msg.sender][factor];
    }
    // function revokeAll(bytes32 factor, address who) {
    //     if(owner != msg.sender) throw;
    //     verified[who] = new mapping(bytes32 => uint256);
    // }
    // function revokeAllMyId() {
    //   delete verified[msg.sender];
    // }
}

pragma solidity ^0.4.2;
/*
We are starting from a simple identity contract supporting KYC using hashes computed off chain, e.g.

sha-1(NAME/GIVENNAMES/DATEOFBIRTH/PLACEOFBIRTH/NATIONALIY/EMAIL/ADDRESS1/ADDRESS2/ADDRESS3/RANDOM)

Specific factors to be hashed in identity hash for RChain is TBD. No identity factors are exposed on the blockchain.

For rchain membership we will need claimed and verified mappings and may want to use encrypted rather than hashed credentials.

Use case using hashes:
1. a membership request is made off chain by supplying rhain with their identity factors kept off chain.
   Google form triggers email, sms, postcard with codes of 6 charactes of the hash.
   The hashed identity (form fields) (with a random string at the end?), contract address and code is sent to the user
   for verifying a cliam.
2. user activates account with ther hash sent by email associating the email addresses with the member hash and ethereum address.
   A small amount of eth is charged to prevent spam and cover costs.
3. Then they they invoke a validator method in the contract which adds the code as a claim
   for the member associated with the ethereum address. A small amount of eth is charged to prevent spam and cover costs.
4. The contract owner (rchain) monitors the log for claims and can add, verify or revoke claims and verifications.
   Claim verification may reward the claiment in rhoc.
5. A member can add or replace an eth address associated with their hash.
6. Anyone can determin if claims have been berified ny rchain associated with the hash id of an ethereum accopunt.
*/
// work in progress, simple proof of concept, comment and suggest edits.
// TODO make Owned? integrate with uPort?
contract MemberIdentityRegistry {
    // TODO bring up to standards (amp/rhoc/divvy bounties, work claimed in comments)
    //   http://solidity.readthedocs.io/en/develop/layout-of-source-files.html
    //   http://solidity.readthedocs.io/en/develop/style-guide.html
    //   http://solidity.readthedocs.io/en/develop/structure-of-a-contract.html
    //   http://solidity.readthedocs.io/en/develop/common-patterns.html
    //   http://solidity.readthedocs.io/en/develop/security-considerations.html
    // TODO test and debug
    address public owner = msg.sender;
    address public wallet; // wallet to hold rhoc rewards and eth commected.
    uint256 public price = .001 ether; // prevent spam, cover costs.
    mapping(address => mapping(bytes32 => uint256)) public verified;
    mapping(address => mapping(bytes32 => uint256)) claimed;
    mapping(address => address) uPortAddress; // future use

    event ClaimedEvent(uint256 hash, bytes32 factor, bytes32 code);
    event Verified(uint256 hash);

    function setPrice(uint256 value) {
        if(owner != msg.sender) throw;
        price = value;
    }

    function setWallet(address addr) {
        if(owner != msg.sender) throw;
        wallet = addr;
    }
    function activate(uint256 hash) payable { // hash sent to email verifies email
        // receive eth fee
	    // if(msg.value != price) throw;
	    if ( ! wallet.send(msg.value) ) throw;
        claimed[msg.sender]["email"] = hash;
        ClaimedEvent(hash, "email", "");
    }
    function claimIFactor(bytes32 factor, uint256 hash) payable {
        // receive eth fee
	    // if(msg.value != price) throw;
	    if ( ! wallet.send(msg.value) ) throw;
        claimed[msg.sender][factor] = hash;
        ClaimedEvent(hash, factor, code);
    }

    function bringuPort(address uPortId) {   // for future
        // TODO verify address belongs to uPortId?
        uPortAddress[msg.sender] = uPortId;
    }

    function getVerifiedHashID(address who, bytes32 factor) returns (uint256) {
        return verified[who][factor];
    }

    function revoke(bytes32 factor,address who) {
        if(owner != msg.sender) throw;
        delete verified[who][factor];
    }
    function revokeMyId(bytes32 factor) {
       delete verified[msg.sender][factor];
    }
    // function revokeAll(bytes32 factor, address who) {
    //     if(owner != msg.sender) throw;
    //     verified[who] = new mapping(bytes32 => uint256);
    // }
    // function revokeAllMyId() {
    //   delete verified[msg.sender];
    // }
}


Convert depricated .send() to transfer()

pragma solidity ^0.4.19;

import './ConfirmationRepository.sol';
import './zeppelin/ownership/Ownable.sol';
import './zeppelin/lifecycle/Destructible.sol';

contract Conference is Destructible {
	string public name;
	uint256 public deposit;
	uint public limitOfParticipants;
	uint public registered;
	uint public attended;
	bool public ended;
	bool public cancelled;
	uint public endedAt;
	uint public coolingPeriod;
	uint256 public payoutAmount;
	ConfirmationRepository public confirmationRepository;
	string public encryption;

	mapping (address => Participant) public participants;
	mapping (uint => address) public participantsIndex;
	bool paid;

	struct Participant {
		string participantName;
		address addr;
		bool attended;
		bool paid;
	}

	event RegisterEvent(address addr, string participantName, string _encryption);
	event AttendEvent(address addr);
	event PaybackEvent(uint256 _payout);
	event WithdrawEvent(address addr, uint256 _payout);
	event CancelEvent();
	event ClearEvent(address addr, uint256 leftOver);

	/* Modifiers */
	modifier onlyActive {
		require(!ended);
		_;
	}

	modifier onlyEnded {
		require(ended);
		_;
	}

	/* Public functions */

	function Conference (
		string _name,
		uint256 _deposit,
		uint _limitOfParticipants,
		uint _coolingPeriod,
		address _confirmation_repository_address,
		string _encryption
	) public {
		if(bytes(_name).length != 0){
			name = _name;
		}else{
			name = 'Test';
		}

		if(_deposit != 0){
			deposit = _deposit;
		}else{
			deposit = 0.02 ether;
		}

		if(_limitOfParticipants !=0){
			limitOfParticipants = _limitOfParticipants;
		}else{
			limitOfParticipants = 20;
		}

		if (_coolingPeriod != 0) {
			coolingPeriod = _coolingPeriod;
		} else {
			coolingPeriod = 1 weeks;
		}

		if (bytes(_encryption).length != 0) {
			encryption = _encryption;
		}

		if (_confirmation_repository_address !=0) {
			confirmationRepository = ConfirmationRepository(_confirmation_repository_address);
		}
	}

	function registerWithEncryption(string _participant, string _encrypted) public payable onlyActive{
		registerInternal(_participant);
		RegisterEvent(msg.sender, _participant, _encrypted);
	}

	function register(string _participant) public payable onlyActive{
		registerInternal(_participant);
		RegisterEvent(msg.sender, _participant, '');
	}

	function registerInternal(string _participant) internal {
		require(msg.value == deposit);
		require(registered < limitOfParticipants);
		require(!isRegistered(msg.sender));

		registered++;
		participantsIndex[registered] = msg.sender;
		participants[msg.sender] = Participant(_participant, msg.sender, false, false);
	}

	function attendWithConfirmation(bytes32 _confirmation) public onlyActive{
		require(isRegistered(msg.sender));
		require(!isAttended(msg.sender));
		require(confirmationRepository.claim(_confirmation, msg.sender));

		participants[msg.sender].attended = true;
		attended++;
		AttendEvent(msg.sender);
	}

	function withdraw() public onlyEnded{
		require(payoutAmount > 0);
		Participant participant = participants[msg.sender];
		require(participant.addr == msg.sender);
		require(cancelled || participant.attended);
		require(participant.paid == false);

		participant.paid = true;
		participant.addr.transfer(payoutAmount);
		WithdrawEvent(msg.sender, payoutAmount);
	}

	/* Constants */
	function totalBalance() constant public returns (uint256){
		return this.balance;
	}

	function confirmation() constant public returns (bool){
		return address(confirmationRepository) != address(0);
	}

	function isRegistered(address _addr) constant public returns (bool){
		return participants[_addr].addr != address(0);
	}

	function isAttended(address _addr) constant public returns (bool){
		return isRegistered(_addr) && participants[_addr].attended;
	}

	function isPaid(address _addr) constant public returns (bool){
		return isRegistered(_addr) && participants[_addr].paid;
	}

	function payout() constant public returns(uint256){
		if (attended == 0) return 0;
		return uint(totalBalance()) / uint(attended);
	}

	/* Admin only functions */

	function payback() public onlyOwner onlyActive{
		payoutAmount = payout();
		ended = true;
		endedAt = now;
		PaybackEvent(payoutAmount);
	}

	function cancel() public onlyOwner onlyActive{
		payoutAmount = deposit;
		cancelled = true;
		ended = true;
		endedAt = now;
		CancelEvent();
	}

	/* return the remaining of balance if there are any unclaimed after cooling period */
	function clear() public onlyOwner onlyEnded{
		require(now > endedAt + coolingPeriod);
		require(ended);
		var leftOver = totalBalance();
		owner.transfer(leftOver);
		ClearEvent(owner, leftOver);
	}

	function setLimitOfParticipants(uint _limitOfParticipants) public onlyOwner onlyActive{
		limitOfParticipants = _limitOfParticipants;
	}

	function attend(address[] _addresses) public onlyOwner onlyActive{
		for(uint i=0;i<_addresses.length;i++){
			var _addr = _addresses[i];
			require(isRegistered(_addr));
			require(!isAttended(_addr));
			AttendEvent(_addr);
			participants[_addr].attended = true;
			attended++;
		}
	}
}

pragma solidity ^0.4.19;

import './ConfirmationRepository.sol';
import './zeppelin/ownership/Ownable.sol';
import './zeppelin/lifecycle/Destructible.sol';

contract Conference is Destructible {
	string public name;
	uint256 public deposit;
	uint public limitOfParticipants;
	uint public registered;
	uint public attended;
	bool public ended;
	bool public cancelled;
	uint public endedAt;
	uint public coolingPeriod;
	uint256 public payoutAmount;
	ConfirmationRepository public confirmationRepository;
	string public encryption;

	mapping (address => Participant) public participants;
	mapping (uint => address) public participantsIndex;
	bool paid;

	struct Participant {
		string participantName;
		address addr;
		bool attended;
		bool paid;
	}

	event RegisterEvent(address addr, string participantName, string _encryption);
	event AttendEvent(address addr);
	event PaybackEvent(uint256 _payout);
	event WithdrawEvent(address addr, uint256 _payout);
	event CancelEvent();
	event ClearEvent(address addr, uint256 leftOver);

	/* Modifiers */
	modifier onlyActive {
		require(!ended);
		_;
	}

	modifier onlyEnded {
		require(ended);
		_;
	}

	/* Public functions */

	function Conference (
		string _name,
		uint256 _deposit,
		uint _limitOfParticipants,
		uint _coolingPeriod,
		address _confirmation_repository_address,
		string _encryption
	) public {
		if(bytes(_name).length != 0){
			name = _name;
		}else{
			name = 'Test';
		}

		if(_deposit != 0){
			deposit = _deposit;
		}else{
			deposit = 0.02 ether;
		}

		if(_limitOfParticipants !=0){
			limitOfParticipants = _limitOfParticipants;
		}else{
			limitOfParticipants = 20;
		}

		if (_coolingPeriod != 0) {
			coolingPeriod = _coolingPeriod;
		} else {
			coolingPeriod = 1 weeks;
		}

		if (bytes(_encryption).length != 0) {
			encryption = _encryption;
		}

		if (_confirmation_repository_address !=0) {
			confirmationRepository = ConfirmationRepository(_confirmation_repository_address);
		}
	}

	function registerWithEncryption(string _participant, string _encrypted) public payable onlyActive{
		registerInternal(_participant);
		RegisterEvent(msg.sender, _participant, _encrypted);
	}

	function register(string _participant) public payable onlyActive{
		registerInternal(_participant);
		RegisterEvent(msg.sender, _participant, '');
	}

	function registerInternal(string _participant) internal {
		require(msg.value == deposit);
		require(registered < limitOfParticipants);
		require(!isRegistered(msg.sender));

		registered++;
		participantsIndex[registered] = msg.sender;
		participants[msg.sender] = Participant(_participant, msg.sender, false, false);
	}

	function attendWithConfirmation(bytes32 _confirmation) public onlyActive{
		require(isRegistered(msg.sender));
		require(!isAttended(msg.sender));
		require(confirmationRepository.claim(_confirmation, msg.sender));

		participants[msg.sender].attended = true;
		attended++;
		AttendEvent(msg.sender);
	}

	function withdraw() public onlyEnded{
		require(payoutAmount > 0);
		Participant participant = participants[msg.sender];
		require(participant.addr == msg.sender);
		require(cancelled || participant.attended);
		require(participant.paid == false);

		participant.paid = true;
		assert(participant.addr.send(payoutAmount));
		WithdrawEvent(msg.sender, payoutAmount);
	}

	/* Constants */
	function totalBalance() constant public returns (uint256){
		return this.balance;
	}

	function confirmation() constant public returns (bool){
		return address(confirmationRepository) != address(0);
	}

	function isRegistered(address _addr) constant public returns (bool){
		return participants[_addr].addr != address(0);
	}

	function isAttended(address _addr) constant public returns (bool){
		return isRegistered(_addr) && participants[_addr].attended;
	}

	function isPaid(address _addr) constant public returns (bool){
		return isRegistered(_addr) && participants[_addr].paid;
	}

	function payout() constant public returns(uint256){
		if (attended == 0) return 0;
		return uint(totalBalance()) / uint(attended);
	}

	/* Admin only functions */

	function payback() public onlyOwner onlyActive{
		payoutAmount = payout();
		ended = true;
		endedAt = now;
		PaybackEvent(payoutAmount);
	}

	function cancel() public onlyOwner onlyActive{
		payoutAmount = deposit;
		cancelled = true;
		ended = true;
		endedAt = now;
		CancelEvent();
	}

	/* return the remaining of balance if there are any unclaimed after cooling period */
	function clear() public onlyOwner onlyEnded{
		require(now > endedAt + coolingPeriod);
		require(ended);
		var leftOver = totalBalance();
		require(owner.send(leftOver));
		ClearEvent(owner, leftOver);
	}

	function setLimitOfParticipants(uint _limitOfParticipants) public onlyOwner onlyActive{
		limitOfParticipants = _limitOfParticipants;
	}

	function attend(address[] _addresses) public onlyOwner onlyActive{
		for(uint i=0;i<_addresses.length;i++){
			var _addr = _addresses[i];
			require(isRegistered(_addr));
			require(!isAttended(_addr));
			AttendEvent(_addr);
			participants[_addr].attended = true;
			attended++;
		}
	}
}


Make conference killable

Make conference killable

import './zeppelin/Rejector.sol';
import './zeppelin/Ownable.sol';
import './zeppelin/Killable.sol';

contract Conference is Rejector, Ownable, Killable {
	string public name;
	uint256 public totalBalance;
	uint256 public deposit;
	uint public limitOfParticipants;
	uint public registered;
	uint public attended;
	bool public ended;
	mapping (address => Participant) public participants;
	mapping (uint => address) public participantsIndex;
	bool paid;
	uint256 _payout;

	struct Participant {
		string participantName;
		address addr;
		bool attended;
		int payout;
	}

	event Register(string participantName, address addr, uint256 balance, uint256 value);
	event Attend(address addr, uint256 balance);
	event Payback(address addr, uint256 _payout, uint256 balance, bool paid);
	event Cancel(address addr, uint256 balance);

	function Conference() {
		name = 'CodeUp';
		deposit = 1 ether;
		totalBalance = 0;
		registered = 0;
		attended = 0;
		limitOfParticipants = 10;
		ended = false;
	}

	modifier sentDepositOrReturn {
		if (msg.value == deposit) {
			_
		}else{
			msg.sender.send(msg.value);
		}
	}

	modifier onlyActive {
		if (ended == false) {
			_
		}
	}

	modifier onlyActiveOrReturn {
		if (ended == false) {
			_
		}else{
			msg.sender.send(msg.value);
		}
	}

	modifier withinLimitOrReturn {
		if (registered < limitOfParticipants ) {
			_
		}else{
			msg.sender.send(msg.value);
		}
	}

	function register(string _participant) sentDepositOrReturn withinLimitOrReturn onlyActiveOrReturn{
		Register(_participant, msg.sender, msg.sender.balance, msg.value);
		if (isRegistered(msg.sender)) throw;
		registered++;
		participantsIndex[registered] = msg.sender;
		participants[msg.sender] = Participant(_participant, msg.sender, false, 0);
		totalBalance = totalBalance + (deposit * 1);
	}

	function setLimitOfParticipants(uint _limitOfParticipants) {
		limitOfParticipants = _limitOfParticipants;
	}

	function attend(address _addr) onlyOwner{
		if (isRegistered(_addr) != true) throw;
		if (isAttended(_addr)) throw;
		Attend(_addr, msg.sender.balance);
		participants[_addr].attended = true;
		attended++;
	}

	function isRegistered(address _addr) returns (bool){
		return participants[_addr].addr != 0x0;
	}

	function isAttended(address _addr) returns (bool){
		return isRegistered(_addr) && participants[_addr].attended;
	}

	function payout() returns(uint256){
		return totalBalance / uint(attended);
	}

	function payback() onlyOwner{
		for(uint i=1;i<=registered;i++)
		{
			if(participants[participantsIndex[i]].attended){
				Payback(participantsIndex[i], payout(), participantsIndex[i].balance,  true);
				participants[participantsIndex[i]].payout = int(payout() - deposit);
				participantsIndex[i].send(payout());
			}else{
				participants[participantsIndex[i]].payout = int(deposit - (deposit * 2));
				Payback(participantsIndex[i], payout(), participantsIndex[i].balance, false);
			}
		}
		/*
		 *	Actual balance may have some left over if 4 payout is divided among 3 attendees
		 *	eg: 4 / 3 = 1.333
		 */
		totalBalance = 0;
		ended = true;
	}

	function cancel() onlyOwner onlyActive{
		Cancel(owner, totalBalance);
		for(uint i=1;i<=registered;i++)
		{
			if(totalBalance > 0){
				participantsIndex[i].send(deposit);
			}
			delete participants[participantsIndex[i]];
			delete participantsIndex[i];
		}
		totalBalance = 0;
		registered = 0;
		attended = 0;
		ended = true;
	}
}

import './zeppelin/Rejector.sol';
import './zeppelin/Ownable.sol';

contract Conference is Rejector, Ownable {
	string public name;
	uint256 public totalBalance;
	uint256 public deposit;
	uint public limitOfParticipants;
	uint public registered;
	uint public attended;
	bool public ended;
	mapping (address => Participant) public participants;
	mapping (uint => address) public participantsIndex;
	bool paid;
	uint256 _payout;

	struct Participant {
		string participantName;
		address addr;
		bool attended;
		int payout;
	}

	event Register(string participantName, address addr, uint256 balance, uint256 value);
	event Attend(address addr, uint256 balance);
	event Payback(address addr, uint256 _payout, uint256 balance, bool paid);
	event Cancel(address addr, uint256 balance);

	function Conference() {
		name = 'CodeUp';
		deposit = 1 ether;
		totalBalance = 0;
		registered = 0;
		attended = 0;
		limitOfParticipants = 10;
		ended = false;
	}

	modifier sentDepositOrReturn {
		if (msg.value == deposit) {
			_
		}else{
			msg.sender.send(msg.value);
		}
	}

	modifier onlyActive {
		if (ended == false) {
			_
		}
	}

	modifier onlyActiveOrReturn {
		if (ended == false) {
			_
		}else{
			msg.sender.send(msg.value);
		}
	}

	modifier withinLimitOrReturn {
		if (registered < limitOfParticipants ) {
			_
		}else{
			msg.sender.send(msg.value);
		}
	}

	function register(string _participant) sentDepositOrReturn withinLimitOrReturn onlyActiveOrReturn{
		Register(_participant, msg.sender, msg.sender.balance, msg.value);
		if (isRegistered(msg.sender)) throw;
		registered++;
		participantsIndex[registered] = msg.sender;
		participants[msg.sender] = Participant(_participant, msg.sender, false, 0);
		totalBalance = totalBalance + (deposit * 1);
	}

	function setLimitOfParticipants(uint _limitOfParticipants) {
		limitOfParticipants = _limitOfParticipants;
	}

	function attend(address _addr) onlyOwner{
		if (isRegistered(_addr) != true) throw;
		if (isAttended(_addr)) throw;
		Attend(_addr, msg.sender.balance);
		participants[_addr].attended = true;
		attended++;
	}

	function isRegistered(address _addr) returns (bool){
		return participants[_addr].addr != 0x0;
	}

	function isAttended(address _addr) returns (bool){
		return isRegistered(_addr) && participants[_addr].attended;
	}

	function payout() returns(uint256){
		return totalBalance / uint(attended);
	}

	function payback() onlyOwner{
		for(uint i=1;i<=registered;i++)
		{
			if(participants[participantsIndex[i]].attended){
				Payback(participantsIndex[i], payout(), participantsIndex[i].balance,  true);
				participants[participantsIndex[i]].payout = int(payout() - deposit);
				participantsIndex[i].send(payout());
			}else{
				participants[participantsIndex[i]].payout = int(deposit - (deposit * 2));
				Payback(participantsIndex[i], payout(), participantsIndex[i].balance, false);
			}
		}
		/*
		 *	Actual balance may have some left over if 4 payout is divided among 3 attendees
		 *	eg: 4 / 3 = 1.333
		 */
		totalBalance = 0;
		ended = true;
	}

	function cancel() onlyOwner onlyActive{
		Cancel(owner, totalBalance);
		for(uint i=1;i<=registered;i++)
		{
			if(totalBalance > 0){
				participantsIndex[i].send(deposit);
			}
			delete participants[participantsIndex[i]];
			delete participantsIndex[i];
		}
		totalBalance = 0;
		registered = 0;
		attended = 0;
		ended = true;
	}
}


Fix wrong setup of start player color

Fix wrong setup of start player color

/**
 * Chess contract
 * Stores any amount of games with two players and current state.
 * State encoding:
 *    positive numbers for white, negative numbers for black
 *    for details, see
 *    https://github.com/ise-ethereum/on-chain-chess/wiki/Chess-board-representation
 */

import "TurnBasedGame.sol";
import "ChessLogic.sol";

contract Chess is TurnBasedGame {
    using ChessLogic for ChessLogic.State;
    mapping (bytes32 => ChessLogic.State) gameStates;

    event GameInitialized(bytes32 indexed gameId, address indexed player1, string player1Alias, address playerWhite, uint value);
    event GameJoined(bytes32 indexed gameId, address indexed player1, string player1Alias, address indexed player2, string player2Alias, address playerWhite, uint value);
    event GameStateChanged(bytes32 indexed gameId, int8[128] state);
    event GameTimeoutStarted(bytes32 indexed gameId,uint timeoutStarted, int8 timeoutState);
    event Move(bytes32 indexed gameId, address indexed player, uint256 fromIndex, uint256 toIndex);

    function Chess(bool enableDebugging) TurnBasedGame(enableDebugging) {
    }

    /**
     * Initialize a new game
     * string player1Alias: Alias of the player creating the game
     * bool playAsWhite: Pass true or false depending on if the creator will play as white
     */
    function initGame(string player1Alias, bool playAsWhite) public returns (bytes32) {
        bytes32 gameId = super.initGame(player1Alias, playAsWhite);

        // Setup game state
        int8 nextPlayerColor = int8(1);
        gameStates[gameId].setupState(nextPlayerColor);
        if (playAsWhite) {
            // Player 1 will play as white
            gameStates[gameId].playerWhite = msg.sender;

            // Game starts with White, so here player 1
            games[gameId].nextPlayer = games[gameId].player1;
        }

        // Sent notification events
        GameInitialized(gameId, games[gameId].player1, player1Alias, gameStates[gameId].playerWhite, games[gameId].value);
        GameStateChanged(gameId, gameStates[gameId].fields);
        return gameId;
    }

    /**
     * Join an initialized game
     * bytes32 gameId: ID of the game to join
     * string player2Alias: Alias of the player that is joining
     */
    function joinGame(bytes32 gameId, string player2Alias) public {
        super.joinGame(gameId, player2Alias);

        // If the other player isn't white, player2 will play as white
        if (gameStates[gameId].playerWhite == 0) {
            gameStates[gameId].playerWhite = msg.sender;
            // Game starts with White, so here player2
            games[gameId].nextPlayer = games[gameId].player2;
        }

        GameJoined(gameId, games[gameId].player1, games[gameId].player1Alias, games[gameId].player2, player2Alias, gameStates[gameId].playerWhite, games[gameId].value);
    }

    function move(bytes32 gameId, uint256 fromIndex, uint256 toIndex) notEnded(gameId) public {
        if (games[gameId].nextPlayer != msg.sender) {
            throw;
        }
        if(games[gameId].timeoutState != 0) {
            games[gameId].timeoutState = 0;
        }
        // Chess move validation
        gameStates[gameId].move(fromIndex, toIndex);

        // Set nextPlayer
        if (msg.sender == games[gameId].player1) {
            games[gameId].nextPlayer = games[gameId].player2;
        } else {
            games[gameId].nextPlayer = games[gameId].player1;
        }

        // Send events
        Move(gameId, msg.sender, fromIndex, toIndex);
        GameStateChanged(gameId, gameStates[gameId].fields);
    }

    /* Explicit set game state. Only in debug mode */
    function setGameState(bytes32 gameId, int8[128] state, address nextPlayer) debugOnly public {
        int8 playerColor = nextPlayer == gameStates[gameId].playerWhite ? int8(1) : int8(-1);
        gameStates[gameId].setState(state, playerColor);
        games[gameId].nextPlayer = nextPlayer;
        GameStateChanged(gameId, gameStates[gameId].fields);
    }

    function getCurrentGameState(bytes32 gameId) constant returns (int8[128]) {
       return gameStates[gameId].fields;
    }

    function getWhitePlayer(bytes32 gameId) constant returns (address) {
       return gameStates[gameId].playerWhite;
    }

    /* The sender claims he has won the game. Starts a timeout. */
    function claimWin(bytes32 gameId) notEnded(gameId) public {
        var game = games[gameId];
        // just the two players currently playing
        if (msg.sender != game.player1 && msg.sender != game.player2)
            throw;
        // only if timeout has not started
        if (game.timeoutState != 0)
            throw;
        // you can only claim draw / victory in the enemies turn
        if (msg.sender == game.nextPlayer)
            throw;
        game.timeoutStarted = now;
        game.timeoutState = 1;

        GameTimeoutStarted(gameId, game.timeoutStarted, game.timeoutState);
    }

    /* The sender offers the other player a draw. Starts a timeout. */
    function offerDraw(bytes32 gameId) notEnded(gameId) public {
        var game = games[gameId];
        // just the two players currently playing
        if (msg.sender != game.player1 && msg.sender != game.player2)
            throw;
        // only if timeout has not started
        if (game.timeoutState != 0)
            throw;
        // you can only claim draw / victory in the enemies turn
        if (msg.sender == game.nextPlayer)
            throw;
        game.timeoutStarted = now;
        game.timeoutState = -1;

        GameTimeoutStarted(gameId,game.timeoutStarted,game.timeoutState);
    }

    /* The sender claims a previously started timeout. */
    function claimTimeout(bytes32 gameId) notEnded(gameId) public {
        var game = games[gameId];
        // just the two players currently playing
        if (msg.sender != game.player1 && msg.sender != game.player2)
            throw;
        if (msg.sender == game.nextPlayer)
            throw;
        if (game.timeoutState == 0)
            throw;
        if (now < game.timeoutStarted + 10 minutes)
            throw;
        if (game.timeoutState == -1){
            game.ended = true;
            GameEnded(gameId, 0);
        } else if (game.timeoutState == 1){
            game.ended = true;
            game.winner = msg.sender;
            GameEnded(gameId, msg.sender);
        } else {
            throw;
        }
    }

    /* A timeout can be confirmed by the non-initializing player. */
    function confirmGameEnded(bytes32 gameId) notEnded(gameId) public {
        var game = games[gameId];
        // just the two players currently playing
        if (msg.sender != game.player1 && msg.sender != game.player2)
            throw;
        if (msg.sender != game.nextPlayer)
            throw;
        if (game.timeoutState == 0)
            throw;
        if (game.timeoutState == -1){
            game.ended = true;
            GameEnded(gameId, 0);
        } else if (game.timeoutState == 1){
            game.ended = true;
            // other player won
            game.winner = (msg.sender == game.player1 ? game.player2 : game.player1);
            GameEnded(gameId, game.winner);
        } else {
            throw;
        }
    }

    /* This unnamed function is called whenever someone tries to send ether to the contract */
    function () {
        throw; // Prevents accidental sending of ether
    }
}

/**
 * Chess contract
 * Stores any amount of games with two players and current state.
 * State encoding:
 *    positive numbers for white, negative numbers for black
 *    for details, see
 *    https://github.com/ise-ethereum/on-chain-chess/wiki/Chess-board-representation
 */

import "TurnBasedGame.sol";
import "ChessLogic.sol";

contract Chess is TurnBasedGame {
    using ChessLogic for ChessLogic.State;
    mapping (bytes32 => ChessLogic.State) gameStates;

    event GameInitialized(bytes32 indexed gameId, address indexed player1, string player1Alias, address playerWhite, uint value);
    event GameJoined(bytes32 indexed gameId, address indexed player1, string player1Alias, address indexed player2, string player2Alias, address playerWhite, uint value);
    event GameStateChanged(bytes32 indexed gameId, int8[128] state);
    event GameTimeoutStarted(bytes32 indexed gameId,uint timeoutStarted, int8 timeoutState);
    event Move(bytes32 indexed gameId, address indexed player, uint256 fromIndex, uint256 toIndex);

    function Chess(bool enableDebugging) TurnBasedGame(enableDebugging) {
    }

    /**
     * Initialize a new game
     * string player1Alias: Alias of the player creating the game
     * bool playAsWhite: Pass true or false depending on if the creator will play as white
     */
    function initGame(string player1Alias, bool playAsWhite) public returns (bytes32) {
        bytes32 gameId = super.initGame(player1Alias, playAsWhite);

        // Setup game state
        int8 nextPlayerColor = playAsWhite ? int8(1) : int8(-1);
        gameStates[gameId].setupState(nextPlayerColor);

        if (playAsWhite) {
            // Player 1 will play as white
            gameStates[gameId].playerWhite = msg.sender;

            // Game starts with White, so here player 1
            games[gameId].nextPlayer = games[gameId].player1;
        }

        // Sent notification events
        GameInitialized(gameId, games[gameId].player1, player1Alias, gameStates[gameId].playerWhite, games[gameId].value);
        GameStateChanged(gameId, gameStates[gameId].fields);
        return gameId;
    }

    /**
     * Join an initialized game
     * bytes32 gameId: ID of the game to join
     * string player2Alias: Alias of the player that is joining
     */
    function joinGame(bytes32 gameId, string player2Alias) public {
        super.joinGame(gameId, player2Alias);

        // If the other player isn't white, player2 will play as white
        if (gameStates[gameId].playerWhite == 0) {
            gameStates[gameId].playerWhite = msg.sender;
            // Game starts with White, so here player2
            games[gameId].nextPlayer = games[gameId].player2;
        }

        GameJoined(gameId, games[gameId].player1, games[gameId].player1Alias, games[gameId].player2, player2Alias, gameStates[gameId].playerWhite, games[gameId].value);
    }

    function move(bytes32 gameId, uint256 fromIndex, uint256 toIndex) notEnded(gameId) public {
        if (games[gameId].nextPlayer != msg.sender) {
            throw;
        }
        if(games[gameId].timeoutState != 0) {
            games[gameId].timeoutState = 0;
        }
        // Chess move validation
        gameStates[gameId].move(fromIndex, toIndex);

        // Set nextPlayer
        if (msg.sender == games[gameId].player1) {
            games[gameId].nextPlayer = games[gameId].player2;
        } else {
            games[gameId].nextPlayer = games[gameId].player1;
        }

        // Send events
        Move(gameId, msg.sender, fromIndex, toIndex);
        GameStateChanged(gameId, gameStates[gameId].fields);
    }

    /* Explicit set game state. Only in debug mode */
    function setGameState(bytes32 gameId, int8[128] state, address nextPlayer) debugOnly public {
        int8 playerColor = nextPlayer == gameStates[gameId].playerWhite ? int8(1) : int8(-1);
        gameStates[gameId].setState(state, playerColor);
        games[gameId].nextPlayer = nextPlayer;
        GameStateChanged(gameId, gameStates[gameId].fields);
    }

    function getCurrentGameState(bytes32 gameId) constant returns (int8[128]) {
       return gameStates[gameId].fields;
    }

    function getWhitePlayer(bytes32 gameId) constant returns (address) {
       return gameStates[gameId].playerWhite;
    }

    /* The sender claims he has won the game. Starts a timeout. */
    function claimWin(bytes32 gameId) notEnded(gameId) public {
        var game = games[gameId];
        // just the two players currently playing
        if (msg.sender != game.player1 && msg.sender != game.player2)
            throw;
        // only if timeout has not started
        if (game.timeoutState != 0)
            throw;
        // you can only claim draw / victory in the enemies turn
        if (msg.sender == game.nextPlayer)
            throw;
        game.timeoutStarted = now;
        game.timeoutState = 1;

        GameTimeoutStarted(gameId, game.timeoutStarted, game.timeoutState);
    }

    /* The sender offers the other player a draw. Starts a timeout. */
    function offerDraw(bytes32 gameId) notEnded(gameId) public {
        var game = games[gameId];
        // just the two players currently playing
        if (msg.sender != game.player1 && msg.sender != game.player2)
            throw;
        // only if timeout has not started
        if (game.timeoutState != 0)
            throw;
        // you can only claim draw / victory in the enemies turn
        if (msg.sender == game.nextPlayer)
            throw;
        game.timeoutStarted = now;
        game.timeoutState = -1;

        GameTimeoutStarted(gameId,game.timeoutStarted,game.timeoutState);
    }

    /* The sender claims a previously started timeout. */
    function claimTimeout(bytes32 gameId) notEnded(gameId) public {
        var game = games[gameId];
        // just the two players currently playing
        if (msg.sender != game.player1 && msg.sender != game.player2)
            throw;
        if (msg.sender == game.nextPlayer)
            throw;
        if (game.timeoutState == 0)
            throw;
        if (now < game.timeoutStarted + 10 minutes)
            throw;
        if (game.timeoutState == -1){
            game.ended = true;
            GameEnded(gameId, 0);
        } else if (game.timeoutState == 1){
            game.ended = true;
            game.winner = msg.sender;
            GameEnded(gameId, msg.sender);
        } else {
            throw;
        }
    }

    /* A timeout can be confirmed by the non-initializing player. */
    function confirmGameEnded(bytes32 gameId) notEnded(gameId) public {
        var game = games[gameId];
        // just the two players currently playing
        if (msg.sender != game.player1 && msg.sender != game.player2)
            throw;
        if (msg.sender != game.nextPlayer)
            throw;
        if (game.timeoutState == 0)
            throw;
        if (game.timeoutState == -1){
            game.ended = true;
            GameEnded(gameId, 0);
        } else if (game.timeoutState == 1){
            game.ended = true;
            // other player won
            game.winner = (msg.sender == game.player1 ? game.player2 : game.player1);
            GameEnded(gameId, game.winner);
        } else {
            throw;
        }
    }

    /* This unnamed function is called whenever someone tries to send ether to the contract */
    function () {
        throw; // Prevents accidental sending of ether
    }
}


Public ACL storage field

Public ACL storage field

import './ACLStorage.sol';

/**
 * @title Access Control List contract
 */
contract ACL {
    ACLStorage public acl;

    modifier onlyGroup(string _name) { if (!acl.isMemberOf(_name, msg.sender)) throw; _ }
}

import './ACLStorage.sol';

/**
 * @title Access Control List contract
 */
contract ACL {
    ACLStorage acl;

    modifier onlyGroup(string _name) { if (!acl.isMemberOf(_name, msg.sender)) throw; _ }
}


Add example contract for loops

Add example contract for loops

pragma solidity ^0.4.8;

// From https://www.blockchain-council.org/solidity/control-structure-solidity-programming-language/

// Solidity follows the same syntax of controle structures as Java script or C.
// hence Most of the control structures from JavaScript are available in Solidity
// except for switch and goto. So there is: if, else, while, do, for, break, continue,
// return, ? :, with the usual semantics known from C or JavaScript.

// Let's quickly go through ther syntax in this lecture.

contract ControlStructure {
  /*
   * @title A Simple Example
   * @author Toshendra Sharma
   * @notice Example for the Solidity Course
   * @dev This is only for demo the simple Coin example
   *
   */
  int public a;

  function ControlStructure(uint input1) {

    // if-else can be used like this
    if(input1 == 2)
      a = 1;
    else
      a = 0;

    // while can be used like this
    while(input1 >= 0){
      if(input1 == 5)
        continue;
      input1 = input1 - 1;
      a++;
    }

    // for loop can be used like this
    for(uint i=0; i<=50; i++)
      {
        a++;
        if(a == 4) break;
      }

    // do while can be used like this
    do{
      a--;
    } while (a>0);

    // Conditional Operator can be used like this
    bool isTrue = (a == 1)? true: false;

  }
}

error: pathspec 'examples/solidity.readthedocs.io/control-structures/loops.sol' did not match any file(s) known to git


Found out that I cant map contract implementations to things (even though the other way around works) so I commented out those lines until we figure it out. Added functions to use the master mappings from outside the master contract.

contract Master
{
  function Master()
  {

  }
  //Initialize master data store
  mapping(address => uint) tokenBalance;
  mapping(address => string) tagName;
  mapping(string => address) tagAddressFromName;
  mapping(address => Tag) tagImplementation;
  //mapping(Tag => address) tagAddressFromImplementation;
  mapping(address => string[]) acheivements;

  function mapTokenBalance(address a, uint b)
  {
    tokenBalance[a] = b;
  }
  function mapTagName(address a, string n)
  {
    tagName[a] = n;
  }
  function mapTagAddressFromName(string n, address a)
  {
    tagAddressFromName[n] = a;
  }
  function mapTagImplementation(address a, Tag t)
  {
    tagImplementation[a] = t;
  }
  function mapAcheivement(address a, string n)
  {
    acheivements[a].push(n);
  }
  function getTokenBalance(address a) returns(uint)
  {
    return tokenBalance[a];
  }
  function getTagName(address a) returns(string)
  {
    return tagName[a];
  }
  function getTagAddressFromName(string n) returns(address)
  {
    return tagAddressFromName[n];
  }
  function getTagImplementation(address a) returns(Tag)
  {
    return tagImplementation[a];
  }
  function getAcheivement(address a, uint i) returns(string)
  {
    return acheivements[a][i];
  }
  function getNumberOfAcheivements(address a) returns(uint)
  {
    return acheivements[a].length;
  }
  function addTag(string name, address[] parentList) returns(uint) //Creates a new tag contract
  {
    uint response = 0;
    if(tokenBalance[msg.sender] < 1)
    {
      response += 1;
    }
    if(tagAddressFromName[name] == 0)
    {
      response += 10;
    }
    if(response==0)
    {
      Tag newTag;
      address newTagAddress = address(newTag);
      tagName[newTagAddress] = name;
      tagAddressFromName[name] = newTagAddress;
      tagImplementation[newTagAddress] = newTag;
      //tagAddressFromImplementation[newTag] = newTagAddress;
      for(uint i=0; i<= parentList.length; i++) //adds all the given parents
      {
        if(parentList[i]==0)
        {
          response += 100;
        }
        if(response==0)
        {
          newTag.addParent(tagImplementation[parentList[i]]);
        }
      }
    }
    newTag.setMaster(this);
    newTag.setName(name);
    return response;
  }
}

//Defines the meta-contract for a Tag
contract Tag
{
  Tag[] parentTags;
  Master master;
  string name;
  address[] owners; //Those who have earned the tag
  mapping(address => address[]) assessmentHistory; //All assessments completed
  mapping(address => uint) scores; //All positive assessements scores
  function Tag()
  {

  }
  function addParent(Tag parentTag)
  {
    parentTags.push(parentTag);
  }
  function setMaster(Master m)
  {
    master = m;
  }
  function setName(string n)
  {
    name = n;
  }
  function getAssessors(uint randomNumber)
  {

  }
  function startAssessment(address assessee, address[] assessors)
  {
    Assessment newAssessment;
    newAssessment.setAssessee(assessee);
    newAssessment.setAssessors(assessors);
    newAssessment.setTag(this);
  }
  function getAssessmentResults(bool result, uint score, address assessee, address assessment) returns(bool)
  {
    if(result == true)
    {
      owners.push(assessee);
      scores[assessee] = score;
      master.mapAcheivement(assessee,name);
    }
    assessmentHistory[assessee].push(assessment);
    return result;
  }
}

//Defines the meta-contract for an assessment
contract Assessment
{
  address assessee; //We need a better word for this
  address[] assessors;
  Tag tag;
  mapping(address => uint[]) assessmentData; //Given by the assessors as IPFS hashes
  mapping(address => uint[]) assessmentAnswers; //Given by the assessee as IPFS hashes
  mapping(address => bool[]) assessmentResults; //Pass/Fail given by assessors
  mapping(address => uint[]) assessmentScores; //Numerical score given by assessors

  function Assessment()
  {

  }
  function setAssessee(address newAssessee)
  {
    assessee = newAssessee;
  }
  function setAssessors(address[] newAssessors)
  {
    assessors = newAssessors;
  }
  function setTag(Tag t)
  {
    tag = t;
  }
  function assess()
  {

  }
  function cashout()
  {

  }
}

contract Master
{
  function Master()
  {

  }
  //Initialize master data store
  mapping(address => uint) tokenBalance;
  mapping(address => string) tagName;
  mapping(string => address) tagAddressFromName;
  mapping(address => Tag) tagImplementation;
  mapping(Tag => address) tagAddressFromImplementation;
  mapping(address => string[]) acheivements;

  function addTag(string name, address[] parentList) returns(uint) //Creates a new tag contract
  {
    uint response = 0;
    if(tokenBalance[msg.sender] < 1)
    {
      response += 1;
    }
    if(tagAddress[name] == 0)
    {
      response += 10;
    }
    if(response==0)
    {
      Tag newTag;
      address newTagAddress = address(newTag);
      tagName[newTagAddress] = name;
      tagAddressFromName[name] = newTagAddress;
      tagImplementation[newTagAddress] = newTag;
      tagAddressFromImplementation[newTag] = newTagAddress;
      for(uint i=0; i<= parentList.length; i++) //adds all the given parents
      {
        if(parentList[i]==0)
        {
          response += 100;
        }
        if(response==0)
        {
          newTag.addParent(tagImplementation[parentList[i]]);
        }
      }
    }
    newTag.setMaster(this);
    return response;
  }
}

//Defines the meta-contract for a Tag
contract Tag
{
  Tag[] parentTags;
  Master master;
  address[] owners; //Those who have earned the tag
  mapping(address => address[]) assessmentHistory; //All assessments completed
  mapping(address => uint) scores; //All positive assessements scores
  function Tag()
  {

  }
  function addParent(Tag parentTag)
  {
    parentTags.push(parentTag);
  }
  function setMaster(Master m)
  {
    master = m;
  }
  function getAssessors(uint randomNumber)
  {

  }
  function startAssessment(address assessee, address[] assessors)
  {
    Assessment newAssessment;
    newAssessment.setAssessee(assessee);
    newAssessment.setAssessors(assessors);
    newAssessment.setTag(this);
  }
  function getAssessmentResults(bool result, uint score, address assessee, address assessment) returns(bool)
  {
    if(result == true)
    {
      owners.push(assessee);
      scores[assessee] = score;
      master.acheivements[assessee].push(master.tagName[address(this)]);
    }
    assessmentHistory[assessee].push(assessment);
    return result;
  }
}

//Defines the meta-contract for an assessment
contract Assessment
{
  address assessee; //We need a better word for this
  address[] assessors;
  Tag tag;
  mapping(address => uint[]) assessmentData; //Given by the assessors as IPFS hashes
  mapping(address => uint[]) assessmentAnswers; //Given by the assessee as IPFS hashes
  mapping(address => bool[]) assessmentResults; //Pass/Fail given by assessors
  mapping(address => uint[]) assessmentScores; //Numerical score given by assessors

  function Assessment()
  {

  }
  function setAssessee(address newAssessee)
  {
    assessee = newAssessee;
  }
  function setAssessors(address[] newAssessors)
  {
    assessors = newAssessors;
  }
  function setTag(Tag t)
  {
    tag = t;
  }
  function assess()
  {

  }
  function cashout()
  {

  }
}


Implement getScore

Implement getScore

import "lookup.sol";
import "accountProviderBase.sol";

contract Storage {
  Lookup lookup;

  address owner;

  modifier owneronly { if (msg.sender == owner) _ }

  function setOwner(address addr) owneronly {
    owner = addr;
  }

  function Storage() {
    owner = msg.sender;
  }

  function setLookup(address addr) owneronly {
    lookup = Lookup(addr);
  }

  struct Account {
    bool verified;
    uint8 accountProvider;
    string userId;
    bytes32 ipfsProof;
    uint24 score; // fits 0..1000000 (where 0 means no score yet, while >1 is a score)
  }

  struct Person {
    bytes32 id;
    address[] ethaddrs; // not yet populated
    mapping (uint8 => Account) accounts;
    mapping (bytes32 => bytes) extraDataBytes; // unverified data
    mapping (bytes32 => uint) extraDataUnit; // unverified data
  }

  // map unique id to person
  mapping (bytes32 => Person) public persons;

  // quick lookup index based on ethereum addresses
  mapping (address => bytes32) public addressToPersonId;

  // well, this can be removed if we assume id != 0
  mapping (address => bool) public addressPresent;

  function bindEthereumAddress(address addr, bytes32 id) internal {
    addressPresent[addr] = true;
    addressToPersonId[addr] = id;
    // FIXME: amend person.ethaddrs too
  }

  function unbindEthereumAddress(address addr, bytes32 id) internal {
    delete addressPresent[addr];
    delete addressToPersonId[addr];
    // FIXME: amend person.ethaddress too
  }

  // For methods which needs to come from a registered user
  modifier useronly {
    if (!addressPresent[msg.sender])
      throw;
    _
  }

  // Register a new user
  function register() returns (bytes32 id) {
    // is it already set up?
    if (addressPresent[msg.sender])
      throw;

    // create new record
    Person memory person;
    id = person.id = sha3(msg.sender, block.number);

    // set up mappings
    persons[id] = person;
    bindEthereumAddress(msg.sender, id);
  }

  // add new ethereum address
  function linkAddress(address addr) useronly {
    if (addressPresent[addr])
      throw; // already linked

    bindEthereumAddress(addr, addressToPersonId[msg.sender]);
  }

  // remove ethereum link
  function unlinkAddress(address addr) useronly {
    bytes32 id = addressToPersonId[addr];

    // does the userid of `addr` belongs to the sender?
    if (addressToPersonId[msg.sender] != id)
      throw;

    // FIXME: check if its the only address linked and reject if it is

    unbindEthereumAddress(addr, id);
  }

  // Start the verification process, call up the actual verifier and expect an answer in `updateAccount`
  function linkAccount(uint8 accountProvider, string userId, string proofLocation) useronly {
    bytes32 id = addressToPersonId[msg.sender];
    Person person = persons[id];

    // Prepare new account for the user, set it to non-verified
    Account memory account;
    account.verified = false;
    account.accountProvider = accountProvider;
    account.userId = userId;
    person.accounts[accountProvider] = account;

    accountProviderBase(lookup.accountProviders(accountProvider)).verify(id, userId, proofLocation);
  }

  function updateAccount(uint8 accountProvider, bytes32 id, bool result, bytes32 ipfsProof) {
    if (msg.sender != lookup.accountProviders(accountProvider))
      throw;

    Person person = persons[id];
    // This ID is not in the system yet
    if (person.id != id)
      throw; // FIXME: throw?

    // Update the account with the verification result
    Account account = person.accounts[accountProvider];
    // This verification wasn't initiated from Storage
    if (account.accountProvider == 0)
      throw; // FIXME: throw?

    account.verified = result;
    account.ipfsProof = ipfsProof;
    person.accounts[accountProvider] = account; // FIXME: is this needed? I don't think its needed as above is not memory? I think it's already done automatically being a reference
  }

  function getScore(uint8 accountProvider, bytes32 id) public returns (uint24) {
    Person person = persons[id];
    // This ID is not in the system yet
    if (person.id != id)
      throw; // FIXME: throw?

    // Update the account with the verification result
    Account account = person.accounts[accountProvider];
    // This verification wasn't initiated from Storage
    if (account.accountProvider == 0)
      throw; // FIXME: throw?

    return account.score;
  }
}

import "lookup.sol";
import "accountProviderBase.sol";

contract Storage {
  Lookup lookup;

  address owner;

  modifier owneronly { if (msg.sender == owner) _ }

  function setOwner(address addr) owneronly {
    owner = addr;
  }

  function Storage() {
    owner = msg.sender;
  }

  function setLookup(address addr) owneronly {
    lookup = Lookup(addr);
  }

  struct Account {
    bool verified;
    uint8 accountProvider;
    string userId;
    bytes32 ipfsProof;
    uint24 score; // fits 0..1000000 (where 0 means no score yet, while >1 is a score)
  }

  struct Person {
    bytes32 id;
    address[] ethaddrs; // not yet populated
    mapping (uint8 => Account) accounts;
    mapping (bytes32 => bytes) extraDataBytes; // unverified data
    mapping (bytes32 => uint) extraDataUnit; // unverified data
  }

  // map unique id to person
  mapping (bytes32 => Person) public persons;

  // quick lookup index based on ethereum addresses
  mapping (address => bytes32) public addressToPersonId;

  // well, this can be removed if we assume id != 0
  mapping (address => bool) public addressPresent;

  function bindEthereumAddress(address addr, bytes32 id) internal {
    addressPresent[addr] = true;
    addressToPersonId[addr] = id;
    // FIXME: amend person.ethaddrs too
  }

  function unbindEthereumAddress(address addr, bytes32 id) internal {
    delete addressPresent[addr];
    delete addressToPersonId[addr];
    // FIXME: amend person.ethaddress too
  }

  // For methods which needs to come from a registered user
  modifier useronly {
    if (!addressPresent[msg.sender])
      throw;
    _
  }

  // Register a new user
  function register() returns (bytes32 id) {
    // is it already set up?
    if (addressPresent[msg.sender])
      throw;

    // create new record
    Person memory person;
    id = person.id = sha3(msg.sender, block.number);

    // set up mappings
    persons[id] = person;
    bindEthereumAddress(msg.sender, id);
  }

  // add new ethereum address
  function linkAddress(address addr) useronly {
    if (addressPresent[addr])
      throw; // already linked

    bindEthereumAddress(addr, addressToPersonId[msg.sender]);
  }

  // remove ethereum link
  function unlinkAddress(address addr) useronly {
    bytes32 id = addressToPersonId[addr];

    // does the userid of `addr` belongs to the sender?
    if (addressToPersonId[msg.sender] != id)
      throw;

    // FIXME: check if its the only address linked and reject if it is

    unbindEthereumAddress(addr, id);
  }

  // Start the verification process, call up the actual verifier and expect an answer in `updateAccount`
  function linkAccount(uint8 accountProvider, string userId, string proofLocation) useronly {
    bytes32 id = addressToPersonId[msg.sender];
    Person person = persons[id];

    // Prepare new account for the user, set it to non-verified
    Account memory account;
    account.verified = false;
    account.accountProvider = accountProvider;
    account.userId = userId;
    person.accounts[accountProvider] = account;

    accountProviderBase(lookup.accountProviders(accountProvider)).verify(id, userId, proofLocation);
  }

  function updateAccount(uint8 accountProvider, bytes32 id, bool result, bytes32 ipfsProof) {
    if (msg.sender != lookup.accountProviders(accountProvider))
      throw;

    Person person = persons[id];
    // This ID is not in the system yet
    if (person.id != id)
      throw; // FIXME: throw?

    // Update the account with the verification result
    Account account = person.accounts[accountProvider];
    // This verification wasn't initiated from Storage
    if (account.accountProvider == 0)
      throw; // FIXME: throw?

    account.verified = result;
    account.ipfsProof = ipfsProof;
    person.accounts[accountProvider] = account; // FIXME: is this needed? I don't think its needed as above is not memory? I think it's already done automatically being a reference
  }
}


Prepare tag 0.3.0

Prepare tag 0.3.0

add mapping element search for DaoNode

contract core {
	string public daoName;
	string public desc;
	address public admin;
	uint public nodesAmount;
	uint public templatesAmount;

	modifier adminCheck { if (msg.sender == admin) _ }

	struct DaoNode {
	    string itemscope;
		string interface;
		string code;
	}

	DaoNode[] daoNodes;
	mapping (string => uint) public daoNodeOf;
	mapping (string => bool) public daoNodeExistOf;

	struct Template {
		string code;
		string interface;
		string actions;
		string itemscope;
		address thesaurus;
		bool inactive;
	}

	Template[] templates;
	mapping (string => uint) public itemscopeTemplateOf;
	mapping (string => bool) public itemscopeTemplateExistOf;

	function core(string _daoName, string _desc) {
		daoName = _daoName;
		desc = _desc;
		admin = msg.sender;
	}

	function setDaoNode(string _itemscope,
	                    string _interface,
						string _code) adminCheck returns(bool result, uint daoNodeID) {
		daoNodeID = daoNodes.length++;
		DaoNode d = daoNodes[daoNodeID];
		d.itemscope = _itemscope;
		d.interface = _interface;
		d.code = _code;
		result = true;
		nodesAmount +=1;
		daoNodeOf[d.itemscope] = daoNodeID;
		daoNodeExistOf[d.itemscope] = true;
        return(result, daoNodeID);
	}

	function getDaoNode() {}

	function setTemplate(string _code,
						 string _interface,
						 string _actions,
						 string _itemscope,
						 address _thesaurus) adminCheck returns(bool result, uint templateID) {
		templateID = templates.length++;
		Template t = templates[templateID];
        t.code = _code;
        t.interface = _interface;
        t.actions = _actions;
        t.itemscope = _itemscope;
        t.thesaurus = _thesaurus;
        itemscopeTemplateExistOf[t.itemscope] = true;
        itemscopeTemplateOf[t.itemscope] = templateID;
        templatesAmount +=1;
        result = true;
        return(result, templateID);
	}

	function getTemplate() {}
}

contract core {
	string public daoName;
	string public desc;
	address public admin;

	modifier adminCheck { if (msg.sender == admin) _ }

	struct DaoNode {
		string interface;
		string code;
	}

	DaoNode[] daoNodes;

	struct Template {
		string code;
		string interface;
		string actions;
		string itemscope;
		address thesaurus;
		bool inactive;
	}

	Template[] templates;
	mapping (string => uint) public itemscopeTemplateOf;
	mapping (string => bool) public itemscopeTemplateExistOf;

	function core(string _daoName, string _desc) {
		daoName = _daoName;
		desc = _desc;
		admin = msg.sender;
	}

	function setDaoNode(string _interface,
						string _code) adminCheck returns(bool result, uint daoNodeID) {
		daoNodeID = daoNodes.length++;
		DaoNode d = daoNodes[daoNodeID];
		d.interface = _interface;
		d.code = _code;
		result = true;
        return(result, daoNodeID);
	}

	function getDaoNode() {}

	function setTemplate(string _code,
						 string _interface,
						 string _actions,
						 string _itemscope,
						 address _thesaurus) adminCheck returns(bool result, uint templateID) {
		templateID = templates.length++;
		Template t = templates[templateID];
        t.code = _code;
        t.interface = _interface;
        t.actions = _actions;
        t.itemscope = _itemscope;
        t.thesaurus = _thesaurus;
        itemscopeTemplateExistOf[t.itemscope] = true;
        itemscopeTemplateOf[t.itemscope] = templateID;
        result = true;
        return(result, templateID);
	}

	function getTemplate() {}
}


Keep mask calc unchecked

Keep mask calc unchecked

pragma solidity ^0.8.4;

/**
* @dev A library for working with mutable byte buffers in Solidity.
*
* Byte buffers are mutable and expandable, and provide a variety of primitives
* for writing to them. At any time you can fetch a bytes object containing the
* current contents of the buffer. The bytes object should not be stored between
* operations, as it may change due to resizing of the buffer.
*/
library Buffer {
    /**
    * @dev Represents a mutable buffer. Buffers have a current value (buf) and
    *      a capacity. The capacity may be longer than the current value, in
    *      which case it can be extended without the need to allocate more memory.
    */
    struct buffer {
        bytes buf;
        uint capacity;
    }

    /**
    * @dev Initializes a buffer with an initial capacity.
    * @param buf The buffer to initialize.
    * @param capacity The number of bytes of space to allocate the buffer.
    * @return The buffer, for chaining.
    */
    function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) {
        if (capacity % 32 != 0) {
            capacity += 32 - (capacity % 32);
        }
        // Allocate space for the buffer data
        buf.capacity = capacity;
        assembly {
            let ptr := mload(0x40)
            mstore(buf, ptr)
            mstore(ptr, 0)
            mstore(0x40, add(32, add(ptr, capacity)))
        }
        return buf;
    }

    /**
    * @dev Initializes a new buffer from an existing bytes object.
    *      Changes to the buffer may mutate the original value.
    * @param b The bytes object to initialize the buffer with.
    * @return A new buffer.
    */
    function fromBytes(bytes memory b) internal pure returns(buffer memory) {
        buffer memory buf;
        buf.buf = b;
        buf.capacity = b.length;
        return buf;
    }

    function resize(buffer memory buf, uint capacity) private pure {
        bytes memory oldbuf = buf.buf;
        init(buf, capacity);
        append(buf, oldbuf);
    }

    function max(uint a, uint b) private pure returns(uint) {
        if (a > b) {
            return a;
        }
        return b;
    }

    /**
    * @dev Sets buffer length to 0.
    * @param buf The buffer to truncate.
    * @return The original buffer, for chaining..
    */
    function truncate(buffer memory buf) internal pure returns (buffer memory) {
        assembly {
            let bufptr := mload(buf)
            mstore(bufptr, 0)
        }
        return buf;
    }

    /**
    * @dev Writes a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The start offset to write to.
    * @param data The data to append.
    * @param len The number of bytes to copy.
    * @return The original buffer, for chaining.
    */
    function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns(buffer memory) {
        require(len <= data.length);

        if (off + len > buf.capacity) {
            resize(buf, max(buf.capacity, len + off) * 2);
        }

        uint dest;
        uint src;
        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Length of existing buffer data
            let buflen := mload(bufptr)
            // Start address = buffer address + offset + sizeof(buffer length)
            dest := add(add(bufptr, 32), off)
            // Update buffer length if we're extending it
            if gt(add(len, off), buflen) {
                mstore(bufptr, add(len, off))
            }
            src := add(data, 32)
        }

        // Copy word-length chunks while possible
        for (; len >= 32; len -= 32) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += 32;
            src += 32;
        }

        // Copy remaining bytes
        unchecked {
            uint mask = (256 ** (32 - len)) - 1;
            assembly {
                let srcpart := and(mload(src), not(mask))
                let destpart := and(mload(dest), mask)
                mstore(dest, or(destpart, srcpart))
            }
        }

        return buf;
    }

    /**
    * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @param len The number of bytes to copy.
    * @return The original buffer, for chaining.
    */
    function append(buffer memory buf, bytes memory data, uint len) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, len);
    }

    /**
    * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, data.length);
    }

    /**
    * @dev Writes a byte to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write the byte at.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function writeUint8(buffer memory buf, uint off, uint8 data) internal pure returns(buffer memory) {
        if (off >= buf.capacity) {
            resize(buf, buf.capacity * 2);
        }

        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Length of existing buffer data
            let buflen := mload(bufptr)
            // Address = buffer address + sizeof(buffer length) + off
            let dest := add(add(bufptr, off), 32)
            mstore8(dest, data)
            // Update buffer length if we extended it
            if eq(off, buflen) {
                mstore(bufptr, add(buflen, 1))
            }
        }
        return buf;
    }

    /**
    * @dev Appends a byte to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) {
        return writeUint8(buf, buf.buf.length, data);
    }

    /**
    * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would
    *      exceed the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @param len The number of bytes to write (left-aligned).
    * @return The original buffer, for chaining.
    */
    function write(buffer memory buf, uint off, bytes32 data, uint len) private pure returns(buffer memory) {
        if (len + off > buf.capacity) {
            resize(buf, (len + off) * 2);
        }

        unchecked {
            uint mask = (256 ** len) - 1;
            // Right-align data
            data = data >> (8 * (32 - len));
            assembly {
                // Memory address of the buffer data
                let bufptr := mload(buf)
                // Address = buffer address + sizeof(buffer length) + off + len
                let dest := add(add(bufptr, off), len)
                mstore(dest, or(and(mload(dest), not(mask)), data))
                // Update buffer length if we extended it
                if gt(add(off, len), mload(bufptr)) {
                    mstore(bufptr, add(off, len))
                }
            }
        }
        return buf;
    }

    /**
    * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function writeBytes20(buffer memory buf, uint off, bytes20 data) internal pure returns (buffer memory) {
        return write(buf, off, bytes32(data), 20);
    }

    /**
    * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chhaining.
    */
    function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, bytes32(data), 20);
    }

    /**
    * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, 32);
    }

    /**
    * @dev Writes an integer to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @param len The number of bytes to write (right-aligned).
    * @return The original buffer, for chaining.
    */
    function writeInt(buffer memory buf, uint off, uint data, uint len) private pure returns(buffer memory) {
        if (len + off > buf.capacity) {
            resize(buf, (len + off) * 2);
        }

        uint mask = (256 ** len) - 1;
        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Address = buffer address + off + sizeof(buffer length) + len
            let dest := add(add(bufptr, off), len)
            mstore(dest, or(and(mload(dest), not(mask)), data))
            // Update buffer length if we extended it
            if gt(add(off, len), mload(bufptr)) {
                mstore(bufptr, add(off, len))
            }
        }
        return buf;
    }

    /**
     * @dev Appends a byte to the end of the buffer. Resizes if doing so would
     * exceed the capacity of the buffer.
     * @param buf The buffer to append to.
     * @param data The data to append.
     * @return The original buffer.
     */
    function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) {
        return writeInt(buf, buf.buf.length, data, len);
    }
}

pragma solidity ^0.8.4;

/**
* @dev A library for working with mutable byte buffers in Solidity.
*
* Byte buffers are mutable and expandable, and provide a variety of primitives
* for writing to them. At any time you can fetch a bytes object containing the
* current contents of the buffer. The bytes object should not be stored between
* operations, as it may change due to resizing of the buffer.
*/
library Buffer {
    /**
    * @dev Represents a mutable buffer. Buffers have a current value (buf) and
    *      a capacity. The capacity may be longer than the current value, in
    *      which case it can be extended without the need to allocate more memory.
    */
    struct buffer {
        bytes buf;
        uint capacity;
    }

    /**
    * @dev Initializes a buffer with an initial capacity.
    * @param buf The buffer to initialize.
    * @param capacity The number of bytes of space to allocate the buffer.
    * @return The buffer, for chaining.
    */
    function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) {
        if (capacity % 32 != 0) {
            capacity += 32 - (capacity % 32);
        }
        // Allocate space for the buffer data
        buf.capacity = capacity;
        assembly {
            let ptr := mload(0x40)
            mstore(buf, ptr)
            mstore(ptr, 0)
            mstore(0x40, add(32, add(ptr, capacity)))
        }
        return buf;
    }

    /**
    * @dev Initializes a new buffer from an existing bytes object.
    *      Changes to the buffer may mutate the original value.
    * @param b The bytes object to initialize the buffer with.
    * @return A new buffer.
    */
    function fromBytes(bytes memory b) internal pure returns(buffer memory) {
        buffer memory buf;
        buf.buf = b;
        buf.capacity = b.length;
        return buf;
    }

    function resize(buffer memory buf, uint capacity) private pure {
        bytes memory oldbuf = buf.buf;
        init(buf, capacity);
        append(buf, oldbuf);
    }

    function max(uint a, uint b) private pure returns(uint) {
        if (a > b) {
            return a;
        }
        return b;
    }

    /**
    * @dev Sets buffer length to 0.
    * @param buf The buffer to truncate.
    * @return The original buffer, for chaining..
    */
    function truncate(buffer memory buf) internal pure returns (buffer memory) {
        assembly {
            let bufptr := mload(buf)
            mstore(bufptr, 0)
        }
        return buf;
    }

    /**
    * @dev Writes a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The start offset to write to.
    * @param data The data to append.
    * @param len The number of bytes to copy.
    * @return The original buffer, for chaining.
    */
    function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns(buffer memory) {
        require(len <= data.length);

        if (off + len > buf.capacity) {
            resize(buf, max(buf.capacity, len + off) * 2);
        }

        uint dest;
        uint src;
        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Length of existing buffer data
            let buflen := mload(bufptr)
            // Start address = buffer address + offset + sizeof(buffer length)
            dest := add(add(bufptr, 32), off)
            // Update buffer length if we're extending it
            if gt(add(len, off), buflen) {
                mstore(bufptr, add(len, off))
            }
            src := add(data, 32)
        }

        // Copy word-length chunks while possible
        for (; len >= 32; len -= 32) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += 32;
            src += 32;
        }

        // Copy remaining bytes
        uint mask = 256 ** ((32 - len) - 1);
        assembly {
            let srcpart := and(mload(src), not(mask))
            let destpart := and(mload(dest), mask)
            mstore(dest, or(destpart, srcpart))
        }

        return buf;
    }

    /**
    * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @param len The number of bytes to copy.
    * @return The original buffer, for chaining.
    */
    function append(buffer memory buf, bytes memory data, uint len) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, len);
    }

    /**
    * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, data.length);
    }

    /**
    * @dev Writes a byte to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write the byte at.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function writeUint8(buffer memory buf, uint off, uint8 data) internal pure returns(buffer memory) {
        if (off >= buf.capacity) {
            resize(buf, buf.capacity * 2);
        }

        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Length of existing buffer data
            let buflen := mload(bufptr)
            // Address = buffer address + sizeof(buffer length) + off
            let dest := add(add(bufptr, off), 32)
            mstore8(dest, data)
            // Update buffer length if we extended it
            if eq(off, buflen) {
                mstore(bufptr, add(buflen, 1))
            }
        }
        return buf;
    }

    /**
    * @dev Appends a byte to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) {
        return writeUint8(buf, buf.buf.length, data);
    }

    /**
    * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would
    *      exceed the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @param len The number of bytes to write (left-aligned).
    * @return The original buffer, for chaining.
    */
    function write(buffer memory buf, uint off, bytes32 data, uint len) private pure returns(buffer memory) {
        if (len + off > buf.capacity) {
            resize(buf, (len + off) * 2);
        }

        unchecked {
            uint mask = (256 ** len) - 1;
            // Right-align data
            data = data >> (8 * (32 - len));
            assembly {
                // Memory address of the buffer data
                let bufptr := mload(buf)
                // Address = buffer address + sizeof(buffer length) + off + len
                let dest := add(add(bufptr, off), len)
                mstore(dest, or(and(mload(dest), not(mask)), data))
                // Update buffer length if we extended it
                if gt(add(off, len), mload(bufptr)) {
                    mstore(bufptr, add(off, len))
                }
            }
        }
        return buf;
    }

    /**
    * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function writeBytes20(buffer memory buf, uint off, bytes20 data) internal pure returns (buffer memory) {
        return write(buf, off, bytes32(data), 20);
    }

    /**
    * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chhaining.
    */
    function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, bytes32(data), 20);
    }

    /**
    * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, 32);
    }

    /**
    * @dev Writes an integer to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @param len The number of bytes to write (right-aligned).
    * @return The original buffer, for chaining.
    */
    function writeInt(buffer memory buf, uint off, uint data, uint len) private pure returns(buffer memory) {
        if (len + off > buf.capacity) {
            resize(buf, (len + off) * 2);
        }

        uint mask = (256 ** len) - 1;
        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Address = buffer address + off + sizeof(buffer length) + len
            let dest := add(add(bufptr, off), len)
            mstore(dest, or(and(mload(dest), not(mask)), data))
            // Update buffer length if we extended it
            if gt(add(off, len), mload(bufptr)) {
                mstore(bufptr, add(off, len))
            }
        }
        return buf;
    }

    /**
     * @dev Appends a byte to the end of the buffer. Resizes if doing so would
     * exceed the capacity of the buffer.
     * @param buf The buffer to append to.
     * @param data The data to append.
     * @return The original buffer.
     */
    function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) {
        return writeInt(buf, buf.buf.length, data, len);
    }
}


Add fallback fn to PresaleToken

Add fallback fn to PresaleToken

pragma solidity ^0.4.4;

// ERC20 token interface is implemented only partially.
// Token transfer is prohibited due to spec (see PRESALE-SPEC.md),
// hence some functions are left undefined:
//  - transfer, transferFrom,
//  - approve, allowance.

contract PresaleToken {

    /// @dev Constructor
    /// @param _tokenManager Token manager address.
    function PresaleToken(address _tokenManager) {
        tokenManager = _tokenManager;
    }

    /*/
     *  Constants
    /*/
    string public name = "DilationPresaleToken";
    string public symbol = "DPT";
    uint   public decimals = 18;

    uint private PRICE = 200; // 200 DPT per Ether
    uint private TOKEN_SUPPLY_LIMIT = 4000000 * (1 ether / 1 wei);

    /*/
     *  Token state
    /*/

    enum Phase {
        Created,
        Running,
        Paused,
        Migrating,
        Migrated
    }
    Phase public currentPhase = Phase.Created;

    uint public totalSupply = 0; // amount of tokens already sold
    mapping (address => uint256) private balance;

    // Token manager has exclusive priveleges to call administrative
    // functions on this contract.
    address private tokenManager;
    // Crowdsale manager has exclusive priveleges to burn presale tokens.
    address public crowdsaleManager;

    modifier onlyTokenManager()     { if(msg.sender != tokenManager) throw; _; }
    modifier onlyCrowdsaleManager() { if(msg.sender != crowdsaleManager) throw; _; }

    /*/
     *  Events
    /*/

    event LogBuy(address indexed owner, uint value);
    event LogBurn(address indexed owner, uint value);
    event LogPhaseSwitch(Phase newPhase);

    /*/
     *  Public functions
    /*/

    function() payable {
        buyTokens(msg.sender);
    }

    /// @dev Lets buy you some tokens.
    function buyTokens(address _buyer) public payable {
        // Available only if presale is running.
        if(currentPhase != Phase.Running) throw;

        if(msg.value == 0) throw;
        uint newTokens = msg.value * PRICE;
        if (totalSupply + newTokens > TOKEN_SUPPLY_LIMIT) throw;
        balance[_buyer] += newTokens;
        totalSupply += newTokens;
        LogBuy(_buyer, newTokens);
    }

    /// @dev Returns number of tokens owned by given address.
    /// @param _owner Address of token owner.
    function burnTokens(address _owner) public
        onlyCrowdsaleManager
    {
        // Available only during migration phase
        if(currentPhase != Phase.Migrating) throw;

        uint tokens = balance[_owner];
        if(tokens == 0) throw;
        balance[_owner] = 0;
        totalSupply -= tokens;
        LogBurn(_owner, tokens);

        // Automatically switch phase when migration is done.
        if(totalSupply == 0) {
            currentPhase = Phase.Migrated;
            LogPhaseSwitch(Phase.Migrated);
        }
    }

    /// @dev Returns number of tokens owned by given address.
    /// @param _owner Address of token owner.
    function balanceOf(address _owner) constant returns (uint256) {
        return balance[_owner];
    }

    /*/
     *  Administrative functions
    /*/

    function setPresalePhase(Phase _nextPhase) public
        onlyTokenManager
    {
        bool canSwitchPhase
            =  (currentPhase == Phase.Created && _nextPhase == Phase.Running)
            || (currentPhase == Phase.Running && _nextPhase == Phase.Paused)
                // switch to migration phase only if crowdsale manager is set
            || ((currentPhase == Phase.Running || currentPhase == Phase.Paused)
                && _nextPhase == Phase.Migrating
                && crowdsaleManager != 0x0)
            || (currentPhase == Phase.Paused && _nextPhase == Phase.Running)
            || (currentPhase == Phase.Migrating && _nextPhase == Phase.Migrated
                && totalSupply == 0);

        if(!canSwitchPhase) throw;
        else {
            currentPhase = _nextPhase;
            LogPhaseSwitch(_nextPhase);
        }
    }

    function withdrawEther() public
        onlyTokenManager
    {
        // Available at any phase.
        if(this.balance > 0) {
            if(!tokenManager.send(this.balance)) throw;
        }
    }

    function setCrowdsaleManager(address _mgr) public
        onlyTokenManager
    {
        // You can't change crowdsale contract when migration is in progress.
        if(currentPhase == Phase.Migrating) throw;
        crowdsaleManager = _mgr;
    }

    function selfdestruct() public
        onlyTokenManager
    {
        // Available only if nothing hapened yet or if presale is totally
        // completed.
        if(currentPhase != Phase.Created && currentPhase != Phase.Migrated)
          throw;
        suicide(tokenManager); // send remaining funds to tokenManager
    }
}

pragma solidity ^0.4.4;

// ERC20 token interface is implemented only partially.
// Token transfer is prohibited due to spec (see PRESALE-SPEC.md),
// hence some functions are left undefined:
//  - transfer, transferFrom,
//  - approve, allowance.

contract PresaleToken {

    /// @dev Constructor
    /// @param _tokenManager Token manager address.
    function PresaleToken(address _tokenManager) {
        tokenManager = _tokenManager;
    }

    /*/
     *  Constants
    /*/
    string public name = "DilationPresaleToken";
    string public symbol = "DPT";
    uint   public decimals = 18;

    uint private PRICE = 200; // 200 DPT per Ether
    uint private TOKEN_SUPPLY_LIMIT = 4000000 * (1 ether / 1 wei);

    /*/
     *  Token state
    /*/

    enum Phase {
        Created,
        Running,
        Paused,
        Migrating,
        Migrated
    }
    Phase public currentPhase = Phase.Created;

    uint public totalSupply = 0; // amount of tokens already sold
    mapping (address => uint256) private balance;

    // Token manager has exclusive priveleges to call administrative
    // functions on this contract.
    address private tokenManager;
    // Crowdsale manager has exclusive priveleges to burn presale tokens.
    address public crowdsaleManager;

    modifier onlyTokenManager()     { if(msg.sender != tokenManager) throw; _; }
    modifier onlyCrowdsaleManager() { if(msg.sender != crowdsaleManager) throw; _; }

    /*/
     *  Events
    /*/

    event LogBuy(address indexed owner, uint value);
    event LogBurn(address indexed owner, uint value);
    event LogPhaseSwitch(Phase newPhase);

    /*/
     *  Public functions
    /*/

    /// @dev Lets buy you some tokens.
    function buyTokens() public payable {
        // Available only if presale is running.
        if(currentPhase != Phase.Running) throw;

        if(msg.value == 0) throw;
        uint newTokens = msg.value * PRICE;
        if (totalSupply + newTokens > TOKEN_SUPPLY_LIMIT) throw;
        balance[msg.sender] += newTokens;
        totalSupply += newTokens;
        LogBuy(msg.sender, newTokens);
    }

    /// @dev Returns number of tokens owned by given address.
    /// @param _owner Address of token owner.
    function burnTokens(address _owner) public
        onlyCrowdsaleManager
    {
        // Available only during migration phase
        if(currentPhase != Phase.Migrating) throw;

        uint tokens = balance[_owner];
        if(tokens == 0) throw;
        balance[_owner] = 0;
        totalSupply -= tokens;
        LogBurn(_owner, tokens);

        // Automatically switch phase when migration is done.
        if(totalSupply == 0) {
            currentPhase = Phase.Migrated;
            LogPhaseSwitch(Phase.Migrated);
        }
    }

    /// @dev Returns number of tokens owned by given address.
    /// @param _owner Address of token owner.
    function balanceOf(address _owner) constant returns (uint256) {
        return balance[_owner];
    }

    /*/
     *  Administrative functions
    /*/

    function setPresalePhase(Phase _nextPhase) public
        onlyTokenManager
    {
        bool canSwitchPhase
            =  (currentPhase == Phase.Created && _nextPhase == Phase.Running)
            || (currentPhase == Phase.Running && _nextPhase == Phase.Paused)
                // switch to migration phase only if crowdsale manager is set
            || ((currentPhase == Phase.Running || currentPhase == Phase.Paused)
                && _nextPhase == Phase.Migrating
                && crowdsaleManager != 0x0)
            || (currentPhase == Phase.Paused && _nextPhase == Phase.Running)
            || (currentPhase == Phase.Migrating && _nextPhase == Phase.Migrated
                && totalSupply == 0);

        if(!canSwitchPhase) throw;
        else {
            currentPhase = _nextPhase;
            LogPhaseSwitch(_nextPhase);
        }
    }

    function withdrawEther() public
        onlyTokenManager
    {
        // Available at any phase.
        if(this.balance > 0) {
            if(!tokenManager.send(this.balance)) throw;
        }
    }

    function setCrowdsaleManager(address _mgr) public
        onlyTokenManager
    {
        // You can't change crowdsale contract when migration is in progress.
        if(currentPhase == Phase.Migrating) throw;
        crowdsaleManager = _mgr;
    }

    function selfdestruct() public
        onlyTokenManager
    {
        // Available only if nothing hapened yet or if presale is totally
        // completed.
        if(currentPhase != Phase.Created && currentPhase != Phase.Migrated)
          throw;
        suicide(tokenManager); // send remaining funds to tokenManager
    }
}