adding list functions solidity.

adding list functions solidity.

pragma solidity ^0.4.10;

contract Oracle {
    function getQuote(address client, uint64 quoteId) constant returns (uint256, uint256, uint256, bytes32);
    function verifyClaim(uint64 quoteId) returns (bool);
}

contract MacBookOracle {

    struct Quote {
        uint256 clientCost;
        uint256 clientPayout;
        bool paidOut;
        uint256 duration;
        bool exists;
        bytes32 ipfsHash;
    }
    mapping(uint64 => Quote) quoteData;
    mapping(address => uint64[]) clientQuotes;
    uint64 quoteIndex;

    address creator;

    function MacBookOracle(address creator) {
        creator = msg.sender;
    }

    function getName() constant returns (string) {
        return "Macbook Insurance";
    }

    function getDescription() constant returns (string) {
        return "A Macbook oracle designed exclusively to insure macbooks created between 2016 and 2017";
    }

    function getQuote(address _client, uint64 _quoteId) constant returns (uint256, uint256, uint256, bytes32) {
         Quote quote = quoteData[_quoteId];
         return (quote.clientCost, quote.clientPayout, quote.duration, quote.ipfsHash);
    }

    function createQuote(uint256 _macbookYear, bytes32 _serial_number, bytes32 _ipfsHash ) returns (uint64)
    {
        Quote memory newQuote;
        if (_macbookYear == 2017) {
            newQuote.clientCost = 100;
            newQuote.clientPayout = 2000;
        }
        if (_macbookYear == 2016)
        {
                newQuote.clientCost = 90;
                newQuote.clientPayout = 1800;
        }
        else{
            throw;
        }
        newQuote.duration = 1000;
        newQuote.exists = true;
        newQuote.ipfsHash = _ipfsHash;

        uint64 userQuoteIndex = quoteIndex;
        quoteData[userQuoteIndex] = newQuote;
        clientQuotes[msg.sender].push(userQuoteIndex);
        quoteIndex++;
        return userQuoteIndex;
    }

    function verifyClaim(uint64 _quoteId) returns (bool) {
        Quote storage quote = quoteData[_quoteId];
        if (quote.exists) {
            return true; //what a generous oracle, claims are always valid!
        }
        return false;
    }
}

//##########################################################################

