nettingChannelContract.sol is now compiling.

/*import "Decoder.sol";*/
contract NettingContract {
    uint lockedTime;
    address assetAddress;
    uint opened;
    uint closed;
    uint settled;
    address closingAddress;

    struct Transfer
    {
        address sender;
        uint nonce;
        address asset;
        uint balance;
        address recipient;
        bytes32 locksroot;
        bytes32 secret;
        uint expiration;
    }
    struct Unlocked
    {
        bytes merkleProof;
        bytes32 hashlock;
        bytes32 secret;
        uint amount;
        uint expiration;
    }
    struct Participant
    {
        address addr;
        uint deposit;
        uint netted;
        uint transferedAmount;
        Transfer lastSentTransfer;
        Unlocked unlocked;
    }
    Participant[2] participants; // We only have two participants at all times

    event ChannelOpened(address assetAdr); // TODO
    event ChannelClosed(); // TODO
    event ChannelSettled(); // TODO
    event ChannelSecretRevealed(); //TODO

    modifier inParticipants {
        if (msg.sender != participants[0].addr &&
            msg.sender != participants[1].addr) throw;
        _
    }

    function NettingContract(address assetAdr, address participant1, address participant2) {
        opened = 0;
        closed = 0;
        settled = 0;
        assetAddress = assetAdr;
        participants[0].addr = participant1;
        participants[1].addr = participant2;
    }

    // Get the index of an address in participants
    function atIndex(address addr) returns (uint index) {
        if (addr == participants[0].addr) return 0;
        else return 1;
    }

    /// @notice deposit(address, uint) to deposit amount to a participant.
    /// @dev Deposit an amount to a participating address.
    /// @param amount (uint) the amount to be deposited to the address
    function deposit(uint amount) inParticipants {
        if (msg.sender.balance < amount) throw; // TODO check asset contract
        participants[atIndex(msg.sender)].deposit += amount;
        if(isOpen() && opened == 0) open();
    }

    /// @notice open() to set the opened to be the current block and triggers
    /// the event ChannelOpened()
    /// @dev Sets the value of `opened` to be the value of the current block.
    /// param none
    /// returns none, but changes the value of `opened` and triggers the event ChannelOpened.
    function open() {
        opened = block.number;

        // trigger event
        ChannelOpened(assetAddress);
    }

    /// @notice partner() to get the partner or other participant of the channel
    /// @dev Get the other participating party of the channel
    /// @return p (address) the partner of the calling party
    function partner(address a) returns (address p) {
        if (a == participants[0].addr) return participants[1].addr;
        else return participants[0].addr;
    }

    /// @notice isOpen() to check if a channel is open
    /// @dev Check if a channel is open and both parties have deposited to the channel
    /// @return open (bool) the status of the channel
    function isOpen() constant returns (bool open) {
        if (closed == 0) throw;
        if (participants[0].deposit > 0 || participants[1].deposit > 0) return true;
        else return false;
    }

    /// @notice close(bytes, bytes) to close a channel between to parties
    /// @dev Close the channel between two parties
    /// @param firstEncoded (bytes) the last sent transfer of the msg.sender
    function close(bytes firstEncoded) inParticipants {
        if (settled > 0) throw; // channel already settled
        if (closed > 0) throw; // channel is closing

        // check if sender of message is a participant
        if (getSender(firstEncoded) != participants[0].addr &&
            getSender(firstEncoded) != participants[1].addr) throw;

        uint partnerId = atIndex(partner(msg.sender));
        uint senderId = atIndex(msg.sender);

        decode(firstEncoded);

        // mark closed
        closed = block.number;
        closingAddress = msg.sender;

        uint amount1 = participants[senderId].transferedAmount;
        uint amount2 = participants[partnerId].transferedAmount;

        uint allowance = participants[senderId].deposit + participants[partnerId].deposit;
        uint difference;
        if(amount1 > amount2) {
            difference = amount1 - amount2;
        } else {
            difference = amount2 - amount1;
        }

        // TODO
        // if (difference > allowance) penalize();

        // trigger event
        //TODO
        ChannelClosed();
    }

    /// @notice close(bytes, bytes) to close a channel between to parties
    /// @dev Close the channel between two parties
    /// @param firstEncoded (bytes) the last sent transfer of the msg.sender
    /// @param secondEncoded (bytes) the last sent transfer of the msg.sender
    function close(bytes firstEncoded, bytes secondEncoded) inParticipants {
        if (settled > 0) throw; // channel already settled
        if (closed > 0) throw; // channel is closing

        // check if the sender of either of the messages is a participant
        if (getSender(firstEncoded) != participants[0].addr &&
            getSender(firstEncoded) != participants[1].addr) throw;
        if (getSender(secondEncoded) != participants[0].addr &&
            getSender(secondEncoded) != participants[1].addr) throw;

        // Don't allow both transfers to be from the same sender
        if (getSender(firstEncoded) == getSender(secondEncoded)) throw;

        uint partnerId = atIndex(partner(msg.sender));
        uint senderId = atIndex(msg.sender);

        decode(firstEncoded);
        decode(secondEncoded);

        // mark closed
        closed = block.number;
        closingAddress = msg.sender;

        uint amount1 = participants[senderId].transferedAmount;
        uint amount2 = participants[partnerId].transferedAmount;

        uint allowance = participants[senderId].deposit + participants[partnerId].deposit;
        uint difference;
        if(amount1 > amount2) {
            difference = amount1 - amount2;
        } else {
            difference = amount2 - amount1;
        }

        // TODO
        // if (difference > allowance) penalize();

        // trigger event
        //TODO
        ChannelClosed();
    }

    /// @notice updateTransfer(bytes) to update last known transfer
    /// @dev Allow the partner to update the last known transfer
    /// @param message (bytes) the encoded transfer message
    function updateTransfer(bytes message) inParticipants {
        if (settled > 0) throw; // channel already settled
        if (closed == 0) throw; // channel is open
        if (msg.sender == closingAddress) throw; // don't allow closer to update
        if (closingAddress == getSender(message)) throw;

        decode(message);

        // TODO check if tampered and penalize
        // TODO check if outdated and penalize

    }

    /// @notice unlock(bytes, bytes, bytes32) to unlock a locked transfer
    /// @dev Unlock a locked transfer
    /// @param lockedEncoded (bytes) the lock
    /// @param merkleProof (bytes) the merkle proof
    /// @param secret (bytes32) the secret
    function unlock(bytes lockedEncoded, bytes merkleProof, bytes32 secret) inParticipants{
        if (settled > 0) throw; // channel already settled
        if (closed == 0) throw; // channel is open

        uint partnerId = atIndex(partner(msg.sender));
        uint senderId = atIndex(msg.sender);

        if (participants[partnerId].lastSentTransfer.nonce == 0) throw;

        bytes32 h = sha3(lockedEncoded);

        for (uint i = 0; i < merkleProof.length; i += 64) {
            bytes32 left;
            left = bytesToBytes32(slice(merkleProof, i, i + 32), left);
            bytes32 right;
            right = bytesToBytes32(slice(merkleProof, i + 32, i + 64), right);
            if (h != left && h != right) throw;
            h = sha3(left, right);
        }

        if (participants[partnerId].lastSentTransfer.locksroot != h) throw;

        // TODO decode lockedEncoded into a Unlocked struct and append

        //participants[partnerId].unlocked.push(lock);
    }

    /// @notice settle() to settle the balance between the two parties
    /// @dev Settles the balances of the two parties fo the channel
    /// @return participants (Participant[]) the participants with netted balances
    /*
    function settle() returns (Participant[] participants) {
        if (settled > 0) throw;
        if (closed == 0) throw;
        if (closed + lockedTime > block.number) throw; //if locked time has expired throw

        for (uint i = 0; i < participants.length; i++) {
            uint otherIdx = atIndex(partner(participants[i].addr));
            participants[i].netted = participants[i].deposit;
            if (participants[i].lastSentTransfer != 0) {
                participants[i].netted = participants[i].lastSentTransfer.balance;
            }
            if (participants[otherIdx].lastSentTransfer != 0) {
                participants[i].netted = participants[otherIdx].lastSentTransfer.balance;
            }
        }

        //for (uint j = 0; j < participants.length; j++) {
            //uint otherIdx = atIndex(partner(participants[j].addr));
        //}

        // trigger event
        //ChannelSettled();
    }
    */

    // Get the nonce of the last sent transfer
    function getNonce(bytes message) returns (uint8 non) {
        // Direct Transfer
        if (message[0] == 5) {
            (non, , , , , , ) = decodeTransfer(message);
        }
        // Locked Transfer
        if (message[0] == 6) {
            (non, , , ) = decodeLockedTransfer1(message);
        }
        // Mediated Transfer
        if (message[0] == 7) {
            (non, , , , ) = decodeMediatedTransfer1(message);
        }
        // Cancel Transfer
        if (message[0] == 8) {
            (non, , , ) = decodeCancelTransfer1(message);
        }
        else throw;
    }

    // Gets the sender of a last sent transfer
    function getSender(bytes message) returns (address sndr) {

        // Secret
        if (message[0] == 4) {
            sndr = dsec(message);
        }
        // Direct Transfer
        if (message[0] == 5) {
            sndr = ddtran(message);
        }
        // Locked Transfer
        if (message[0] == 6) {
            sndr = dltran(message);
        }
        // Mediated Transfer
        if (message[0] == 7) {
            sndr = dmtran(message);
        }
        // Cancel Transfer
        if (message[0] == 8) {
            sndr = dctran(message);
        }
        else throw;
    }

    function dsec(bytes message) returns (address sndr) {
        var(sec, sig) = decodeSecret(message);
        bytes32 h = sha3(sec);
        sndr = ecrecovery(h, sig);
    }
    function ddtran(bytes message) returns (address sndr) {
        var(non, ass, rec, bal, olo, , sig) = decodeTransfer(message);
        bytes32 h = sha3(non, ass, bal, rec, olo); //need the optionalLocksroot
        sndr = ecrecovery(h, sig);
    }
    function dltran(bytes message) returns (address sndr) {
        bytes32 lock;
        var(non, , ass, rec) = decodeLockedTransfer1(message);
        var(loc, bal, , has, sig) = decodeLockedTransfer2(message);
        bytes32 h = sha3(non, ass, bal, rec, loc, lock ); //need the lock
        sndr = ecrecovery(h, sig);
    }
    function dmtran(bytes message) returns (address sndr) {
        bytes32 lock;
        var(non, , ass, rec, tar) = decodeMediatedTransfer1(message);
        var(ini, loc, bal, , , fee, sig) = decodeMediatedTransfer2(message);
        bytes32 h = sha3(non, ass, bal, rec, loc, lock, tar, ini, fee); //need the lock
        sndr = ecrecovery(h, sig);
    }
    function dctran(bytes message) returns (address sndr) {
        bytes32 lock;
        var(non, , ass, rec) = decodeCancelTransfer1(message);
        var(loc, bal, , , sig) = decodeCancelTransfer2(message);
        bytes32 h = sha3(non, ass, bal, rec, loc, lock); //need the lock
        sndr = ecrecovery(h, sig);
    }

    function decode(bytes message) {
        bytes32 hash;
        // Secret
        uint i;
        if (message[0] == 4) {
            decsec(message);
        }
        // Direct Transfer
        if (message[0] == 5) {
            decdir(message);
        }
        // Locked Transfer
        if (message[0] == 6) {
            hash = decloc1(message);
            decloc2(message, hash);
        }
        // Mediated Transfer
        if (message[0] == 7) {
            hash = decmed1(message);
            decmed2(message, hash);
        }
        // Cancel Transfer
        if (message[0] == 8) {
            hash = deccan1(message);
            deccan2(message, hash);
        }
        else throw;
    }

    function decsec(bytes message) {
        uint i = atIndex(getSender(message));
        var(sec, sig) = decodeSecret(message);
        participants[atIndex(msg.sender)].lastSentTransfer.secret = sec;
        bytes32 h = sha3(sec);
        participants[i].lastSentTransfer.sender = ecrecovery(h, sig);
    }
    function decdir(bytes message) {
        bytes32 lock;
        uint i = atIndex(getSender(message));
        var(non, ass, rec, bal, loc, sec, sig) = decodeTransfer(message);
        participants[i].lastSentTransfer.nonce = non;
        participants[i].lastSentTransfer.asset = ass;
        participants[i].lastSentTransfer.recipient = rec;
        participants[i].lastSentTransfer.balance = bal;
        bytes32 h = sha3(non, ass, bal, rec, loc);
        participants[i].lastSentTransfer.sender = ecrecovery(h, sig);
    }
    function decloc1(bytes message) returns (bytes32 hh) {
        uint i = atIndex(getSender(message));
        var(non, exp, ass, rec) = decodeLockedTransfer1(message);
        participants[i].lastSentTransfer.nonce = non;
        lockedTime = exp;
        participants[i].lastSentTransfer.asset = ass;
        participants[i].lastSentTransfer.recipient = rec;
        hh = sha3(non, ass, rec);
    }
    function decloc2(bytes message, bytes32 hh) {
        bytes32 lock;
        uint i = atIndex(getSender(message));
        var(loc, bal, amo, has, sig) = decodeLockedTransfer2(message);
        participants[i].lastSentTransfer.locksroot = loc;
        participants[i].lastSentTransfer.balance = bal;
        participants[i].unlocked.amount = amo; // should be changed to transferedAmount
        participants[i].unlocked.hashlock = has;
        bytes32 h = sha3(hh, bal, loc, lock ); //need the lock
        participants[i].lastSentTransfer.sender = ecrecovery(h, sig);
    }
    function decmed1(bytes message) returns (bytes32 hh) {
        uint i = atIndex(getSender(message));
        var(non, exp, ass, rec, tar) = decodeMediatedTransfer1(message);
        participants[i].lastSentTransfer.nonce = non;
        lockedTime = exp;
        participants[i].lastSentTransfer.asset = ass;
        participants[i].lastSentTransfer.recipient = rec;
        hh = sha3(non, ass, rec, tar);
    }
    function decmed2(bytes message, bytes32 hh) {
        bytes32 lock;
        uint i = atIndex(getSender(message));
        var(ini, loc, has, bal, amo, fee, sig) = decodeMediatedTransfer2(message);
        participants[i].lastSentTransfer.locksroot = loc;
        participants[i].unlocked.hashlock = has;
        participants[i].lastSentTransfer.balance = bal;
        participants[i].unlocked.amount = amo; // should be changed to transferedAmount
        bytes32 h = sha3(hh, bal, loc, lock, ini, fee); //need the lock
        participants[i].lastSentTransfer.sender = ecrecovery(h, sig);
    }
    function deccan1(bytes message) returns (bytes32 hh) {
        uint i = atIndex(getSender(message));
        var(non, exp, ass, rec) = decodeCancelTransfer1(message);
        participants[i].lastSentTransfer.nonce = non;
        lockedTime = exp;
        participants[i].lastSentTransfer.asset = ass;
        participants[i].lastSentTransfer.recipient = rec;
        hh = sha3(non, ass, rec);
    }
    function deccan2(bytes message, bytes32 hh) {
        bytes32 lock;
        uint i = atIndex(getSender(message));
        var(loc, bal, amo, has, sig) = decodeCancelTransfer2(message);
        participants[i].lastSentTransfer.locksroot = loc;
        participants[i].lastSentTransfer.balance = bal;
        participants[i].unlocked.amount = amo; // should be changed to transferedAmount
        participants[i].unlocked.hashlock = has;
        bytes32 h = sha3(hh, bal, loc, lock); //need the lock
        participants[i].lastSentTransfer.sender = ecrecovery(h, sig);
    }

    // Written by Alex Beregszaszi (@axic), use it under the terms of the MIT license.
    function ecrecovery(bytes32 hash, bytes sig) returns (address) {
        bytes32 r;
        bytes32 s;
        uint8 v;

        // FIXME: Should this throw, or return 0?
        if (sig.length != 65)
          return 0;

        // The signature format is a compact form of:
        //   {bytes32 r}{bytes32 s}{uint8 v}
        // Compact means, uint8 is not padded to 32 bytes.
        assembly {
            r := mload(add(sig, 32))
            s := mload(add(sig, 64))
            // Here we are loading the last 32 bytes, including 31 bytes
            // of 's'. There is no 'mload8' to do this.
            //
            // 'byte' is not working due to the Solidity parser, so lets
            // use the second best option, 'and'
            v := and(mload(add(sig, 65)), 1)
        }

        // old geth sends a `v` value of [0,1], while the new, in line with the YP sends [27,28]
        if (v < 27)
          v += 27;

        return ecrecover(hash, v, r, s);
    }

    function ecverify(bytes32 hash, bytes sig, address signer) returns (bool) {
        return ecrecovery(hash, sig) == signer;
    }

    function slice(bytes a, uint start, uint end) returns (bytes n) {
        if (a.length < end) throw;
        if (start < 0) throw;
        if (start > end) throw;
        n = new bytes(end-start);
        for ( uint i = start; i < end; i ++) { //python style slice
            n[i-start] = a[i];
        }
    }

    function decodeSecret(bytes m) returns (bytes32 secret, bytes signature) {
        if (m.length != 101) throw;
        secret = bytesToBytes32(slice(m, 4, 36), secret);
        signature = slice(m, 36, 101);
    }

    function decodeTransfer(bytes m) returns (uint8 nonce, address asset, address recipient,
                                                uint balance, bytes32 optionalLocksroot,
                                                bytes32 optionalSecret, bytes signature)
    {
        if (m.length != 213) throw;
        nonce = bytesToIntEight(slice(m, 4, 12), nonce);
        uint160 ia;
        asset = bytesToAddress(slice(m, 12, 32), ia);
        uint160 ir;
        recipient = bytesToAddress(slice(m, 32, 52), ir);
        balance = bytesToInt(slice(m, 52, 84), balance);
        optionalLocksroot = bytesToBytes32(slice(m, 84, 116), optionalLocksroot);
        optionalSecret = bytesToBytes32(slice(m, 116, 148), optionalSecret);
        signature = slice(m, 148, 213);

    }

    function decodeLockedTransfer1(bytes m) returns (uint8 nonce, uint8 expiration,
                                                        address asset, address recipient)
    {
        if (m.length != 253) throw;
        nonce = bytesToIntEight(slice(m, 4, 12), nonce);
        expiration = bytesToIntEight(slice(m, 12, 20), expiration);
        uint160 ia;
        asset = bytesToAddress(slice(m, 20, 40), ia);
        uint160 ir;
        recipient = bytesToAddress(slice(m, 40, 60), ir);

    }

    function decodeLockedTransfer2(bytes m) returns
                                    (bytes32 locksroot, uint balance, uint amount,
                                        bytes32 hashlock, bytes signature)
    {

        locksroot = bytesToBytes32(slice(m, 60, 92), locksroot);
        balance = bytesToInt(slice(m, 92, 124), balance);
        amount = bytesToInt(slice(m, 124, 156), amount);
        hashlock = bytesToBytes32(slice(m, 156, 188), hashlock);
        signature = slice(m, 188, 253);
    }

    function decodeMediatedTransfer1(bytes m) returns (uint8 nonce, uint8 expiration,
                                                        address asset, address recipient,
                                                        address target)
    {
        if (m.length != 325) throw;
        nonce = bytesToIntEight(slice(m, 4, 12), nonce);
        expiration = bytesToIntEight(slice(m, 12, 20), expiration);
        uint160 ia;
        asset = bytesToAddress(slice(m, 20, 40), ia);
        uint160 ir;
        recipient = bytesToAddress(slice(m, 40, 60), ir);
        uint160 it;
        target = bytesToAddress(slice(m, 60, 80), it);

    }

    function decodeMediatedTransfer2(bytes m) returns
                                    (address initiator, bytes32 locksroot, bytes32 hashlock,
                                        uint balance, uint amount, uint fee, bytes signature)
    {
        uint160 ii;
        initiator = bytesToAddress(slice(m, 80, 100), ii);
        locksroot = bytesToBytes32(slice(m, 100, 132), locksroot);
        hashlock = bytesToBytes32(slice(m, 132, 164), hashlock);
        balance = bytesToInt(slice(m, 164, 196), balance);
        amount = bytesToInt(slice(m, 196, 228), amount);
        fee = bytesToInt(slice(m, 228, 260), fee);
        signature = slice(m, 260, 325);
    }

    function decodeCancelTransfer1(bytes m) returns (uint8 nonce, uint8 expiration,
                                                address asset, address recipient)
    {
        if (m.length != 253) throw;
        nonce = bytesToIntEight(slice(m, 4, 12), nonce);
        expiration = bytesToIntEight(slice(m, 12, 20), expiration);
        uint160 ia;
        asset = bytesToAddress(slice(m, 20, 40), ia);
        uint160 ir;
        recipient = bytesToAddress(slice(m, 40, 60), ir);
    }

    function decodeCancelTransfer2(bytes m) returns (bytes32 locksroot, uint balance,
                                                        uint amount, bytes32 hashlock, bytes signature)
    {
        locksroot = bytesToBytes32(slice(m, 60, 92), locksroot);
        balance = bytesToInt(slice(m, 92, 124), balance);
        amount = bytesToInt(slice(m, 124, 156), amount);
        hashlock = bytesToBytes32(slice(m, 156, 188), hashlock);
        signature = slice(m, 188, 253);
    }

    /* HELPER FUNCTIONS */

    function bytesToIntEight(bytes b, uint8 i) returns (uint8 res) {
        assembly { i := mload(add(b, 0x8)) }
        res = i;
    }

    // helper function
    function bytesToInt(bytes b, uint i) returns (uint res) {
        assembly { i := mload(add(b, 0x20)) }
        res = i;
    }

    // helper function
    function bytesToAddress(bytes b, uint160 i) returns (address add) {
        assembly { i := mload(add(b, 0x14)) }
        uint160 a = uint160(i);
        add = address(i);
    }

    function bytesToBytes32(bytes b, bytes32 i) returns (bytes32 bts) {
        assembly { i := mload(add(b, 0x20)) }
        bts = i;
    }

    // empty function to handle wrong calls
    function () { throw; }
}

