releaseFunds method added

releaseFunds method added

/**
 * Copyright 2016 Everex https://everex.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* String utility library */
library strUtils {
    string constant CHAINY_JSON_ID = '"id":"CHAINY"';
    uint8 constant CHAINY_JSON_MIN_LEN = 32;

    /* Converts given number to base58, limited by _maxLength symbols */
    function toBase58(uint256 _value, uint8 _maxLength) internal returns (string) {
        string memory letters = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
        bytes memory alphabet = bytes(letters);
        uint8 base = 58;
        uint8 len = 0;
        uint256 remainder = 0;
        bool needBreak = false;
        bytes memory bytesReversed = bytes(new string(_maxLength));

        for (uint8 i = 0; i < _maxLength; i++) {
            if(_value < base){
                needBreak = true;
            }
            remainder = _value % base;
            _value = uint256(_value / base);
            bytesReversed[i] = alphabet[remainder];
            len++;
            if(needBreak){
                break;
            }
        }

        // Reverse
        bytes memory result = bytes(new string(len));
        for (i = 0; i < len; i++) {
            result[i] = bytesReversed[len - i - 1];
        }
        return string(result);
    }

    /* Concatenates two strings */
    function concat(string _s1, string _s2) internal returns (string) {
        bytes memory bs1 = bytes(_s1);
        bytes memory bs2 = bytes(_s2);
        string memory s3 = new string(bs1.length + bs2.length);
        bytes memory bs3 = bytes(s3);

        uint256 j = 0;
        for (uint256 i = 0; i < bs1.length; i++) {
            bs3[j++] = bs1[i];
        }
        for (i = 0; i < bs2.length; i++) {
            bs3[j++] = bs2[i];
        }

        return string(bs3);
    }

    /* Checks if provided JSON string has valid Chainy format */
    function isValidChainyJson(string _json) internal returns (bool) {
        bytes memory json = bytes(_json);
        bytes memory id = bytes(CHAINY_JSON_ID);

        if (json.length < CHAINY_JSON_MIN_LEN) {
            return false;
        } else {
            uint len = 0;
            if (json[1] == id[0]) {
                len = 1;
                while (len < id.length && (1 + len) < json.length && json[1 + len] == id[len]) {
                    len++;
                }
                if (len == id.length) {
                    return true;
                }
            }
        }

        return false;
    }
}

// Ownership
contract owned {
    address public owner;

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

    modifier onlyOwner {
        if (msg.sender != owner) throw;
        _
    }

    function transferOwnership(address newOwner) onlyOwner {
        owner = newOwner;
    }
}

contract Chainy is owned {
    string constant CHAINY_URL = "https://txn.me/";

    // Configuration
    mapping(string => uint256) private chainyConfig;

    // Service accounts
    mapping (address => bool) private srvAccount;

    // Fee receiver
    address private receiverAddress;

    struct data {uint256 timestamp; string json; address sender;}
    mapping (string => data) private chainy;

    event chainyShortLink(uint256 timestamp, string code);

    // Constructor
    function Chainy(){
        setConfig("fee", 0);
        // change the block offset to 1000000 to use contract in testnet
        setConfig("blockoffset", 2000000);
    }

    // Sets configuration option
    function setConfig(string _key, uint256 _value) onlyOwner {
        chainyConfig[_key] = _value;
    }

    // Returns configuration option
    function getConfig(string _key) constant returns (uint256 _value) {
        return chainyConfig[_key];
    }

    // Add/Remove service account
    function setServiceAccount(address _address, bool _value) onlyOwner {
        srvAccount[_address] = _value;
    }

    // Set receiver address
    function setReceiverAddress(address _address) onlyOwner {
        receiverAddress = _address;
    }

    // Send all ether back to owner
    function releaseFunds() onlyOwner {
        if(!owner.send(this.balance)) throw;
    }

    // Add record
    function addChainyData(string json) {
        checkFormat(json);

        var code = generateShortLink();
        // Checks if the record exist
        if (getChainyTimestamp(code) > 0) throw;

        processFee();
        chainy[code] = data({
            timestamp: block.timestamp,
            json: json,
            sender: tx.origin
        });

        // Fire event
        var link = strUtils.concat(CHAINY_URL, code);
        chainyShortLink(block.timestamp, link);
    }

    // Get record timestamp
    function getChainyTimestamp(string code) constant returns (uint256) {
        return chainy[code].timestamp;
    }

    // Get record JSON
    function getChainyData(string code) constant returns (string) {
        return chainy[code].json;
    }

    // Get record sender
    function getChainySender(string code) constant returns (address) {
        return chainy[code].sender;
    }

    // Checks if enough fee provided
    function processFee() internal {
        var fee = getConfig("fee");
        if (srvAccount[msg.sender] || (fee == 0)) return;

        if (msg.value < fee)
            throw;
        else
            if (!receiverAddress.send(fee)) throw;
    }

    // Checks if provided string has valid format
    function checkFormat(string json) internal {
        if (!strUtils.isValidChainyJson(json)) throw;
    }

    function generateShortLink() internal returns (string) {
        var s1 = strUtils.toBase58(block.number - getConfig("blockoffset"), 11);
        var s2 = strUtils.toBase58(uint256(tx.origin), 2);

        var s = strUtils.concat(s1, s2);
        return s;
    }

}

/**
 * Copyright 2016 Everex https://everex.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* String utility library */
library strUtils {
    string constant CHAINY_JSON_ID = '"id":"CHAINY"';
    uint8 constant CHAINY_JSON_MIN_LEN = 32;

    /* Converts given number to base58, limited by _maxLength symbols */
    function toBase58(uint256 _value, uint8 _maxLength) internal returns (string) {
        string memory letters = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
        bytes memory alphabet = bytes(letters);
        uint8 base = 58;
        uint8 len = 0;
        uint256 remainder = 0;
        bool needBreak = false;
        bytes memory bytesReversed = bytes(new string(_maxLength));

        for (uint8 i = 0; i < _maxLength; i++) {
            if(_value < base){
                needBreak = true;
            }
            remainder = _value % base;
            _value = uint256(_value / base);
            bytesReversed[i] = alphabet[remainder];
            len++;
            if(needBreak){
                break;
            }
        }

        // Reverse
        bytes memory result = bytes(new string(len));
        for (i = 0; i < len; i++) {
            result[i] = bytesReversed[len - i - 1];
        }
        return string(result);
    }

    /* Concatenates two strings */
    function concat(string _s1, string _s2) internal returns (string) {
        bytes memory bs1 = bytes(_s1);
        bytes memory bs2 = bytes(_s2);
        string memory s3 = new string(bs1.length + bs2.length);
        bytes memory bs3 = bytes(s3);

        uint256 j = 0;
        for (uint256 i = 0; i < bs1.length; i++) {
            bs3[j++] = bs1[i];
        }
        for (i = 0; i < bs2.length; i++) {
            bs3[j++] = bs2[i];
        }

        return string(bs3);
    }

    /* Checks if provided JSON string has valid Chainy format */
    function isValidChainyJson(string _json) internal returns (bool) {
        bytes memory json = bytes(_json);
        bytes memory id = bytes(CHAINY_JSON_ID);

        if (json.length < CHAINY_JSON_MIN_LEN) {
            return false;
        } else {
            uint len = 0;
            if (json[1] == id[0]) {
                len = 1;
                while (len < id.length && (1 + len) < json.length && json[1 + len] == id[len]) {
                    len++;
                }
                if (len == id.length) {
                    return true;
                }
            }
        }

        return false;
    }
}

// Ownership
contract owned {
    address public owner;

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

    modifier onlyOwner {
        if (msg.sender != owner) throw;
        _
    }

    function transferOwnership(address newOwner) onlyOwner {
        owner = newOwner;
    }
}

contract Chainy is owned {
    string constant CHAINY_URL = "https://txn.me/";

    // Configuration
    mapping(string => uint256) private chainyConfig;

    // Service accounts
    mapping (address => bool) private srvAccount;

    // Fee receiver
    address private receiverAddress;

    struct data {uint256 timestamp; string json; address sender;}
    mapping (string => data) private chainy;

    event chainyShortLink(uint256 timestamp, string code);

    // Constructor
    function Chainy(){
        setConfig("fee", 0);
        // change the block offset to 1000000 to use contract in testnet
        setConfig("blockoffset", 2000000);
    }

    // Sets configuration option
    function setConfig(string _key, uint256 _value) onlyOwner {
        chainyConfig[_key] = _value;
    }

    // Returns configuration option
    function getConfig(string _key) constant returns (uint256 _value) {
        return chainyConfig[_key];
    }

    // Add/Remove service account
    function setServiceAccount(address _address, bool _value) onlyOwner {
        srvAccount[_address] = _value;
    }

    // Set receiver address
    function setReceiverAddress(address _address) onlyOwner {
        receiverAddress = _address;
    }

    // Add record
    function addChainyData(string json) {
        checkFormat(json);

        var code = generateShortLink();
        // Checks if the record exist
        if (getChainyTimestamp(code) > 0) throw;

        processFee();
        chainy[code] = data({
            timestamp: block.timestamp,
            json: json,
            sender: tx.origin
        });

        // Fire event
        var link = strUtils.concat(CHAINY_URL, code);
        chainyShortLink(block.timestamp, link);
    }

    // Get record timestamp
    function getChainyTimestamp(string code) constant returns (uint256) {
        return chainy[code].timestamp;
    }

    // Get record JSON
    function getChainyData(string code) constant returns (string) {
        return chainy[code].json;
    }

    // Get record sender
    function getChainySender(string code) constant returns (address) {
        return chainy[code].sender;
    }

    // Checks if enough fee provided
    function processFee() internal {
        var fee = getConfig("fee");
        if (srvAccount[msg.sender] || (fee == 0)) return;

        if (msg.value < fee)
            throw;
        else
            if (!receiverAddress.send(msg.value)) throw;
    }

    // Checks if provided string has valid format
    function checkFormat(string json) internal {
        if (!strUtils.isValidChainyJson(json)) throw;
    }

    function generateShortLink() internal returns (string) {
        var s1 = strUtils.toBase58(block.number - getConfig("blockoffset"), 11);
        var s2 = strUtils.toBase58(uint256(tx.origin), 2);

        var s = strUtils.concat(s1, s2);
        return s;
    }

}


Rename mapping idPackedRevisionBlockNumbers to packedRevisionBlockNumbers.

/**
 * @title BlobStore
 * @author Jonathan Brown <jbrown@bluedroplet.com>
 */