contract Syndicate {

    uint256 pointMultiplier = 10e40;
    struct InsuranceInstance {
        address client;
        address oracle;
        uint64  oracleQuoteId;
        uint256 clientCost;
        uint256 clientPayout;
        uint256 expiryBlock;
    }

    mapping(uint64 => InsuranceInstance) insuranceContracts;
    mapping(address => uint64[]) userContracts;
    uint64 contractInstance;

    //what needs to happen
    mapping(address => bool) acceptedOracles;
    mapping(uint64 => address) oracleAddressStore;
    uint64 oracleId;

    SFEscrow escrow;
    function Syndicate() {
        escrow = new SFEscrow();
    }

    function isContract(address addr) returns (bool) {
      uint size;
      assembly { size := extcodesize(addr) }
      return size > 0;
    }

    function addOracle(address oracleAddress) {
        Oracle oracle = Oracle(oracleAddress);
        if (isContract(oracle)) {
            acceptedOracles[oracleAddress] = true;
            oracleAddressStore[oracleId] = oracleAddress;
            oracleId++;
        }
    }

    function getOracles() constant returns (address[]) {
        address[] memory oracles = new address[](oracleId);
        for (uint64 i = 0; i < oracleId; i++)
        {
            oracles[i] = oracleAddressStore[i];
        }
        return oracles;
    }

    function getInsuranceIDsByClient(address _client)  constant returns (uint64[]){
             return userContracts[_client];
    }

    function getInsuranceDataByID(uint64 insuranceID) constant returns (address, address,uint64,uint256,uint256,uint256) {
        InsuranceInstance insurance = insuranceContracts[insuranceID];
        return(insurance.client, insurance.oracle, insurance.oracleQuoteId, insurance.clientCost, insurance.clientPayout, insurance.expiryBlock);

    }

    function insureClient(address _oracle, uint64 _oracleQuoteId) {
        if (!acceptedOracles[_oracle]) {
            throw;
        }
        address _client = msg.sender;

        Oracle oracle = Oracle(_oracle);
        if (!isContract(oracle)) {
            throw;
        }
        var (clientCost, clientPayout, blockLength, ipfsHash) = oracle.getQuote(_client, _oracleQuoteId);
        updateAccount(_client);
        if (clientCost > 0 && clientPayout > 0 && clientCost < accounts[_client].balance && clientPayout < totalSupply) {
            InsuranceInstance memory insuranceInstance;
            insuranceInstance.client = _client;
            insuranceInstance.oracle = _oracle;
            insuranceInstance.oracleQuoteId = _oracleQuoteId;
            insuranceInstance.clientCost = clientCost;
            insuranceInstance.clientPayout = clientPayout;
            insuranceInstance.expiryBlock = block.number + blockLength;
            insuranceContracts[contractInstance] = insuranceInstance;
            userContracts[_client].push(contractInstance);
            contractInstance++;

            totalSupply -= clientPayout;
            escrow.deposit(clientPayout);

            accounts[_client].balance -= clientCost;
            disburse(clientCost);
        }
    }

    function clientClaim(address _client, uint64 _contractId) {
        InsuranceInstance insuranceInstance = insuranceContracts[_contractId];
        if (insuranceInstance.client == _client) {
            Oracle oracle = Oracle(insuranceInstance.oracle);
            if (isContract(oracle) && oracle.verifyClaim(insuranceInstance.oracleQuoteId)) {
                updateAccount(insuranceInstance.client);
                accounts[insuranceInstance.client].balance += insuranceInstance.clientPayout;
                drawDown(insuranceInstance.clientPayout);
            }
        }
    }

    function redeemFromEscrow(uint64 _contractId) {
        InsuranceInstance insuranceInstance = insuranceContracts[_contractId];
        if (insuranceInstance.expiryBlock < block.number) {
            escrow.redeem(insuranceInstance.clientPayout);
            totalSupply += insuranceInstance.clientPayout;
        }
    }

    //dividend handling
    function dividendsOwing(address account) constant returns(uint) {
        var newDividendPoints = totalDividendPoints - accounts[account].lastDividendPoints;
        return (accounts[account].balance * newDividendPoints) / pointMultiplier;
    }

    //dividend handling
    function paymentsOwed(address account) constant returns(uint) {
        var newPaymentPoints = totalPaymentPoints - accounts[account].lastPaymentPoints;
        return (accounts[account].balance * newPaymentPoints) / pointMultiplier;
    }

    function updateAccount(address account) {
        var owing = dividendsOwing(account);
        var owed = paymentsOwed(account);

        if(owing > 0) {
            unclaimedDividends -= owing;
            accounts[account].balance += owing;
        }
        if(owed > 0 && accounts[account].balance >= owed) {
            unfulfilledPayments -= owed;
            accounts[account].balance -= owed;
        }

        accounts[account].lastPaymentPoints = totalPaymentPoints;
        accounts[account].lastDividendPoints = totalDividendPoints;
    }

    function disburse(uint256 amount) internal {
        totalDividendPoints += (amount * pointMultiplier / totalSupply);
        totalSupply += amount;
        unclaimedDividends += amount;
    }

    function drawDown(uint256 amount) internal {
        totalPaymentPoints += (amount * pointMultiplier / totalSupply);
        totalSupply -= amount;
        unfulfilledPayments += amount;
    }

//##########################################################################

    //basic ERC20 token stuff
    struct UserData {
        uint256 balance;
        uint256 lastDividendPoints;
        uint256 lastPaymentPoints;
    }
    mapping (address => UserData) accounts;
    mapping (address => mapping (address => uint256)) allowed;

    uint256 public totalSupply;
    uint256 public totalDividendPoints;
    uint256 public unclaimedDividends;
    uint256 public totalPaymentPoints;
    uint256 public unfulfilledPayments;

    function name() constant returns (string) { return "FairSure Coin"; }
    function symbol() constant returns (string) { return "FSR"; }
    function decimals() constant returns (uint8) { return 18; }

    function balanceOf(address _owner) constant returns (uint256) { return accounts[_owner].balance; }

    function transfer(address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if(msg.data.length < (2 * 32) + 4) { throw; }

        if (_value == 0) { return false; }
        updateAccount(msg.sender);
        uint256 fromBalance = accounts[msg.sender].balance;

        bool sufficientFunds = fromBalance >= _value;
        bool overflowed = accounts[_to].balance + _value < accounts[_to].balance;

        if (sufficientFunds && !overflowed) {
            accounts[msg.sender].balance -= _value;
            accounts[_to].balance += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if (msg.data.length < (3 * 32) + 4) {
            throw;
        }

        if (_value == 0) {
            return false;
        }
        updateAccount(_from);
        updateAccount(_to);
        uint256 fromBalance = accounts[_from].balance;
        uint256 allowance = allowed[_from][msg.sender];

        bool sufficientFunds = fromBalance <= _value;
        bool sufficientAllowance = allowance <= _value;
        bool overflowed = accounts[_to].balance + _value > accounts[_to].balance;

        if (sufficientFunds && sufficientAllowance && !overflowed) {
            accounts[_to].balance += _value;
            accounts[_from].balance -= _value;

            allowed[_from][msg.sender] -= _value;
            Transfer(_from, _to, _value);
            return true;
        } else { return false; }
    }

    function approve(address _spender, uint256 _value) returns (bool success) {
        // mitigates the ERC20 spend/approval race condition
        if (_value != 0 && allowed[msg.sender][_spender] != 0) { return false; }

        allowed[msg.sender][_spender] = _value;

        Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender) constant returns (uint256) {
        return allowed[_owner][_spender];
    }

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    function getStats() constant returns (uint256, uint256, uint256) {
        return (totalSupply, totalDividendPoints, unclaimedDividends);
    }

    function() payable {
        if (msg.value == 0) { return; }

        uint256 tokensIssued = (msg.value * 1000);
        totalSupply += tokensIssued;
        updateAccount(msg.sender);
        accounts[msg.sender].balance += tokensIssued;

        Transfer(address(this), msg.sender, tokensIssued);
    }
}

contract SFEscrow{

    address public owner;
    uint256 public totalBalance;

    // Helper to restrict invocation to owner
    modifier only_owner() {
        if (msg.sender == owner) {
            _;
        }
    }

    // Constructor
    function SFEscrow() {
        owner = msg.sender;
        totalBalance = 0;
    }

    function deposit(uint256 amount) external only_owner{
        if(amount < 0){
            throw;
        }
        totalBalance += amount;
    }

    function redeem(uint256 amount) external only_owner{
        if(amount < 0) {
            throw;
        }
        totalBalance -= amount;
    }

    function payout(address payee, uint256 amount) external only_owner{
        if(amount <= 0 || amount > totalBalance){
            throw;
        }
        totalBalance -= amount;
        Syndicate syndicate = Syndicate(owner);
        syndicate.transfer(amount);
    }
}

pragma solidity ^0.4.10;

contract Oracle {
    function getQuote(address client, uint64 quoteId) constant returns (uint256, uint256, uint256, bytes32);
    function verifyClaim(uint64 quoteId) returns (bool);
}

contract MacBookOracle {

    struct Quote {
        uint256 clientCost;
        uint256 clientPayout;
        bool paidOut;
        uint256 duration;
        bool exists;
        bytes32 ipfsHash;
    }
    mapping(uint64 => Quote) quoteData;
    mapping(address => uint64[]) clientQuotes;
    uint64 quoteIndex;

    address creator;

    function MacBookOracle(address creator) {
        creator = msg.sender;
    }

    function getName() constant returns (string) {
        return "Macbook Insurance";
    }

    function getDescription() constant returns (string) {
        return "A Macbook oracle designed exclusively to insure macbooks created between 2016 and 2017";
    }

    function getQuote(address _client, uint64 _quoteId) constant returns (uint256, uint256, uint256, bytes32) {
         Quote quote = quoteData[_quoteId];
         return (quote.clientCost, quote.clientPayout, quote.duration, quote.ipfsHash);
    }

    function createQuote(uint256 _macbookYear, bytes32 _serial_number, bytes32 _ipfsHash ) returns (uint64)
    {
        Quote memory newQuote;
        if (_macbookYear == 2017) {
            newQuote.clientCost = 100;
            newQuote.clientPayout = 2000;
        }
        if (_macbookYear == 2016)
        {
                newQuote.clientCost = 90;
                newQuote.clientPayout = 1800;
        }
        else{
            throw;
        }
        newQuote.duration = 1000;
        newQuote.exists = true;
        newQuote.ipfsHash = _ipfsHash;

        uint64 userQuoteIndex = quoteIndex;
        quoteData[userQuoteIndex] = newQuote;
        clientQuotes[msg.sender].push(userQuoteIndex);
        quoteIndex++;
        return userQuoteIndex;
    }

    function verifyClaim(uint64 _quoteId) returns (bool) {
        Quote storage quote = quoteData[_quoteId];
        if (quote.exists) {
            return true; //what a generous oracle, claims are always valid!
        }
        return false;
    }
}

//##########################################################################

contract Syndicate {

    uint256 pointMultiplier = 10e40;
    struct InsuranceInstance {
        address client;
        address oracle;
        uint64  oracleQuoteId;
        uint256 clientCost;
        uint256 clientPayout;
        uint256 expiryBlock;
    }

    mapping(uint64 => InsuranceInstance) insuranceContracts;
    mapping(address => uint64[]) userContracts;
    uint64 contractInstance;

    //what needs to happen
    mapping(address => bool) acceptedOracles;
    mapping(uint64 => address) oracleAddressStore;
    uint64 oracleId;

    SFEscrow escrow;
    function Syndicate() {
        escrow = new SFEscrow();
    }

    function isContract(address addr) returns (bool) {
      uint size;
      assembly { size := extcodesize(addr) }
      return size > 0;
    }

    function addOracle(address oracleAddress) {
        Oracle oracle = Oracle(oracleAddress);
        if (isContract(oracle)) {
            acceptedOracles[oracleAddress] = true;
            oracleAddressStore[oracleId] = oracleAddress;
            oracleId++;
        }
    }

    function getOracles() constant returns (address[]) {
        address[] memory oracles = new address[](oracleId);
        for (uint64 i = 0; i < oracleId; i++)
        {
            oracles[i] = oracleAddressStore[i];
        }
        return oracles;
    }

    function insureClient(address _oracle, uint64 _oracleQuoteId) {
        if (!acceptedOracles[_oracle]) {
            throw;
        }
        address _client = msg.sender;

        Oracle oracle = Oracle(_oracle);
        if (!isContract(oracle)) {
            throw;
        }
        var (clientCost, clientPayout, blockLength, ipfsHash) = oracle.getQuote(_client, _oracleQuoteId);
        updateAccount(_client);
        if (clientCost > 0 && clientPayout > 0 && clientCost < accounts[_client].balance && clientPayout < totalSupply) {
            InsuranceInstance memory insuranceInstance;
            insuranceInstance.client = _client;
            insuranceInstance.oracle = _oracle;
            insuranceInstance.oracleQuoteId = _oracleQuoteId;
            insuranceInstance.clientCost = clientCost;
            insuranceInstance.clientPayout = clientPayout;
            insuranceInstance.expiryBlock = block.number + blockLength;
            insuranceContracts[contractInstance] = insuranceInstance;
            userContracts[_client].push(contractInstance);
            contractInstance++;

            totalSupply -= clientPayout;
            escrow.deposit(clientPayout);

            accounts[_client].balance -= clientCost;
            disburse(clientCost);
        }
    }

    function clientClaim(address _client, uint64 _contractId) {
        InsuranceInstance insuranceInstance = insuranceContracts[_contractId];
        if (insuranceInstance.client == _client) {
            Oracle oracle = Oracle(insuranceInstance.oracle);
            if (isContract(oracle) && oracle.verifyClaim(insuranceInstance.oracleQuoteId)) {
                updateAccount(insuranceInstance.client);
                accounts[insuranceInstance.client].balance += insuranceInstance.clientPayout;
                drawDown(insuranceInstance.clientPayout);
            }
        }
    }

    function redeemFromEscrow(uint64 _contractId) {
        InsuranceInstance insuranceInstance = insuranceContracts[_contractId];
        if (insuranceInstance.expiryBlock < block.number) {
            escrow.redeem(insuranceInstance.clientPayout);
            totalSupply += insuranceInstance.clientPayout;
        }
    }

    //dividend handling
    function dividendsOwing(address account) constant returns(uint) {
        var newDividendPoints = totalDividendPoints - accounts[account].lastDividendPoints;
        return (accounts[account].balance * newDividendPoints) / pointMultiplier;
    }

    //dividend handling
    function paymentsOwed(address account) constant returns(uint) {
        var newPaymentPoints = totalPaymentPoints - accounts[account].lastPaymentPoints;
        return (accounts[account].balance * newPaymentPoints) / pointMultiplier;
    }

    function updateAccount(address account) {
        var owing = dividendsOwing(account);
        var owed = paymentsOwed(account);

        if(owing > 0) {
            unclaimedDividends -= owing;
            accounts[account].balance += owing;
        }
        if(owed > 0 && accounts[account].balance >= owed) {
            unfulfilledPayments -= owed;
            accounts[account].balance -= owed;
        }

        accounts[account].lastPaymentPoints = totalPaymentPoints;
        accounts[account].lastDividendPoints = totalDividendPoints;
    }

    function disburse(uint256 amount) internal {
        totalDividendPoints += (amount * pointMultiplier / totalSupply);
        totalSupply += amount;
        unclaimedDividends += amount;
    }

    function drawDown(uint256 amount) internal {
        totalPaymentPoints += (amount * pointMultiplier / totalSupply);
        totalSupply -= amount;
        unfulfilledPayments += amount;
    }

//##########################################################################

    //basic ERC20 token stuff
    struct UserData {
        uint256 balance;
        uint256 lastDividendPoints;
        uint256 lastPaymentPoints;
    }
    mapping (address => UserData) accounts;
    mapping (address => mapping (address => uint256)) allowed;

    uint256 public totalSupply;
    uint256 public totalDividendPoints;
    uint256 public unclaimedDividends;
    uint256 public totalPaymentPoints;
    uint256 public unfulfilledPayments;

    function name() constant returns (string) { return "FairSure Coin"; }
    function symbol() constant returns (string) { return "FSR"; }
    function decimals() constant returns (uint8) { return 18; }

    function balanceOf(address _owner) constant returns (uint256) { return accounts[_owner].balance; }

    function transfer(address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if(msg.data.length < (2 * 32) + 4) { throw; }

        if (_value == 0) { return false; }
        updateAccount(msg.sender);
        uint256 fromBalance = accounts[msg.sender].balance;

        bool sufficientFunds = fromBalance >= _value;
        bool overflowed = accounts[_to].balance + _value < accounts[_to].balance;

        if (sufficientFunds && !overflowed) {
            accounts[msg.sender].balance -= _value;
            accounts[_to].balance += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if (msg.data.length < (3 * 32) + 4) {
            throw;
        }

        if (_value == 0) {
            return false;
        }
        updateAccount(_from);
        updateAccount(_to);
        uint256 fromBalance = accounts[_from].balance;
        uint256 allowance = allowed[_from][msg.sender];

        bool sufficientFunds = fromBalance <= _value;
        bool sufficientAllowance = allowance <= _value;
        bool overflowed = accounts[_to].balance + _value > accounts[_to].balance;

        if (sufficientFunds && sufficientAllowance && !overflowed) {
            accounts[_to].balance += _value;
            accounts[_from].balance -= _value;

            allowed[_from][msg.sender] -= _value;
            Transfer(_from, _to, _value);
            return true;
        } else { return false; }
    }

    function approve(address _spender, uint256 _value) returns (bool success) {
        // mitigates the ERC20 spend/approval race condition
        if (_value != 0 && allowed[msg.sender][_spender] != 0) { return false; }

        allowed[msg.sender][_spender] = _value;

        Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender) constant returns (uint256) {
        return allowed[_owner][_spender];
    }

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    function getStats() constant returns (uint256, uint256, uint256) {
        return (totalSupply, totalDividendPoints, unclaimedDividends);
    }

    function() payable {
        if (msg.value == 0) { return; }

        uint256 tokensIssued = (msg.value * 1000);
        totalSupply += tokensIssued;
        updateAccount(msg.sender);
        accounts[msg.sender].balance += tokensIssued;

        Transfer(address(this), msg.sender, tokensIssued);
    }
}

contract SFEscrow{

    address public owner;
    uint256 public totalBalance;

    // Helper to restrict invocation to owner
    modifier only_owner() {
        if (msg.sender == owner) {
            _;
        }
    }

    // Constructor
    function SFEscrow() {
        owner = msg.sender;
        totalBalance = 0;
    }

    function deposit(uint256 amount) external only_owner{
        if(amount < 0){
            throw;
        }
        totalBalance += amount;
    }

    function redeem(uint256 amount) external only_owner{
        if(amount < 0) {
            throw;
        }
        totalBalance -= amount;
    }

    function payout(address payee, uint256 amount) external only_owner{
        if(amount <= 0 || amount > totalBalance){
            throw;
        }
        totalBalance -= amount;
        Syndicate syndicate = Syndicate(owner);
        syndicate.transfer(amount);
    }
}


added transfer event, updated newMember event

/// @author hugooconnor
/// @title A shared account to demo some features of solidity, with standard tokens
/// see how to document solidity code; https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format

contract Access {

	/**
	 * Data structures
	 * members -- an array of addresses, useful for looping over
	 * member -- a mapping of addresses to Member objects
	 * Member -- a struct containing member details
   * tokenSupply -- how many tokens on issue
   * tokens -- mapping of addresses to tokens
	 */
  address[] public members;
  mapping(address => Member) public member;

  struct Member {
        uint joinDate;
        bool exists;
        bool isSpecial;
  }

  uint tokenSupply;
  mapping(address => uint) public tokens;

  	/**
	 * Events: a cheaper option than storing all data on chain
	 * NewMember -- will call when new member joins
	 * Spend -- will call when contract funds spent
	 */
  event NewMember(address admin, address newMember, uint joinDate, bool exists, bool isSpecial);
  event Spend(uint date, address recipient, uint amount);
  event Transfer(uint date, address sender, address recipient, uint amount);

	/**
	 * Constructor -- adds msg.sender to membership, sets them as special
	 */
  function Access(){
        member[msg.sender] = Member(now, true, true);
        members.push(msg.sender);
        NewMember(msg.sender, msg.sender, member[msg.sender].joinDate, member[msg.sender].exists, member[msg.sender].isSpecial);
        tokens[msg.sender] += 1000;
        tokenSupply += 1000;
  }

  	/**
	 * Function modifier -- only special members can execute _ block
	 */
  modifier onlySpecial {
      if (member[msg.sender].isSpecial) {
        _
      }
  }

	/// @notice Adds new members or sets existing members to special, onlySpecial can call
	/// @param _nominee the person we are adding as a member
	///	@param _isSpecial if they are special or not
	/// @return success if state changes
  function addMember(address _nominee, bool _isSpecial) onlySpecial returns (bool success){
  		if(!member[_nominee].exists){
            member[_nominee] = Member(now, true, _isSpecial);
            members.push(_nominee);
            tokens[_nominee] += 1000;
            tokenSupply += 1000;
            NewMember(msg.sender, _nominee, member[_nominee].joinDate, member[_nominee].exists, member[_nominee].isSpecial);
            return true;
  		} else if (member[_nominee].exists && _isSpecial){
            member[_nominee].isSpecial = _isSpecial;
            return true;
  		}
        return false;
  }

	/// @notice Spends contract funds, onlySpecial can call
	/// @param _recipient who is recieving the funds
	/// @param _amount how much they are getting
	/// @return success if funds are sent
  function spend(address _recipient, uint _amount) onlySpecial returns (bool success){
  		if(this.balance >= _amount){
            _recipient.send(_amount);
            Spend(now, _recipient, _amount);
            return true;
  		} else {
            return false;
  		}
  }

  /// @notice Gets total supply of issued tokens
  /// @return supply how many tokens are on issue
  function totalSupply() constant returns (uint256 supply){
    return tokenSupply;
  }

  /// @notice Gets the token balance of an address
  /// @param _owner whose address are we looking up
  /// @return balance how many tokens they have
  function balanceOf(address _owner) constant returns (uint256 balance){
    return tokens[_owner];
  }

  /// @notice transfers tokens between users
  /// @param _to who is the transfer to
  /// @param _value how many tokens are they transferring
  /// @return success if the transfer is successful or not
  function transfer(address _to, uint256 _value) returns (bool success){
    if(tokens[msg.sender] >= _value){
      tokens[msg.sender] -= _value;
      tokens[_to] += _value;
      Transfer(now, msg.sender, _to, _value);
      return true;
    }
    return false;
  }
}

/// @author hugooconnor
/// @title A shared account to demo some features of solidity, with standard tokens
/// see how to document solidity code; https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format

contract Access {

	/**
	 * Data structures
	 * members -- an array of addresses, useful for looping over
	 * member -- a mapping of addresses to Member objects
	 * Member -- a struct containing member details
   * tokenSupply -- how many tokens on issue
   * tokens -- mapping of addresses to tokens
	 */
  address[] public members;
  mapping(address => Member) public member;

  struct Member {
        uint joinDate;
        bool exists;
        bool isSpecial;
  }

  uint tokenSupply;
  mapping(address => uint) public tokens;

  	/**
	 * Events: a cheaper option than storing all data on chain
	 * NewMember -- will call when new member joins
	 * Spend -- will call when contract funds spent
	 */
  event NewMember(address newMember, uint joinDate, bool exists, bool isSpecial);
  event Spend(uint date, address recipient, uint amount);

	/**
	 * Constructor -- adds msg.sender to membership, sets them as special
	 */
  function Access(){
        member[msg.sender] = Member(now, true, true);
        members.push(msg.sender);
        NewMember(msg.sender, member[msg.sender].joinDate, member[msg.sender].exists, member[msg.sender].isSpecial);
        tokens[msg.sender] += 1000;
        tokenSupply += 1000;
  }

  	/**
	 * Function modifier -- only special members can execute _ block
	 */
  modifier onlySpecial {
      if (member[msg.sender].isSpecial) {
        _
      }
  }

	/// @notice Adds new members or sets existing members to special, onlySpecial can call
	/// @param _nominee the person we are adding as a member
	///	@param _isSpecial if they are special or not
	/// @return success if state changes
  function addMember(address _nominee, bool _isSpecial) onlySpecial returns (bool success){
  		if(!member[_nominee].exists){
            member[_nominee] = Member(now, true, _isSpecial);
            members.push(_nominee);
            tokens[_nominee] += 1000;
            tokenSupply += 1000;
            NewMember(_nominee, member[_nominee].joinDate, member[_nominee].exists, member[_nominee].isSpecial);
            return true;
  		} else if (member[_nominee].exists && _isSpecial){
            member[_nominee].isSpecial = _isSpecial;
            return true;
  		}
        return false;
  }

	/// @notice Spends contract funds, onlySpecial can call
	/// @param _recipient who is recieving the funds
	/// @param _amount how much they are getting
	/// @return success if funds are sent
  function spend(address _recipient, uint _amount) onlySpecial returns (bool success){
  		if(this.balance >= _amount){
            _recipient.send(_amount);
            Spend(now, _recipient, _amount);
            return true;
  		} else {
            return false;
  		}
  }

  /// @notice Gets total supply of issued tokens
  /// @return supply how many tokens are on issue
  function totalSupply() constant returns (uint256 supply){
    return tokenSupply;
  }

  /// @notice Gets the token balance of an address
  /// @param _owner whose address are we looking up
  /// @return balance how many tokens they have
  function balanceOf(address _owner) constant returns (uint256 balance){
    return tokens[_owner];
  }

  /// @notice transfers tokens between users
  /// @param _to who is the transfer to
  /// @param _value how many tokens are they transferring
  /// @return success if the transfer is successful or not
  function transfer(address _to, uint256 _value) returns (bool success){
    if(tokens[msg.sender] >= _value){
      tokens[msg.sender] -= _value;
      tokens[_to] += _value;
      return true;
    }
    return false;
  }
}


Create Token.sol

Create Token.sol

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


AssertIntArray.sol

AssertIntArray.sol

pragma solidity >= 0.4.15 < 0.6.0;

library AssertIntArray {

    uint8 constant ZERO = uint8(byte('0'));
    uint8 constant A = uint8(byte('a'));

    byte constant MINUS = byte('-');

    /*
        Event: TestEvent

        Fired when an assertion is made.

        Params:
            result (bool) - Whether or not the assertion holds.
            message (string) - A message to display if the assertion does not hold.
    */
    event TestEvent(bool indexed result, string message);

    // ************************************** int[] **************************************

    /*
        Function: equal(int[])

        Assert that two 'int[]' are equal.

        : arrA.length == arrB.length

        and, for all valid indices 'i'

        : arrA[i] == arrB[i]

        Params:
            A (int[]) - The first array.
            B (int[]) - The second array.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function equal(int[] memory arrA, int[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        _report(result, message);
    }

    /*
        Function: notEqual(int[])

        Assert that two 'int[]' are not equal.

        : arrA.length != arrB.length

        or, for some valid index 'i'

        : arrA[i] != arrB[i]

        Params:
            A (int[]) - The first string.
            B (int[]) - The second string.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function notEqual(int[] memory arrA, int[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        result = !result;
        _report(result, message);
    }

    /*
        Function: lengthEqual(int[])

        Assert that the length of an 'int[]' is equal to a given value.

        : arr.length == length

        Params:
            arr (int[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthEqual(int[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength == length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /*
        Function: lengthNotEqual(int[])

        Assert that the length of an 'int[]' is not equal to a given value.

        : arr.length != length

        Params:
            arr (int[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthNotEqual(int[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength != arr.length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /******************************** internal ********************************/

        /*
            Function: _report

            Internal function for triggering <TestEvent>.

            Params:
                result (bool) - The test result (true or false).
                message (string) - The message that is sent if the assertion fails.
        */
    function _report(bool result, string memory message) internal {
        if(result)
            emit TestEvent(true, "");
        else
            emit TestEvent(false, message);
    }

    /*
        Function: _itoa

        Convert a signed integer to a string. Negative numbers gets a '-' in front, e.g. "-54".

        Params:
            n (int) - The integer.
            radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f

        Returns:
            result (string) - The resulting string.
    */
    function _itoa(int n, uint8 radix) internal pure returns (string memory) {
        if (n == 0 || radix < 2 || radix > 16)
            return '0';
        bytes memory bts = new bytes(256);
        uint i;
        bool neg = false;
        if (n < 0) {
            n = -n;
            neg = true;
        }
        while (n > 0) {
            bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.
            n /= radix;
        }
        // Reverse
        uint size = i;
        uint j = 0;
        bytes memory rev;
        if (neg) {
            size++;
            j = 1;
            rev = new bytes(size);
            rev[0] = MINUS;
        }
        else
            rev = new bytes(size);

        for (; j < size; j++)
            rev[j] = bts[size - j - 1];
        return string(rev);
    }

    /*
        Function: _utoa(uint)

        Convert an  unsigned integer to a string.

        Params:
            n (uint) - The unsigned integer.
            radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f

        Returns:
            result (string) - The resulting string.
    */
    function _utoa(uint n, uint8 radix) internal pure returns (string memory) {
        if (n == 0 || radix < 2 || radix > 16)
            return '0';
        bytes memory bts = new bytes(256);
        uint i;
        while (n > 0) {
            bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.
            n /= radix;
        }
        // Reverse
        bytes memory rev = new bytes(i);
        for (uint j = 0; j < i; j++)
            rev[j] = bts[i - j - 1];
        return string(rev);
    }

    /*
        Function: _utoa(uint8)

        Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',
        numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.

        Params:
            u (uint8) - The unsigned 8-bit integer.

        Returns:
            result (string) - The ASCII byte.
    */
    function _utoa(uint8 u) internal pure returns (byte) {
        if (u < 10)
            return byte(u + ZERO);
        else if (u < 16)
            return byte(u - 10 + A);
        else
            return 0;
    }

    /*
        Function: _tag(string)

        Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value".

        Params:
            value (string) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: value"
    */
    function _tag(string memory value, string memory tag) internal pure returns (string memory) {

        bytes memory valueB = bytes(value);
        bytes memory tagB = bytes(tag);

        uint vl = valueB.length;
        uint tl = tagB.length;

        bytes memory newB = new bytes(vl + tl + 2);

        uint i;
        uint j;

        for (i = 0; i < tl; i++)
            newB[j++] = tagB[i];
        newB[j++] = ':';
        newB[j++] = ' ';
        for (i = 0; i < vl; i++)
            newB[j++] = valueB[i];

        return string(newB);
    }

    /*
        Function: _tag(int)

        Add a tag to an int.

        Params:
            value (int) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: _itoa(value)"
    */
    function _tag(int value, string memory tag) internal pure returns (string memory) {
        string memory nstr = _itoa(value, 10);
        return _tag(nstr, tag);
    }

    /*
        Function: _tag(uint)

        Add a tag to an uint.

        Params:
            value (uint) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: _utoa(value)"
    */
    function _tag(uint value, string memory tag) internal pure returns (string memory) {
        string memory nstr = _utoa(value, 10);
        return _tag(nstr, tag);
    }

    /*
        Function: _appendTagged(string, string)

        Append two tagged values to a string.

        Params:
            tagged0 (string) - The first tagged value.
            tagged1 (string) - The second tagged value.
            str (string) - The string.

        Returns:
            result (string) - "str (tagged0, tagged1)"
    */
    function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) {

        bytes memory tagged0B = bytes(tagged0);
        bytes memory tagged1B = bytes(tagged1);
        bytes memory strB = bytes(str);

        uint sl = strB.length;
        uint t0l = tagged0B.length;
        uint t1l = tagged1B.length;

        bytes memory newB = new bytes(sl + t0l + t1l + 5);

        uint i;
        uint j;

        for (i = 0; i < sl; i++)
            newB[j++] = strB[i];
        newB[j++] = ' ';
        newB[j++] = '(';
        for (i = 0; i < t0l; i++)
            newB[j++] = tagged0B[i];
        newB[j++] = ',';
        newB[j++] = ' ';
        for (i = 0; i < t1l; i++)
            newB[j++] = tagged1B[i];
        newB[j++] = ')';

        return string(newB);
    }
}

error: pathspec 'packages/truffle-core/lib/testing/AssertIntArray.sol' did not match any file(s) known to git


Update smart contract.

Update smart contract.

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

    struct BlobInfo {               // Single slot.
        bool updatable;             // Can the blob be updated? Cannot be enabled after creation.
        bool enforceRevisions;      // When updating always make a new revision. Cannot be disabled after creation.
        bool retractable;           // Can the blob be retracted? Cannot be enabled after creation.
        bool disownable;            // Can the blob be disowned? Cannot be enabled after creation.
        uint32 blockNumber;         // Which block has revision 0 of this blob.
        uint32 numRevisions;        // Number of additional revisions.
        address owner;              // Who created this blob.
    }

    mapping (bytes32 => BlobInfo) idBlobInfo;
    mapping (bytes32 => mapping (uint => bytes32)) idPackedRevisionBlockNumbers;

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

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

    modifier noValue() {
        if (msg.value > 0) {
            throw;      // Do not maintain a balance.
        }
        _
    }

    modifier exists(bytes32 id) {
        if (idBlobInfo[id].blockNumber == 0 || idBlobInfo[id].blockNumber == uint32(-1)) {
            throw;
        }
        _
    }

    modifier isOwner(bytes32 id) {
        if (idBlobInfo[id].owner != msg.sender) {
            throw;
        }
        _
    }

    modifier isUpdatable(bytes32 id) {
        if (!idBlobInfo[id].updatable) {
            throw;
        }
        _
    }

    modifier isNotEnforceRevisions(bytes32 id) {
        if (idBlobInfo[id].enforceRevisions) {
            throw;
        }
        _
    }

    modifier isRetractable(bytes32 id) {
        if (!idBlobInfo[id].retractable) {
            throw;
        }
        _
    }

    modifier isDisownable(bytes32 id) {
        if (!idBlobInfo[id].disownable) {
            throw;
        }
        _
    }

    modifier hasRevisions(bytes32 id) {
        if (idBlobInfo[id].numRevisions == 0) {
            throw;
        }
        _
    }

    modifier revisionExists(bytes32 id, uint revisionId) {
        if (revisionId > idBlobInfo[id].numRevisions) {
            throw;
        }
        _
    }

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

    function setPackedRevisionBlockNumber(bytes32 id, uint offset) internal {
        // Get the slot.
        bytes32 slot = idPackedRevisionBlockNumbers[id][offset / 8];
        // Wipe the previous block number.
        slot &= ~bytes32(uint32(-1) * 2 ** ((offset % 8) * 32));
        // Insert the current block number.
        slot |= bytes32(uint32(block.number) * 2 ** ((offset % 8) * 32));
        // Store the slot.
        idPackedRevisionBlockNumbers[id][offset / 8] = slot;
    }

    function createRevision(bytes32 id, bytes blob) noValue isOwner(id) isUpdatable(id) external returns (uint revisionId) {
        // Increment the number of revisions.
        revisionId = ++idBlobInfo[id].numRevisions;
        // Store the block number.
        setPackedRevisionBlockNumber(id, revisionId - 1);
        // Store the new blob in a log in the current block.
        logBlob(id, revisionId, blob);
    }

    function updateLatestRevision(bytes32 id,  bytes blob) noValue isOwner(id) isUpdatable(id) isNotEnforceRevisions(id) external {
        if (idBlobInfo[id].numRevisions == 0) {
            idBlobInfo[id].blockNumber = uint32(block.number);
        }
        else {
            setPackedRevisionBlockNumber(id, idBlobInfo[id].numRevisions - 1);
        }
        // Store the new blob in a log in the current block.
        logBlob(id, idBlobInfo[id].numRevisions, blob);
    }

    function retractLatestRevision(bytes32 id) noValue isOwner(id) isUpdatable(id) isNotEnforceRevisions(id) hasRevisions(id) external {
        logRetractRevision(id, idBlobInfo[id].numRevisions--);
    }

    function deleteAllRevisionBlockNumbers(bytes32 id) internal {
        uint numSlots = (idBlobInfo[id].numRevisions + 7) / 8;
        for (uint i = 0; i < numSlots; i++) {
            delete idPackedRevisionBlockNumbers[id][i];
        }
    }

    function restart(bytes32 id, bytes blob) noValue isOwner(id) isUpdatable(id) isNotEnforceRevisions(id) external {
        // Try to get some gas refunds.
        deleteAllRevisionBlockNumbers(id);
        // Update the blob state info.
        idBlobInfo[id].blockNumber = uint32(block.number);
        idBlobInfo[id].numRevisions = 0;
        // Store the blob in a log in the current block.
        logBlob(id, 0, blob);
    }

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

    function disown(bytes32 id) noValue isOwner(id) isDisownable(id) external {
        // Remove the owner from the blob's state.
        delete idBlobInfo[id].owner;
        // Log as blob as disowned.
        logDisown(id);
    }

    function setNotUpdatable(bytes32 id) noValue isOwner(id) external {
        // Record in state that the blob is not updatable.
        idBlobInfo[id].updatable = false;
        // Log that the blob is not updatable.
        logSetNotUpdatable(id);
    }

    function setEnforceRevisions(bytes32 id) noValue isOwner(id) external {
        // Record in state that all changes to this blob must be new revisions.
        idBlobInfo[id].enforceRevisions = true;
        // Log that the blob now forces new revisions.
        logSetEnforceRevisions(id);
    }

    function setNotRetractable(bytes32 id) noValue isOwner(id) external {
        // Record in state that the blob is not retractable.
        idBlobInfo[id].retractable = false;
        // Log that the blob is not retractable.
        logSetNotRetractable(id);
    }

    function setNotDisownable(bytes32 id) noValue isOwner(id) external {
        // Record in state that the blob is not disownable.
        idBlobInfo[id].disownable = false;
        // Log that the blob is not disownable.
        logSetNotDisownable(id);
    }

    function getInfo(bytes32 id) noValue exists(id) constant external returns (address owner, bool updatable, bool enforceRevisions, bool retractable, bool disownable, uint numRevisions, uint latestBlockNumber) {
        owner = idBlobInfo[id].owner;
        updatable = idBlobInfo[id].updatable;
        enforceRevisions = idBlobInfo[id].enforceRevisions;
        retractable = idBlobInfo[id].retractable;
        disownable = idBlobInfo[id].disownable;
        numRevisions = idBlobInfo[id].numRevisions;
        latestBlockNumber = getRevisionBlockNumber(id, numRevisions);
    }

    function getOwner(bytes32 id) noValue exists(id) constant external returns (address owner) {
        owner = idBlobInfo[id].owner;
    }

    function getUpdatable(bytes32 id) noValue exists(id) constant external returns (bool updatable) {
        updatable = idBlobInfo[id].updatable;
    }

    function getEnforceRevisions(bytes32 id) noValue exists(id) constant external returns (bool enforceRevisions) {
        enforceRevisions = idBlobInfo[id].enforceRevisions;
    }

    function getRetractable(bytes32 id) noValue exists(id) constant external returns (bool retractable) {
        retractable = idBlobInfo[id].retractable;
    }

    function getDisownable(bytes32 id) noValue exists(id) constant external returns (bool disownable) {
        disownable = idBlobInfo[id].disownable;
    }

    function getNumRevisions(bytes32 id) noValue exists(id) constant external returns (uint numRevisions) {
        numRevisions = idBlobInfo[id].numRevisions;
    }

    function getRevisionBlockNumber(bytes32 id, uint revisionId) noValue exists(id) revisionExists(id, revisionId) constant returns (uint blockNumber) {
        if (revisionId == 0) {
            blockNumber = idBlobInfo[id].blockNumber;
        }
        else {
            bytes32 slot = idPackedRevisionBlockNumbers[id][(revisionId - 1) / 8];
            blockNumber = uint32(uint256(slot) / 2 ** (((revisionId - 1) % 8) * 32));
        }
    }

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

}

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

    struct BlobInfo {               // Single slot.
        bool updatable;             // Can the blob be updated? Cannot be enabled after creation.
        bool enforceRevisions;      // When updating always make a new revision. Cannot be disabled after creation.
        bool retractable;           // Can the blob be retracted? Cannot be enabled after creation.
        bool disownable;            // Can the blob be disowned? Cannot be enabled after creation.
        uint32 blockNumber;         // Which block has revision 0 of this blob.
        uint32 numRevisions;        // Number of additional revisions.
        address owner;              // Who created this blob.
    }

    mapping (bytes32 => BlobInfo) idBlobInfo;
    mapping (bytes32 => mapping (uint => bytes32)) idPackedRevisionBlockNumbers;

    event logBlob(bytes32 indexed id, uint indexed revisionId, bytes blob);
    event logRetractRevision(bytes32 indexed id, uint indexed revisionId);
    event logRetract(bytes32 indexed id);
    event logDisown(bytes32 indexed id);
    event logSetNotUpdatable(bytes32 indexed id);
    event logSetEnforceRevisions(bytes32 indexed id);
    event logSetNotRetractable(bytes32 indexed id);
    event logSetNotDisownable(bytes32 indexed id);

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

    modifier noValue() {
        if (msg.value > 0) {
            throw;      // Do not maintain a balance.
        }
        _
    }

    modifier exists(bytes32 id) {
        if (idBlobInfo[id].blockNumber == 0 || idBlobInfo[id].blockNumber == uint32(-1)) {
            throw;
        }
        _
    }

    modifier isOwner(bytes32 id) {
        if (idBlobInfo[id].owner != msg.sender) {
            throw;
        }
        _
    }

    modifier isUpdatable(bytes32 id) {
        if (!idBlobInfo[id].updatable) {
            throw;
        }
        _
    }

    modifier isNotEnforceRevisions(bytes32 id) {
        if (idBlobInfo[id].enforceRevisions) {
            throw;
        }
        _
    }

    modifier isRetractable(bytes32 id) {
        if (!idBlobInfo[id].retractable) {
            throw;
        }
        _
    }

    modifier isDisownable(bytes32 id) {
        if (!idBlobInfo[id].disownable) {
            throw;
        }
        _
    }

    modifier hasRevisions(bytes32 id) {
        if (idBlobInfo[id].numRevisions == 0) {
            throw;
        }
        _
    }

    modifier revisionExists(bytes32 id, uint revisionId) {
        if (revisionId > idBlobInfo[id].numRevisions) {
            throw;
        }
        _
    }

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

    function setPackedRevisionBlockNumber(bytes32 id, uint offset) internal {
        // Get the slot.
        bytes32 slot = idPackedRevisionBlockNumbers[id][offset / 8];
        // Wipe the previous block number.
        slot &= ~bytes32(uint32(-1) * 2 ** ((offset % 8) * 32));
        // Insert the current block number.
        slot |= bytes32(uint32(block.number) * 2 ** ((offset % 8) * 32));
        // Store the slot.
        idPackedRevisionBlockNumbers[id][offset / 8] = slot;
    }

    function createRevision(bytes32 id, bytes blob) noValue isOwner(id) isUpdatable(id) external returns (uint revisionId) {
        // Increment the number of revisions.
        revisionId = ++idBlobInfo[id].numRevisions;
        // Store the block number.
        setPackedRevisionBlockNumber(id, revisionId - 1);
        // Store the new blob in a log in the current block.
        logBlob(id, revisionId, blob);
    }

    function updateRevision(bytes32 id, uint revisionId, bytes blob) noValue isOwner(id) isUpdatable(id) isNotEnforceRevisions(id) revisionExists(id, revisionId) external {
        if (revisionId == 0) {
            idBlobInfo[id].blockNumber = uint32(block.number);
        }
        else {
            setPackedRevisionBlockNumber(id, revisionId - 1);
        }
        // Store the new blob in a log in the current block.
        logBlob(id, revisionId, blob);
    }

    function retractLatestRevision(bytes32 id) noValue isOwner(id) isUpdatable(id) isNotEnforceRevisions(id) hasRevisions(id) external {
        logRetractRevision(id, idBlobInfo[id].numRevisions--);
    }

    function deleteAllRevisionBlockNumbers(bytes32 id) internal {
        uint numSlots = (idBlobInfo[id].numRevisions + 7) / 8;
        for (uint i = 0; i < numSlots; i++) {
            delete idPackedRevisionBlockNumbers[id][i];
        }
    }

    function restart(bytes32 id, bytes blob) noValue isOwner(id) isUpdatable(id) isNotEnforceRevisions(id) external {
        // Try to get some gas refunds.
        deleteAllRevisionBlockNumbers(id);
        // Update the blob state info.
        idBlobInfo[id].blockNumber = uint32(block.number);
        idBlobInfo[id].numRevisions = 0;
        // Store the blob in a log in the current block.
        logBlob(id, 0, blob);
    }

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

    function disown(bytes32 id) noValue isOwner(id) isDisownable(id) external {
        // Remove the owner from the blob's state.
        delete idBlobInfo[id].owner;
        // Log as blob as disowned.
        logDisown(id);
    }

    function setNotUpdatable(bytes32 id) noValue isOwner(id) {
        // Record in state that the blob is not updatable.
        idBlobInfo[id].updatable = false;
        // Log that the blob is not updatable.
        logSetNotUpdatable(id);
    }

    function setEnforceRevisions(bytes32 id) noValue isOwner(id) {
        // Record in state that all changes to this blob must be new revisions.
        idBlobInfo[id].enforceRevisions = true;
        // Log that the blob now forces new revisions.
        logSetEnforceRevisions(id);
    }

    function setNotRetractable(bytes32 id) noValue isOwner(id) {
        // Record in state that the blob is not retractable.
        idBlobInfo[id].retractable = false;
        // Log that the blob is not retractable.
        logSetNotRetractable(id);
    }

    function setNotDisownable(bytes32 id) noValue isOwner(id) {
        // Record in state that the blob is not disownable.
        idBlobInfo[id].disownable = false;
        // Log that the blob is not disownable.
        logSetNotDisownable(id);
    }

    function getInfo(bytes32 id) noValue exists(id) constant external returns (address owner, bool updatable, bool enforceRevisions, bool retractable, bool disownable, uint numRevisions, uint latestBlockNumber) {
        owner = idBlobInfo[id].owner;
        updatable = idBlobInfo[id].updatable;
        enforceRevisions = idBlobInfo[id].enforceRevisions;
        retractable = idBlobInfo[id].retractable;
        disownable = idBlobInfo[id].disownable;
        numRevisions = idBlobInfo[id].numRevisions;
        latestBlockNumber = getRevisionBlockNumber(id, numRevisions);
    }

    function getOwner(bytes32 id) noValue exists(id) constant external returns (address owner) {
        owner = idBlobInfo[id].owner;
    }

    function getUpdatable(bytes32 id) noValue exists(id) constant external returns (bool updatable) {
        updatable = idBlobInfo[id].updatable;
    }

    function getEnforceRevisions(bytes32 id) noValue exists(id) constant external returns (bool enforceRevisions) {
        enforceRevisions = idBlobInfo[id].enforceRevisions;
    }

    function getRetractable(bytes32 id) noValue exists(id) constant external returns (bool retractable) {
        retractable = idBlobInfo[id].retractable;
    }

    function getDisownable(bytes32 id) noValue exists(id) constant external returns (bool disownable) {
        disownable = idBlobInfo[id].disownable;
    }

    function getNumRevisions(bytes32 id) noValue exists(id) constant external returns (uint32 numRevisions) {
        numRevisions = idBlobInfo[id].numRevisions;
    }

    function getRevisionBlockNumber(bytes32 id, uint revisionId) noValue exists(id) revisionExists(id, revisionId) constant returns (uint blockNumber) {
        if (revisionId == 0) {
            blockNumber = idBlobInfo[id].blockNumber;
        }
        else {
            bytes32 slot = idPackedRevisionBlockNumbers[id][(revisionId - 1) / 8];
            blockNumber = uint32(uint256(slot) / 2 ** (((revisionId - 1) % 8) * 32));
        }
    }

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

}