import "Decoder.sol";
contract NettingContract {
    uint lockedTime;
    address assetAddress;
    uint opened;
    uint closed;
    uint settled;
    address closingAddress;

    struct Transfer
    {
        address sender;
        uint nonce;
        address asset;
        uint balance;
        address recipient;
        bytes32 locksroot;
        bytes32 secret;
        uint expiration;
    }
    struct Unlocked
    {
        bytes merkleProof;
        bytes32 hashlock;
        bytes32 secret;
        uint amount;
        uint expiration;
    }
    struct Participant
    {
        address addr;
        uint deposit;
        uint netted;
        uint transferedAmount;
        Transfer lastSentTransfer;
        Unlocked unlocked;
    }
    Participant[2] participants; // We only have two participants at all times

    event ChannelOpened(address assetAdr); // TODO
    event ChannelClosed(); // TODO
    event ChannelSettled(); // TODO
    event ChannelSecretRevealed(); //TODO

    modifier inParticipants {
        if (msg.sender != participants[0].addr &&
            msg.sender != participants[1].addr) throw;
        _
    }

    function NettingContract(address assetAdr, address participant1, address participant2) {
        opened = 0;
        closed = 0;
        settled = 0;
        assetAddress = assetAdr;
        participants[0].addr = participant1;
        participants[1].addr = participant2;
    }

    // Get the index of an address in participants
    function atIndex(address addr) returns (uint index) {
        if (addr == participants[0].addr) return 0;
        else return 1;
    }

    /// @notice deposit(address, uint) to deposit amount to a participant.
    /// @dev Deposit an amount to a participating address.
    /// @param amount (uint) the amount to be deposited to the address
    function deposit(uint amount) inParticipants {
        if (msg.sender.balance < amount) throw; // TODO check asset contract
        participants[atIndex(msg.sender)].deposit += amount;
        if(isOpen() && opened == 0) open();
    }

    /// @notice open() to set the opened to be the current block and triggers
    /// the event ChannelOpened()
    /// @dev Sets the value of `opened` to be the value of the current block.
    /// param none
    /// returns none, but changes the value of `opened` and triggers the event ChannelOpened.
    function open() {
        opened = block.number;

        // trigger event
        ChannelOpened(assetAddress);
    }

    /// @notice partner() to get the partner or other participant of the channel
    /// @dev Get the other participating party of the channel
    /// @return p (address) the partner of the calling party
    function partner(address a) returns (address p) {
        if (a == participants[0].addr) return participants[1].addr;
        else return participants[0].addr;
    }

    /// @notice isOpen() to check if a channel is open
    /// @dev Check if a channel is open and both parties have deposited to the channel
    /// @return open (bool) the status of the channel
    function isOpen() constant returns (bool open) {
        if (closed == 0) throw;
        if (participants[0].deposit > 0 || participants[1].deposit > 0) return true;
        else return false;
    }

    /// @notice close(bytes, bytes) to close a channel between to parties
    /// @dev Close the channel between two parties
    /// @param firstEncoded (bytes) the last sent transfer of the msg.sender
    function close(bytes firstEncoded) inParticipants {
        if (settled > 0) throw; // channel already settled
        if (closed > 0) throw; // channel is closing

        // check if sender of message is a participant
        if (getSender(firstEncoded) != participants[0].addr &&
            getSender(firstEncoded) != participants[1].addr) throw;

        uint partnerId = atIndex(partner(msg.sender));
        uint senderId = atIndex(msg.sender);

        decode(firstEncoded);

        // mark closed
        closed = block.number;
        closingAddress = msg.sender;

        uint amount1 = participants[senderId].transferedAmount;
        uint amount2 = participants[partnerId].transferedAmount;

        uint allowance = participants[senderId].deposit + participants[partnerId].deposit;
        uint difference;
        if(amount1 > amount2) {
            difference = amount1 - amount2;
        } else {
            difference = amount2 - amount1;
        }

        // TODO
        // if (difference > allowance) penalize();

        // trigger event
        //TODO
        ChannelClosed();
    }

    /// @notice close(bytes, bytes) to close a channel between to parties
    /// @dev Close the channel between two parties
    /// @param firstEncoded (bytes) the last sent transfer of the msg.sender
    /// @param secondEncoded (bytes) the last sent transfer of the msg.sender
    function close(bytes firstEncoded, bytes secondEncoded) inParticipants {
        if (settled > 0) throw; // channel already settled
        if (closed > 0) throw; // channel is closing

        // check if the sender of either of the messages is a participant
        if (getSender(firstEncoded) != participants[0].addr &&
            getSender(firstEncoded) != participants[1].addr) throw;
        if (getSender(secondEncoded) != participants[0].addr &&
            getSender(secondEncoded) != participants[1].addr) throw;

        // Don't allow both transfers to be from the same sender
        if (getSender(firstEncoded) == getSender(secondEncoded)) throw;

        uint partnerId = atIndex(partner(msg.sender));
        uint senderId = atIndex(msg.sender);

        decode(firstEncoded);
        decode(secondEncoded);

        // mark closed
        closed = block.number;
        closingAddress = msg.sender;

        uint amount1 = participants[senderId].transferedAmount;
        uint amount2 = participants[partnerId].transferedAmount;

        uint allowance = participants[senderId].deposit + participants[partnerId].deposit;
        uint difference;
        if(amount1 > amount2) {
            difference = amount1 - amount2;
        } else {
            difference = amount2 - amount1;
        }

        // TODO
        // if (difference > allowance) penalize();

        // trigger event
        //TODO
        ChannelClosed();
    }

    /// @notice updateTransfer(bytes) to update last known transfer
    /// @dev Allow the partner to update the last known transfer
    /// @param message (bytes) the encoded transfer message
    function updateTransfer(bytes message) inParticipants {
        if (settled > 0) throw; // channel already settled
        if (closed == 0) throw; // channel is open
        if (msg.sender == closingAddress) throw; // don't allow closer to update
        if (closingAddress == getSender(message)) throw;

        decode(message);

        // TODO check if tampered and penalize
        // TODO check if outdated and penalize

    }

    /// @notice unlock(bytes, bytes, bytes32) to unlock a locked transfer
    /// @dev Unlock a locked transfer
    /// @param lockedEncoded (bytes) the lock
    /// @param merkleProof (bytes) the merkle proof
    /// @param secret (bytes32) the secret
    function unlock(bytes lockedEncoded, bytes merkleProof, bytes32 secret) inParticipants{
        if (settled > 0) throw; // channel already settled
        if (closed == 0) throw; // channel is open

        uint partnerId = atIndex(partner(msg.sender));
        uint senderId = atIndex(msg.sender);

        if (participants[partnerId].lastSentTransfer.nonce == 0) throw;

        bytes32 h = sha3(lockedEncoded);

        for (uint i = 0; i < merkleProof.length; i += 64) {
            bytes32 left;
            left = bytesToBytes32(slice(merkleProof, i, i + 32), left);
            bytes32 right;
            right = bytesToBytes32(slice(merkleProof, i + 32, i + 64), right);
            if (h != left && h != right) throw;
            h = sha3(left, right);
        }

        if (participants[partnerId].lastSentTransfer.locksroot != h) throw;

        // TODO decode lockedEncoded into a Unlocked struct and append

        //participants[partnerId].unlocked.push(lock);
    }
    function bytesToBytes32(bytes b, bytes32 i) returns (bytes32 bts) {
        assembly { i := mload(add(b, 0x20)) }
        bts = i;
    }

    /// @notice settle() to settle the balance between the two parties
    /// @dev Settles the balances of the two parties fo the channel
    /// @return participants (Participant[]) the participants with netted balances
    /*
    function settle() returns (Participant[] participants) {
        if (settled > 0) throw;
        if (closed == 0) throw;
        if (closed + lockedTime > block.number) throw; //if locked time has expired throw

        for (uint i = 0; i < participants.length; i++) {
            uint otherIdx = atIndex(partner(participants[i].addr));
            participants[i].netted = participants[i].deposit;
            if (participants[i].lastSentTransfer != 0) {
                participants[i].netted = participants[i].lastSentTransfer.balance;
            }
            if (participants[otherIdx].lastSentTransfer != 0) {
                participants[i].netted = participants[otherIdx].lastSentTransfer.balance;
            }
        }

        //for (uint j = 0; j < participants.length; j++) {
            //uint otherIdx = atIndex(partner(participants[j].addr));
        //}

        // trigger event
        //ChannelSettled();
    }
    */

    // Get the nonce of the last sent transfer
    function getNonce(bytes message) returns (uint8 non) {
        // Direct Transfer
        if (message[0] == 5) {
            (non, , , , , , ) = Decoder.decodeTransfer(message);
        }
        // Locked Transfer
        if (message[0] == 6) {
            (non, , , ) = Decoder.decodeLockedTransfer1(message);
        }
        // Mediated Transfer
        if (message[0] == 7) {
            (non, , , , ) = Decoder.decodeMediatedTransfer1(message);
        }
        // Cancel Transfer
        if (message[0] == 8) {
            (non, , , ) = Decoder.decodeCancelTransfer1(message);
        }
        else throw;
    }

    // Gets the sender of a last sent transfer
    function getSender(bytes message) returns (address sndr) {
        // Secret
        bytes sig;
        bytes32 h;
        bytes32 sec;
        uint8 non;
        address ass;
        address rec;
        uint bal;
        bytes32 olo;
        uint amo;
        bytes32 has;
        bytes32 loc;
        bytes32 lock;
        uint8 exp;
        address tar;
        address ini;
        uint fee;
        if (message[0] == 4) {
            (sec, sig) = Decoder.decodeSecret(message);
            h = sha3(sec);
            sndr = ecrecovery(h, sig);
        }
        // Direct Transfer
        if (message[0] == 5) {
            (non, ass, rec, bal, olo, , sig) = Decoder.decodeTransfer(message);
            h = sha3(non, ass, bal, rec, olo); //need the optionalLocksroot
            sndr = ecrecovery(h, sig);
        }
        // Locked Transfer
        if (message[0] == 6) {
            (non, exp, ass, rec) = Decoder.decodeLockedTransfer1(message);
            (loc, bal, amo, has, sig) = Decoder.decodeLockedTransfer2(message);
            h = sha3(non, ass, bal, rec, loc, lock); //need the lock
            sndr = ecrecovery(h, sig);
        }
        // Mediated Transfer
        if (message[0] == 7) {
            (non, exp, ass, rec, tar) = Decoder.decodeMediatedTransfer1(message);
            (ini, loc, , , , fee, sig) = Decoder.decodeMediatedTransfer2(message);
            h = sha3(non, ass, bal, rec, loc, lock, tar, ini, fee); //need the lock
            sndr = ecrecovery(h, sig);
        }
        // Cancel Transfer
        if (message[0] == 8) {
            (non, , ass, rec) = Decoder.decodeCancelTransfer1(message);
            (loc, bal, , , sig) = Decoder.decodeCancelTransfer2(message);
            h = sha3(non, ass, bal, rec, loc, lock); //need the lock
            sndr = ecrecovery(h, sig);
        }
        else throw;
    }

    function decode(bytes message) {
        // Secret
        bytes sig;
        bytes32 h;
        bytes32 sec;
        uint8 non;
        address ass;
        address rec;
        uint bal;
        bytes32 olo;
        uint amo;
        bytes32 has;
        bytes32 loc;
        bytes32 lock;
        uint8 exp;
        address tar;
        address ini;
        uint fee;
        bytes32 h;
        uint i;
        if (message[0] == 4) {
            (sec, sig) = Decoder.decodeSecret(message);
            participants[atIndex(msg.sender)].lastSentTransfer.secret = sec;
            h = sha3(sec);
            participants[i].lastSentTransfer.sender = ecrecovery(h, sig);
        }
        // Direct Transfer
        if (message[0] == 5) {
            (non, ass, rec, bal, loc, sec, sig) = Decoder.decodeTransfer(message);
            i = atIndex(msg.sender); // should be sender of message
            participants[i].lastSentTransfer.nonce = non;
            participants[i].lastSentTransfer.asset = ass;
            participants[i].lastSentTransfer.recipient = rec;
            participants[i].lastSentTransfer.balance = bal;
            h = sha3(non, ass, bal, rec, loc);
            participants[i].lastSentTransfer.sender = ecrecovery(h, sig);
        }
        // Locked Transfer
        if (message[0] == 6) {
            (non, exp, ass, rec) = Decoder.decodeLockedTransfer1(message);
            (loc, bal, amo, has, sig) = Decoder.decodeLockedTransfer2(message);
            i = atIndex(msg.sender);
            participants[i].lastSentTransfer.nonce = non;
            lockedTime = exp;
            participants[i].lastSentTransfer.asset = ass;
            participants[i].lastSentTransfer.recipient = rec;
            participants[i].lastSentTransfer.locksroot = loc;
            participants[i].lastSentTransfer.balance = bal;
            /*participants[i].unlocked.amount = amo; // not sure we need this*/
            participants[i].unlocked.hashlock = has;
            h = sha3(non, ass, bal, rec, loc, lock, tar, ini, fee); //need the lock
            participants[i].lastSentTransfer.sender = ecrecovery(h, sig);
        }
        // Mediated Transfer
        if (message[0] == 7) {
            (non, exp, ass, rec, tar) = Decoder.decodeMediatedTransfer1(message);
            (ini, loc, has, bal, amo, fee, sig) = Decoder.decodeMediatedTransfer2(message);
            i = atIndex(msg.sender);
            participants[i].lastSentTransfer.nonce = non;
            lockedTime = exp;
            participants[i].lastSentTransfer.asset = ass;
            participants[i].lastSentTransfer.recipient = rec;
            participants[i].lastSentTransfer.locksroot = loc;
            participants[i].unlocked.hashlock = has;
            participants[i].lastSentTransfer.balance = bal;
            // amount not needed?
            h = sha3(non, ass, bal, rec, loc, lock, tar, ini, fee); //need the lock
            participants[i].lastSentTransfer.sender = ecrecovery(h, sig);
        }
        // Cancel Transfer
        if (message[0] == 8) {
            (non, exp, ass, rec) = Decoder.decodeCancelTransfer1(message);
            (loc, bal, amo, has, sig) = Decoder.decodeCancelTransfer2(message);
            i = atIndex(msg.sender);
            participants[i].lastSentTransfer.nonce = non;
            lockedTime = exp;
            participants[i].lastSentTransfer.asset = ass;
            participants[i].lastSentTransfer.recipient = rec;
            participants[i].lastSentTransfer.locksroot = loc;
            participants[i].lastSentTransfer.balance = bal;
            /*participants[i].unlocked.amount = amo; // not sure we need this*/
            participants[i].unlocked.hashlock = has;
            h = sha3(non, ass, bal, rec, loc, lock); //need the lock
            participants[i].lastSentTransfer.sender = ecrecovery(h, sig);
        }
        else throw;
    }

    // Written by Alex Beregszaszi (@axic), use it under the terms of the MIT license.
    function ecrecovery(bytes32 hash, bytes sig) returns (address) {
        bytes32 r;
        bytes32 s;
        uint8 v;

        // FIXME: Should this throw, or return 0?
        if (sig.length != 65)
          return 0;

        // The signature format is a compact form of:
        //   {bytes32 r}{bytes32 s}{uint8 v}
        // Compact means, uint8 is not padded to 32 bytes.
        assembly {
            r := mload(add(sig, 32))
            s := mload(add(sig, 64))
            // Here we are loading the last 32 bytes, including 31 bytes
            // of 's'. There is no 'mload8' to do this.
            //
            // 'byte' is not working due to the Solidity parser, so lets
            // use the second best option, 'and'
            v := and(mload(add(sig, 65)), 1)
        }

        // old geth sends a `v` value of [0,1], while the new, in line with the YP sends [27,28]
        if (v < 27)
          v += 27;

        return ecrecover(hash, v, r, s);
    }

    function ecverify(bytes32 hash, bytes sig, address signer) returns (bool) {
        return ecrecovery(hash, sig) == signer;
    }

    function slice(bytes a, uint start, uint end) returns (bytes n) {
        if (a.length < end) throw;
        if (start < 0) throw;
        if (start > end) throw;
        n = new bytes(end-start);
        for ( uint i = start; i < end; i ++) { //python style slice
            n[i-start] = a[i];
        }
    }

    // empty function to handle wrong calls
    function () { throw; }
}