contract BlobStore {

    struct BlobInfo {               // Single slot.
        bool updatable;             // Can the blob be updated? Can be disabled.
        bool enforceRevisions;      // When updating, always make a new revision. Can be enabled.
        bool retractable;           // Can the blob be retracted? Can be disabled.
        bool transferable;          // Can the blob be transfered to another user or disowned? Can be disabled.
        uint32 blockNumber;         // Which block has revision 0 of this blob.
        uint32 numRevisions;        // Number of additional revisions.
        address owner;              // Who owns this blob.
    }

    mapping (bytes32 => BlobInfo) blobInfo;
    mapping (bytes32 => mapping (uint => bytes32)) packedRevisionBlockNumbers;
    mapping (bytes32 => mapping (address => bool)) enabledTransfers;

    event logBlob(bytes32 indexed id, uint indexed revisionId, bytes blob);     // Greatest revisionId for the blob at time of logging.
    event logRetractRevision(bytes32 indexed id, uint indexed revisionId);
    event logRetract(bytes32 indexed id);
    event logTransfer(bytes32 indexed id, address indexed sender, address indexed recipient);
    event logDisown(bytes32 indexed id);
    event logSetNotUpdatable(bytes32 indexed id);
    event logSetEnforceRevisions(bytes32 indexed id);
    event logSetNotRetractable(bytes32 indexed id);
    event logSetNotTransferable(bytes32 indexed id);

    // Create a 96-bit id for this contract. This is unique across all blockchains.
    // Wait a few minutes after deploying for this id to settle.
    bytes12 constant contractId = bytes12(sha3(this, block.blockhash(block.number - 1)));

    /**
     * @dev Throw if the current message is sending a payment.
     */
    modifier noValue() {
        if (msg.value > 0) {
            throw;      // Do not maintain a balance.
        }
        _
    }

    /**
     * @dev Throw if the blob has not been used before or it has been retracted.
     * @param id Id of the blob.
     */
    modifier exists(bytes32 id) {
        if (blobInfo[id].blockNumber == 0 || blobInfo[id].blockNumber == uint32(-1)) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if the owner of the blob is not the message sender.
     * @param id Id of the blob.
     */
    modifier isOwner(bytes32 id) {
        if (blobInfo[id].owner != msg.sender) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if the blob is not updatable.
     * @param id Id of the blob.
     */
    modifier isUpdatable(bytes32 id) {
        if (!blobInfo[id].updatable) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if the blob is not enforcing revisions.
     * @param id Id of the blob.
     */
    modifier isNotEnforceRevisions(bytes32 id) {
        if (blobInfo[id].enforceRevisions) {
            throw;
        }
        _
    }

    /**
     * @dev Throw is the blob is not retractable.
     * @param id Id of the blob.
     */
    modifier isRetractable(bytes32 id) {
        if (!blobInfo[id].retractable) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if the blob is not transferable.
     * @param id Id of the blob.
     */
    modifier isTransferable(bytes32 id) {
        if (!blobInfo[id].transferable) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if the blob is not transferable to a specific user.
     * @param id Id of the blob.
     * @param recipient Address of the user.
     */
    modifier isTransferEnabled(bytes32 id, address recipient) {
        if (!enabledTransfers[id][recipient]) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if the blob does not have revisions.
     * @param id Id of the blob.
     */
    modifier hasRevisions(bytes32 id) {
        if (blobInfo[id].numRevisions == 0) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if a specific blob revision does not exist.
     * @param id Id of the blob.
     * @param revisionId Id of the revision.
     */
    modifier revisionExists(bytes32 id, uint revisionId) {
        if (revisionId > blobInfo[id].numRevisions) {
            throw;
        }
        _
    }

    /**
     * @dev Stores new blob in the transaction log. It is guaranteed that each user will get a different id from the same nonce.
     * @param blob Blob that should be stored.
     * @param nonce Any value that the user has not used previously to create a blob.
     * @param updatable Should the blob be updatable?
     * @param enforceRevisions Should the blob enforce revisions when updating?
     * @param retractable Should the blob be retractable?
     * @param transferable Should the blob be transferable?
     * @param anon Should the blob be anonymous?
     * @return id Id of the blob.
     */
    function create(bytes blob, bytes32 nonce, bool updatable, bool enforceRevisions, bool retractable, bool transferable, bool anon) noValue external returns (bytes32 id) {
        // Determine the id.
        id = contractId | (sha3(msg.sender, nonce) & (2 ** 160 - 1));
        // Make sure this id has not been used before.
        if (blobInfo[id].blockNumber != 0) {
            throw;
        }
        // Store blob info in state.
        blobInfo[id] = BlobInfo({
            updatable: updatable,
            enforceRevisions: enforceRevisions,
            retractable: retractable,
            transferable: transferable,
            numRevisions: 0,
            blockNumber: uint32(block.number),
            owner: anon ? 0 : msg.sender,
        });
        // Store the blob in a log in the current block.
        logBlob(id, 0, blob);
    }

    /**
     * @dev Store a blob revision block number in a packed slot.
     * @param id Id of the blob.
     * @param offset The offset of the block number should be retreived.
     */
    function setPackedRevisionBlockNumber(bytes32 id, uint offset) internal {
        // Get the slot.
        bytes32 slot = packedRevisionBlockNumbers[id][offset / 8];
        // Wipe the previous block number.
        slot &= ~bytes32(uint32(-1) * 2 ** ((offset % 8) * 32));
        // Insert the current block number.
        slot |= bytes32(uint32(block.number) * 2 ** ((offset % 8) * 32));
        // Store the slot.
        packedRevisionBlockNumbers[id][offset / 8] = slot;
    }

    /**
     * @dev Create a new blob revision.
     * @param id Id of the blob.
     * @param blob Blob that should be stored as the new revision.
     * @return revisionId The new revisionId.
     */
    function createRevision(bytes32 id, bytes blob) noValue isOwner(id) isUpdatable(id) external returns (uint revisionId) {
        // Increment the number of revisions.
        revisionId = ++blobInfo[id].numRevisions;
        // Store the block number.
        setPackedRevisionBlockNumber(id, revisionId - 1);
        // Store the new blob in a log in the current block.
        logBlob(id, revisionId, blob);
    }

    /**
     * @dev Update a blob's latest revsion.
     * @param id Id of the blob.
     * @param blob Blob that should be stored as the latest revision.
     */
    function updateLatestRevision(bytes32 id,  bytes blob) noValue isOwner(id) isUpdatable(id) isNotEnforceRevisions(id) external {
        if (blobInfo[id].numRevisions == 0) {
            blobInfo[id].blockNumber = uint32(block.number);
        }
        else {
            setPackedRevisionBlockNumber(id, blobInfo[id].numRevisions - 1);
        }
        // Store the new blob in a log in the current block.
        logBlob(id, blobInfo[id].numRevisions, blob);
    }

    /**
     * @dev Retract a blob's latest revision.
     * @param id Id of the blob.
     */
    function retractLatestRevision(bytes32 id) noValue isOwner(id) isUpdatable(id) isNotEnforceRevisions(id) hasRevisions(id) external {
        // Delete slot if empty
        if (blobInfo[id].numRevisions % 8 == 1) {
            delete packedRevisionBlockNumbers[id][blobInfo[id].numRevisions / 8];
        }
        // Log the retraction.
        logRetractRevision(id, blobInfo[id].numRevisions--);
    }

    /**
     * @dev Delete all of a blob's packed revision block numbers.
     * @param id Id of the blob.
     */
    function deleteAllRevisionBlockNumbers(bytes32 id) internal {
        uint numSlots = (blobInfo[id].numRevisions + 7) / 8;
        for (uint i = 0; i < numSlots; i++) {
            delete packedRevisionBlockNumbers[id][i];
        }
    }

    /**
     * @dev Delete all a blob's revisions and replace it with a new blob.
     * @param id Id of the blob.
     * @param blob Blob that should be stored.
     */
    function restart(bytes32 id, bytes blob) noValue isOwner(id) isUpdatable(id) isNotEnforceRevisions(id) external {
        // Try to get some gas refunds.
        deleteAllRevisionBlockNumbers(id);
        // Update the blob state info.
        blobInfo[id].blockNumber = uint32(block.number);
        blobInfo[id].numRevisions = 0;
        // Store the blob in a log in the current block.
        logBlob(id, 0, blob);
    }

    /**
     * @dev Retract a blob.
     * @param id Id of the blob.
     */
    function retract(bytes32 id) noValue isOwner(id) isRetractable(id) external {
        // Delete the packed revision block numbers.
        deleteAllRevisionBlockNumbers(id);
        // Mark this blob as retracted.
        blobInfo[id] = BlobInfo({
            updatable: false,
            enforceRevisions: false,
            retractable: false,
            transferable: false,
            numRevisions: 0,
            blockNumber: uint32(-1),
            owner: 0,
        });
        // Log that the blob has been retracted.
        logRetract(id);
    }

    /**
     * @dev Enable transfer of the blob to the current user.
     * @param id Id of the blob.
     */
    function transferEnable(bytes32 id) noValue isTransferable(id) external {
        // Record in state that the current user will accept this blob.
        enabledTransfers[id][msg.sender] = true;
    }

    /**
     * @dev Disable transfer of the blob to the current user.
     * @param id Id of the blob.
     */
    function transferDisable(bytes32 id) noValue external {
        // Record in state that the current user will not accept this blob.
        enabledTransfers[id][msg.sender] = false;
    }

    /**
     * @dev Transfer a blob to a new user.
     * @param id Id of the blob.
     * @param recipient Address of the user to transfer to blob to.
     */
    function transfer(bytes32 id, address recipient) noValue isOwner(id) isTransferable(id) isTransferEnabled(id, recipient) external {
        // Update ownership of the blob.
        blobInfo[id].owner = recipient;
        // Disable this transfer and free up the slot.
        enabledTransfers[id][recipient] = false;
        // Log the transfer.
        logTransfer(id, msg.sender, recipient);
    }

    /**
     * @dev Disown a blob.
     * @param id Id of the blob.
     */
    function disown(bytes32 id) noValue isOwner(id) isTransferable(id) external {
        // Remove the owner from the blob's state.
        delete blobInfo[id].owner;
        // Log as blob as disowned.
        logDisown(id);
    }

    /**
     * @dev Set a blob as not updatable.
     * @param id Id of the blob.
     */
    function setNotUpdatable(bytes32 id) noValue isOwner(id) external {
        // Record in state that the blob is not updatable.
        blobInfo[id].updatable = false;
        // Log that the blob is not updatable.
        logSetNotUpdatable(id);
    }

    /**
     * @dev Set a blob to enforce revisions.
     * @param id Id of the blob.
     */
    function setEnforceRevisions(bytes32 id) noValue isOwner(id) external {
        // Record in state that all changes to this blob must be new revisions.
        blobInfo[id].enforceRevisions = true;
        // Log that the blob now forces new revisions.
        logSetEnforceRevisions(id);
    }

    /**
     * @dev Set a blob to not be retractable.
     * @param id Id of the blob.
     */
    function setNotRetractable(bytes32 id) noValue isOwner(id) external {
        // Record in state that the blob is not retractable.
        blobInfo[id].retractable = false;
        // Log that the blob is not retractable.
        logSetNotRetractable(id);
    }

    /**
     * @dev Set a blob to not be transferable.
     * @param id Id of the blob.
     */
    function setNotTransferable(bytes32 id) noValue isOwner(id) external {
        // Record in state that the blob is not transferable.
        blobInfo[id].transferable = false;
        // Log that the blob is not transferable.
        logSetNotTransferable(id);
    }

    function getContractId() noValue constant external returns (bytes12 _contractId) {
        _contractId = contractId;
    }

    /**
     * @dev Get info about a blob.
     * @param id Id of the blob.
     * @return owner Owner of the blob.
     * @return updatable Is the blob updatable?
     * @return enforceRevisions Does the blob enforce revisions?
     * @return retractable Is the blob retractable?
     * @return transferable Is the blob transferable?
     * @return numRevisions How many revisions the blob has.
     * @return latestBlockNumber The block number of the latest revision.
     */
    function getInfo(bytes32 id) noValue exists(id) constant external returns (address owner, bool updatable, bool enforceRevisions, bool retractable, bool transferable, uint numRevisions, uint latestBlockNumber) {
        owner = blobInfo[id].owner;
        updatable = blobInfo[id].updatable;
        enforceRevisions = blobInfo[id].enforceRevisions;
        retractable = blobInfo[id].retractable;
        transferable = blobInfo[id].transferable;
        numRevisions = blobInfo[id].numRevisions;
        latestBlockNumber = getRevisionBlockNumber(id, numRevisions);
    }

    /**
     * @dev Get the owner of a blob.
     * @param id Id of the blob.
     * @return owner Owner of the blob.
     */
    function getOwner(bytes32 id) noValue exists(id) constant external returns (address owner) {
        owner = blobInfo[id].owner;
    }

    /**
     * @dev Is a blob updatable?
     * @param id Id of the blob.
     * @return updatable Is the blob updatable?
     */
    function getUpdatable(bytes32 id) noValue exists(id) constant external returns (bool updatable) {
        updatable = blobInfo[id].updatable;
    }

    /**
     * @dev Does a blob enforce revisions?
     * @param id Id of the blob.
     * @return enforceRevisions Does the blob enforce revisions?
     */
    function getEnforceRevisions(bytes32 id) noValue exists(id) constant external returns (bool enforceRevisions) {
        enforceRevisions = blobInfo[id].enforceRevisions;
    }

    /**
     * @dev Is a blob retractable?
     * @param id Id of the blob.
     * @return retractable Is the blob retractable?
     */
    function getRetractable(bytes32 id) noValue exists(id) constant external returns (bool retractable) {
        retractable = blobInfo[id].retractable;
    }

    /**
     * @dev Is a blob transferable.
     * @param id Id of the blob.
     * @return transferable Is the blob transferable?
     */
    function getTransferable(bytes32 id) noValue exists(id) constant external returns (bool transferable) {
        transferable = blobInfo[id].transferable;
    }

    /**
     * @dev Get the number of revisions a blob has.
     * @param id Id of the blob.
     * @return numRevisions How many revisions the blob has.
     */
    function getNumRevisions(bytes32 id) noValue exists(id) constant external returns (uint numRevisions) {
        numRevisions = blobInfo[id].numRevisions;
    }

    /**
     * @dev Get the block number for a specific blob revision.
     * @param id Id of the blob.
     * @param revisionId Id of the revision.
     * @return blockNumber Block number of the specified revision.
     */
    function getRevisionBlockNumber(bytes32 id, uint revisionId) noValue exists(id) revisionExists(id, revisionId) constant returns (uint blockNumber) {
        if (revisionId == 0) {
            blockNumber = blobInfo[id].blockNumber;
        }
        else {
            bytes32 slot = packedRevisionBlockNumbers[id][(revisionId - 1) / 8];
            blockNumber = uint32(uint256(slot) / 2 ** (((revisionId - 1) % 8) * 32));
        }
    }

    /**
     * @dev Default function.
     */
    function() {
        throw;      // Do not maintain a balance.
    }

}

/**
 * @title BlobStore
 * @author Jonathan Brown <jbrown@bluedroplet.com>
 */
contract BlobStore {

    struct BlobInfo {               // Single slot.
        bool updatable;             // Can the blob be updated? Can be disabled.
        bool enforceRevisions;      // When updating, always make a new revision. Can be enabled.
        bool retractable;           // Can the blob be retracted? Can be disabled.
        bool transferable;          // Can the blob be transfered to another user or disowned? Can be disabled.
        uint32 blockNumber;         // Which block has revision 0 of this blob.
        uint32 numRevisions;        // Number of additional revisions.
        address owner;              // Who owns this blob.
    }

    mapping (bytes32 => BlobInfo) blobInfo;
    mapping (bytes32 => mapping (uint => bytes32)) idPackedRevisionBlockNumbers;
    mapping (bytes32 => mapping (address => bool)) enabledTransfers;

    event logBlob(bytes32 indexed id, uint indexed revisionId, bytes blob);     // Greatest revisionId for the blob at time of logging.
    event logRetractRevision(bytes32 indexed id, uint indexed revisionId);
    event logRetract(bytes32 indexed id);
    event logTransfer(bytes32 indexed id, address indexed sender, address indexed recipient);
    event logDisown(bytes32 indexed id);
    event logSetNotUpdatable(bytes32 indexed id);
    event logSetEnforceRevisions(bytes32 indexed id);
    event logSetNotRetractable(bytes32 indexed id);
    event logSetNotTransferable(bytes32 indexed id);

    // Create a 96-bit id for this contract. This is unique across all blockchains.
    // Wait a few minutes after deploying for this id to settle.
    bytes12 constant contractId = bytes12(sha3(this, block.blockhash(block.number - 1)));

    /**
     * @dev Throw if the current message is sending a payment.
     */
    modifier noValue() {
        if (msg.value > 0) {
            throw;      // Do not maintain a balance.
        }
        _
    }

    /**
     * @dev Throw if the blob has not been used before or it has been retracted.
     * @param id Id of the blob.
     */
    modifier exists(bytes32 id) {
        if (blobInfo[id].blockNumber == 0 || blobInfo[id].blockNumber == uint32(-1)) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if the owner of the blob is not the message sender.
     * @param id Id of the blob.
     */
    modifier isOwner(bytes32 id) {
        if (blobInfo[id].owner != msg.sender) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if the blob is not updatable.
     * @param id Id of the blob.
     */
    modifier isUpdatable(bytes32 id) {
        if (!blobInfo[id].updatable) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if the blob is not enforcing revisions.
     * @param id Id of the blob.
     */
    modifier isNotEnforceRevisions(bytes32 id) {
        if (blobInfo[id].enforceRevisions) {
            throw;
        }
        _
    }

    /**
     * @dev Throw is the blob is not retractable.
     * @param id Id of the blob.
     */
    modifier isRetractable(bytes32 id) {
        if (!blobInfo[id].retractable) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if the blob is not transferable.
     * @param id Id of the blob.
     */
    modifier isTransferable(bytes32 id) {
        if (!blobInfo[id].transferable) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if the blob is not transferable to a specific user.
     * @param id Id of the blob.
     * @param recipient Address of the user.
     */
    modifier isTransferEnabled(bytes32 id, address recipient) {
        if (!enabledTransfers[id][recipient]) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if the blob does not have revisions.
     * @param id Id of the blob.
     */
    modifier hasRevisions(bytes32 id) {
        if (blobInfo[id].numRevisions == 0) {
            throw;
        }
        _
    }

    /**
     * @dev Throw if a specific blob revision does not exist.
     * @param id Id of the blob.
     * @param revisionId Id of the revision.
     */
    modifier revisionExists(bytes32 id, uint revisionId) {
        if (revisionId > blobInfo[id].numRevisions) {
            throw;
        }
        _
    }

    /**
     * @dev Stores new blob in the transaction log. It is guaranteed that each user will get a different id from the same nonce.
     * @param blob Blob that should be stored.
     * @param nonce Any value that the user has not used previously to create a blob.
     * @param updatable Should the blob be updatable?
     * @param enforceRevisions Should the blob enforce revisions when updating?
     * @param retractable Should the blob be retractable?
     * @param transferable Should the blob be transferable?
     * @param anon Should the blob be anonymous?
     * @return id Id of the blob.
     */
    function create(bytes blob, bytes32 nonce, bool updatable, bool enforceRevisions, bool retractable, bool transferable, bool anon) noValue external returns (bytes32 id) {
        // Determine the id.
        id = contractId | (sha3(msg.sender, nonce) & (2 ** 160 - 1));
        // Make sure this id has not been used before.
        if (blobInfo[id].blockNumber != 0) {
            throw;
        }
        // Store blob info in state.
        blobInfo[id] = BlobInfo({
            updatable: updatable,
            enforceRevisions: enforceRevisions,
            retractable: retractable,
            transferable: transferable,
            numRevisions: 0,
            blockNumber: uint32(block.number),
            owner: anon ? 0 : msg.sender,
        });
        // Store the blob in a log in the current block.
        logBlob(id, 0, blob);
    }

    /**
     * @dev Store a blob revision block number in a packed slot.
     * @param id Id of the blob.
     * @param offset The offset of the block number should be retreived.
     */
    function setPackedRevisionBlockNumber(bytes32 id, uint offset) internal {
        // Get the slot.
        bytes32 slot = idPackedRevisionBlockNumbers[id][offset / 8];
        // Wipe the previous block number.
        slot &= ~bytes32(uint32(-1) * 2 ** ((offset % 8) * 32));
        // Insert the current block number.
        slot |= bytes32(uint32(block.number) * 2 ** ((offset % 8) * 32));
        // Store the slot.
        idPackedRevisionBlockNumbers[id][offset / 8] = slot;
    }

    /**
     * @dev Create a new blob revision.
     * @param id Id of the blob.
     * @param blob Blob that should be stored as the new revision.
     * @return revisionId The new revisionId.
     */
    function createRevision(bytes32 id, bytes blob) noValue isOwner(id) isUpdatable(id) external returns (uint revisionId) {
        // Increment the number of revisions.
        revisionId = ++blobInfo[id].numRevisions;
        // Store the block number.
        setPackedRevisionBlockNumber(id, revisionId - 1);
        // Store the new blob in a log in the current block.
        logBlob(id, revisionId, blob);
    }

    /**
     * @dev Update a blob's latest revsion.
     * @param id Id of the blob.
     * @param blob Blob that should be stored as the latest revision.
     */
    function updateLatestRevision(bytes32 id,  bytes blob) noValue isOwner(id) isUpdatable(id) isNotEnforceRevisions(id) external {
        if (blobInfo[id].numRevisions == 0) {
            blobInfo[id].blockNumber = uint32(block.number);
        }
        else {
            setPackedRevisionBlockNumber(id, blobInfo[id].numRevisions - 1);
        }
        // Store the new blob in a log in the current block.
        logBlob(id, blobInfo[id].numRevisions, blob);
    }

    /**
     * @dev Retract a blob's latest revision.
     * @param id Id of the blob.
     */
    function retractLatestRevision(bytes32 id) noValue isOwner(id) isUpdatable(id) isNotEnforceRevisions(id) hasRevisions(id) external {
        // Delete slot if empty
        if (blobInfo[id].numRevisions % 8 == 1) {
            delete idPackedRevisionBlockNumbers[id][blobInfo[id].numRevisions / 8];
        }
        // Log the retraction.
        logRetractRevision(id, blobInfo[id].numRevisions--);
    }

    /**
     * @dev Delete all of a blob's packed revision block numbers.
     * @param id Id of the blob.
     */
    function deleteAllRevisionBlockNumbers(bytes32 id) internal {
        uint numSlots = (blobInfo[id].numRevisions + 7) / 8;
        for (uint i = 0; i < numSlots; i++) {
            delete idPackedRevisionBlockNumbers[id][i];
        }
    }

    /**
     * @dev Delete all a blob's revisions and replace it with a new blob.
     * @param id Id of the blob.
     * @param blob Blob that should be stored.
     */
    function restart(bytes32 id, bytes blob) noValue isOwner(id) isUpdatable(id) isNotEnforceRevisions(id) external {
        // Try to get some gas refunds.
        deleteAllRevisionBlockNumbers(id);
        // Update the blob state info.
        blobInfo[id].blockNumber = uint32(block.number);
        blobInfo[id].numRevisions = 0;
        // Store the blob in a log in the current block.
        logBlob(id, 0, blob);
    }

    /**
     * @dev Retract a blob.
     * @param id Id of the blob.
     */
    function retract(bytes32 id) noValue isOwner(id) isRetractable(id) external {
        // Delete the packed revision block numbers.
        deleteAllRevisionBlockNumbers(id);
        // Mark this blob as retracted.
        blobInfo[id] = BlobInfo({
            updatable: false,
            enforceRevisions: false,
            retractable: false,
            transferable: false,
            numRevisions: 0,
            blockNumber: uint32(-1),
            owner: 0,
        });
        // Log that the blob has been retracted.
        logRetract(id);
    }

    /**
     * @dev Enable transfer of the blob to the current user.
     * @param id Id of the blob.
     */
    function transferEnable(bytes32 id) noValue isTransferable(id) external {
        // Record in state that the current user will accept this blob.
        enabledTransfers[id][msg.sender] = true;
    }

    /**
     * @dev Disable transfer of the blob to the current user.
     * @param id Id of the blob.
     */
    function transferDisable(bytes32 id) noValue external {
        // Record in state that the current user will not accept this blob.
        enabledTransfers[id][msg.sender] = false;
    }

    /**
     * @dev Transfer a blob to a new user.
     * @param id Id of the blob.
     * @param recipient Address of the user to transfer to blob to.
     */
    function transfer(bytes32 id, address recipient) noValue isOwner(id) isTransferable(id) isTransferEnabled(id, recipient) external {
        // Update ownership of the blob.
        blobInfo[id].owner = recipient;
        // Disable this transfer and free up the slot.
        enabledTransfers[id][recipient] = false;
        // Log the transfer.
        logTransfer(id, msg.sender, recipient);
    }

    /**
     * @dev Disown a blob.
     * @param id Id of the blob.
     */
    function disown(bytes32 id) noValue isOwner(id) isTransferable(id) external {
        // Remove the owner from the blob's state.
        delete blobInfo[id].owner;
        // Log as blob as disowned.
        logDisown(id);
    }

    /**
     * @dev Set a blob as not updatable.
     * @param id Id of the blob.
     */
    function setNotUpdatable(bytes32 id) noValue isOwner(id) external {
        // Record in state that the blob is not updatable.
        blobInfo[id].updatable = false;
        // Log that the blob is not updatable.
        logSetNotUpdatable(id);
    }

    /**
     * @dev Set a blob to enforce revisions.
     * @param id Id of the blob.
     */
    function setEnforceRevisions(bytes32 id) noValue isOwner(id) external {
        // Record in state that all changes to this blob must be new revisions.
        blobInfo[id].enforceRevisions = true;
        // Log that the blob now forces new revisions.
        logSetEnforceRevisions(id);
    }

    /**
     * @dev Set a blob to not be retractable.
     * @param id Id of the blob.
     */
    function setNotRetractable(bytes32 id) noValue isOwner(id) external {
        // Record in state that the blob is not retractable.
        blobInfo[id].retractable = false;
        // Log that the blob is not retractable.
        logSetNotRetractable(id);
    }

    /**
     * @dev Set a blob to not be transferable.
     * @param id Id of the blob.
     */
    function setNotTransferable(bytes32 id) noValue isOwner(id) external {
        // Record in state that the blob is not transferable.
        blobInfo[id].transferable = false;
        // Log that the blob is not transferable.
        logSetNotTransferable(id);
    }

    function getContractId() noValue constant external returns (bytes12 _contractId) {
        _contractId = contractId;
    }

    /**
     * @dev Get info about a blob.
     * @param id Id of the blob.
     * @return owner Owner of the blob.
     * @return updatable Is the blob updatable?
     * @return enforceRevisions Does the blob enforce revisions?
     * @return retractable Is the blob retractable?
     * @return transferable Is the blob transferable?
     * @return numRevisions How many revisions the blob has.
     * @return latestBlockNumber The block number of the latest revision.
     */
    function getInfo(bytes32 id) noValue exists(id) constant external returns (address owner, bool updatable, bool enforceRevisions, bool retractable, bool transferable, uint numRevisions, uint latestBlockNumber) {
        owner = blobInfo[id].owner;
        updatable = blobInfo[id].updatable;
        enforceRevisions = blobInfo[id].enforceRevisions;
        retractable = blobInfo[id].retractable;
        transferable = blobInfo[id].transferable;
        numRevisions = blobInfo[id].numRevisions;
        latestBlockNumber = getRevisionBlockNumber(id, numRevisions);
    }

    /**
     * @dev Get the owner of a blob.
     * @param id Id of the blob.
     * @return owner Owner of the blob.
     */
    function getOwner(bytes32 id) noValue exists(id) constant external returns (address owner) {
        owner = blobInfo[id].owner;
    }

    /**
     * @dev Is a blob updatable?
     * @param id Id of the blob.
     * @return updatable Is the blob updatable?
     */
    function getUpdatable(bytes32 id) noValue exists(id) constant external returns (bool updatable) {
        updatable = blobInfo[id].updatable;
    }

    /**
     * @dev Does a blob enforce revisions?
     * @param id Id of the blob.
     * @return enforceRevisions Does the blob enforce revisions?
     */
    function getEnforceRevisions(bytes32 id) noValue exists(id) constant external returns (bool enforceRevisions) {
        enforceRevisions = blobInfo[id].enforceRevisions;
    }

    /**
     * @dev Is a blob retractable?
     * @param id Id of the blob.
     * @return retractable Is the blob retractable?
     */
    function getRetractable(bytes32 id) noValue exists(id) constant external returns (bool retractable) {
        retractable = blobInfo[id].retractable;
    }

    /**
     * @dev Is a blob transferable.
     * @param id Id of the blob.
     * @return transferable Is the blob transferable?
     */
    function getTransferable(bytes32 id) noValue exists(id) constant external returns (bool transferable) {
        transferable = blobInfo[id].transferable;
    }

    /**
     * @dev Get the number of revisions a blob has.
     * @param id Id of the blob.
     * @return numRevisions How many revisions the blob has.
     */
    function getNumRevisions(bytes32 id) noValue exists(id) constant external returns (uint numRevisions) {
        numRevisions = blobInfo[id].numRevisions;
    }

    /**
     * @dev Get the block number for a specific blob revision.
     * @param id Id of the blob.
     * @param revisionId Id of the revision.
     * @return blockNumber Block number of the specified revision.
     */
    function getRevisionBlockNumber(bytes32 id, uint revisionId) noValue exists(id) revisionExists(id, revisionId) constant returns (uint blockNumber) {
        if (revisionId == 0) {
            blockNumber = blobInfo[id].blockNumber;
        }
        else {
            bytes32 slot = idPackedRevisionBlockNumbers[id][(revisionId - 1) / 8];
            blockNumber = uint32(uint256(slot) / 2 ** (((revisionId - 1) % 8) * 32));
        }
    }

    /**
     * @dev Default function.
     */
    function() {
        throw;      // Do not maintain a balance.
    }

}


add burn function

add burn function

pragma solidity ^0.4.18;

import '../node_modules/zeppelin-solidity/contracts/token/StandardToken.sol';

contract MugenMoney is StandardToken {

    // token information
    string public constant NAME = "Mugen Money";
    string public constant SYMBOL = "MGM";
    uint32 public constant DECIMALS = 18;

    event Mint(address indexed _receiver, uint _amount);

    function getMoney(address _receiver, uint _amount) public returns (uint newBalance) {
        require(_amount > 0);
        if (_receiver == 0x0) {
            _receiver = msg.sender;
        }

        totalSupply = totalSupply.add(_amount);
        balances[_receiver] = balances[_receiver].add(_amount);

        assert(balances[_receiver] > 0);
        Mint(_receiver, _amount);
        return balanceOf(_receiver);
    }

    function burnMyToken() public returns (bool success) {
        uint balance = balanceOf(msg.sender);
        balances[msg.sender] = 0;
        totalSupply = totalSupply.sub(balance);
        return true;
    }

}

pragma solidity ^0.4.18;

import '../node_modules/zeppelin-solidity/contracts/token/StandardToken.sol';

contract MugenMoney is StandardToken {

    // token information
    string constant NAME = "Mugen Money";
    string constant SYMBOL = "MGM";
    uint32 constant DECIMALS = 18;

    event Mint(address indexed _receiver, uint256 _amount);

    function getMoney(address _receiver, uint256 _amount) public returns (uint newBalance) {
        require(_amount > 0);
        if (_receiver == 0x0) {
            _receiver = msg.sender;
        }

        totalSupply = totalSupply.add(_amount);
        balances[_receiver] = balances[_receiver].add(_amount);

        assert(balances[_receiver] > 0);
        Mint(_receiver, _amount);
        return balances[_receiver];
    }

}


multiowned: refactoring: using correct data type for addresses

// Code taken from https://github.com/ethereum/dapp-bin/blob/master/wallet/wallet.sol
// Audit, refactoring and improvements by github.com/Eenae

// @authors:
// Gav Wood <g@ethdev.com>
// inheritable "property" contract that enables methods to be protected by requiring the acquiescence of either a
// single, or, crucially, each of a number of, designated owners.
// usage:
// use modifiers onlyowner (just own owned) or onlymanyowners(hash), whereby the same hash must be provided by
// some number (specified in constructor) of the set of owners (specified in the constructor, modifiable) before the
// interior is executed.

pragma solidity ^0.4.10;

contract multiowned {

	// TYPES

    // struct for the status of a pending operation.
    struct PendingState {
        // count of confirmations needed
        uint yetNeeded;

        // bitmap of confirmations where owner #ownerIndex's decision corresponds to 2**ownerIndex bit
        uint ownersDone;

        // position of this operation key in m_pendingIndex
        uint index;
    }

	// EVENTS

    // this contract only has six types of events: it can accept a confirmation, in which case
    // we record owner and operation (hash) alongside it.
    event Confirmation(address owner, bytes32 operation);
    event Revoke(address owner, bytes32 operation);
    // some others are in the case of an owner changing.
    event OwnerChanged(address oldOwner, address newOwner);
    event OwnerAdded(address newOwner);
    event OwnerRemoved(address oldOwner);
    // the last one is emitted if the required signatures change
    event RequirementChanged(uint newRequirement);

	// MODIFIERS

    // simple single-sig function modifier.
    modifier onlyowner {
        require(isOwner(msg.sender));
        _;
    }
    // multi-sig function modifier: the operation must have an intrinsic hash in order
    // that later attempts can be realised as the same underlying operation and
    // thus count as confirmations.
    modifier onlymanyowners(bytes32 _operation) {
        if (confirmAndCheck(_operation)) {
            _;
        }
        // Even if required number of confirmations has't been collected yet,
        // we can't throw here - because changes to the state have to be preserved.
        // But, confirmAndCheck itself will throw in case sender is not an owner.
    }

    modifier validNumOwners(uint _numOwners) {
        require(_numOwners > 0 && _numOwners <= c_maxOwners);
        _;
    }

    modifier validRequirement(uint _required, uint _numOwners) {
        require(_required > 0 && _required <= _numOwners);
        _;
    }

    modifier ownerExists(address _address) {
        require(isOwner(_address));
        _;
    }

    modifier ownerDoesNotExist(address _address) {
        require(!isOwner(_address));
        _;
    }

    modifier operationIsActive(bytes32 _operation) {
        require(isOperationActive(_operation));
        _;
    }

	// METHODS

    // constructor is given number of sigs required to do protected "onlymanyowners" transactions
    // as well as the selection of extra addresses capable of confirming them (msg.sender also added to owners).
    function multiowned(address[] _extraOwners, uint _required)
        validNumOwners(_extraOwners.length + 1)
        validRequirement(_required, _extraOwners.length + 1)
    {
        assert(c_maxOwners <= 255);

        m_numOwners = _extraOwners.length + 1;
        m_required = _required;

        m_owners[1] = msg.sender;
        m_ownerIndex[msg.sender] = 1;
        for (uint i = 0; i < _extraOwners.length; ++i)
        {
            uint currentOwnerIndex = checkOwnerIndex(
                i
                + 1 /* first slot is unused */
                + 1 /* first owner is msg.sender */);
            m_owners[currentOwnerIndex] = _extraOwners[i];
            m_ownerIndex[_extraOwners[i]] = currentOwnerIndex;
        }

        assertOwnersAreConsistent();
    }

    // Replaces an owner `_from` with another `_to`.
    // All pending operations will be canceled!
    function changeOwner(address _from, address _to)
        external
        ownerExists(_from)
        ownerDoesNotExist(_to)
        onlymanyowners(sha3(msg.data))
    {
        assertOwnersAreConsistent();

        clearPending();
        uint ownerIndex = checkOwnerIndex(m_ownerIndex[_from]);
        m_owners[ownerIndex] = _to;
        m_ownerIndex[_from] = 0;
        m_ownerIndex[_to] = ownerIndex;

        assertOwnersAreConsistent();
        OwnerChanged(_from, _to);
    }

    // All pending operations will be canceled!
    function addOwner(address _owner)
        external
        ownerDoesNotExist(_owner)
        validNumOwners(m_numOwners + 1)
        onlymanyowners(sha3(msg.data))
    {
        assertOwnersAreConsistent();

        clearPending();
        m_numOwners++;
        m_owners[m_numOwners] = _owner;
        m_ownerIndex[_owner] = checkOwnerIndex(m_numOwners);

        assertOwnersAreConsistent();
        OwnerAdded(_owner);
    }

    // All pending operations will be canceled!
    function removeOwner(address _owner)
        external
        ownerExists(_owner)
        validNumOwners(m_numOwners - 1)
        validRequirement(m_required, m_numOwners - 1)
        onlymanyowners(sha3(msg.data))
    {
        assertOwnersAreConsistent();

        clearPending();
        uint ownerIndex = checkOwnerIndex(m_ownerIndex[_owner]);
        m_owners[ownerIndex] = 0;
        m_ownerIndex[_owner] = 0;
        //make sure m_numOwners is equal to the number of owners and always points to the last owner
        reorganizeOwners();

        assertOwnersAreConsistent();
        OwnerRemoved(_owner);
    }

    // All pending operations will be canceled!
    function changeRequirement(uint _newRequired)
        external
        validRequirement(_newRequired, m_numOwners)
        onlymanyowners(sha3(msg.data))
    {
        m_required = _newRequired;
        clearPending();
        RequirementChanged(_newRequired);
    }

    // Gets an owner by 0-indexed position
    function getOwner(uint ownerIndex) external constant returns (address) {
        return m_owners[ownerIndex + 1];
    }

    function isOwner(address _addr) constant returns (bool) {
        return m_ownerIndex[_addr] > 0;
    }

    // Tests ownership of the current caller.
    // It's advisable to call it by new owner to make sure that the same erroneous address is not copy-pasted to
    // addOwner/changeOwner and to isOwner.
    function amIOwner() external constant onlyowner returns (bool) {
        return true;
    }

    // Revokes a prior confirmation of the given operation
    function revoke(bytes32 _operation)
        external
        operationIsActive(_operation)
        onlyowner
    {
        uint ownerIndexBit = makeOwnerBitmapBit(msg.sender);
        var pending = m_pending[_operation];
        require(pending.ownersDone & ownerIndexBit > 0);

        assertOperationIsConsistent(_operation);

        pending.yetNeeded++;
        pending.ownersDone -= ownerIndexBit;

        assertOperationIsConsistent(_operation);
        Revoke(msg.sender, _operation);
    }

    function hasConfirmed(bytes32 _operation, address _owner)
        external
        constant
        operationIsActive(_operation)
        ownerExists(_owner)
        returns (bool)
    {
        return !(m_pending[_operation].ownersDone & makeOwnerBitmapBit(_owner) == 0);
    }

    // INTERNAL METHODS

    function confirmAndCheck(bytes32 _operation)
        private
        onlyowner
        returns (bool)
    {
        var pending = m_pending[_operation];

        // if we're not yet working on this operation, switch over and reset the confirmation status.
        if (! isOperationActive(_operation)) {
            // reset count of confirmations needed.
            pending.yetNeeded = m_required;
            // reset which owners have confirmed (none) - set our bitmap to 0.
            pending.ownersDone = 0;
            pending.index = m_pendingIndex.length++;
            m_pendingIndex[pending.index] = _operation;
            assertOperationIsConsistent(_operation);
        }

        // determine the bit to set for this owner.
        uint ownerIndexBit = makeOwnerBitmapBit(msg.sender);
        // make sure we (the message sender) haven't confirmed this operation previously.
        if (pending.ownersDone & ownerIndexBit == 0) {
            Confirmation(msg.sender, _operation);
            // ok - check if count is enough to go ahead.
            assert(pending.yetNeeded > 0);
            if (pending.yetNeeded == 1) {
                // enough confirmations: reset and run interior.
                delete m_pendingIndex[m_pending[_operation].index];
                delete m_pending[_operation];
                return true;
            }
            else
            {
                // not enough: record that this owner in particular confirmed.
                pending.yetNeeded--;
                pending.ownersDone |= ownerIndexBit;
                assertOperationIsConsistent(_operation);
            }
        }
    }

    // Reclaims free slots between valid owners in m_owners.
    // TODO given that its called after each removal, it could be simplified.
    function reorganizeOwners() private {
        uint free = 1;
        while (free < m_numOwners)
        {
            // iterating to the first free slot from the beginning
            while (free < m_numOwners && m_owners[free] != 0) free++;

            // iterating to the first occupied slot from the end
            while (m_numOwners > 1 && m_owners[m_numOwners] == 0) m_numOwners--;

            // swap, if possible, so free slot is located at the end after the swap
            if (free < m_numOwners && m_owners[m_numOwners] != 0 && m_owners[free] == 0)
            {
                // owners between swapped slots should't be renumbered - that saves a lot of gas
                m_owners[free] = m_owners[m_numOwners];
                m_ownerIndex[m_owners[free]] = free;
                m_owners[m_numOwners] = 0;
            }
        }
    }

    function clearPending() internal {
        uint length = m_pendingIndex.length;
        for (uint i = 0; i < length; ++i)
            if (m_pendingIndex[i] != 0)
                delete m_pending[m_pendingIndex[i]];
        delete m_pendingIndex;
    }

    function checkOwnerIndex(uint ownerIndex) private constant returns (uint) {
        assert(0 != ownerIndex && ownerIndex <= c_maxOwners);
        return ownerIndex;
    }

    function makeOwnerBitmapBit(address owner) private constant returns (uint) {
        uint ownerIndex = checkOwnerIndex(m_ownerIndex[owner]);
        return 2 ** ownerIndex;
    }

    function isOperationActive(bytes32 _operation) private constant returns (bool) {
        return 0 != m_pending[_operation].yetNeeded;
    }

    function assertOwnersAreConsistent() private constant {
        assert(m_numOwners > 0);
        assert(m_numOwners <= c_maxOwners);
        assert(m_owners[0] == 0);
        assert(0 != m_required && m_required <= m_numOwners);
    }

    function assertOperationIsConsistent(bytes32 _operation) private constant {
        var pending = m_pending[_operation];
        assert(0 != pending.yetNeeded);
        assert(m_pendingIndex[pending.index] == _operation);
        assert(pending.yetNeeded <= m_required);
    }

   	// FIELDS

    uint constant c_maxOwners = 250;

    // the number of owners that must confirm the same operation before it is run.
    uint public m_required;

    // pointer used to find a free slot in m_owners
    uint public m_numOwners;

    // list of owners (addresses),
    // slot 0 is unused so there are no owner which index is 0.
    // TODO could we save space at the end of the array for the common case of <10 owners? and should we?
    address[256] m_owners;

    // index on the list of owners to allow reverse lookup: owner address => index in m_owners
    mapping(address => uint) m_ownerIndex;

    // the ongoing operations.
    mapping(bytes32 => PendingState) m_pending;
    bytes32[] m_pendingIndex;
}

// Code taken from https://github.com/ethereum/dapp-bin/blob/master/wallet/wallet.sol
// Audit, refactoring and improvements by github.com/Eenae

// @authors:
// Gav Wood <g@ethdev.com>
// inheritable "property" contract that enables methods to be protected by requiring the acquiescence of either a
// single, or, crucially, each of a number of, designated owners.
// usage:
// use modifiers onlyowner (just own owned) or onlymanyowners(hash), whereby the same hash must be provided by
// some number (specified in constructor) of the set of owners (specified in the constructor, modifiable) before the
// interior is executed.

pragma solidity ^0.4.10;

contract multiowned {

	// TYPES

    // struct for the status of a pending operation.
    struct PendingState {
        // count of confirmations needed
        uint yetNeeded;

        // bitmap of confirmations where owner #ownerIndex's decision corresponds to 2**ownerIndex bit
        uint ownersDone;

        // position of this operation key in m_pendingIndex
        uint index;
    }

	// EVENTS

    // this contract only has six types of events: it can accept a confirmation, in which case
    // we record owner and operation (hash) alongside it.
    event Confirmation(address owner, bytes32 operation);
    event Revoke(address owner, bytes32 operation);
    // some others are in the case of an owner changing.
    event OwnerChanged(address oldOwner, address newOwner);
    event OwnerAdded(address newOwner);
    event OwnerRemoved(address oldOwner);
    // the last one is emitted if the required signatures change
    event RequirementChanged(uint newRequirement);

	// MODIFIERS

    // simple single-sig function modifier.
    modifier onlyowner {
        require(isOwner(msg.sender));
        _;
    }
    // multi-sig function modifier: the operation must have an intrinsic hash in order
    // that later attempts can be realised as the same underlying operation and
    // thus count as confirmations.
    modifier onlymanyowners(bytes32 _operation) {
        if (confirmAndCheck(_operation)) {
            _;
        }
        // Even if required number of confirmations has't been collected yet,
        // we can't throw here - because changes to the state have to be preserved.
        // But, confirmAndCheck itself will throw in case sender is not an owner.
    }

    modifier validNumOwners(uint _numOwners) {
        require(_numOwners > 0 && _numOwners <= c_maxOwners);
        _;
    }

    modifier validRequirement(uint _required, uint _numOwners) {
        require(_required > 0 && _required <= _numOwners);
        _;
    }

    modifier ownerExists(address _address) {
        require(isOwner(_address));
        _;
    }

    modifier ownerDoesNotExist(address _address) {
        require(!isOwner(_address));
        _;
    }

    modifier operationIsActive(bytes32 _operation) {
        require(isOperationActive(_operation));
        _;
    }

	// METHODS

    // constructor is given number of sigs required to do protected "onlymanyowners" transactions
    // as well as the selection of extra addresses capable of confirming them (msg.sender also added to owners).
    function multiowned(address[] _extraOwners, uint _required)
        validNumOwners(_extraOwners.length + 1)
        validRequirement(_required, _extraOwners.length + 1)
    {
        assert(c_maxOwners <= 255);

        m_numOwners = _extraOwners.length + 1;
        m_required = _required;

        m_owners[1] = uint(msg.sender);
        m_ownerIndex[uint(msg.sender)] = 1;
        for (uint i = 0; i < _extraOwners.length; ++i)
        {
            uint currentOwnerIndex = checkOwnerIndex(
                i
                + 1 /* first slot is unused */
                + 1 /* first owner is msg.sender */);
            m_owners[currentOwnerIndex] = uint(_extraOwners[i]);
            m_ownerIndex[uint(_extraOwners[i])] = currentOwnerIndex;
        }

        assertOwnersAreConsistent();
    }

    // Replaces an owner `_from` with another `_to`.
    // All pending operations will be canceled!
    function changeOwner(address _from, address _to)
        external
        ownerExists(_from)
        ownerDoesNotExist(_to)
        onlymanyowners(sha3(msg.data))
    {
        assertOwnersAreConsistent();

        clearPending();
        uint ownerIndex = checkOwnerIndex(m_ownerIndex[uint(_from)]);
        m_owners[ownerIndex] = uint(_to);
        m_ownerIndex[uint(_from)] = 0;
        m_ownerIndex[uint(_to)] = ownerIndex;

        assertOwnersAreConsistent();
        OwnerChanged(_from, _to);
    }

    // All pending operations will be canceled!
    function addOwner(address _owner)
        external
        ownerDoesNotExist(_owner)
        validNumOwners(m_numOwners + 1)
        onlymanyowners(sha3(msg.data))
    {
        assertOwnersAreConsistent();

        clearPending();
        m_numOwners++;
        m_owners[m_numOwners] = uint(_owner);
        m_ownerIndex[uint(_owner)] = checkOwnerIndex(m_numOwners);

        assertOwnersAreConsistent();
        OwnerAdded(_owner);
    }

    // All pending operations will be canceled!
    function removeOwner(address _owner)
        external
        ownerExists(_owner)
        validNumOwners(m_numOwners - 1)
        validRequirement(m_required, m_numOwners - 1)
        onlymanyowners(sha3(msg.data))
    {
        assertOwnersAreConsistent();

        clearPending();
        uint ownerIndex = m_ownerIndex[uint(_owner)];
        m_owners[ownerIndex] = 0;
        m_ownerIndex[uint(_owner)] = 0;
        //make sure m_numOwners is equal to the number of owners and always points to the last owner
        reorganizeOwners();

        assertOwnersAreConsistent();
        OwnerRemoved(_owner);
    }

    // All pending operations will be canceled!
    function changeRequirement(uint _newRequired)
        external
        validRequirement(_newRequired, m_numOwners)
        onlymanyowners(sha3(msg.data))
    {
        m_required = _newRequired;
        clearPending();
        RequirementChanged(_newRequired);
    }

    // Gets an owner by 0-indexed position
    function getOwner(uint ownerIndex) external constant returns (address) {
        return address(m_owners[checkOwnerIndex(ownerIndex + 1)]);
    }

    function isOwner(address _addr) constant returns (bool) {
        return m_ownerIndex[uint(_addr)] > 0;
    }

    // Tests ownership of the current caller.
    // It's advisable to call it by new owner to make sure that the same erroneous address is not copy-pasted to
    // addOwner/changeOwner and to isOwner.
    function amIOwner() external constant onlyowner returns (bool) {
        return true;
    }

    // Revokes a prior confirmation of the given operation
    function revoke(bytes32 _operation)
        external
        operationIsActive(_operation)
        onlyowner
    {
        uint ownerIndexBit = makeOwnerBitmapBit(msg.sender);
        var pending = m_pending[_operation];
        require(pending.ownersDone & ownerIndexBit > 0);

        assertOperationIsConsistent(_operation);

        pending.yetNeeded++;
        pending.ownersDone -= ownerIndexBit;

        assertOperationIsConsistent(_operation);
        Revoke(msg.sender, _operation);
    }

    function hasConfirmed(bytes32 _operation, address _owner)
        external
        constant
        operationIsActive(_operation)
        ownerExists(_owner)
        returns (bool)
    {
        return !(m_pending[_operation].ownersDone & makeOwnerBitmapBit(_owner) == 0);
    }

    // INTERNAL METHODS

    function confirmAndCheck(bytes32 _operation)
        private
        onlyowner
        returns (bool)
    {
        var pending = m_pending[_operation];

        // if we're not yet working on this operation, switch over and reset the confirmation status.
        if (! isOperationActive(_operation)) {
            // reset count of confirmations needed.
            pending.yetNeeded = m_required;
            // reset which owners have confirmed (none) - set our bitmap to 0.
            pending.ownersDone = 0;
            pending.index = m_pendingIndex.length++;
            m_pendingIndex[pending.index] = _operation;
            assertOperationIsConsistent(_operation);
        }

        // determine the bit to set for this owner.
        uint ownerIndexBit = makeOwnerBitmapBit(msg.sender);
        // make sure we (the message sender) haven't confirmed this operation previously.
        if (pending.ownersDone & ownerIndexBit == 0) {
            Confirmation(msg.sender, _operation);
            // ok - check if count is enough to go ahead.
            assert(pending.yetNeeded > 0);
            if (pending.yetNeeded == 1) {
                // enough confirmations: reset and run interior.
                delete m_pendingIndex[m_pending[_operation].index];
                delete m_pending[_operation];
                return true;
            }
            else
            {
                // not enough: record that this owner in particular confirmed.
                pending.yetNeeded--;
                pending.ownersDone |= ownerIndexBit;
                assertOperationIsConsistent(_operation);
            }
        }
    }

    // Reclaims free slots between valid owners in m_owners.
    // TODO given that its called after each removal, it could be simplified.
    function reorganizeOwners() private {
        uint free = 1;
        while (free < m_numOwners)
        {
            // iterating to the first free slot from the beginning
            while (free < m_numOwners && m_owners[free] != 0) free++;

            // iterating to the first occupied slot from the end
            while (m_numOwners > 1 && m_owners[m_numOwners] == 0) m_numOwners--;

            // swap, if possible, so free slot is located at the end after the swap
            if (free < m_numOwners && m_owners[m_numOwners] != 0 && m_owners[free] == 0)
            {
                // owners between swapped slots should't be renumbered - that saves a lot of gas
                m_owners[free] = m_owners[m_numOwners];
                m_ownerIndex[m_owners[free]] = free;
                m_owners[m_numOwners] = 0;
            }
        }
    }

    function clearPending() internal {
        uint length = m_pendingIndex.length;
        for (uint i = 0; i < length; ++i)
            if (m_pendingIndex[i] != 0)
                delete m_pending[m_pendingIndex[i]];
        delete m_pendingIndex;
    }

    function checkOwnerIndex(uint ownerIndex) private constant returns (uint) {
        assert(0 != ownerIndex && ownerIndex <= c_maxOwners);
        return ownerIndex;
    }

    function makeOwnerBitmapBit(address owner) private constant returns (uint) {
        uint ownerIndex = checkOwnerIndex(m_ownerIndex[uint(owner)]);
        return 2 ** ownerIndex;
    }

    function isOperationActive(bytes32 _operation) private constant returns (bool) {
        return 0 != m_pending[_operation].yetNeeded;
    }

    function assertOwnersAreConsistent() private constant {
        assert(m_numOwners > 0);
        assert(m_numOwners <= c_maxOwners);
        assert(m_owners[0] == 0);
        assert(0 != m_required && m_required <= m_numOwners);
    }

    function assertOperationIsConsistent(bytes32 _operation) private constant {
        var pending = m_pending[_operation];
        assert(0 != pending.yetNeeded);
        assert(m_pendingIndex[pending.index] == _operation);
        assert(pending.yetNeeded <= m_required);
    }

   	// FIELDS

    uint constant c_maxOwners = 250;

    // the number of owners that must confirm the same operation before it is run.
    uint public m_required;

    // pointer used to find a free slot in m_owners
    uint public m_numOwners;

    // list of owners (addresses),
    // slot 0 is unused so there are no owner which index is 0.
    // TODO could we save space at the end of the array for the common case of <10 owners? and should we?
    uint[256] m_owners;

    // index on the list of owners to allow reverse lookup: owner address => index in m_owners
    mapping(uint => uint) m_ownerIndex;

    // the ongoing operations.
    mapping(bytes32 => PendingState) m_pending;
    bytes32[] m_pendingIndex;
}


Add test for longer JSON

Add test for longer JSON

pragma solidity ^0.4.5;

import "truffle/Assert.sol";
import "../contracts/JsmnSolLib.sol";

contract TestPrimitives {

    uint constant RETURN_SUCCESS = 0;
    uint constant RETURN_ERROR_INVALID_JSON = 1;
    uint constant RETURN_ERROR_PART = 2;
    uint constant RETURN_ERROR_NO_MEM = 3;

    function testStringKeyValue() {
        string memory json = '{"key": "value"}';

        uint returnValue;
        JsmnSolLib.Token[] memory tokens;
        uint actualNum;

        (returnValue, tokens, actualNum) = JsmnSolLib.parse(json, 5);

        Assert.equal(returnValue, RETURN_SUCCESS, 'Valid JSON should return a success.');
        Assert.equal(JsmnSolLib.getBytes(json, tokens[1].start, tokens[1].end), 'key', 'Not equal');
        Assert.equal(JsmnSolLib.getBytes(json, tokens[2].start, tokens[2].end), 'value', 'Not equal');
    }

    function testLongerJson() {
        string memory json = '{ "key1": { "key1.1": "value", "key1.2": 3, "key1.3": true, "key1.4": "val2"} }';

        uint returnValue;
        JsmnSolLib.Token[] memory tokens;
        uint actualNum;

        JsmnSolLib.Token memory t;

        (returnValue, tokens, actualNum) = JsmnSolLib.parse(json, 20);
        Assert.equal(returnValue, RETURN_SUCCESS, 'Valid JSON should return a success.');
        t = tokens[1];
        Assert.equal(JsmnSolLib.getBytes(json, t.start, t.end), 'key1', 'Not equal');

        t = tokens[3];
        Assert.equal(JsmnSolLib.getBytes(json, t.start, t.end), 'key1.1', 'Not equal');

        t = tokens[4];
        Assert.equal(JsmnSolLib.getBytes(json, t.start, t.end), 'value', 'Not equal');

        t = tokens[5];
        Assert.equal(JsmnSolLib.getBytes(json, t.start, t.end), 'key1.2', 'Not equal');

        t = tokens[6];
        Assert.equal(JsmnSolLib.parseInt(JsmnSolLib.getBytes(json, t.start, t.end)), 3, 'Not equal');

        t = tokens[7];
        Assert.equal(JsmnSolLib.getBytes(json, t.start, t.end), 'key1.3', 'Not equal');

        t = tokens[8];
        Assert.equal(JsmnSolLib.parseBool(JsmnSolLib.getBytes(json, t.start, t.end)), true, 'Not equal');

        t = tokens[9];
        Assert.equal(JsmnSolLib.getBytes(json, t.start, t.end), 'key1.4', 'Not equal');

        t = tokens[10];
        Assert.equal(JsmnSolLib.getBytes(json, t.start, t.end), 'val2', 'Not equal');
    }

    function testIntegerKeyValue() {
        string memory json = '{"key": 23}';

        uint returnValue;
        JsmnSolLib.Token[] memory tokens;
        uint actualNum;

        (returnValue, tokens, actualNum) = JsmnSolLib.parse(json, 5);

        Assert.equal(returnValue, RETURN_SUCCESS, 'Valid JSON should return a success.');
        Assert.equal(JsmnSolLib.getBytes(json, tokens[1].start, tokens[1].end), 'key', 'Not equal');
        Assert.equal(JsmnSolLib.parseInt(JsmnSolLib.getBytes(json, tokens[2].start, tokens[2].end)), 23, 'Not equal');
    }

    function testNegativeIntegerKeyValue() {
        string memory json = '{"key": -4523}';

        uint returnValue;
        JsmnSolLib.Token[] memory tokens;
        uint actualNum;

        (returnValue, tokens, actualNum) = JsmnSolLib.parse(json, 5);

        Assert.equal(returnValue, RETURN_SUCCESS, 'Valid JSON should return a success.');
        Assert.equal(JsmnSolLib.getBytes(json, tokens[1].start, tokens[1].end), 'key', 'Not equal');
        Assert.equal(JsmnSolLib.parseInt(JsmnSolLib.getBytes(json, tokens[2].start, tokens[2].end)), -4523, 'Not equal');
    }

    function testBoolKeyValue() {
        string memory json = '{"key": true}';

        uint returnValue;
        JsmnSolLib.Token[] memory tokens;
        uint actualNum;

        (returnValue, tokens, actualNum) = JsmnSolLib.parse(json, 5);

        Assert.equal(returnValue, RETURN_SUCCESS, 'Valid JSON should return a success.');
        Assert.equal(JsmnSolLib.getBytes(json, tokens[1].start, tokens[1].end), 'key', 'Not equal');
        Assert.isTrue(JsmnSolLib.parseBool(JsmnSolLib.getBytes(json, tokens[2].start, tokens[2].end)), 'Not equal');
    }

    function testFloatKeyValue() {
        string memory json = '{"key": 23.45, "key2": 5, "key3": "23.66", "key4": "236.6"}';

        uint returnValue;
        JsmnSolLib.Token[] memory tokens;
        uint actualNum;

        (returnValue, tokens, actualNum) = JsmnSolLib.parse(json, 10);

        Assert.equal(returnValue, RETURN_SUCCESS, 'Valid JSON should return a success.');
        Assert.equal(JsmnSolLib.getBytes(json, tokens[1].start, tokens[1].end), 'key', 'Not equal');
        Assert.equal(JsmnSolLib.parseInt(JsmnSolLib.getBytes(json, tokens[2].start, tokens[2].end), 2), 2345, 'Not equal');
    }

}

pragma solidity ^0.4.5;

import "truffle/Assert.sol";
import "../contracts/JsmnSolLib.sol";

contract TestPrimitives {

    uint constant RETURN_SUCCESS = 0;
    uint constant RETURN_ERROR_INVALID_JSON = 1;
    uint constant RETURN_ERROR_PART = 2;
    uint constant RETURN_ERROR_NO_MEM = 3;

    function testStringKeyValue() {
        string memory json = '{"key": "value"}';

        uint returnValue;
        JsmnSolLib.Token[] memory tokens;
        uint actualNum;

        (returnValue, tokens, actualNum) = JsmnSolLib.parse(json, 5);

        Assert.equal(returnValue, RETURN_SUCCESS, 'Valid JSON should return a success.');
        Assert.equal(JsmnSolLib.getBytes(json, tokens[1].start, tokens[1].end), 'key', 'Not equal');
        Assert.equal(JsmnSolLib.getBytes(json, tokens[2].start, tokens[2].end), 'value', 'Not equal');
    }

    function testIntegerKeyValue() {
        string memory json = '{"key": 23}';

        uint returnValue;
        JsmnSolLib.Token[] memory tokens;
        uint actualNum;

        (returnValue, tokens, actualNum) = JsmnSolLib.parse(json, 5);

        Assert.equal(returnValue, RETURN_SUCCESS, 'Valid JSON should return a success.');
        Assert.equal(JsmnSolLib.getBytes(json, tokens[1].start, tokens[1].end), 'key', 'Not equal');
        Assert.equal(JsmnSolLib.parseInt(JsmnSolLib.getBytes(json, tokens[2].start, tokens[2].end)), 23, 'Not equal');
    }

    function testNegativeIntegerKeyValue() {
        string memory json = '{"key": -4523}';

        uint returnValue;
        JsmnSolLib.Token[] memory tokens;
        uint actualNum;

        (returnValue, tokens, actualNum) = JsmnSolLib.parse(json, 5);

        Assert.equal(returnValue, RETURN_SUCCESS, 'Valid JSON should return a success.');
        Assert.equal(JsmnSolLib.getBytes(json, tokens[1].start, tokens[1].end), 'key', 'Not equal');
        Assert.equal(JsmnSolLib.parseInt(JsmnSolLib.getBytes(json, tokens[2].start, tokens[2].end)), -4523, 'Not equal');
    }

    function testBoolKeyValue() {
        string memory json = '{"key": true}';

        uint returnValue;
        JsmnSolLib.Token[] memory tokens;
        uint actualNum;

        (returnValue, tokens, actualNum) = JsmnSolLib.parse(json, 5);

        Assert.equal(returnValue, RETURN_SUCCESS, 'Valid JSON should return a success.');
        Assert.equal(JsmnSolLib.getBytes(json, tokens[1].start, tokens[1].end), 'key', 'Not equal');
        Assert.isTrue(JsmnSolLib.parseBool(JsmnSolLib.getBytes(json, tokens[2].start, tokens[2].end)), 'Not equal');
    }

    function testFloatKeyValue() {
        string memory json = '{"key": 23.45, "key2": 5, "key3": "23.66", "key4": "236.6"}';

        uint returnValue;
        JsmnSolLib.Token[] memory tokens;
        uint actualNum;

        (returnValue, tokens, actualNum) = JsmnSolLib.parse(json, 10);

        Assert.equal(returnValue, RETURN_SUCCESS, 'Valid JSON should return a success.');
        Assert.equal(JsmnSolLib.getBytes(json, tokens[1].start, tokens[1].end), 'key', 'Not equal');
        Assert.equal(JsmnSolLib.parseInt(JsmnSolLib.getBytes(json, tokens[2].start, tokens[2].end), 2), 2345, 'Not equal');
    }

}


Added approval system and external token trasfer fucntion

import "lib/random.sol";
import "userMaster.sol";
import "concept.sol";
import "assessment.sol";
import "conceptMaster.sol";

/*
@type: contract
@name: User
@purpose: To act as a representation for a user in the system
*/
contract User
{
  address user; //The address of the user's wallet
  address master; //The address of the userMaster that spawned this user
  address conceptMaster; //The address of the conceptMaster
  string public userData; //An IPFS hash containing the user's data
  mapping (address => bool) public conceptPassed;
  mapping (address => Approval) transactApproved;
  mapping (address => Approval) assessApproved;
  struct Approval
  {
    bool approved;
    int value; //fix stakes pls
  }

  /*
  @type: modifier
  @name: onlyUser
  @purpose: to only allow the user's wallet contract to call a function to which this modifier is applied
  */
  modifier onlyUser()
  {
    if(msg.sender != user) //checks if msg.sender has the same address as the user's wallet
    {
      throw; //throws the function call if not
    }
    _;
  }

  modifier onlyConcept()
  {
    if(ConceptMaster(conceptMaster).conceptExists(msg.sender) == false)
    {
      throw;
    }
    _;
  }
  /*
  @type: event
  @name: Notification
  @purpose: To provide a user with notifications
  */
  event Notification
  ( address _sender, //The notification sender
    address _user, //The address of the user that received the notification
    address _concept, //The address of the concept involved in this notification
    uint _code); //The notification code

  /*
  @type: constructor function
  @purpose: To initialize the user contract
  @param: address userAddress = the address of the user's wallet
  @param: address masterAddress = the address of the user master that spawned this user
  @returns: nothing
  */
  function User(address userAddress, address masterAddress, address conceptMasterAddress)
  {
    user = userAddress; //Sets the user variable
    master = masterAddress; //Sets the master variable
    conceptMaster = conceptMasterAddress; //Sets the conceptMaster variable
  }

  /*
  @type: function
  @purpose: To set the availability of the user
  @param: bool available = the availability of the user
  @returns: nothing
  */
  function setAvailability(bool available) onlyUser()
  {
    UserMaster(master).mapAvailability(available); //Sets the user's availability to the value of the parameter
  }

  /*
  @type: function
  @purpose: To confirm that a user is assessing or not assessing
  @param: address assessment =  The assessment that the user has been called to assess
  @param: uint confirm = The user's confirmation code
  @returns: nothing
  */
  function confirmAssessment(address assessment, uint confirm) onlyUser()
  {
    Assessment(assessment).confirmAssessor(confirm); //Sends the user's confromation to the assessmnet
  }

  /*
  @type: function
  @purpose: To send and IPFS hash to the assessment
  @param: address assessment =  The assessment that the user has been called to assess
  @param: string data = the IPFS hash
  @returns: nothing
  */
  function setAssessmentData(address assessment, string data) onlyUser()
  {
    Assessment(assessment).setData(data); //Gives the assessment the IPFS hash
  }

  /*
  @type: function
  @purpose: To notify the assessment that the user is done assessing
  @param: address assessment =  The assessment that the user has been called to assess
  @returns: nothing
  */
  function doneAssessing(address assessment) onlyUser()
  {
    Assessment(assessment).doneAssessing(); //Sets the user as done assessing in the assessment
  }

  /*
  @type: function
  @purpose: To send the score that the user has decided on to the assessment
  @param: address assessment =  The assessment that the user has been called to assess
  @param: uint score = the score that the user decided on
  @returns: nothing
  */
  function setResult(address assessment, int score) onlyUser()
  {
    Assessment(assessment).setResult(score); //Sends to score to the assessment
  }

  /*
  @type: function
  @purpose: To send this user a notification
  @param: string description = the notification message
  @param: address concept = the address of the concept involved in this notification
  @param: uint code = the address of the concept involved in this notification
  @returns: nothing
  */
  function notification(address concept, uint code)
  {
    Notification(msg.sender, address(this), concept, code);
  }

  /*
  @type: function
  @purpose: To set the user's IPFS hash containing their information
  @param: string hash = IPFS hash containing the user information
  @returns: nothing
  */
  function setUserData(string hash) onlyUser()
  {
    userData = hash; //Sets userData to the hash value
  }

  function transferTokens(address user, int amount) onlyUser() returns(bool)
  {
    return UserMaster(master).transferTokens(user,amount);
  }

  function extTransferTokens(address user, int amount) returns(bool)
  {
    if(transactApproved[msg.sender].approved = false)
    {
      return false;
    }
    else if(transactApproved[msg.sender].value > amount)
    {
      return false;
    }
    else
    {
      return UserMaster(master).transferTokens(user,amount);
    }
  }

  function setConceptPassed(bool passed) onlyConcept()
  {
    conceptPassed[msg.sender] = passed;
  }

  /*
  @type: function
  @purpose: to remove this contract
  @param: address receiver = the address of the wallet that will receive of the ether
  @returns: nothing
  */
  function remove(address reciever) onlyUser()
  {
    suicide(reciever);
  }
}

import "lib/random.sol";
import "userMaster.sol";
import "concept.sol";
import "assessment.sol";
import "conceptMaster.sol";

/*
@type: contract
@name: User
@purpose: To act as a representation for a user in the system
*/
contract User
{
  address user; //The address of the user's wallet
  address master; //The address of the userMaster that spawned this user
  address conceptMaster; //The address of the conceptMaster
  string public userData; //An IPFS hash containing the user's data
  mapping (address => bool) public conceptPassed;

  /*
  @type: modifier
  @name: onlyUser
  @purpose: to only allow the user's wallet contract to call a function to which this modifier is applied
  */
  modifier onlyUser()
  {
    if(msg.sender != user) //checks if msg.sender has the same address as the user's wallet
    {
      throw; //throws the function call if not
    }
    _;
  }

  modifier onlyConcept()
  {
    if(ConceptMaster(conceptMaster).conceptExists(msg.sender) == false)
    {
      throw;
    }
    _;
  }
  /*
  @type: event
  @name: Notification
  @purpose: To provide a user with notifications
  */
  event Notification
  ( address _sender, //The notification sender
    address _user, //The address of the user that received the notification
    address _concept, //The address of the concept involved in this notification
    uint _code); //The notification code

  /*
  @type: constructor function
  @purpose: To initialize the user contract
  @param: address userAddress = the address of the user's wallet
  @param: address masterAddress = the address of the user master that spawned this user
  @returns: nothing
  */
  function User(address userAddress, address masterAddress, address conceptMasterAddress)
  {
    user = userAddress; //Sets the user variable
    master = masterAddress; //Sets the master variable
    conceptMaster = conceptMasterAddress; //Sets the conceptMaster variable
  }

  /*
  @type: function
  @purpose: To set the availability of the user
  @param: bool available = the availability of the user
  @returns: nothing
  */
  function setAvailability(bool available) onlyUser()
  {
    UserMaster(master).mapAvailability(available); //Sets the user's availability to the value of the parameter
  }

  /*
  @type: function
  @purpose: To confirm that a user is assessing or not assessing
  @param: address assessment =  The assessment that the user has been called to assess
  @param: uint confirm = The user's confirmation code
  @returns: nothing
  */
  function confirmAssessment(address assessment, uint confirm) onlyUser()
  {
    Assessment(assessment).confirmAssessor(confirm); //Sends the user's confromation to the assessmnet
  }

  /*
  @type: function
  @purpose: To send and IPFS hash to the assessment
  @param: address assessment =  The assessment that the user has been called to assess
  @param: string data = the IPFS hash
  @returns: nothing
  */
  function setAssessmentData(address assessment, string data) onlyUser()
  {
    Assessment(assessment).setData(data); //Gives the assessment the IPFS hash
  }

  /*
  @type: function
  @purpose: To notify the assessment that the user is done assessing
  @param: address assessment =  The assessment that the user has been called to assess
  @returns: nothing
  */
  function doneAssessing(address assessment) onlyUser()
  {
    Assessment(assessment).doneAssessing(); //Sets the user as done assessing in the assessment
  }

  /*
  @type: function
  @purpose: To send the score that the user has decided on to the assessment
  @param: address assessment =  The assessment that the user has been called to assess
  @param: uint score = the score that the user decided on
  @returns: nothing
  */
  function setResult(address assessment, int score) onlyUser()
  {
    Assessment(assessment).setResult(score); //Sends to score to the assessment
  }

  /*
  @type: function
  @purpose: To send this user a notification
  @param: string description = the notification message
  @param: address concept = the address of the concept involved in this notification
  @param: uint code = the address of the concept involved in this notification
  @returns: nothing
  */
  function notification(address concept, uint code)
  {
    Notification(msg.sender, address(this), concept, code);
  }

  /*
  @type: function
  @purpose: To set the user's IPFS hash containing their information
  @param: string hash = IPFS hash containing the user information
  @returns: nothing
  */
  function setUserData(string hash) onlyUser()
  {
    userData = hash; //Sets userData to the hash value
  }

  function transferTokens(address user, int amount) onlyUser() returns(bool)
  {
    return UserMaster(master).transferTokens(user,amount);
  }

  function setConceptPassed(bool passed) onlyConcept()
  {
    conceptPassed[msg.sender] = passed;
  }

  /*
  @type: function
  @purpose: to remove this contract
  @param: address receiver = the address of the wallet that will receive of the ether
  @returns: nothing
  */
  function remove(address reciever) onlyUser()
  {
    suicide(reciever);
  }
}


multiowned: refactoring: removed some copy-paste


Typo in return statement

Typo in return statement

Just looking at this quickly, it looks like you mean to return success and not just TRUE each time

contract Etherdoc {
    address owner;

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

    // In case you sent funds by accident
    function empty(){
     uint256 balance = address(this).balance;
     address(owner).send(balance);
    }

    function newDocument(bytes32 hash) returns (bool success){
        if (documentExists(hash)) {
            success = false;
        }else{

            createHistory(hash, msg.sender, msg.sender);
            usedHashes[hash] = true;
            success = true;
        }
        return success;
    }
    function createHistory (bytes32 hash, address from, address to) internal{
            ++latestDocument;
            documentHashMap[hash] = to;
            usedHashes[hash] = true;
            history[latestDocument] = DocumentTransfer(block.number, hash, from, to);
            DocumentEvent(block.number, hash, from,to);
    }

    function transferDocument(bytes32 hash, address recipient) returns (bool success){
        success = false;

        if (documentExists(hash)){
            if (documentHashMap[hash] == msg.sender){
                createHistory(hash, msg.sender, recipient);
                success = true;
            }
        }

        return success;
    }

    function documentExists(bytes32 hash) constant returns (bool exists){
        if (usedHashes[hash]) {
            exists = true;
        }else{
            exists= false;
        }
        return exists;
    }

    function getDocument(uint docId) constant returns (uint blockNumber, bytes32 hash, address from, address to){
        DocumentTransfer doc = history[docId];
        blockNumber = doc.blockNumber;
        hash = doc.hash;
        from = doc.from;
        to = doc.to;
    }

    event DocumentEvent(uint blockNumber, bytes32 indexed hash, address indexed from, address indexed to);

    struct DocumentTransfer {
        uint blockNumber;
        bytes32 hash;
        address from;
        address to;
    }

    function getLatest() constant returns (uint latest){
        return latestDocument;
    }

    uint latestDocument;

    mapping(uint => DocumentTransfer) public history;
    mapping(bytes32 => bool) public usedHashes;
    mapping(bytes32 => address) public documentHashMap;
}

contract Etherdoc {
    address owner;

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

    // In case you sent funds by accident
    function empty(){
     uint256 balance = address(this).balance;
     address(owner).send(balance);
    }

    function newDocument(bytes32 hash) returns (bool success){
        if (documentExists(hash)) {
            success = false;
        }else{

            createHistory(hash, msg.sender, msg.sender);
            usedHashes[hash] = true;
            success = true;
        }
        return true;
    }
    function createHistory (bytes32 hash, address from, address to) internal{
            ++latestDocument;
            documentHashMap[hash] = to;
            usedHashes[hash] = true;
            history[latestDocument] = DocumentTransfer(block.number, hash, from, to);
            DocumentEvent(block.number, hash, from,to);
    }

    function transferDocument(bytes32 hash, address recipient) returns (bool success){
        success = false;

        if (documentExists(hash)){
            if (documentHashMap[hash] == msg.sender){
                createHistory(hash, msg.sender, recipient);
                success = true;
            }
        }

        return success;
    }

    function documentExists(bytes32 hash) constant returns (bool exists){
        if (usedHashes[hash]) {
            exists = true;
        }else{
            exists= false;
        }
        return exists;
    }

    function getDocument(uint docId) constant returns (uint blockNumber, bytes32 hash, address from, address to){
        DocumentTransfer doc = history[docId];
        blockNumber = doc.blockNumber;
        hash = doc.hash;
        from = doc.from;
        to = doc.to;
    }

    event DocumentEvent(uint blockNumber, bytes32 indexed hash, address indexed from, address indexed to);

    struct DocumentTransfer {
        uint blockNumber;
        bytes32 hash;
        address from;
        address to;
    }

    function getLatest() constant returns (uint latest){
        return latestDocument;
    }

    uint latestDocument;

    mapping(uint => DocumentTransfer) public history;
    mapping(bytes32 => bool) public usedHashes;
    mapping(bytes32 => address) public documentHashMap;
}