Updates

Updates

pragma solidity ^0.4.10;
contract Registrar {
    function entries(bytes32 _hash) constant returns (uint, address, uint, uint, uint);
    function transfer(bytes32 _hash, address newOwner);
}

contract Deed {
    address public registrar;
    function getCreationDate() constant returns(uint);
    uint public creationDate;
    address public owner;
    address public previousOwner;
    uint public value;
    function Deed(address _owner);
    function setOwner(address newOwner);
    function setRegistrar(address newRegistrar);
    function setBalance(uint newValue, bool throwOnFailure);
    function closeDeed(uint refundRatio);
    function destroyDeed();
}

contract ENSTrade {
    struct Record {
        string name;
        bool listed;
        uint buyPrice;
        bytes32 nextRecord;
        bytes32 previousRecord;
        string message;
    }

    struct RecordOffers {
        address lastOffer;
        uint totalOfferCount;
        uint totalOfferValue;
    }

    struct Offer {
        address nextOffer;
        address previousOffer;
        uint value;
        string message;
    }

    event TradeComplete(bytes32 indexed hash, address from, address to, uint256 value);
    event OfferCreated(bytes32 indexed hash, address from, uint256 value);
    event OfferCancelled(bytes32 indexed hash, address from);
    event ListingCreated(bytes32 indexed hash, address from, uint256 buyPrice);
    event ListingRemoved(bytes32 indexed hash, address from);
    event RecordReclaimed(bytes32 indexed hash, address to);

    address feeAddress;
    uint public fee = 0; // Out of 10000 (0% for alpha)
    uint public minimumOfferPrice = 0.01 ether;

    uint public recordsCurrentlyListed;
    uint public totalRecordsTraded;
    uint public totalValueTraded;

    Registrar registrar;

    mapping (bytes32 => Record) records;
    mapping (bytes32 => mapping (address => Offer)) offers;
    mapping (bytes32 => RecordOffers) recordOffers;
    bytes32 public lastRecord;

    modifier onlyOwner(bytes32 _hash) {
        // Check who owns the name using the previousOwner() function, as ens.trade should currently owns it.
        var (,_deedAddress,,,) = registrar.entries(_hash);
        Deed d = Deed(_deedAddress);
        if (d.owner() != address(this)) throw;
        if (d.previousOwner() != msg.sender) throw;
        _;
    }

    modifier onlyFeeAddress {
        if (msg.sender != feeAddress) throw;
        _;
    }

    function ENSTrade(Registrar _registrarAddress) {
        feeAddress = msg.sender;
        registrar = Registrar(_registrarAddress);
    }
    function setFeeAddress(address _feeAddress) onlyFeeAddress {
        feeAddress = _feeAddress;
    }
    function setMinimumOfferPrice(uint _minimumOfferPrice) onlyFeeAddress {
        minimumOfferPrice = _minimumOfferPrice;
    }
    function setFee(uint _fee) onlyFeeAddress {
        if (_fee > 500) throw; // Maximum 5%
        fee = _fee;
    }

    function sha(string _string) constant returns(bytes32) {
        return sha3(_string);
    }

    function newListing(string _name, uint256 _buyPrice, string _message) {
        // Hashes the name and checks that the sender previously owned it
        bytes32 _hash = sha3(_name);
        Deed d = getDeed(_hash);
        if (d.owner() != address(this)) throw;
        if (d.previousOwner() != msg.sender) throw;
        if (_buyPrice == 0 || _buyPrice < minimumOfferPrice) throw; // For extra security

        Record r = records[_hash];
        if (lastRecord != 0x0) {
            records[lastRecord].nextRecord = _hash;
        }
        r.previousRecord = lastRecord;
        r.listed = true;
        r.name = _name;
        r.buyPrice = _buyPrice;
        r.message = _message;
        lastRecord = _hash;
        recordsCurrentlyListed++;

        ListingCreated(_hash, msg.sender, _buyPrice);
    }

    function deList(bytes32 _hash) onlyOwner(_hash) {
        Record r = records[_hash];
        if (r.listed) {
            deleteRecord(_hash);
            ListingRemoved(_hash, msg.sender);
        }
    }

    function reclaim(bytes32 _hash) onlyOwner(_hash) {
        Record r = records[_hash];
        registrar.transfer(_hash, msg.sender);
        if (r.listed) {
            deleteRecord(_hash);
            ListingRemoved(_hash, msg.sender);
        }
        RecordReclaimed(_hash, msg.sender);
    }

    function deleteRecord(bytes32 _hash) internal {
        Record r = records[_hash];
        records[r.previousRecord].nextRecord = r.nextRecord;
        if (_hash == lastRecord) {
            lastRecord = r.previousRecord;
        }
        delete records[_hash];
        recordsCurrentlyListed--;
    }

    function newOffer(bytes32 _hash, string _message) payable {
        if (msg.value == 0) throw;
        Offer o = offers[_hash][msg.sender];
        if (o.value > 0) throw; // Offer exists
        Record r = records[_hash];
        if (msg.value >= r.buyPrice && r.buyPrice != 0) {
            // Offer is above asking price, finish trade
            transferRecord(_hash, msg.sender, msg.value);
            return;
        }
        if (msg.value < minimumOfferPrice) throw;
        o.value = msg.value;
        o.message = _message;

        RecordOffers ro = recordOffers[_hash];
        if (ro.lastOffer != 0x0) {
            offers[_hash][ro.lastOffer].nextOffer = msg.sender;
        }
        o.previousOffer = ro.lastOffer;
        ro.lastOffer = msg.sender;
        ro.totalOfferCount++;
        ro.totalOfferValue += msg.value;

        OfferCreated(_hash, msg.sender, msg.value);
    }

    function cancelOffer(bytes32 _hash) {
        Offer o = offers[_hash][msg.sender];
        if (o.value == 0) throw;
        uint valueToSend = o.value;
        deleteOffer(_hash, msg.sender);
        msg.sender.transfer(valueToSend);

        OfferCancelled(_hash, msg.sender);
    }

    function acceptOffer(bytes32 _hash, address _offerAddress, uint256 _offerValue) onlyOwner(_hash) {
        Offer o = offers[_hash][_offerAddress];
        if (o.value != _offerValue || o.value == 0) throw; // For extra security and race conditions

        Record r = records[_hash];
        if (!r.listed) throw;

        transferRecord(_hash, _offerAddress, o.value);
        deleteOffer(_hash, _offerAddress);
    }

    function deleteOffer(bytes32 _hash, address _offerAddress) internal {
        RecordOffers ro = recordOffers[_hash];
        Offer o = offers[_hash][_offerAddress];
        offers[_hash][o.previousOffer].nextOffer = o.nextOffer;
        if (ro.lastOffer == _offerAddress) {
            ro.lastOffer = o.previousOffer;
        }
        ro.totalOfferCount--;
        ro.totalOfferValue -= offers[_hash][_offerAddress].value;
        delete offers[_hash][_offerAddress];
    }

    function getDeed(bytes32 _hash) constant internal returns (Deed) {
        var (,_deedAddress,,,) = registrar.entries(_hash);
        return Deed(_deedAddress);
    }

    function transferRecord(bytes32 _hash, address _toAddress, uint256 _value) internal {
        uint _fee = _value * fee / 10000;
        // Deed d = Deed(_deedAddress);
        totalRecordsTraded++;
        totalValueTraded += _value;

        Deed d = getDeed(_hash);
        address _previousOwner = d.previousOwner();

        registrar.transfer(_hash, _toAddress);
        deleteRecord(_hash);

        _previousOwner.transfer(_value - _fee);
        feeAddress.transfer(_fee);

        TradeComplete(_hash, _previousOwner, _toAddress, _value);
    }

    function getBuyPriceAndPreviousRecord(bytes32 _hash) constant returns (uint256, bytes32) {
        // For quick iterating on the home page
        Record r = records[_hash];
        return (r.buyPrice, r.previousRecord);
    }

    function getRecord(bytes32 _hash) constant returns(bool, string, uint256, bytes32, bytes32, string) {
        Record r = records[_hash];
        return (r.listed, r.name, r.buyPrice, r.nextRecord, r.previousRecord, r.message);
    }

    function getFullRecord(bytes32 _hash) constant returns(bool, string, uint256, bytes32, bytes32, string, address, address, uint256, uint256) {
        Record r = records[_hash];
        Deed d = getDeed(_hash);
        return (r.listed, r.name, r.buyPrice, r.nextRecord, r.previousRecord, r.message, d.owner(), d.previousOwner(), d.value(), d.creationDate());
    }

    function getRecordOffers(bytes32 _hash) constant returns(address, uint256, uint256) {
        RecordOffers ro = recordOffers[_hash];
        return (ro.lastOffer, ro.totalOfferCount, ro.totalOfferValue);
    }

    function getOffer(bytes32 _hash, address _offerAddress) constant returns(address, address, uint256, string) {
        Offer o = offers[_hash][_offerAddress];
        return (o.nextOffer, o.previousOffer, o.value, o.message);
    }
}