Remove readUint96 from bytesutils

Remove readUint96 from bytesutils

pragma solidity >=0.8.4;

library BytesUtils {
    /*
    * @dev Returns the keccak-256 hash of a byte range.
    * @param self The byte string to hash.
    * @param offset The position to start hashing at.
    * @param len The number of bytes to hash.
    * @return The hash of the byte range.
    */
    function keccak(bytes memory self, uint offset, uint len) internal pure returns (bytes32 ret) {
        require(offset + len <= self.length);
        assembly {
            ret := keccak256(add(add(self, 32), offset), len)
        }
    }

    /**
     * @dev Returns the ENS namehash of a DNS-encoded name.
     * @param self The DNS-encoded name to hash.
     * @param offset The offset at which to start hashing.
     * @return The namehash of the name.
     */
    function namehash(bytes memory self, uint offset) internal pure returns(bytes32) {
        (bytes32 labelhash, uint newOffset) = readLabel(self, offset);
        if(labelhash == bytes32(0)) {
            return bytes32(0);
        }
        return keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));
    }

    /**
     * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.
     * @param self The byte string to read a label from.
     * @param idx The index to read a label at.
     * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.
     * @return newIdx The index of the start of the next label.
     */
    function readLabel(bytes memory self, uint256 idx) internal pure returns (bytes32 labelhash, uint newIdx) {
        require(idx < self.length, "readLabel: Index out of bounds");
        uint len = uint(uint8(self[idx]));
        if(len > 0) {
            labelhash = keccak(self, idx + 1, len);
        } else {
            labelhash = bytes32(0);
        }
        newIdx = idx + len + 1;
    }
}