pragma solidity ^0.4.10;
contract Registrar {
    function entries(bytes32 _hash) constant returns (uint, address, uint, uint, uint);
    function transfer(bytes32 _hash, address newOwner);
}

contract Deed {
    address public registrar;
    function getCreationDate() constant returns(uint);
    uint public creationDate;
    address public owner;
    address public previousOwner;
    uint public value;
    function Deed(address _owner);
    function setOwner(address newOwner);
    function setRegistrar(address newRegistrar);
    function setBalance(uint newValue, bool throwOnFailure);
    function closeDeed(uint refundRatio);
    function destroyDeed();
}

contract ENSTrade {
    struct Record {
        string name;
        bool listed;
        uint buyPrice;
        bytes32 nextRecord;
        bytes32 previousRecord;
        string message;
    }

    struct RecordOffers {
        address lastOffer;
        uint totalOfferCount;
        uint totalOfferValue;
    }

    struct Offer {
        address nextOffer;
        address previousOffer;
        uint value;
        string message;
    }

    event TradeComplete(bytes32 indexed hash, address from, address to, uint value);
    event OfferCreated(bytes32 indexed hash, address from, uint value);
    event OfferCancelled(bytes32 indexed hash, address from);
    event ListingCreated(bytes32 indexed hash, address from, uint buyPrice);
    event ListingRemoved(bytes32 indexed hash, address from);
    event RecordReclaimed(bytes32 indexed hash, address to);

    address feeAddress;
    uint public fee = 0; // Out of 10000 (0% for alpha)
    uint public minimumOfferPrice = 0.01 ether;

    uint public recordsCurrentlyListed;
    uint public totalRecordsTraded;
    uint public totalValueTraded;

    Registrar registrar;

    mapping (bytes32 => Record) records;
    mapping (bytes32 => mapping (address => Offer)) offers;
    mapping (bytes32 => RecordOffers) recordOffers;
    bytes32 public lastRecord;

    modifier onlyOwner(bytes32 _hash) {
        // Check who owns the name using the previousOwner() function, as ens.trade should currently owns it.
        var (,_deedAddress,,,) = registrar.entries(_hash);
        Deed d = Deed(_deedAddress);
        if (d.owner() != address(this)) throw;
        if (d.previousOwner() != msg.sender) throw;
        _;
    }

    modifier onlyFeeAddress {
        if (msg.sender != feeAddress) throw;
        _;
    }

    function ENSTrade(Registrar _registrarAddress) {
        feeAddress = msg.sender;
        registrar = Registrar(_registrarAddress);
    }
    function setFeeAddress(address _feeAddress) onlyFeeAddress {
        feeAddress = _feeAddress;
    }
    function setMinimumOfferPrice(uint _minimumOfferPrice) onlyFeeAddress {
        minimumOfferPrice = _minimumOfferPrice;
    }
    function setFee(uint _fee) onlyFeeAddress {
        if (_fee > 500) throw; // Maximum 5%
        fee = _fee;
    }

    function sha(string _string) constant returns(bytes32) {
        return sha3(_string);
    }

    function newListing(string _name, uint _buyPrice, string _message) {
        // Hashes the name and checks that the sender previously owned it
        bytes32 _hash = sha3(_name);
        var (,_deedAddress,,,) = registrar.entries(_hash);
        Deed d = Deed(_deedAddress);
        if (d.owner() != address(this)) throw;
        if (d.previousOwner() != msg.sender) throw;
        if (_buyPrice == 0 || _buyPrice < minimumOfferPrice) throw; // For extra security

        Record r = records[_hash];
        if (lastRecord != 0x0) {
            records[lastRecord].nextRecord = _hash;
        }
        r.previousRecord = lastRecord;
        r.listed = true;
        r.name = _name;
        r.buyPrice = _buyPrice;
        r.message = _message;
        lastRecord = _hash;
        recordsCurrentlyListed++;

        ListingCreated(_hash, msg.sender, _buyPrice);
    }

    function deList(bytes32 _hash) onlyOwner(_hash) {
        Record r = records[_hash];
        if (r.listed) {
            deleteRecord(_hash);
            ListingRemoved(_hash, msg.sender);
        }
    }

    function reclaim(bytes32 _hash) onlyOwner(_hash) {
        Record r = records[_hash];
        registrar.transfer(_hash, msg.sender);
        if (r.listed) {
            deleteRecord(_hash);
            ListingRemoved(_hash, msg.sender);
        }
        RecordReclaimed(_hash, msg.sender);
    }

    function deleteRecord(bytes32 _hash) internal {
        Record r = records[_hash];
        records[r.previousRecord].nextRecord = r.nextRecord;
        if (_hash == lastRecord) {
            lastRecord = r.previousRecord;
        }
        delete records[_hash];
        recordsCurrentlyListed--;
    }

    function newOffer(bytes32 _hash, string _message) payable {
        if (msg.value == 0) throw;
        Offer o = offers[_hash][msg.sender];
        if (o.value > 0) throw; // Offer exists
        Record r = records[_hash];
        if (msg.value >= r.buyPrice && r.buyPrice != 0) {
            // Offer is above asking price, finish trade
            transferRecord(_hash, msg.sender, msg.value);
            return;
        }
        if (msg.value < minimumOfferPrice) throw;
        o.value = msg.value;
        o.message = _message;

        RecordOffers ro = recordOffers[_hash];
        if (ro.lastOffer != 0x0) {
            offers[_hash][ro.lastOffer].nextOffer = msg.sender;
        }
        o.previousOffer = ro.lastOffer;
        ro.lastOffer = msg.sender;
        ro.totalOfferCount++;
        ro.totalOfferValue += msg.value;

        OfferCreated(_hash, msg.sender, msg.value);
    }

    function cancelOffer(bytes32 _hash) {
        Offer o = offers[_hash][msg.sender];
        if (o.value == 0) throw;
        uint valueToSend = o.value;
        deleteOffer(_hash, msg.sender);
        msg.sender.transfer(valueToSend);

        OfferCancelled(_hash, msg.sender);
    }

    function acceptOffer(bytes32 _hash, address _offerAddress, uint256 _offerValue) onlyOwner(_hash) {
        Offer o = offers[_hash][_offerAddress];
        if (o.value != _offerValue || o.value == 0) throw; // For extra security and race conditions

        Record r = records[_hash];
        if (!r.listed) throw;

        transferRecord(_hash, _offerAddress, o.value);
        deleteOffer(_hash, _offerAddress);
    }

    function deleteOffer(bytes32 _hash, address _offerAddress) internal {
        RecordOffers ro = recordOffers[_hash];
        Offer o = offers[_hash][_offerAddress];
        offers[_hash][o.previousOffer].nextOffer = o.nextOffer;
        if (ro.lastOffer == _offerAddress) {
            ro.lastOffer = o.previousOffer;
        }
        ro.totalOfferCount--;
        ro.totalOfferValue -= offers[_hash][_offerAddress].value;
        delete offers[_hash][_offerAddress];
    }

    function transferRecord(bytes32 _hash, address _toAddress, uint256 _value) internal {
        uint _fee = _value * fee / 10000;
        // Deed d = Deed(_deedAddress);
        totalRecordsTraded++;
        totalValueTraded += _value;

        registrar.transfer(_hash, _toAddress);
        // d.setOwner(_toAddress);
        deleteRecord(_hash);

        var (,_deedAddress,,,) = registrar.entries(_hash);
        Deed d = Deed(_deedAddress);
        d.previousOwner().transfer(_value - _fee);
        feeAddress.transfer(_fee);

        TradeComplete(_hash, d.previousOwner(), _toAddress, _value);
    }

    function getBuyPriceAndPreviousRecord(bytes32 _hash) constant returns (uint256, bytes32) {
        // For quick iterating on the home page
        Record r = records[_hash];
        return (r.buyPrice, r.previousRecord);
    }

    function getRecord(bytes32 _hash) constant returns(bool, string, uint256, bytes32, bytes32, string) {
        Record r = records[_hash];
        return (r.listed, r.name, r.buyPrice, r.nextRecord, r.previousRecord, r.message);
    }

    function getFullRecord(bytes32 _hash) constant returns(bool, string, uint256, bytes32, bytes32, string, address, address, uint256, uint256) {
        Record r = records[_hash];
        var (,_deedAddress,,,) = registrar.entries(_hash);
        Deed d = Deed(_deedAddress);
        return (r.listed, r.name, r.buyPrice, r.nextRecord, r.previousRecord, r.message, d.owner(), d.previousOwner(), d.value(), d.creationDate());
    }

    function getRecordOffers(bytes32 _hash) constant returns(address, uint256, uint256) {
        RecordOffers ro = recordOffers[_hash];
        return (ro.lastOffer, ro.totalOfferCount, ro.totalOfferValue);
    }

    function getOffer(bytes32 _hash, address _offerAddress) constant returns(address, address, uint256, string) {
        Offer o = offers[_hash][_offerAddress];
        return (o.nextOffer, o.previousOffer, o.value, o.message);
    }
}