pragma solidity >=0.8.4;

library BytesUtils {
    /*
     * @dev Returns the 96-bit number at the specified index of self.
     * @param self The byte string.
     * @param idx The index into the bytes
     * @return The specified 96 bits of the string, interpreted as an integer.
     */

    function readUint96(bytes memory self, uint256 idx)
        internal
        pure
        returns (uint96 ret)
    {
        require(idx + 12 <= self.length);
        assembly {
            ret := and(
                mload(add(add(self, 12), idx)),
                0xFFFFFFFFFFFFFFFFFFFFFFFF
            )
        }
    }

    /*
    * @dev Returns the keccak-256 hash of a byte range.
    * @param self The byte string to hash.
    * @param offset The position to start hashing at.
    * @param len The number of bytes to hash.
    * @return The hash of the byte range.
    */
    function keccak(bytes memory self, uint offset, uint len) internal pure returns (bytes32 ret) {
        require(offset + len <= self.length);
        assembly {
            ret := keccak256(add(add(self, 32), offset), len)
        }
    }

    /**
     * @dev Returns the ENS namehash of a DNS-encoded name.
     * @param self The DNS-encoded name to hash.
     * @param offset The offset at which to start hashing.
     * @return The namehash of the name.
     */
    function namehash(bytes memory self, uint offset) internal pure returns(bytes32) {
        (bytes32 labelhash, uint newOffset) = readLabel(self, offset);
        if(labelhash == bytes32(0)) {
            return bytes32(0);
        }
        return keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));
    }

    /**
     * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.
     * @param self The byte string to read a label from.
     * @param idx The index to read a label at.
     * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.
     * @return newIdx The index of the start of the next label.
     */
    function readLabel(bytes memory self, uint256 idx) internal pure returns (bytes32 labelhash, uint newIdx) {
        require(idx < self.length, "readLabel: Index out of bounds");
        uint len = uint(uint8(self[idx]));
        if(len > 0) {
            labelhash = keccak(self, idx + 1, len);
        } else {
            labelhash = bytes32(0);
        }
        newIdx = idx + len + 1;
    }
}


contracts: Add rough draft for KetherNFT contract

//SPDX-License-Identifier: MIT
pragma solidity ^0.7;

// FIXME: Use 4.x pre-release which slims down the 721 implementation
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

import "KetherHomepage.sol";

contract KetherNFT is ERC721 {
  /// instance is the KetherHomepage contract that this wrapper interfaces with.
  KetherHomepage public instance;

  address public constant metadataSigner = 0x0; // TODO: ...

  // TODO: Do we want to emit events?

  constructor(address _ketherContract) ERC721("Thousand Ether Homepage Ad", "1KAD") {
    instance = KetherHomepage(_ketherContract);
  }

  function wrap(uint _idx) external {
    // FIXME: Should this be _safeMint? It's more gas but guarantees receiver supports ERC721
    _mint(msg.sender, _idx);

    // Transfer contract ownership to this contract as a delegate.
    // -> KetherHomepage(_ketherContract).setAdOwner(_idx, newOwner);
    (bool success, bytes memory returnData) = address(instance).delegatecall(
      bytes4(keccak256("setAdOwner(uint, address)")), _idx, address(this));
    require(success);
  }

  function unwrap(uint _idx, address _newOwner) external {
    require(ownerOf(_idx) == msg.sender);

    // TODO: Test that if this fails, the rest of the call fails
    instance.setAdOwner(_idx, _newOwner);

    _burn(_idx);
  }

  // TODO: Should we have a setTokenURI function so owners can change the rendering of their token?

  function tokenURI(uint256 _tokenId) external pure view override(ERC721) returns (string memory) {
    // FIXME: Replace with IPFS URI? Perhaps set on wrap?
    return "ipfs://1000ether.com/ad/" + _tokenID; // FIXME: Need to convert the uint256 to string, maybe Strings.uint2str?
  }

  /// publish is a delegated proxy for KetherHomapage's publish function.
  ///
  /// Publish allows for setting the link, image, and NSFW status for the ad
  /// unit that is identified by the idx which was returned during the buy step.
  /// The link and image must be full web3-recognizeable URLs, such as:
  ///  - bzz://a5c10851ef054c268a2438f10a21f6efe3dc3dcdcc2ea0e6a1a7a38bf8c91e23
  ///  - bzz://mydomain.eth/ad.png
  ///  - https://cdn.mydomain.com/ad.png
  ///  - https://ipfs.io/ipfs/Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu
  ///  - ipfs://Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu
  /// Images should be valid PNG.
  /// Content-addressable storage links like IPFS are encouraged.
  function publish(uint _idx, string _link, string _image, string _title, bool _NSFW) external {
    // FIXME: Should this be ownerOf? Letting approved accounts publish would allow lending.
    require(getApproved(_idx) == msg.sender);

    instance.publish(_idx, _link, _image, _title, _NSFW);
  }

}

error: pathspec 'contracts/KetherNFT.sol' did not match any file(s) known to git


changed decimal to be uint8 so that it matches the ERC20 specification.

pragma solidity ^0.4.11;

import "../token/StandardToken.sol";

/**
 * @title SimpleToken
 * @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
 * Note they can later distribute these tokens as they wish using `transfer` and other
 * `StandardToken` functions.
 */
contract SimpleToken is StandardToken {

  string public constant name = "SimpleToken";
  string public constant symbol = "SIM";
  uint8 public constant decimals = 18;

  uint256 public constant INITIAL_SUPPLY = 10000;

  /**
   * @dev Contructor that gives msg.sender all of existing tokens.
   */
  function SimpleToken() {
    totalSupply = INITIAL_SUPPLY;
    balances[msg.sender] = INITIAL_SUPPLY;
  }

}

pragma solidity ^0.4.11;

import "../token/StandardToken.sol";

/**
 * @title SimpleToken
 * @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
 * Note they can later distribute these tokens as they wish using `transfer` and other
 * `StandardToken` functions.
 */
contract SimpleToken is StandardToken {

  string public constant name = "SimpleToken";
  string public constant symbol = "SIM";
  uint256 public constant decimals = 18;

  uint256 public constant INITIAL_SUPPLY = 10000;

  /**
   * @dev Contructor that gives msg.sender all of existing tokens.
   */
  function SimpleToken() {
    totalSupply = INITIAL_SUPPLY;
    balances[msg.sender] = INITIAL_SUPPLY;
  }

}


Fix `operatorBurn` description typo. (#2091)

pragma solidity ^0.6.0;

/**
 * @dev Interface of the ERC777Token standard as defined in the EIP.
 *
 * This contract uses the
 * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let
 * token holders and recipients react to token movements by using setting implementers
 * for the associated interfaces in said registry. See {IERC1820Registry} and
 * {ERC1820Implementer}.
 */
interface IERC777 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the smallest part of the token that is not divisible. This
     * means all token operations (creation, movement and destruction) must have
     * amounts that are a multiple of this number.
     *
     * For most token contracts, this value will equal 1.
     */
    function granularity() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by an account (`owner`).
     */
    function balanceOf(address owner) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * If send or receive hooks are registered for the caller and `recipient`,
     * the corresponding functions will be called with `data` and empty
     * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits a {Sent} event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function send(address recipient, uint256 amount, bytes calldata data) external;

    /**
     * @dev Destroys `amount` tokens from the caller's account, reducing the
     * total supply.
     *
     * If a send hook is registered for the caller, the corresponding function
     * will be called with `data` and empty `operatorData`. See {IERC777Sender}.
     *
     * Emits a {Burned} event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     */
    function burn(uint256 amount, bytes calldata data) external;

    /**
     * @dev Returns true if an account is an operator of `tokenHolder`.
     * Operators can send and burn tokens on behalf of their owners. All
     * accounts are their own operator.
     *
     * See {operatorSend} and {operatorBurn}.
     */
    function isOperatorFor(address operator, address tokenHolder) external view returns (bool);

    /**
     * @dev Make an account an operator of the caller.
     *
     * See {isOperatorFor}.
     *
     * Emits an {AuthorizedOperator} event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function authorizeOperator(address operator) external;

    /**
     * @dev Make an account an operator of the caller.
     *
     * See {isOperatorFor} and {defaultOperators}.
     *
     * Emits a {RevokedOperator} event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function revokeOperator(address operator) external;

    /**
     * @dev Returns the list of default operators. These accounts are operators
     * for all token holders, even if {authorizeOperator} was never called on
     * them.
     *
     * This list is immutable, but individual holders may revoke these via
     * {revokeOperator}, in which case {isOperatorFor} will return false.
     */
    function defaultOperators() external view returns (address[] memory);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
     * be an operator of `sender`.
     *
     * If send or receive hooks are registered for `sender` and `recipient`,
     * the corresponding functions will be called with `data` and
     * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits a {Sent} event.
     *
     * Requirements
     *
     * - `sender` cannot be the zero address.
     * - `sender` must have at least `amount` tokens.
     * - the caller must be an operator for `sender`.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function operatorSend(
        address sender,
        address recipient,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the total supply.
     * The caller must be an operator of `account`.
     *
     * If a send hook is registered for `account`, the corresponding function
     * will be called with `data` and `operatorData`. See {IERC777Sender}.
     *
     * Emits a {Burned} event.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     * - the caller must be an operator for `account`.
     */
    function operatorBurn(
        address account,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;

    event Sent(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 amount,
        bytes data,
        bytes operatorData
    );

    event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);

    event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);

    event AuthorizedOperator(address indexed operator, address indexed tokenHolder);

    event RevokedOperator(address indexed operator, address indexed tokenHolder);
}

pragma solidity ^0.6.0;

/**
 * @dev Interface of the ERC777Token standard as defined in the EIP.
 *
 * This contract uses the
 * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let
 * token holders and recipients react to token movements by using setting implementers
 * for the associated interfaces in said registry. See {IERC1820Registry} and
 * {ERC1820Implementer}.
 */
interface IERC777 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the smallest part of the token that is not divisible. This
     * means all token operations (creation, movement and destruction) must have
     * amounts that are a multiple of this number.
     *
     * For most token contracts, this value will equal 1.
     */
    function granularity() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by an account (`owner`).
     */
    function balanceOf(address owner) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * If send or receive hooks are registered for the caller and `recipient`,
     * the corresponding functions will be called with `data` and empty
     * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits a {Sent} event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function send(address recipient, uint256 amount, bytes calldata data) external;

    /**
     * @dev Destroys `amount` tokens from the caller's account, reducing the
     * total supply.
     *
     * If a send hook is registered for the caller, the corresponding function
     * will be called with `data` and empty `operatorData`. See {IERC777Sender}.
     *
     * Emits a {Burned} event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     */
    function burn(uint256 amount, bytes calldata data) external;

    /**
     * @dev Returns true if an account is an operator of `tokenHolder`.
     * Operators can send and burn tokens on behalf of their owners. All
     * accounts are their own operator.
     *
     * See {operatorSend} and {operatorBurn}.
     */
    function isOperatorFor(address operator, address tokenHolder) external view returns (bool);

    /**
     * @dev Make an account an operator of the caller.
     *
     * See {isOperatorFor}.
     *
     * Emits an {AuthorizedOperator} event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function authorizeOperator(address operator) external;

    /**
     * @dev Make an account an operator of the caller.
     *
     * See {isOperatorFor} and {defaultOperators}.
     *
     * Emits a {RevokedOperator} event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function revokeOperator(address operator) external;

    /**
     * @dev Returns the list of default operators. These accounts are operators
     * for all token holders, even if {authorizeOperator} was never called on
     * them.
     *
     * This list is immutable, but individual holders may revoke these via
     * {revokeOperator}, in which case {isOperatorFor} will return false.
     */
    function defaultOperators() external view returns (address[] memory);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
     * be an operator of `sender`.
     *
     * If send or receive hooks are registered for `sender` and `recipient`,
     * the corresponding functions will be called with `data` and
     * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits a {Sent} event.
     *
     * Requirements
     *
     * - `sender` cannot be the zero address.
     * - `sender` must have at least `amount` tokens.
     * - the caller must be an operator for `sender`.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function operatorSend(
        address sender,
        address recipient,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;

    /**
     * @dev Destoys `amount` tokens from `account`, reducing the total supply.
     * The caller must be an operator of `account`.
     *
     * If a send hook is registered for `account`, the corresponding function
     * will be called with `data` and `operatorData`. See {IERC777Sender}.
     *
     * Emits a {Burned} event.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     * - the caller must be an operator for `account`.
     */
    function operatorBurn(
        address account,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;

    event Sent(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 amount,
        bytes data,
        bytes operatorData
    );

    event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);

    event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);

    event AuthorizedOperator(address indexed operator, address indexed tokenHolder);

    event RevokedOperator(address indexed operator, address indexed tokenHolder);
}


Make old revisions accessible.

Make old revisions accessible.

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

    struct BlobInfo {
        uint96 blockNumber;
        address owner;
    }

    mapping (bytes32 => BlobInfo) blobInfo;
    mapping (bytes32 => uint256[]) revisionBlockNumbers;

    event logBlob(bytes32 indexed hash, uint256 indexed revisionId, bytes blob) anonymous;
    event logRetraction(bytes32 indexed hash) anonymous;

    modifier isOwner(bytes32 hash) {
        if (blobInfo[hash].owner == msg.sender) {
            throw;
        }
        _
    }

    /**
     * @dev Stores a blob in the transaction log. It is guaranteed that each user will get a different hash when storing the same blob.
     * @param blob Blob that should be stored.
     * @return hash Hash of sender and blob.
     */
    function storeBlob(bytes blob) external returns (bytes32 hash) {
        // Calculate the hash.
        hash = sha3(msg.sender, blob);
        // Store block number and owner in state.
        blobInfo[hash] = BlobInfo({
            blockNumber: uint96(block.number),
            owner: msg.sender,
        });
        // Store the blob in a log in the current block.
        logBlob(hash, 0, blob);
    }

    function updateBlob(bytes32 hash, bytes blob) isOwner(hash) external {
        revisionBlockNumbers[hash].push(block.number);
        // Store the new blob in a log in the current block.
        logBlob(hash, revisionBlockNumbers[hash].length, blob);
    }

    function retractBlob(bytes32 hash) isOwner(hash) external {
        // Get a refund for the storage slots.
        delete blobInfo[hash];
        delete revisionBlockNumbers[hash];
        // Log the retraction.
        logRetraction(hash);
    }

    function getBlobInfo(bytes32 hash) constant external returns (address owner, uint256 blockNumber) {
        owner = blobInfo[hash].owner;
        blockNumber = blobInfo[hash].blockNumber;
    }

    function() {
        throw;      // Do not maintain an ether balance.
    }

}

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

    mapping (bytes32 => bytes32) blobInfo;      // Block number and user.

    event logBlob(bytes32 indexed hash, bytes blob) anonymous;
    event logRetraction(bytes32 indexed hash) anonymous;

    modifier isOwner(bytes32 hash) {
        if (address(blobInfo[hash] & (2**160)) == msg.sender) {
            throw;
        }
        _
    }

    /**
     * @dev Stores a blob in the transaction log. It is guaranteed that each user will get a different hash when storing the same blob.
     * @param blob Blob that should be stored.
     * @return hash Hash of sender and blob.
     */
    function storeBlob(bytes blob) external returns (bytes32 hash) {
        // Calculate the hash.
        hash = sha3(msg.sender, blob);
        // Store the blob owner and block number in state.
        blobInfo[hash] = bytes32(block.number * (2**208)) | bytes32(msg.sender);
        // Store the blob in a log in the current block.
        logBlob(hash, blob);
    }

    function updateBlob(bytes32 hash, bytes blob) isOwner(hash) external {
        // Update block number in state.
        blobInfo[hash] = bytes32(block.number * (2**208)) | bytes32(msg.sender);
        // Store the new blob in a log in the current block.
        logBlob(hash, blob);
    }

    function retractBlob(bytes32 hash) isOwner(hash) external {
        // Get a refund for the storage slot.
        delete blobInfo[hash];
        // Log the retraction.
        logRetraction(hash);
    }

    function getBlobInfo(bytes32 hash) constant external returns (address owner, uint256 blockNumber) {
        owner = address(blobInfo[hash] & ((2**208) - 1));
        blockNumber = uint256(blobInfo[hash]) / (2**208);
    }

    function() {
        throw;      // Do not maintain an ether balance.
    }

}