updated send function

updated send function

/// @author hugooconnor
/// @title A shared account to demo some features of solidity, with standard tokens
/// see how to document solidity code; https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format

contract Access {

	/**
	 * Data structures
	 * members -- an array of addresses, useful for looping over
	 * member -- a mapping of addresses to Member objects
	 * Member -- a struct containing member details
   * tokenSupply -- how many tokens on issue
   * tokens -- mapping of addresses to tokens
	 */
  address[] public members;
  mapping(address => Member) public member;

  struct Member {
        uint joinDate;
        bool exists;
        bool isSpecial;
  }

  uint tokenSupply;
  mapping(address => uint) public tokens;

  	/**
	 * Events: a cheaper option than storing all data on chain - append Log to events for clarity
	 * NewMember -- will call when new member joins
	 * Spend -- will call when contract funds spent
   * Transfer -- will call when token is transfered
	 */
  event NewMemberLog(address admin, address newMember, uint joinDate, bool exists, bool isSpecial);
  event SpendLog(uint date, address recipient, uint amount);
  event TransferLog(uint date, address sender, address recipient, uint amount);

	/**
	 * Constructor -- adds msg.sender to membership, sets them as special
	 */
  function Access(){
        member[msg.sender] = Member(now, true, true);
        members.push(msg.sender);
        NewMemberLog(msg.sender, msg.sender, member[msg.sender].joinDate, member[msg.sender].exists, member[msg.sender].isSpecial);
        tokens[msg.sender] += 1000;
        tokenSupply += 1000;
  }

  	/**
	 * Function modifier -- only special members can execute _ block
	 */
  modifier onlySpecial {
      if (member[msg.sender].isSpecial) {
        _
      }
  }

	/// @notice Adds new members or sets existing members to special, onlySpecial can call
	/// @param _nominee the person we are adding as a member
	///	@param _isSpecial if they are special or not
	/// @return success if state changes
  function addMember(address _nominee, bool _isSpecial) onlySpecial returns (bool success){
  		if(!member[_nominee].exists){
            member[_nominee] = Member(now, true, _isSpecial);
            members.push(_nominee);
            tokens[_nominee] += 1000;
            tokenSupply += 1000;
            NewMemberLog(msg.sender, _nominee, member[_nominee].joinDate, member[_nominee].exists, member[_nominee].isSpecial);
            return true;
  		} else if (member[_nominee].exists && _isSpecial){
            member[_nominee].isSpecial = _isSpecial;
            return true;
  		}
        return false;
  }

	/// @notice Spends contract funds, onlySpecial can call
	/// @param _recipient who is recieving the funds
	/// @param _amount how much they are getting
	/// @return success if funds are sent
  function spend(address _recipient, uint _amount) onlySpecial returns (bool success){
  		if(this.balance >= _amount){
            if(_recipient.send(_amount)){
              SpendLog(now, _recipient, _amount);
              return true;
            }
            return false;
  		} else {
            return false;
  		}
  }

  /// @notice Gets total supply of issued tokens
  /// @return supply how many tokens are on issue
  function totalSupply() constant returns (uint256 supply){
    return tokenSupply;
  }

  /// @notice Gets the token balance of an address
  /// @param _owner whose address are we looking up
  /// @return balance how many tokens they have
  function balanceOf(address _owner) constant returns (uint256 balance){
    return tokens[_owner];
  }

  /// @notice transfers tokens between users
  /// @param _to who is the transfer to
  /// @param _value how many tokens are they transferring
  /// @return success if the transfer is successful or not
  function transfer(address _to, uint256 _value) returns (bool success){
    if(tokens[msg.sender] >= _value){
      tokens[msg.sender] -= _value;
      tokens[_to] += _value;
      TransferLog(now, msg.sender, _to, _value);
      return true;
    }
    return false;
  }
}