Fix mapping of oracle id to iudex id

Fix mapping of oracle id to iudex id

// Example:
// html(https://twitter.com/oraclizeit/status/671316655893561344).xpath(//*[contains(@class, 'tweet-text')]/text())

import "accountProvider.sol";

contract Twitter is accountProvider {
  // map the expected identifier to an oraclize identifier
  mapping (bytes32 => bytes32) expectedId;

  function __callback(bytes32 myid, string result) {
    if (msg.sender != oraclize_cbAddress()) throw;

    // this is basically a bytes32 to hexstring piece
    string memory expected = string(addressToBytes(address(expectedId[myid])));
    if (strCompare(expected, result) == 0) {
      // matches, call back storage and let it know that expectedId has verified twitter
    }
  }

  function verify(bytes32 id, string tweetUrl) {
  //    bytes32 oraclizeId = oraclize_query("html(https://twitter.com/oraclizeit/status/671316655893561344).xpath(//*[contains(@class, 'tweet-text')]/text())");

    // build up the request string
    string memory head = "html(";
    bytes memory _head = bytes(head);
    string memory tail = ").xpath(//*[contains(@class, 'tweet-text')]/text())";
    bytes memory _tail = bytes(tail);

    bytes memory _tweetUrl = bytes(tweetUrl);

    string memory query = new string(_head.length + _tail.length + _tweetUrl.length + 2);
    bytes memory _query = bytes(query);
    uint i = 0;
    for (uint j = 0; j < _head.length; j++)
      _query[i++] = _head[j];
    for (j = 0; j < _tweetUrl.length; j++)
      _query[i++] = _tweetUrl[j];
    for (j = 0; j < _tail.length; j++)
      _query[i++] = _tail[j];
    _query[i++] = 0;

    //expectedId[oraclize_query("URL", query)] = id;
    bytes32 oraclizeId = oraclize_query("URL", query);
    expectedId[oraclizeId] = id;
  }
}

// Example:
// html(https://twitter.com/oraclizeit/status/671316655893561344).xpath(//*[contains(@class, 'tweet-text')]/text())

import "accountProvider.sol";

contract Twitter is accountProvider {
  // map the expected identifier to an oraclize identifier
  mapping (bytes32 => bytes32) expectedId;

  function __callback(bytes32 myid, string result) {
    if (msg.sender != oraclize_cbAddress()) throw;

    // this is basically a bytes32 to hexstring piece
    string memory expected = string(addressToBytes(address(expectedId[myid])));
    if (strCompare(expected, result) == 0) {
      // matches, call back storage and let it know that expectedId has verified twitter
    }
  }

  function verify(bytes32 id, string tweetUrl) {
  //    bytes32 oraclizeId = oraclize_query("html(https://twitter.com/oraclizeit/status/671316655893561344).xpath(//*[contains(@class, 'tweet-text')]/text())");

    // build up the request string
    string memory head = "html(";
    bytes memory _head = bytes(head);
    string memory tail = ").xpath(//*[contains(@class, 'tweet-text')]/text())";
    bytes memory _tail = bytes(tail);

    bytes memory _tweetUrl = bytes(tweetUrl);

    string memory query = new string(_head.length + _tail.length + _tweetUrl.length + 2);
    bytes memory _query = bytes(query);
    uint i = 0;
    for (uint j = 0; j < _head.length; j++)
      _query[i++] = _head[j];
    for (j = 0; j < _tweetUrl.length; j++)
      _query[i++] = _tweetUrl[j];
    for (j = 0; j < _tail.length; j++)
      _query[i++] = _tail[j];
    _query[i++] = 0;

    expectedId[id] = oraclize_query("URL", query);
  }
}


Changed data type to reflect that it is the hash

pragma solidity ^0.4.18;

contract DQuestions {
    string[] questions;
    bytes32[] answers;

    function numberOfQuestions() public view returns (uint) {
        return questions.length;
    }

    function add(string question, bytes32 answer) public {
        questions.push(question);
        answers.push(answer);
    }

    function getQuestion(uint index) public view returns (string) {
        return questions[index];
    }

    function getAnswer(uint index) public view returns (bytes32) {
        return answers[index];
    }
}

pragma solidity ^0.4.18;

contract DQuestions {
    string[] questions;
    string[] answers;

    function numberOfQuestions() public view returns (uint) {
        return questions.length;
    }

    function add(string question, string answer) public {
        questions.push(question);
        answers.push(answer);
    }

    function getQuestion(uint index) public view returns (string) {
        return questions[index];
    }

    function getAnswer(uint index) public view returns (string) {
        return answers[index];
    }
}


Create contractNew.sol

Create contractNew.sol

pragma solidity ^0.4.11;

contract communityCurrency {

	// @title Community Currency
	// @author Rogelio SEGOVIA
	// @notice register
	// @param currencyName the name of the currency
	// @param symbol the symbol of the currency
	// @param baseUnits is the number of units before the comma
    uint baseUnits;
    string currencyName;
    string symbol;
	string communityName;

	// @notice communityCurrency general variables
    // @param _treasury the address of the treasury of the DAO. The creator and minter of the currency
    // @param _commune the address of the Community account. Where donations and taxes are paid. Account used to pay community works
    // @param _demurrage the depreciation at each transaction. The demurrage to be paid to the DAO at the community account. % x 100
    // @param _rewardRate reward Rate to the moneyLender of a successful credit, as a multiplier of the Reputation Cost of the credit. % x 100
    // @param _iniMemberCCUs initial Community Currency Units given to any new member. The monetary mass is automatically increased with any new member
    // @param _iniMemberReputation initial Reputation given to any new member
	// @param _exchange is the exchange rate in EUROS per Community Currency units
    address _treasury;
	address _commune;
	int _demurrage;
	uint _rewardRate;
	int _iniMemberCCUs;
	uint _iniMemberReputation;
	uint _exchange;

	// @notice Budget parameters
	uint _goalDemurrage;
	uint _goalCrowdFunding;
	uint _goalCommunityHours;
	uint _goalExpenses;
	int _realDemurrage;
	uint _realCrowdFunding;
	int _realCommunityHours;
	uint _realExpenses;

	//@notice monetary Totals
	int _totalMinted;
	uint _totalCredit;
	uint _totalTrustCost;
	uint _totalTrustAvailable;

	// @notice communityCurrency parameters and key addresses for a given Community
	function communityCurrency () public {
		_treasury = msg.sender;
		_commune = msg.sender;
		baseUnits = 100;
    	currencyName = "HOURS";
    	symbol = "HR";
		communityName = "DESPERADO";
	}

	// @notice structure the members wallet
	// @param _CCUs is the actual balance of the currency CCs in the Wallet of the account. It can be negative!!!
	// @param _credit is the limit of _CCUs the account is authorized to become negative
	// @param _deadline is the time limit on which the credit should be already cancelled and becomes zero again
	// @param _moneyLender is the address of the money lender. The credit line authorizer
	// @param _unitsOfTrust is the cost in reputation (Units of Trust) of credit line the account has been authorized. The Trust endorsed to this account by the money lender. It is calculated in terms of credit volume = time x amountCCs
	// @param _isMember boolean if it is an accepted member
	// @param _alias is a string with the alias or ID of the member
	// @param _reputation is the volume of the credit in terms of balance of Units of Trust the money lender can authorize; that is, his available balance in Units of Trust he may endorse to others
	// @param _last time stamp of the last transaction
	// @param _gdpActivity measures the average economic activity of the account in a time period. It measures the monetary mass moved by an account as m x v
	struct Wallet {
		int _CCUs;
		uint _credit;
		uint _deadline;
		address _moneyLender;
		uint _unitsOfTrust;
		bool _isMember;
		uint _reputation;
		string _alias;
	}

	mapping (address => Wallet) balancesOf;

	event Transfer(uint _amount, address indexed _from, address indexed _to, uint _timeStampT);
	event NewMember(address indexed _member, string _alias);
	event OldMember(address indexed _exMember, string _exAlias);
	event Credit(address indexed _MoneyLender, address indexed _borrowerAddress, uint _cDealine, uint _endorsedUoT);
    event CreditExp(address indexed _MoneyLender, address indexed _exBorrowerAddress, uint _oldUoT , bool _success, uint _timeStampCX);
	event ClaimH(address indexed _hFrom, string _servantC, int _claimedH, uint _timeStampCH);
	event PaidH(address indexed _hTo, string _servantP, uint _paidH, uint _timeStampPH);

	// @notice the community account can accept accounts as members. The Community should ensure the unique correspondence to a real person
	// @notice a community can opt to name itself member or not and therefore give credits or not
	// @param _newMember is the address of the new member
	// @param _newAlias is the alias or human readable ID of the new member
	// @return changed alias, initial balance in CCUs, initial reputation in UoT
	function acceptMember (address _newMember, string _newAlias) public {
        if (msg.sender != _commune) return;
        balancesOf[_newMember]._isMember = true;
		balancesOf[_newMember]._CCUs = _iniMemberCCUs;
        balancesOf[_newMember]._reputation = _iniMemberReputation;
 		balancesOf[_newMember]._alias = _newAlias;
		_totalMinted += _iniMemberCCUs;
		_totalTrustAvailable += _iniMemberReputation;
		NewMember(_newMember, _newAlias);
    }

	// @notice the community account can kick out members. The action deletes all balances
	// @param _oldMember is the address of the member to be kicked out
	// @return isMember turned to false, all other account balances to zero, except _CCUs
	function kickOutMember (address _oldMember) public {
        if (msg.sender != _commune) return;
        balancesOf[_oldMember]._isMember = false;
        string storage _oldAlias = balancesOf[_oldMember]._alias;
		_totalCredit -= balancesOf[_oldMember]._credit;
		_totalTrustAvailable -= balancesOf[_oldMember]._reputation;
		_totalTrustCost += balancesOf[_oldMember]._unitsOfTrust;
        balancesOf[_oldMember]._credit = 0;
        OldMember(_oldMember, _oldAlias);
    }

	// @notice get the currency parameters
	function getParameters() public constant returns (address _getTreasury, address _getCommunity, int _getDemurrage, uint _getRewardRate, int _getIniMemberCCUs, uint _getIniMemberReputation, uint _getExchange, string getName, string getSymbol, string getCommunityName, uint getBaseUnits) {
		_getTreasury = _treasury;
		_getCommunity = _commune;
		_getDemurrage = _demurrage;
		_getRewardRate = _rewardRate;
		_getIniMemberCCUs = _iniMemberCCUs;
		_getIniMemberReputation = _iniMemberReputation;
		_getExchange = _exchange;
		getName = currencyName;
		getSymbol = symbol;
		getCommunityName = communityName;
		getBaseUnits = baseUnits;
	}

	// @ notice get the monetary Totals
	function getMoneyTotals() public constant returns (int _getTotalMinted, uint _getTotalCredit, uint _getTotalTrustCost, uint _getTotalTrustAvailable) {
		_getTotalMinted = _totalMinted;
		_getTotalCredit = _totalCredit;
		_getTotalTrustCost = _totalTrustCost;
		_getTotalTrustAvailable = _totalTrustAvailable;
	}

	// @notice the treasury account can change the currency parameters
	// @param _newDemurrage is the new demurrage rate. % x 100
	// @param _newrewardRate is the new reward rate for successful credits. % x 100
	// @param _newIniCCUs is the new initial Community Currency Units given to any new member
	// @param _newIniR is the new initial Reputation given to any new member
	// @return new demurrage, reward rate, initial CCUs and initial reputation for new members
	function newParameters (int _newDemurrage, uint _newRewardRate, int _newIniCCUs, uint _newIniR) public {
		if (msg.sender != _treasury) return;
		_demurrage = _newDemurrage;
		_rewardRate = _newRewardRate;
		_iniMemberCCUs = _newIniCCUs;
		_iniMemberReputation = _newIniR;
	}

	// @notice the treasury account can change to a new community address
	// @param _newCommunity is the new address holding the Community permissions
	// @return new community address
	function newCommune (address _newCommune) public {
		if (msg.sender != _treasury) return;
		_commune = _newCommune;
	}

	// @notice the community account can change to a new treasury address
	// @param _newTreasury is the new address holding the Community permissions
	// @return new treasury address
	function newTreasury (address _newTreasury) public {
		if (msg.sender != _commune) return;
		_treasury = _newTreasury;
	}

	// @notice get Commune budget state
	function getBudget() public constant returns (uint _getGoalDemurrage, uint _getGoalCrowdFunding, uint _getGoalCommunityHours, uint _getGoalExpenses, int _getRealDemurrage, uint _getRealCrowdFunding, int _getRealCommunityHours, uint _getRealExpenses, int _getCommuneBalance, int _getTreasuryBalance) {
			_getGoalDemurrage = _goalDemurrage;
			_getGoalCrowdFunding = _goalCrowdFunding;
			_getGoalCommunityHours = _goalCommunityHours;
			_getGoalExpenses = _goalExpenses;
			_getRealDemurrage = _realDemurrage;
			_getRealCrowdFunding = _realCrowdFunding;
			_getRealCommunityHours = _realCommunityHours;
			_getRealExpenses = _realExpenses;
			_getCommuneBalance = balancesOf[_commune]._CCUs;
			_getTreasuryBalance = balancesOf[_treasury]._CCUs;
		}

	// @notice set new rolling Commune budget
	function setNewBudget (uint _newGoalDemurrage, uint _newGoalCrowdFunding, uint _newGoalCommunityHours, uint _newGoalExpenses) public {
			_goalDemurrage = _newGoalDemurrage;
			_goalCrowdFunding = _newGoalCrowdFunding;
			_goalCommunityHours = _newGoalCommunityHours;
			_goalExpenses = _newGoalExpenses;
			_realDemurrage = 0;
			_realCrowdFunding = 0;
			_realCommunityHours = 0;
			_realExpenses = 0;
		}

	function setExchange (uint _newExchange) public {
		if (msg.sender != _treasury) return;
		_exchange = _newExchange;
	}

	function creditUpdate () public {
		// @notice update the credit status
		if (balancesOf[msg.sender]._credit > 0) {
		// @notice check if deadline is over
			if (now >= balancesOf[msg.sender]._deadline) {
				bool _success = false;
				uint _oldUoT = balancesOf[msg.sender]._unitsOfTrust;
				address _oldMoneyLenderAddress = balancesOf[msg.sender]._moneyLender;
			// @notice if time is over reset credit to zero, deadline to zero
				balancesOf[msg.sender]._deadline = 0;
				_totalCredit -= balancesOf[msg.sender]._credit;
				balancesOf[msg.sender]._credit = 0;
				// @notice if balance is negative the credit was not returned, the money lender balanceReputation is not restored and is penalized with a 20%
				// @notice as regards the borrower will not be able to make any new transfer until future incomes cover the debts
				// @return money lender reputation penalized
				if (balancesOf[msg.sender]._CCUs < 0) {
					_totalTrustCost -= balancesOf[msg.sender]._unitsOfTrust;
					_totalTrustAvailable -= balancesOf[msg.sender]._unitsOfTrust * _rewardRate/100;
					balancesOf[balancesOf[msg.sender]._moneyLender]._reputation -= balancesOf[msg.sender]._unitsOfTrust * _rewardRate/100;
				}
				// @notice if balance is not negative the credit was returned, the money lender balanceReputation is restored and is rewardRateed with a 20%
				// @return money lender reputation rewarded
				else {
					_success = true;
					_totalTrustCost -= balancesOf[msg.sender]._unitsOfTrust;
					_totalTrustAvailable += balancesOf[msg.sender]._unitsOfTrust * _rewardRate/100;
					balancesOf[balancesOf[msg.sender]._moneyLender]._reputation += balancesOf[msg.sender]._unitsOfTrust * (100 + _rewardRate)/100;
				}
				// @notice reset money lender information
				// @return money lender information deleted
				// @notice close access to monitor the account to money lender
				balancesOf[msg.sender]._moneyLender = msg.sender;
				balancesOf[msg.sender]._unitsOfTrust = 0;
				CreditExp(_oldMoneyLenderAddress, msg.sender, _oldUoT , _success, now);
				}
			}

	}

	// @notice function make a payment
	// @notice anybody with an ethereum account can make a payment if he has sufficient CCUs in the balance
	// @notice any member can add to the amount available at the balance, what remains unused in the credit line
	// @param _payee is the account to be credited
	// @param _payment is the amount in CCUs to be send
	// @return balance of payee increased
	// @return balance of sender decreased
	// @return in case of need, available credit decreased
	function transfer (address _payee, uint _payment) public {
	// @return credit information updated
		creditUpdate ();
	// @notice pay with the CCUs available at the balance and the credit
		int _creditLine = int(balancesOf[msg.sender]._credit);
		// @param _available is the spending limit of an account, given the account balance in _CCUs and the _credit
		int _available = balancesOf[msg.sender]._CCUs + _creditLine;
		int _amountCCUs = int(_payment);
		if (_available > _amountCCUs) {
			balancesOf[msg.sender]._CCUs -= _amountCCUs;
			balancesOf[_payee]._CCUs += _amountCCUs;
			// @notice apply demurrage and send it to the Community account
			balancesOf[_payee]._CCUs -= _amountCCUs * _demurrage/100;
			balancesOf[_commune]._CCUs += _amountCCUs * _demurrage/100;
			_realDemurrage += _amountCCUs * _demurrage/100;
			Transfer(_payment, msg.sender, _payee, now);
		}
	}

	// @notice function authorize a credit
	// @notice only members can authorize or get a credit
	// @param _borrower is the address of the credit borrower
	// @param _credit is the amount of the credit line in CCUs
	// @param _daysAfter is the deadline of the credit line in number of days from today
	function credit(address _borrower, uint _credit, uint _daysAfter) public {
		if (balancesOf[msg.sender]._isMember == true) {
		if (balancesOf[_borrower]._isMember == true) {
		if (balancesOf[_borrower]._credit > 0) return;
			uint _unitsOfTrust = _credit * _daysAfter;
			if (balancesOf[msg.sender]._reputation > _unitsOfTrust) {
				balancesOf[msg.sender]._reputation -= _unitsOfTrust;
				balancesOf[_borrower]._credit += _credit;
				balancesOf[_borrower]._moneyLender = msg.sender;
				// @notice the _deadline is established as a number of days ahead
				uint _creditDeadline = now + _daysAfter * 1 days;
				balancesOf[_borrower]._deadline = _creditDeadline;
				balancesOf[_borrower]._unitsOfTrust = _unitsOfTrust;
				_totalCredit += _credit;
				_totalTrustCost += _unitsOfTrust;
				_totalTrustAvailable -= _unitsOfTrust;
				Credit(msg.sender, _borrower, _creditDeadline, _unitsOfTrust);
			}
		}}
	}

  	// @notice monitor Wallet
  	// @notice the borrower candidate has given access to monitor all relevant parameters of his account to the money lender
	// @notice the community can also monitor all accounts
	// @dev if you want to disallow the community to monitor all accounts delete the OR | (msg.sender == _commune) |
	// @param _monitored is the address to be monitored
	// @return _getCCUs is the balance in CCUs
	// @return _getCredit is the remaining credit
	// @return _getDeadline is the credit deadline
	// @return _getMoneyLender is the address of the current money lender or the candidate money lender
	// @return _getUnitsOfTrust is the cost in reputation of the credit
	// @return _getIsMember is boolean if the account is a member
	// @return _getAlias is the alias
	// @return _getReputation is the reputation in UoTs
	// @return _getLast is the date of the last transaction
	// @return _getGdpActivity is the average activity
	function monitorWallet(address _monitored) public constant returns (int _getCCUs, uint _getCredit, uint _getDeadline, address _getMoneyLender, uint _getUnitsOfTrust, bool _getIsMember, uint _getReputation, string _getAlias) {
		if ((_monitored == msg.sender) || (msg.sender == _commune) || (msg.sender == balancesOf[_monitored]._moneyLender)) {
    	_getCCUs = balancesOf[_monitored]._CCUs;
		_getCredit = balancesOf[_monitored]._credit;
		_getDeadline = balancesOf[_monitored]._deadline;
		_getMoneyLender = balancesOf[_monitored]._moneyLender;
		_getUnitsOfTrust = balancesOf[_monitored]._unitsOfTrust;
		_getIsMember = balancesOf[_monitored]._isMember;
		_getReputation = balancesOf[_monitored]._reputation;
		_getAlias = balancesOf[_monitored]._alias;
		}
    	}

   // @notice authorize monitoring
   function accessMyWallet (address _authorized) public {
	   // @notice during a credit, only the money lender and the community have access
	   // @notice normally, the authorization to monitor own accounts is given to a candidate money lender
	   if (balancesOf[msg.sender]._credit != 0) return;
	   balancesOf[msg.sender]._moneyLender = _authorized;
   }

	// @notice claim Hours to paid from Community
	function claimHours (int _claimH) public {
		string storage myAlias = balancesOf[msg.sender]._alias;
		ClaimH(msg.sender, myAlias, _claimH, now);
		}

	// @notice pay Hours
	function payHours (address _servant, uint _payH) public {
	if (msg.sender != _commune) return;
	if (balancesOf[_servant]._isMember != true) return;
    	transfer (_servant, _payH);
		_realCommunityHours += int(_payH);
		string storage _servantAlias = balancesOf[_servant]._alias;
		PaidH(_servant, _servantAlias, _payH, now);
	}

	// @notice pay Funding
	function payFunding (uint _payF) public {
    	transfer (_commune, _payF);
		_realCrowdFunding += _payF;
	}

	// @notice pay Expenses
	function payExpenses (address _contractor, uint _payE) public {
	if (msg.sender != _commune) return;
    	transfer (_contractor, _payE);
		_realExpenses += _payE;
	}

}