/// @author hugooconnor
/// @title A shared account to demo some features of solidity, with standard tokens
/// see how to document solidity code; https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format

contract Access {

	/**
	 * Data structures
	 * members -- an array of addresses, useful for looping over
	 * member -- a mapping of addresses to Member objects
	 * Member -- a struct containing member details
   * tokenSupply -- how many tokens on issue
   * tokens -- mapping of addresses to tokens
	 */
  address[] public members;
  mapping(address => Member) public member;

  struct Member {
        uint joinDate;
        bool exists;
        bool isSpecial;
  }

  uint tokenSupply;
  mapping(address => uint) public tokens;

  	/**
	 * Events: a cheaper option than storing all data on chain - append Log to events for clarity
	 * NewMember -- will call when new member joins
	 * Spend -- will call when contract funds spent
   * Transfer -- will call when token is transfered
	 */
  event NewMemberLog(address admin, address newMember, uint joinDate, bool exists, bool isSpecial);
  event SpendLog(uint date, address recipient, uint amount);
  event TransferLog(uint date, address sender, address recipient, uint amount);

	/**
	 * Constructor -- adds msg.sender to membership, sets them as special
	 */
  function Access(){
        member[msg.sender] = Member(now, true, true);
        members.push(msg.sender);
        NewMemberLog(msg.sender, msg.sender, member[msg.sender].joinDate, member[msg.sender].exists, member[msg.sender].isSpecial);
        tokens[msg.sender] += 1000;
        tokenSupply += 1000;
  }

  	/**
	 * Function modifier -- only special members can execute _ block
	 */
  modifier onlySpecial {
      if (member[msg.sender].isSpecial) {
        _
      }
  }

	/// @notice Adds new members or sets existing members to special, onlySpecial can call
	/// @param _nominee the person we are adding as a member
	///	@param _isSpecial if they are special or not
	/// @return success if state changes
  function addMember(address _nominee, bool _isSpecial) onlySpecial returns (bool success){
  		if(!member[_nominee].exists){
            member[_nominee] = Member(now, true, _isSpecial);
            members.push(_nominee);
            tokens[_nominee] += 1000;
            tokenSupply += 1000;
            NewMemberLog(msg.sender, _nominee, member[_nominee].joinDate, member[_nominee].exists, member[_nominee].isSpecial);
            return true;
  		} else if (member[_nominee].exists && _isSpecial){
            member[_nominee].isSpecial = _isSpecial;
            return true;
  		}
        return false;
  }

	/// @notice Spends contract funds, onlySpecial can call
	/// @param _recipient who is recieving the funds
	/// @param _amount how much they are getting
	/// @return success if funds are sent
  function spend(address _recipient, uint _amount) onlySpecial returns (bool success){
  		if(this.balance >= _amount){
            _recipient.send(_amount);
            SpendLog(now, _recipient, _amount);
            return true;
  		} else {
            return false;
  		}
  }

  /// @notice Gets total supply of issued tokens
  /// @return supply how many tokens are on issue
  function totalSupply() constant returns (uint256 supply){
    return tokenSupply;
  }

  /// @notice Gets the token balance of an address
  /// @param _owner whose address are we looking up
  /// @return balance how many tokens they have
  function balanceOf(address _owner) constant returns (uint256 balance){
    return tokens[_owner];
  }

  /// @notice transfers tokens between users
  /// @param _to who is the transfer to
  /// @param _value how many tokens are they transferring
  /// @return success if the transfer is successful or not
  function transfer(address _to, uint256 _value) returns (bool success){
    if(tokens[msg.sender] >= _value){
      tokens[msg.sender] -= _value;
      tokens[_to] += _value;
      TransferLog(now, msg.sender, _to, _value);
      return true;
    }
    return false;
  }
}