error: pathspec 'contractNew.sol' did not match any file(s) known to git


Fixes and whatnot.

Fixes and whatnot.

//sol FixedFeeRegistrar
// Simple global registrar with fixed-fee reservations.
// @authors:
//   Gav Wood <g@ethdev.com>

contract Registrar {
	event Changed(string indexed name);

	function owner(string _name) constant returns (address o_owner);
	function addr(string _name) constant returns (address o_address);
	function subRegistrar(string _name) constant returns (address o_subRegistrar);
	function content(string _name) constant returns (bytes32 o_content);
	function name(address _addr) constant returns (string o_name);
}

contract ExpRegistrar is Registrar {
	struct Record {
		address addr;
		address subRegistrar;
		bytes32 content;
		address owner;
		uint price;
	}

	event OwnerChanged(string indexed name);
	event AddressChanged(address indexed name);

	modifier onlyrecordowner(string _name) { if (m_record[_name].owner == msg.sender) _ }

	function ExpRegistrar() {
		m_record["gavofyork"].owner = 0x00fc9b9fd6ae40fd47941399915b9ce4fd5e1f28;
		m_record["gavofyork"].price = 2**200;
		m_reverse[0x00fc9b9fd6ae40fd47941399915b9ce4fd5e1f28] = "gavofyork";
		m_record["NameReg"].owner = this;
		m_record["NameReg"].price = 2**200;
		m_reverse[uint160(this)] = "NameReg";
	}

	function reserve(string _name) {
	    Record rec = m_record[_name];
		if ((rec.owner == 0 && msg.value >= 1 ether) || (rec.owner != 0 && msg.value >= rec.price)) {
			if (rec.price > 0)
				rec.owner.send(rec.price);
			else
				rec.price = msg.value;
			rec.price *= 10;
			rec.owner = msg.sender;
			OwnerChanged(_name);
		}
	}
	function transfer(string _name, address _newOwner) onlyrecordowner(_name) {
		m_record[_name].owner = _newOwner;
		Changed(_name);
	}
	function setAddr(string _name, address _a) onlyrecordowner(_name) {
		m_record[_name].addr = _a;
		Changed(_name);
	}
	function setSubRegistrar(string _name, address _registrar) onlyrecordowner(_name) {
		m_record[_name].subRegistrar = _registrar;
		Changed(_name);
	}
	function setContent(string _name, bytes32 _content) onlyrecordowner(_name) {
		m_record[_name].content = _content;
		Changed(_name);
	}
	function setName(string _name) {
		m_reverse[uint160(msg.sender)] = _name;
		AddressChanged(msg.sender);
	}

	function record(string _name) constant returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {
	    Record rec = m_record[_name];
		o_addr = rec.addr;
		o_subRegistrar = rec.subRegistrar;
		o_content = rec.content;
		o_owner = rec.owner;
	}
	function addr(string _name) constant returns (address) { return m_record[_name].addr; }
	function subRegistrar(string _name) constant returns (address) { return m_record[_name].subRegistrar; }
	function content(string _name) constant returns (bytes32) { return m_record[_name].content; }
	function owner(string _name) constant returns (address) { return m_record[_name].owner; }
	function name(address _addr) constant returns (string) { return m_reverse[uint160(_addr)]; }

	string[2**160] m_reverse;
	mapping (string => Record) m_record;
}

//sol FixedFeeRegistrar
// Simple global registrar with fixed-fee reservations.
// @authors:
//   Gav Wood <g@ethdev.com>

contract Registrar {
	event Changed(string indexed name);

	function owner(string _name) constant returns (address o_owner);
	function addr(string _name) constant returns (address o_address);
	function subRegistrar(string _name) constant returns (address o_subRegistrar);
	function content(string _name) constant returns (bytes32 o_content);
}

contract ExpRegistrar is Registrar {
	struct Record {
		address addr;
		address subRegistrar;
		bytes32 content;
		address owner;
		uint price;
	}

	modifier onlyrecordowner(string _name) { if (m_record[_name].owner == msg.sender) _ }

	function reserve(string _name) {
	    Record rec = m_record[_name];
		if ((rec.owner == 0 && msg.value >= 1 ether) || msg.value >= rec.price) {
			if (rec.price > 0)
				rec.owner.send(rec.price);
			else
				rec.price = msg.value;
			rec.price *= 2;
			rec.owner = msg.sender;
			Changed(_name);
		}
	}
	function transfer(string _name, address _newOwner) onlyrecordowner(_name) {
		m_record[_name].owner = _newOwner;
		Changed(_name);
	}
	function setAddr(string _name, address _a) onlyrecordowner(_name) {
		m_record[_name].addr = _a;
		Changed(_name);
	}
	function setSubRegistrar(string _name, address _registrar) onlyrecordowner(_name) {
		m_record[_name].subRegistrar = _registrar;
		Changed(_name);
	}
	function setContent(string _name, bytes32 _content) onlyrecordowner(_name) {
		m_record[_name].content = _content;
		Changed(_name);
	}

	function record(string _name) constant returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {
	    Record rec = m_record[_name];
		o_addr = rec.addr;
		o_subRegistrar = rec.subRegistrar;
		o_content = rec.content;
		o_owner = rec.owner;
	}
	function addr(string _name) constant returns (address) { return m_record[_name].addr; }
	function subRegistrar(string _name) constant returns (address) { return m_record[_name].subRegistrar; }
	function content(string _name) constant returns (bytes32) { return m_record[_name].content; }
	function owner(string _name) constant returns (address) { return m_record[_name].owner; }

	mapping (string => Record) m_record;
}

var ExpRegistrar = web3.eth.contract([{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_a","type":"address"}],"name":"setAddr","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"addr","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"subRegistrar","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"reserve","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_registrar","type":"address"}],"name":"setSubRegistrar","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"content","outputs":[{"name":"","type":"bytes32"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"record","outputs":[{"name":"o_addr","type":"address"},{"name":"o_subRegistrar","type":"address"},{"name":"o_content","type":"bytes32"},{"name":"o_owner","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_newOwner","type":"address"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_content","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"}],"name":"Changed","type":"event"}]);
contract ExpRegistrar{function setAddr(string _name,address _a);function addr(string _name)constant returns(address );function subRegistrar(string _name)constant returns(address );function reserve(string _name);function setSubRegistrar(string _name,address _registrar);function content(string _name)constant returns(bytes32 );function owner(string _name)constant returns(address );function record(string _name)constant returns(address o_addr,address o_subRegistrar,bytes32 o_content,address o_owner);function transfer(string _name,address _newOwner);function setContent(string _name,bytes32 _content);}
213b9eb8… :setAddr
511b1df9… :addr
7f445c24… :subRegistrar
ae999ece… :reserve
ccf4f413… :setSubRegistrar
dd54a62f… :content
df55b41a… :owner
e51ace16… :record
fbf58b3e… :transfer
fd6f5430… :setContent


add other assert methods to lib

add other assert methods to lib

pragma solidity ^0.4.7;

library Assert {

  event AssertionEvent(
    bool indexed passed,
    string message
  );

  function ok(bool a, string message) public returns (bool result) {
    result = a;
    AssertionEvent(result, message);
  }

  function equal(uint a, uint b, string message) public returns (bool result) {
    result = (a == b);
    AssertionEvent(result, message);
  }

  function equal(int a, int b, string message) public returns (bool result) {
    result = (a == b);
    AssertionEvent(result, message);
  }

  function equal(bool a, bool b, string message) public returns (bool result) {
    result = (a == b);
    AssertionEvent(result, message);
  }

  //function equal(fixed a, fixed b, string message) public returns (bool result) {
  //  result = (a == b);
  //  AssertionEvent(result, message);
  //}

  //function equal(ufixed a, ufixed b, string message) public returns (bool result) {
  //  result = (a == b);
  //  AssertionEvent(result, message);
  //}

  function equal(address a, address b, string message) public returns (bool result) {
    result = (a == b);
    AssertionEvent(result, message);
  }

  function equal(bytes32 a, bytes32 b, string message) public returns (bool result) {
    result = (a == b);
    AssertionEvent(result, message);
  }

  // probably need to convert to bytes first
  //function equal(string a, string b, string message) public returns (bool result) {
  //  result = (a == b);
  //  AssertionEvent(result, message);
  //}

  function notEqual(uint a, uint b, string message) public returns (bool result) {
    result = (a != b);
    AssertionEvent(result, message);
  }

  function notEqual(int a, int b, string message) public returns (bool result) {
    result = (a != b);
    AssertionEvent(result, message);
  }

  function notEqual(bool a, bool b, string message) public returns (bool result) {
    result = (a != b);
    AssertionEvent(result, message);
  }

  //function notEqual(fixed a, fixed b, string message) public returns (bool result) {
  //  result = (a != b);
  //  AssertionEvent(result, message);
  //}

  //function notEqual(ufixed a, ufixed b, string message) public returns (bool result) {
  //  result = (a != b);
  //  AssertionEvent(result, message);
  //}

  function notEqual(address a, address b, string message) public returns (bool result) {
    result = (a != b);
    AssertionEvent(result, message);
  }

  function notEqual(bytes32 a, bytes32 b, string message) public returns (bool result) {
    result = (a != b);
    AssertionEvent(result, message);
  }

  // probably need to convert to bytes first
  //function notEqual(string a, string b, string message) public returns (bool result) {
  //  result = (a != b);
  //  AssertionEvent(result, message);
  //}

}

pragma solidity ^0.4.7;

library Assert {

  event AssertionEvent(
    bool indexed passed,
    string message
  );

  function equal(uint a, uint b, string message) public returns (bool result) {
    result = (a == b);
    AssertionEvent(result, message);
  }

}