lang => language

lang => language

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

  enum GlofileType { Anon, Person, Project, Organization, Proxy, Parody, Bot }
  enum SafetyLevel { Safe, NSFW, NSFL }

  struct Glofile {
    bool dontIndex;
    GlofileType glofileType;
    SafetyLevel safetyLevel;
    string fullName;
    string location;
    bytes3[] foregroundColors;
    bytes3[] backgroundColors;
    bytes3[] languages;
    bytes3[] bioLanguages;
    bytes[] avatars;
    bytes[] coverImages;
    bytes[] backgroundImages;
    string[] topics;
    string[] parents;
    string[] children;
    string[] uris;
    mapping (bytes3 => bytes) bioTranslations;
  }

  mapping (address => Glofile) glofiles;

  event Update(address indexed account);
  event Delete(address indexed account);

  /**
   * @notice Set your Glofile don't index flag to `dontIndex`
   * @dev Sets the "don't index" flag. Glofiles with this flag set should only be accessible directly and not be discoverable via search.
   * @param dontIndex flag to indicate that this Glofile should not be indexed
   */
  function setDontIndex(bool dontIndex) {
    glofiles[msg.sender].dontIndex = dontIndex;
    Update(msg.sender);
  }

  /**
   * @notice Set your Glofile type to `glofileType`
   * @dev Sets the Glofile type.
   * @param glofileType Glofile type
   */
  function setGlofileType(GlofileType glofileType) {
    glofiles[msg.sender].glofileType = glofileType;
    Update(msg.sender);
  }

  /**
   * @notice Set your Glofile safety level to `safetyLevel`
   * @dev Sets the safety level. The account may publish content that is less safe than this, so long as it is flagged as such.
   * @param safetyLevel safety level
   */
  function setSafetyLevel(SafetyLevel safetyLevel) {
    glofiles[msg.sender].safetyLevel = safetyLevel;
    Update(msg.sender);
  }

  /**
   * @notice Set your Glofile full name to `fullName`
   * @dev Sets the full name.
   * @param fullName UTF-8 string of full name - max length 128 chars
   */
  function setFullName(string fullName) {
    glofiles[msg.sender].fullName = fullName;
    Update(msg.sender);
  }

  /**
   * @notice Set your Glofile location
   * @dev Sets the location. A dedicated contract could be used for more sophisticated location functionality.
   * @param location UTF-8 string of location - max string length 128 chars
   */
  function setLocation(string location) {
    glofiles[msg.sender].location = location;
    Update(msg.sender);
  }

  /**
   * @notice Set your Glofile foreground colors
   * @dev Sets all the foreground colors.
   * @param colors array of RGB triplets
   */
  function setForegroundColors(bytes3[] colors) {
    glofiles[msg.sender].foregroundColors = colors;
    Update(msg.sender);
  }

  /**
   * @notice Set your Glofile background colors
   * @dev Sets all the background colors.
   * @param colors array of RGB triplets
   */
  function setBackgroundColors(bytes3[] colors) {
    glofiles[msg.sender].backgroundColors = colors;
    Update(msg.sender);
  }

  /**
   * @notice Sets the Glofile langauges your account may publish in
   * @dev Sets all the languages the account may publish in.
   * @param languages array of 3 letter ISO 639-3 language codes
   */
  function setLanguages(bytes3[] languages) {
    glofiles[msg.sender].languages = languages;
    Update(msg.sender);
  }

  /**
   * @notice Get Glofile basic info
   * @dev Gets all the info that can be retreived in a single call.
   * @param account Glofile to access
   * @return dontIndex flag to indicate that this Glofile should not be indexed
   * @return glofileType Glofile type
   * @return safetyLevel safety level
   * @return fullName UTF-8 string of full name
   * @return location UTF-8 string of location
   * @return foregroundColors array of RGB triplets of foreground colors
   * @return backgroundColors array of RGB triplets of background colors
   * @return languages array of 3 letter ISO 639-3 language codes
   */
  function getBasicInfo(address account) constant returns (bool dontIndex, GlofileType glofileType, SafetyLevel safetyLevel, string fullName, string location, bytes3[] foregroundColors, bytes3[] backgroundColors, bytes3[] languages) {
    Glofile glofile = glofiles[account];
    dontIndex = glofile.dontIndex;
    glofileType = glofile.glofileType;
    safetyLevel = glofile.safetyLevel;
    fullName = glofile.fullName;
    location = glofile.location;
    foregroundColors = glofile.foregroundColors;
    backgroundColors = glofile.backgroundColors;
    languages = glofile.languages;
  }

  /**
   * @notice Set your Glofile bio with langauge code `language`
   * @dev Sets the bio in a specific language.
   * @param language 3 letter ISO 639-3 language code
   * @param translation UTF-8 Markdown of bio compressed with DEFLATE - max Markdown length 256 chars
   */
  function setBio(bytes3 language, bytes translation) {
    Glofile glofile = glofiles[msg.sender];
    // Check if we already have the language code.
    for (uint i = 0; i < glofile.bioLanguages.length; i++) {
      if (glofile.bioLanguages[i] == language) {
        break;
      }
    }
    if (i == glofile.bioLanguages.length) {
      // We didn't find it. Try to find a free slot.
      for (i = 0; i < glofile.bioLanguages.length; i++) {
        if (glofile.bioLanguages[i] == 0) {
          break;
        }
      }
      if (i == glofile.bioLanguages.length) {
        // We didn't find a free slot. Make the array bigger.
        glofile.bioLanguages.length++;
      }
      glofile.bioLanguages[i] = language;
    }
    // Set translation.
    glofile.bioTranslations[language] = translation;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile bio with language code `language`
   * @dev Deletes a bio translation.
   * @param language 3 letter ISO 639-3 language code
   */
  function deleteBio(bytes3 language) {
    Glofile glofile = glofiles[msg.sender];
    for (uint i = 0; i < glofile.bioLanguages.length; i++) {
      if (glofile.bioLanguages[i] == language) {
        delete glofile.bioLanguages[i];
        break;
      }
    }
    // Delete the actual mapping in case a client accesses without checking
    // language key.
    delete glofile.bioTranslations[language];
    Update(msg.sender);
  }

  /**
   * @notice Delete all of your Glofile bio translations
   * @dev Deletes all of the bio translations.
   */
  function deleteAllBioTranslations() {
    Glofile glofile = glofiles[msg.sender];
    // Delete the actual mappings in case a client accesses without checking
    // language key.
    for (uint i = 0; i < glofile.bioLanguages.length; i++) {
      delete glofile.bioTranslations[glofile.bioLanguages[i]];
    }
    delete glofile.bioLanguages;
    Update(msg.sender);
  }

  /**
   * @notice Get the list of language code a Glofile bio is available in
   * @dev Gets the list of language codes the bio is available in.
   * @param account Glofile to access
   * @return array of 3 letter ISO 639-3 language codes
   */
  function getBioLanguages(address account) constant returns (bytes3[]) {
    return glofiles[account].bioLanguages;
  }

  /**
   * @notice Get the Glofile bio with language code `language`
   * @dev Gets the bio in a specific language.
   * @param account Glofile to access
   * @param language 3 letter ISO 639-3 language code
   * @return UTF-8 Markdown of bio compressed with DEFLATE
   */
  function getBio(address account, bytes3 language) constant returns (bytes) {
    return glofiles[account].bioTranslations[language];
  }

  /**
   * @notice Set your Glofile avatar with index `i` to `ipfsHash`
   * @dev Sets the avatar with a specific index to an IPFS hash.
   * @param i index of avatar to set
   * @param ipfsHash binary IPFS hash of image
   */
  function setAvatar(uint i, bytes ipfsHash) {
    bytes[] avatars = glofiles[msg.sender].avatars;
    // Make sure the array is long enough.
    if (avatars.length <= i) {
      avatars.length = i + 1;
    }
    avatars[i] = ipfsHash;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile avatar with index `i`
   * @dev Deletes an avatar with a specific index.
   * @param i index of avatar to delete
   */
  function deleteAvatar(uint i) {
    delete glofiles[msg.sender].avatars[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile avatars
   * @dev Deletes all avatars from the Glofile.
   */
  function deleteAllAvatars() {
    delete glofiles[msg.sender].avatars;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile avatars
   * @dev Gets the number of avatars.
   * @param account Glofile to access
   * @return number of avatars
   */
  function getAvatarCount(address account) constant returns (uint) {
    return glofiles[account].avatars.length;
  }

  /**
   * @notice Get the Glofile avatar with index `i`
   * @dev Gets the avatar with a specific index.
   * @param account Glofile to access
   * @param i index of avatar to get
   * @return binary IPFS hash of image
   */
  function getAvatar(address account, uint i) constant returns (bytes) {
    return glofiles[account].avatars[i];
  }

  /**
   * @notice Set your Glofile cover image with index `i` to `ipfsHash`
   * @dev Sets the cover image with a specific index to an IPFS hash.
   * @param i index of cover image to set
   * @param ipfsHash binary IPFS hash of image
   */
  function setCoverImage(uint i, bytes ipfsHash) {
    bytes[] coverImages = glofiles[msg.sender].coverImages;
    // Make sure the array is long enough.
    if (coverImages.length <= i) {
      coverImages.length = i + 1;
    }
    coverImages[i] = ipfsHash;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile cover image with index `i`
   * @dev Deletes the cover image with a specific index.
   * @param i index of cover image to delete
   */
  function deleteCoverImage(uint i) {
    delete glofiles[msg.sender].coverImages[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile cover images
   * @dev Deletes all cover images from the Glofile.
   */
  function deleteAllCoverImages() {
    delete glofiles[msg.sender].coverImages;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile cover images
   * @dev Gets the number of cover images.
   * @param account Glofile to access
   * @return number of cover images
   */
  function getCoverImageCount(address account) constant returns (uint) {
    return glofiles[account].coverImages.length;
  }

  /**
   * @notice Get the Glofile cover image with index `i`
   * @dev Gets the cover image with a specific index.
   * @param account Glofile to access
   * @param i index of cover image to get
   * @return binary IPFS hash of image
   */
  function getCoverImage(address account, uint i) constant returns (bytes) {
    return glofiles[account].coverImages[i];
  }

  /**
   * @notice Set your Glofile background image with index `i` to `ipfsHash`
   * @dev Sets the background image with a specific index to an IPFS hash.
   * @param i index of background image to set
   * @param ipfsHash binary IPFS hash of image
   */
  function setBackgroundImage(uint i, bytes ipfsHash) {
    bytes[] backgroundImages = glofiles[msg.sender].backgroundImages;
    // Make sure the array is long enough.
    if (backgroundImages.length <= i) {
      backgroundImages.length = i + 1;
    }
    backgroundImages[i] = ipfsHash;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile background image with index `i`
   * @dev Deletes the background image with a specific index.
   * @param i index of background image to delete
   */
  function deleteBackgroundImage(uint i) {
    delete glofiles[msg.sender].backgroundImages[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile background images
   * @dev Deletes all the background images.
   */
  function deleteAllBackgroundImages() {
    delete glofiles[msg.sender].backgroundImages;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile background images
   * @dev Gets the number of background images.
   * @param account Glofile to access
   * @return number of background images
   */
  function getBackgroundImageCount(address account) constant returns (uint) {
    return glofiles[account].backgroundImages.length;
  }

  /**
   * @notice Get the Glofile background image with index `i`
   * @dev Gets the background image with a specific index.
   * @param i index of cover image to get
   * @param account Glofile to access
   * @return binary IPFS hash of image
   */
  function getBackgroundImage(address account, uint i) constant returns (bytes) {
    return glofiles[account].backgroundImages[i];
  }

  /**
   * @notice Set your Glofile topic with index `i` to `topic`
   * @dev Sets the topic with a specific index.
   * @param i index of topic to set
   * @param topic UTF-8 string of topic (no whitespace)
   */
  function setTopic(uint i, string topic) {
    string[] topics = glofiles[msg.sender].topics;
    // Make sure the array is long enough.
    if (topics.length <= i) {
      topics.length = i + 1;
    }
    topics[i] = topic;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile topic with index `i`
   * @dev Deletes an topic with a specific index.
   * @param i index of topic to delete
   */
  function deleteTopic(uint i) {
    delete glofiles[msg.sender].topics[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile topics
   * @dev Deletes all topics from the Glofile.
   */
  function deleteAllTopics() {
    delete glofiles[msg.sender].topics;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile topics
   * @dev Gets the number of topics.
   * @param account Glofile to access
   * @return number of topics
   */
  function getTopicCount(address account) constant returns (uint) {
    return glofiles[account].topics.length;
  }

  /**
   * @notice Get the Glofile topic with index `i`
   * @dev Gets the topic with a specific index.
   * @param account Glofile to access
   * @param i index of topic to get
   * @return UTF-8 string of topic
   */
  function getTopic(address account, uint i) constant returns (string) {
    return glofiles[account].topics[i];
  }

  /**
   * @notice Set your Glofile parent with index `i` to `parent`
   * @dev Sets the parent with a specific index.
   * @param i index of parent to set
   * @param parent UTF-8 string of parent
   */
  function setParent(uint i, string parent) {
    string[] parents = glofiles[msg.sender].parents;
    // Make sure the array is long enough.
    if (parents.length <= i) {
      parents.length = i + 1;
    }
    parents[i] = parent;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile parent with index `i`
   * @dev Deletes an parent with a specific index.
   * @param i index of parent to delete
   */
  function deleteParent(uint i) {
    delete glofiles[msg.sender].parents[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile parents
   * @dev Deletes all parents from the Glofile.
   */
  function deleteAllParents() {
    delete glofiles[msg.sender].parents;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile parents
   * @dev Gets the number of parents.
   * @param account Glofile to access
   * @return number of parents
   */
  function getParentCount(address account) constant returns (uint) {
    return glofiles[account].parents.length;
  }

  /**
   * @notice Get the Glofile parent with index `i`
   * @dev Gets the parent with a specific index.
   * @param account Glofile to access
   * @param i index of parent to get
   * @return UTF-8 string of parent
   */
  function getParent(address account, uint i) constant returns (string) {
    return glofiles[account].parents[i];
  }

  /**
   * @notice Set your Glofile child with index `i` to `child`
   * @dev Sets the child with a specific index.
   * @param i index of child to set
   * @param child UTF-8 string of child
   */
  function setChild(uint i, string child) {
    string[] children = glofiles[msg.sender].children;
    // Make sure the array is long enough.
    if (children.length <= i) {
      children.length = i + 1;
    }
    children[i] = child;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile child with index `i`
   * @dev Deletes an child with a specific index.
   * @param i index of child to delete
   */
  function deleteChild(uint i) {
    delete glofiles[msg.sender].children[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile children
   * @dev Deletes all children from the Glofile.
   */
  function deleteAllChildren() {
    delete glofiles[msg.sender].children;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile children
   * @dev Gets the number of children.
   * @param account Glofile to access
   * @return number of children
   */
  function getChildCount(address account) constant returns (uint) {
    return glofiles[account].children.length;
  }

  /**
   * @notice Get the Glofile child with index `i`
   * @dev Gets the child with a specific index.
   * @param account Glofile to access
   * @param i index of child to get
   * @return UTF-8 string of child
   */
  function getChild(address account, uint i) constant returns (string) {
    return glofiles[account].children[i];
  }

  /**
   * @notice Set your Glofile uri with index `i` to `uri`
   * @dev Sets the uri with a specific index.
   * @param i index of uri to set
   * @param uri UTF-8 string of uri
   */
  function setUri(uint i, string uri) {
    string[] uris = glofiles[msg.sender].uris;
    // Make sure the array is long enough.
    if (uris.length <= i) {
      uris.length = i + 1;
    }
    uris[i] = uri;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile uri with index `i`
   * @dev Deletes an uri with a specific index.
   * @param i index of uri to delete
   */
  function deleteUri(uint i) {
    delete glofiles[msg.sender].uris[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile uris
   * @dev Deletes all uris from the Glofile.
   */
  function deleteAllUris() {
    delete glofiles[msg.sender].uris;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile uris
   * @dev Gets the number of uris.
   * @param account Glofile to access
   * @return number of uris
   */
  function getUriCount(address account) constant returns (uint) {
    return glofiles[account].uris.length;
  }

  /**
   * @notice Get the Glofile uri with index `i`
   * @dev Gets the uri with a specific index.
   * @param account Glofile to access
   * @param i index of uri to get
   * @return UTF-8 string of uri
   */
  function getUri(address account, uint i) constant returns (string) {
    return glofiles[account].uris[i];
  }

  /**
   * @notice Copy entire Glofile from `source`
   * @dev Copies the Glofile from another account to this one.
   * @param source account of Glofile to copy from
   * TODO: check this works
   */
  function copyEntireGlofile(address source) {
    glofiles[msg.sender] = glofiles[source];
    Update(msg.sender);
  }

  /**
   * @notice Delete your entire Glofile
   * @dev Deletes the Glofile completely.
   * TODO: make sure this deletes everything
   */
  function deleteEntireGlofile() {
    delete glofiles[msg.sender];
    Delete(msg.sender);
  }

}

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

  enum GlofileType { Anon, Person, Project, Organization, Proxy, Parody, Bot }
  enum SafetyLevel { Safe, NSFW, NSFL }

  struct Glofile {
    bool dontIndex;
    GlofileType glofileType;
    SafetyLevel safetyLevel;
    string fullName;
    string location;
    bytes3[] foregroundColors;
    bytes3[] backgroundColors;
    bytes3[] languages;
    bytes3[] bioLangs;
    bytes[] avatars;
    bytes[] coverImages;
    bytes[] backgroundImages;
    string[] topics;
    string[] parents;
    string[] children;
    string[] uris;
    mapping (bytes3 => bytes) bioTranslations;
  }

  mapping (address => Glofile) glofiles;

  event Update(address indexed account);
  event Delete(address indexed account);

  /**
   * @notice Set your Glofile don't index flag to `dontIndex`
   * @dev Sets the "don't index" flag. Glofiles with this flag set should only be accessible directly and not be discoverable via search.
   * @param dontIndex flag to indicate that this Glofile should not be indexed
   */
  function setDontIndex(bool dontIndex) {
    glofiles[msg.sender].dontIndex = dontIndex;
    Update(msg.sender);
  }

  /**
   * @notice Set your Glofile type to `glofileType`
   * @dev Sets the Glofile type.
   * @param glofileType Glofile type
   */
  function setGlofileType(GlofileType glofileType) {
    glofiles[msg.sender].glofileType = glofileType;
    Update(msg.sender);
  }

  /**
   * @notice Set your Glofile safety level to `safetyLevel`
   * @dev Sets the safety level. The account may publish content that is less safe than this, so long as it is flagged as such.
   * @param safetyLevel safety level
   */
  function setSafetyLevel(SafetyLevel safetyLevel) {
    glofiles[msg.sender].safetyLevel = safetyLevel;
    Update(msg.sender);
  }

  /**
   * @notice Set your Glofile full name to `fullName`
   * @dev Sets the full name.
   * @param fullName UTF-8 string of full name - max length 128 chars
   */
  function setFullName(string fullName) {
    glofiles[msg.sender].fullName = fullName;
    Update(msg.sender);
  }

  /**
   * @notice Set your Glofile location
   * @dev Sets the location. A dedicated contract could be used for more sophisticated location functionality.
   * @param location UTF-8 string of location - max string length 128 chars
   */
  function setLocation(string location) {
    glofiles[msg.sender].location = location;
    Update(msg.sender);
  }

  /**
   * @notice Set your Glofile foreground colors
   * @dev Sets all the foreground colors.
   * @param colors array of RGB triplets
   */
  function setForegroundColors(bytes3[] colors) {
    glofiles[msg.sender].foregroundColors = colors;
    Update(msg.sender);
  }

  /**
   * @notice Set your Glofile background colors
   * @dev Sets all the background colors.
   * @param colors array of RGB triplets
   */
  function setBackgroundColors(bytes3[] colors) {
    glofiles[msg.sender].backgroundColors = colors;
    Update(msg.sender);
  }

  /**
   * @notice Sets the Glofile langauges your account may publish in
   * @dev Sets all the languages the account may publish in.
   * @param languages array of 3 letter ISO 639-3 language codes
   */
  function setLanguages(bytes3[] languages) {
    glofiles[msg.sender].languages = languages;
    Update(msg.sender);
  }

  /**
   * @notice Get Glofile basic info
   * @dev Gets all the info that can be retreived in a single call.
   * @param account Glofile to access
   * @return dontIndex flag to indicate that this Glofile should not be indexed
   * @return glofileType Glofile type
   * @return safetyLevel safety level
   * @return fullName UTF-8 string of full name
   * @return location UTF-8 string of location
   * @return foregroundColors array of RGB triplets of foreground colors
   * @return backgroundColors array of RGB triplets of background colors
   * @return languages array of 3 letter ISO 639-3 language codes
   */
  function getBasicInfo(address account) constant returns (bool dontIndex, GlofileType glofileType, SafetyLevel safetyLevel, string fullName, string location, bytes3[] foregroundColors, bytes3[] backgroundColors, bytes3[] languages) {
    Glofile glofile = glofiles[account];
    dontIndex = glofile.dontIndex;
    glofileType = glofile.glofileType;
    safetyLevel = glofile.safetyLevel;
    fullName = glofile.fullName;
    location = glofile.location;
    foregroundColors = glofile.foregroundColors;
    backgroundColors = glofile.backgroundColors;
    languages = glofile.languages;
  }

  /**
   * @notice Set your Glofile bio with langauge code `lang`
   * @dev Sets the bio in a specific language.
   * @param lang 3 letter ISO 639-3 language code
   * @param translation UTF-8 Markdown of bio compressed with DEFLATE - max Markdown length 256 chars
   */
  function setBio(bytes3 lang, bytes translation) {
    Glofile glofile = glofiles[msg.sender];
    // Check if we already have the language code.
    for (uint i = 0; i < glofile.bioLangs.length; i++) {
      if (glofile.bioLangs[i] == lang) {
        break;
      }
    }
    if (i == glofile.bioLangs.length) {
      // We didn't find it. Try to find a free slot.
      for (i = 0; i < glofile.bioLangs.length; i++) {
        if (glofile.bioLangs[i] == 0) {
          break;
        }
      }
      if (i == glofile.bioLangs.length) {
        // We didn't find a free slot. Make the array bigger.
        glofile.bioLangs.length++;
      }
      glofile.bioLangs[i] = lang;
    }
    // Set translation.
    glofile.bioTranslations[lang] = translation;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile bio with language code `lang`
   * @dev Deletes a bio translation.
   * @param lang 3 letter ISO 639-3 language code
   */
  function deleteBio(bytes3 lang) {
    Glofile glofile = glofiles[msg.sender];
    for (uint i = 0; i < glofile.bioLangs.length; i++) {
      if (glofile.bioLangs[i] == lang) {
        delete glofile.bioLangs[i];
        break;
      }
    }
    // Delete the actual mapping in case a client accesses without checking
    // language key.
    delete glofile.bioTranslations[lang];
    Update(msg.sender);
  }

  /**
   * @notice Delete all of your Glofile bio translations
   * @dev Deletes all of the bio translations.
   */
  function deleteAllBioTranslations() {
    Glofile glofile = glofiles[msg.sender];
    // Delete the actual mappings in case a client accesses without checking
    // language key.
    for (uint i = 0; i < glofile.bioLangs.length; i++) {
      delete glofile.bioTranslations[glofile.bioLangs[i]];
    }
    delete glofile.bioLangs;
    Update(msg.sender);
  }

  /**
   * @notice Get the list of language code a Glofile bio is available in
   * @dev Gets the list of language codes the bio is available in.
   * @param account Glofile to access
   * @return array of 3 letter ISO 639-3 language codes
   */
  function getBioLangCodes(address account) constant returns (bytes3[]) {
    return glofiles[account].bioLangs;
  }

  /**
   * @notice Get the Glofile bio with language code `lang`
   * @dev Gets the bio in a specific language.
   * @param account Glofile to access
   * @param lang 3 letter ISO 639-3 language code
   * @return UTF-8 Markdown of bio compressed with DEFLATE
   */
  function getBio(address account, bytes3 lang) constant returns (bytes) {
    return glofiles[account].bioTranslations[lang];
  }

  /**
   * @notice Set your Glofile avatar with index `i` to `ipfsHash`
   * @dev Sets the avatar with a specific index to an IPFS hash.
   * @param i index of avatar to set
   * @param ipfsHash binary IPFS hash of image
   */
  function setAvatar(uint i, bytes ipfsHash) {
    bytes[] avatars = glofiles[msg.sender].avatars;
    // Make sure the array is long enough.
    if (avatars.length <= i) {
      avatars.length = i + 1;
    }
    avatars[i] = ipfsHash;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile avatar with index `i`
   * @dev Deletes an avatar with a specific index.
   * @param i index of avatar to delete
   */
  function deleteAvatar(uint i) {
    delete glofiles[msg.sender].avatars[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile avatars
   * @dev Deletes all avatars from the Glofile.
   */
  function deleteAllAvatars() {
    delete glofiles[msg.sender].avatars;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile avatars
   * @dev Gets the number of avatars.
   * @param account Glofile to access
   * @return number of avatars
   */
  function getAvatarCount(address account) constant returns (uint) {
    return glofiles[account].avatars.length;
  }

  /**
   * @notice Get the Glofile avatar with index `i`
   * @dev Gets the avatar with a specific index.
   * @param account Glofile to access
   * @param i index of avatar to get
   * @return binary IPFS hash of image
   */
  function getAvatar(address account, uint i) constant returns (bytes) {
    return glofiles[account].avatars[i];
  }

  /**
   * @notice Set your Glofile cover image with index `i` to `ipfsHash`
   * @dev Sets the cover image with a specific index to an IPFS hash.
   * @param i index of cover image to set
   * @param ipfsHash binary IPFS hash of image
   */
  function setCoverImage(uint i, bytes ipfsHash) {
    bytes[] coverImages = glofiles[msg.sender].coverImages;
    // Make sure the array is long enough.
    if (coverImages.length <= i) {
      coverImages.length = i + 1;
    }
    coverImages[i] = ipfsHash;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile cover image with index `i`
   * @dev Deletes the cover image with a specific index.
   * @param i index of cover image to delete
   */
  function deleteCoverImage(uint i) {
    delete glofiles[msg.sender].coverImages[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile cover images
   * @dev Deletes all cover images from the Glofile.
   */
  function deleteAllCoverImages() {
    delete glofiles[msg.sender].coverImages;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile cover images
   * @dev Gets the number of cover images.
   * @param account Glofile to access
   * @return number of cover images
   */
  function getCoverImageCount(address account) constant returns (uint) {
    return glofiles[account].coverImages.length;
  }

  /**
   * @notice Get the Glofile cover image with index `i`
   * @dev Gets the cover image with a specific index.
   * @param account Glofile to access
   * @param i index of cover image to get
   * @return binary IPFS hash of image
   */
  function getCoverImage(address account, uint i) constant returns (bytes) {
    return glofiles[account].coverImages[i];
  }

  /**
   * @notice Set your Glofile background image with index `i` to `ipfsHash`
   * @dev Sets the background image with a specific index to an IPFS hash.
   * @param i index of background image to set
   * @param ipfsHash binary IPFS hash of image
   */
  function setBackgroundImage(uint i, bytes ipfsHash) {
    bytes[] backgroundImages = glofiles[msg.sender].backgroundImages;
    // Make sure the array is long enough.
    if (backgroundImages.length <= i) {
      backgroundImages.length = i + 1;
    }
    backgroundImages[i] = ipfsHash;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile background image with index `i`
   * @dev Deletes the background image with a specific index.
   * @param i index of background image to delete
   */
  function deleteBackgroundImage(uint i) {
    delete glofiles[msg.sender].backgroundImages[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile background images
   * @dev Deletes all the background images.
   */
  function deleteAllBackgroundImages() {
    delete glofiles[msg.sender].backgroundImages;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile background images
   * @dev Gets the number of background images.
   * @param account Glofile to access
   * @return number of background images
   */
  function getBackgroundImageCount(address account) constant returns (uint) {
    return glofiles[account].backgroundImages.length;
  }

  /**
   * @notice Get the Glofile background image with index `i`
   * @dev Gets the background image with a specific index.
   * @param i index of cover image to get
   * @param account Glofile to access
   * @return binary IPFS hash of image
   */
  function getBackgroundImage(address account, uint i) constant returns (bytes) {
    return glofiles[account].backgroundImages[i];
  }

  /**
   * @notice Set your Glofile topic with index `i` to `topic`
   * @dev Sets the topic with a specific index.
   * @param i index of topic to set
   * @param topic UTF-8 string of topic (no whitespace)
   */
  function setTopic(uint i, string topic) {
    string[] topics = glofiles[msg.sender].topics;
    // Make sure the array is long enough.
    if (topics.length <= i) {
      topics.length = i + 1;
    }
    topics[i] = topic;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile topic with index `i`
   * @dev Deletes an topic with a specific index.
   * @param i index of topic to delete
   */
  function deleteTopic(uint i) {
    delete glofiles[msg.sender].topics[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile topics
   * @dev Deletes all topics from the Glofile.
   */
  function deleteAllTopics() {
    delete glofiles[msg.sender].topics;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile topics
   * @dev Gets the number of topics.
   * @param account Glofile to access
   * @return number of topics
   */
  function getTopicCount(address account) constant returns (uint) {
    return glofiles[account].topics.length;
  }

  /**
   * @notice Get the Glofile topic with index `i`
   * @dev Gets the topic with a specific index.
   * @param account Glofile to access
   * @param i index of topic to get
   * @return UTF-8 string of topic
   */
  function getTopic(address account, uint i) constant returns (string) {
    return glofiles[account].topics[i];
  }

  /**
   * @notice Set your Glofile parent with index `i` to `parent`
   * @dev Sets the parent with a specific index.
   * @param i index of parent to set
   * @param parent UTF-8 string of parent
   */
  function setParent(uint i, string parent) {
    string[] parents = glofiles[msg.sender].parents;
    // Make sure the array is long enough.
    if (parents.length <= i) {
      parents.length = i + 1;
    }
    parents[i] = parent;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile parent with index `i`
   * @dev Deletes an parent with a specific index.
   * @param i index of parent to delete
   */
  function deleteParent(uint i) {
    delete glofiles[msg.sender].parents[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile parents
   * @dev Deletes all parents from the Glofile.
   */
  function deleteAllParents() {
    delete glofiles[msg.sender].parents;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile parents
   * @dev Gets the number of parents.
   * @param account Glofile to access
   * @return number of parents
   */
  function getParentCount(address account) constant returns (uint) {
    return glofiles[account].parents.length;
  }

  /**
   * @notice Get the Glofile parent with index `i`
   * @dev Gets the parent with a specific index.
   * @param account Glofile to access
   * @param i index of parent to get
   * @return UTF-8 string of parent
   */
  function getParent(address account, uint i) constant returns (string) {
    return glofiles[account].parents[i];
  }

  /**
   * @notice Set your Glofile child with index `i` to `child`
   * @dev Sets the child with a specific index.
   * @param i index of child to set
   * @param child UTF-8 string of child
   */
  function setChild(uint i, string child) {
    string[] children = glofiles[msg.sender].children;
    // Make sure the array is long enough.
    if (children.length <= i) {
      children.length = i + 1;
    }
    children[i] = child;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile child with index `i`
   * @dev Deletes an child with a specific index.
   * @param i index of child to delete
   */
  function deleteChild(uint i) {
    delete glofiles[msg.sender].children[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile children
   * @dev Deletes all children from the Glofile.
   */
  function deleteAllChildren() {
    delete glofiles[msg.sender].children;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile children
   * @dev Gets the number of children.
   * @param account Glofile to access
   * @return number of children
   */
  function getChildCount(address account) constant returns (uint) {
    return glofiles[account].children.length;
  }

  /**
   * @notice Get the Glofile child with index `i`
   * @dev Gets the child with a specific index.
   * @param account Glofile to access
   * @param i index of child to get
   * @return UTF-8 string of child
   */
  function getChild(address account, uint i) constant returns (string) {
    return glofiles[account].children[i];
  }

  /**
   * @notice Set your Glofile uri with index `i` to `uri`
   * @dev Sets the uri with a specific index.
   * @param i index of uri to set
   * @param uri UTF-8 string of uri
   */
  function setUri(uint i, string uri) {
    string[] uris = glofiles[msg.sender].uris;
    // Make sure the array is long enough.
    if (uris.length <= i) {
      uris.length = i + 1;
    }
    uris[i] = uri;
    Update(msg.sender);
  }

  /**
   * @notice Delete your Glofile uri with index `i`
   * @dev Deletes an uri with a specific index.
   * @param i index of uri to delete
   */
  function deleteUri(uint i) {
    delete glofiles[msg.sender].uris[i];
    Update(msg.sender);
  }

  /**
   * @notice Delete all your Glofile uris
   * @dev Deletes all uris from the Glofile.
   */
  function deleteAllUris() {
    delete glofiles[msg.sender].uris;
    Update(msg.sender);
  }

  /**
   * @notice Get the number of Glofile uris
   * @dev Gets the number of uris.
   * @param account Glofile to access
   * @return number of uris
   */
  function getUriCount(address account) constant returns (uint) {
    return glofiles[account].uris.length;
  }

  /**
   * @notice Get the Glofile uri with index `i`
   * @dev Gets the uri with a specific index.
   * @param account Glofile to access
   * @param i index of uri to get
   * @return UTF-8 string of uri
   */
  function getUri(address account, uint i) constant returns (string) {
    return glofiles[account].uris[i];
  }

  /**
   * @notice Copy entire Glofile from `source`
   * @dev Copies the Glofile from another account to this one.
   * @param source account of Glofile to copy from
   * TODO: check this works
   */
  function copyEntireGlofile(address source) {
    glofiles[msg.sender] = glofiles[source];
    Update(msg.sender);
  }

  /**
   * @notice Delete your entire Glofile
   * @dev Deletes the Glofile completely.
   * TODO: make sure this deletes everything
   */
  function deleteEntireGlofile() {
    delete glofiles[msg.sender];
    Delete(msg.sender);
  }

}


Added Grand Factory

Added Grand Factory

/*
Factory: Contains all coin contracts.
+ Separate Factories.
+ Grand Overarching Factory.
*/

contract Coin {
    function sendCoin(uint _value, address _to) returns (bool _success) {}
    function sendCoinFrom(address _from, uint _value, address _to) returns (bool _success) {}
    function coinBalance() constant returns (uint _r) {}
    function coinBalanceOf(address _addr) constant returns (uint _r) {}
    function approve(address _addr) {}
    function approveOnce(address _addr, uint256 _maxValue) {}
    function unapprove(address _addr) {}
    function isApproved(address _proxy) constant returns (bool _r) {}
    function isApprovedFor(address _target, address _proxy) constant returns (bool _r) {}
}

contract Token is Coin {

    function Token(uint _initialAmount) {
        balances[msg.sender] = _initialAmount;
    }

    event CoinTransfer(address indexed from, address indexed to, uint256 value);
    event AddressApproval(address indexed from, address indexed to, bool result);
    event AddressApprovalOnce(address indexed from, address indexed to, uint256 value);

    function sendCoin(uint _value, address _to) returns (bool _success) {
        if (balances[msg.sender] >= _value) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            CoinTransfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function sendCoinFrom(address _from, uint _value, address _to) returns (bool _success) {
        if (balances[_from] >= _value) {
            bool transfer = false;
            if(approved[_from][msg.sender]) {
                transfer = true;
            } else {
                if(_value < approved_once[_from][msg.sender]) {
                    transfer = true;
                    approved_once[_from][msg.sender] = 0; //reset
                }
            }

            if(transfer == true) {
                balances[_from] -= _value;
                balances[_to] += _value;
                CoinTransfer(_from, _to, _value);
                return true;
            } else { return false; }
        }
    }

    function coinBalance() constant returns (uint _r) {
        return balances[msg.sender];
    }

    function coinBalanceOf(address _addr) constant returns (uint _r) {
        return balances[_addr];
    }

    function approve(address _addr) {
        approved[msg.sender][_addr] = true;
        AddressApproval(msg.sender, _addr, true);
    }

    function approveOnce(address _addr, uint256 _maxValue) {
        approved_once[msg.sender][_addr] = _maxValue;
        AddressApprovalOnce(msg.sender, _addr, _maxValue);
    }

    function unapprove(address _addr) {
        approved[msg.sender][_addr] = false;
        approved_once[msg.sender][_addr] = 0;
        AddressApproval(msg.sender, _addr, false);
        AddressApprovalOnce(msg.sender, _addr, 0);
    }

    function isApproved(address _proxy) constant returns (bool _r) {
        if(approved[msg.sender][_proxy] == true || approved_once[msg.sender][_proxy] > 0) {
            return true;
        }
    }

    function isApprovedFor(address _target, address _proxy) constant returns (bool _r) {
        if(approved[_target][_proxy] == true || approved_once[_target][_proxy] > 0) {
            return true;
        }
    }

    mapping (address => uint) public balances;
    mapping (address => mapping (address => bool)) public approved;
    mapping (address => mapping (address => uint256)) public approved_once;
}

import "owned"; //standard library

contract Token_With_Owner_And_Create is Token, owned {

    function Token_With_Owner_And_Create(uint _initialAmount) Token(_initialAmount) {}

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

    function createToken(address _for, uint256 _value) isOwner {
        balances[_for] += _value;
    }
}

contract Standard_Token_Factory {

    function createStandardToken(uint256 _initialAmount) returns (address) {
        return address(new Token(_initialAmount));
    }
}

contract Standard_Token_With_Owner_And_Create_Factory {

    function createStandardTokenWithOwnerAndCreate(uint256 _initialAmount) returns (address) {
        return address(new Token_With_Owner_And_Create(_initialAmount));
    }
}

contract Grand_Factory is
        Standard_Token_Factory,
        Standard_Token_With_Owner_And_Create_Factory
{}

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


Use decending for loops where possible

Use decending for loops where possible

Decending for loops are more efficient than ascending for loops when
iterating through arrays.  Solidity does not cache the lengths of arrays
so, as a result, it takes a bit more gas each time in order to get the
length of the array.

import "BulletinBoard.sol";

/**
 * This contract performs an "eval" on arbitrary contracts but only with the
 * consent of all participants named.
 */
contract UnanimousConsent {

	enum ConsentState {
		NONE,
		CONSENTED,
		EXECUTED
	}

	struct Action {
		address target;
		uint value;
		bytes calldata;
		bool initialized;
	}

	// Records the current state of consent for a given hash and address
	mapping (bytes32 =>
			mapping (address => ConsentState)) consentStates;

	// Contains all of the sent execution actions
	mapping (bytes32 => Action) actions;

	// Holds all of the participants in the current UnanimousConsent contract
	address[] participants;

	// Holds the BulletinBoard for counterfactual addressing
	BulletinBoard public bulletinBoard;

	modifier onlySelf {
		if (msg.sender == address(this)) {
			_
		} else {
			throw;
		}
	}

	/**
	 * Creates a new UnanimousConsent contract.
	 *
	 * _participants: The initial participants in the contract
	 */
	function UnanimousConsent(address[] _participants) {
		participants = _participants;
		bulletinBoard = new BulletinBoard(this);
	}

	/**
	 * Adds an `Action` to potentially be executed.
	 *
	 * _target: The target of the execution call
	 * _value: The amount of Ether to send
	 * _calldata: The calldata associated with the call
	 */
	function addAction(address _target, uint _value, bytes _calldata) external {
		Action memory action = Action(_target, _value, _calldata, true);
		actions[sha3(action)] = action;// hashing a struct is broken
	}

	/**
	 * Evaluates arbitrary functions of contracts, but only with universal
	 * consent. Note that any `eval` sub-calls should `throw` in the event that
	 * there is a contract execution failure (such as if a precondition isn't
	 * met or if a verification of some sort fails) to prevent this call from
	 * finishing.
	 *
	 * _actionHashes: The hashes of the `Action` that have been submitted
	 */
	function eval(bytes32[] _actionHashes) {
		uint i;
		bytes32 hash = sha3(_actionHashes);

		for (i = participants.length; i > 0; i--) {
			if (consentStates[hash][participants[i-1]] == ConsentState.CONSENTED) {
				consentStates[hash][participants[i-1]] = ConsentState.EXECUTED;
			} else {
				throw;
			}
		}

		for (i = 0; i < _actionHashes.length; i++) {
			Action memory action = actions[_actionHashes[i]];
			if (action.initialized && !action.target.call.value(action.value)(action.calldata)) {
				throw;
			}
		}
	}

	/**
	 * Provides consent for the hash of an execution call for the sender of the
	 * message.
	 *
	 * _hash: The hash of the execution call
	 *
	 * returns: `true` if successful, otherwise `false`
	 */
	function consent(bytes32 _hash) returns (bool) {
		if (consentStates[_hash][msg.sender] == ConsentState.NONE) {
			consentStates[_hash][msg.sender] = ConsentState.CONSENTED;
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Changes the participants in the current contract. Intended to only be
	 * called by this contract's `eval`.
	 *
	 * _participants: The new participants in the contract
	 */
	function changeParticipants(address[] _participants) external onlySelf {
		participants = _participants;
	}

	/**
	 * Removes a group of `Action` that have been submitted. Intended to be
	 * called by this contract's `eval`.
	 *
	 * _actionHashes: The hashes of the `Action` that have been submitted
	 */
	function cleanActions(bytes32[] _actionHashes) external onlySelf {
		for (uint i = _actionHash.length; i > 0; i--) {
			delete actions[_actionHashes[i-1]];
		}
	}

	/**
	 * Cleans up previously approved consents. Intended to only be called by
	 * this contract's `eval`.
	 *
	 * _hashes: The list of hashes to clean
	 * _participants: The list of address whose hashes should be cleaned
	 */
	function clean(bytes32[] _hashes, address[] _participants) external onlySelf {
		for (uint i = _hashes.length; i > 0; i--) {
			for (uint j = _participants.length; j > 0; j--) {
				delete consentStates[_hashes[i-1]][_participants[j-1]];
			}
		}
	}

	/**
	 * Kills the current contract. Intended to only be called by this contract's
	 * eval.
	 *
	 * _recipient: The recipient of funds from the `selfdestruct` call
	 */
	function kill(address _recipient) external onlySelf {
		selfdestruct(_recipient);
	}
}

import "BulletinBoard.sol";

/**
 * This contract performs an "eval" on arbitrary contracts but only with the
 * consent of all participants named.
 */
contract UnanimousConsent {

	enum ConsentState {
		NONE,
		CONSENTED,
		EXECUTED
	}

	struct Action {
		address target;
		uint value;
		bytes calldata;
		bool initialized;
	}

	// Records the current state of consent for a given hash and address
	mapping (bytes32 =>
			mapping (address => ConsentState)) consentStates;

	// Contains all of the sent execution actions
	mapping (bytes32 => Action) actions;

	// Holds all of the participants in the current UnanimousConsent contract
	address[] participants;

	// Holds the BulletinBoard for counterfactual addressing
	BulletinBoard public bulletinBoard;

	modifier onlySelf {
		if (msg.sender == address(this)) {
			_
		} else {
			throw;
		}
	}

	/**
	 * Creates a new UnanimousConsent contract.
	 *
	 * _participants: The initial participants in the contract
	 */
	function UnanimousConsent(address[] _participants) {
		participants = _participants;
		bulletinBoard = new BulletinBoard(this);
	}

	/**
	 * Adds an `Action` to potentially be executed.
	 *
	 * _target: The target of the execution call
	 * _value: The amount of Ether to send
	 * _calldata: The calldata associated with the call
	 */
	function addAction(address _target, uint _value, bytes _calldata) external {
		Action memory action = Action(_target, _value, _calldata, true);
		actions[sha3(action)] = action;// hashing a struct is broken
	}

	/**
	 * Evaluates arbitrary functions of contracts, but only with universal
	 * consent. Note that any `eval` sub-calls should `throw` in the event that
	 * there is a contract execution failure (such as if a precondition isn't
	 * met or if a verification of some sort fails) to prevent this call from
	 * finishing.
	 *
	 * _actionHashes: The hashes of the `Action` that have been submitted
	 */
	function eval(bytes32[] _actionHashes) {
		uint i;
		bytes32 hash = sha3(_actionHashes);

		for (i = 0; i < participants.length; i++) {
			if (consentStates[hash][participants[i]] == ConsentState.CONSENTED) {
				consentStates[hash][participants[i]] = ConsentState.EXECUTED;
			} else {
				throw;
			}
		}

		for (i = 0; i < _actionHashes.length; i++) {
			Action memory action = actions[_actionHashes[i]];
			if (action.initialized && !action.target.call.value(action.value)(action.calldata)) {
				throw;
			}
		}
	}

	/**
	 * Provides consent for the hash of an execution call for the sender of the
	 * message.
	 *
	 * _hash: The hash of the execution call
	 *
	 * returns: `true` if successful, otherwise `false`
	 */
	function consent(bytes32 _hash) returns (bool) {
		if (consentStates[_hash][msg.sender] == ConsentState.NONE) {
			consentStates[_hash][msg.sender] = ConsentState.CONSENTED;
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Changes the participants in the current contract. Intended to only be
	 * called by this contract's `eval`.
	 *
	 * _participants: The new participants in the contract
	 */
	function changeParticipants(address[] _participants) external onlySelf {
		participants = _participants;
	}

	/**
	 * Removes a group of `Action` that have been submitted. Intended to be
	 * called by this contract's `eval`.
	 *
	 * _actionHashes: The hashes of the `Action` that have been submitted
	 */
	function cleanActions(bytes32[] _actionHashes) external onlySelf {
		for (uint i = 0; i < _actionHash.length; i++) {
			delete actions[_actionHashes[i]];
		}
	}

	/**
	 * Cleans up previously approved consents. Intended to only be called by
	 * this contract's `eval`.
	 *
	 * _hashes: The list of hashes to clean
	 * _participants: The list of address whose hashes should be cleaned
	 */
	function clean(bytes32[] _hashes, address[] _participants) external onlySelf {
		for (uint i = 0; i < _hashes.length; i++) {
			for (uint j = 0; j < _participants.length; j++) {
				delete consentStates[_hashes[i]][_participants[j]];
			}
		}
	}

	/**
	 * Kills the current contract. Intended to only be called by this contract's
	 * eval.
	 *
	 * _recipient: The recipient of funds from the `selfdestruct` call
	 */
	function kill(address _recipient) external onlySelf {
		selfdestruct(_recipient);
	}
}


Access modifiers in Project

Access modifiers in Project

pragma solidity ^0.4.11;

import 'zeppelin-solidity/contracts/ownership/Ownable.sol';
import 'zeppelin-solidity/contracts/math/SafeMath.sol';
import 'zeppelin-solidity/contracts/token/ERC20.sol';

import "./impact/ImpactRegistry.sol";
import "../ContractProvider.sol";

contract Project is Ownable {
    using SafeMath for uint256;

    string public name;
    address public judgeAddress;
    address public beneficiaryAddress;
    address public IMPACT_REGISTRY_ADDRESS;
    address public CONTRACT_PROVIDER_ADDRESS;

    /* This creates a map with donations per user */
    mapping (address => uint) accountBalances;

    /* Additional structure to help to iterate over donations */
    address[] accountIndex;

    /* Total amount of all of the donations */
    uint public total;

    /* This generates a public event on the blockchain that will notify clients */
    event OutcomeEvent(string id, uint value);
    event DonationEvent(address indexed from, uint value);

    function Project(string _name) public {
        name = _name;
    }

    function setJudge(address _judgeAddress) public onlyOwner {
        judgeAddress = _judgeAddress;
    }

    function setBeneficiary(address _beneficiaryAddress) public onlyOwner {
        beneficiaryAddress = _beneficiaryAddress;
    }

    function setImpactRegistry(address impactRegistryAddress) public onlyOwner {
        IMPACT_REGISTRY_ADDRESS = impactRegistryAddress;
    }

    function setContractProvider(address _contractProvider) public onlyOwner {
        CONTRACT_PROVIDER_ADDRESS = _contractProvider;
    }

    function notify(address _from, uint _amount) public onlyOwner {
        registerDonation(_from, _amount);
    }

    function registerDonation(address _from, uint _amount) internal {
        total = total.add(_amount);
        ImpactRegistry(IMPACT_REGISTRY_ADDRESS).registerDonation(_from, _amount);
        DonationEvent(_from, _amount);
    }

    function donateFromWallet(ERC20 _token, uint _amount) public {
        _token.transferFrom(msg.sender, address(this), _amount);
        registerDonation(msg.sender, _amount);
    }

    function fund(uint _value) public onlyOwner {
        total = total.add(_value);
    }

    function unlockOutcome(ERC20 _token, string _name, uint _value) public {
        require (msg.sender == judgeAddress);
        require (_value <= total);

        _token.transfer(beneficiaryAddress, _value);
        total = total.sub(_value);

        ImpactRegistry(IMPACT_REGISTRY_ADDRESS).registerOutcome(_name, _value);

        OutcomeEvent(_name, _value);
    }

    function payBack(ERC20 _token, address account) public onlyOwner {
        uint balance = getBalance(account);
        if (balance > 0) {
            _token.transfer(account, balance);
            total = total.sub(accountBalances[account]);
            ImpactRegistry(IMPACT_REGISTRY_ADDRESS).payBack(account);
        }
    }

    function getBalance(address donor) public view returns(uint) {
        return ImpactRegistry(IMPACT_REGISTRY_ADDRESS).getBalance(donor);
    }

    /* Extra security measure to save funds in case of critical error or attack */
    function escape(ERC20 _token, address escapeAddress) public onlyOwner {
        _token.transfer(escapeAddress, total);
        total = 0;
    }
}

pragma solidity ^0.4.11;

import 'zeppelin-solidity/contracts/ownership/Ownable.sol';
import 'zeppelin-solidity/contracts/math/SafeMath.sol';
import 'zeppelin-solidity/contracts/token/ERC20.sol';

import "./impact/ImpactRegistry.sol";
import "../ContractProvider.sol";

contract Project is Ownable {
    using SafeMath for uint256;

    string public name;
    address public judgeAddress;
    address public beneficiaryAddress;
    address public IMPACT_REGISTRY_ADDRESS;
    address public CONTRACT_PROVIDER_ADDRESS;

    /* This creates a map with donations per user */
    mapping (address => uint) accountBalances;

    /* Additional structure to help to iterate over donations */
    address[] accountIndex;

    /* Total amount of all of the donations */
    uint public total;

    /* This generates a public event on the blockchain that will notify clients */
    event OutcomeEvent(string id, uint value);
    event DonationEvent(address indexed from, uint value);

    function Project(string _name) {
        name = _name;
    }

    function setJudge(address _judgeAddress) onlyOwner {
        judgeAddress = _judgeAddress;
    }

    function setBeneficiary(address _beneficiaryAddress) onlyOwner {
        beneficiaryAddress = _beneficiaryAddress;
    }

    function setImpactRegistry(address impactRegistryAddress) onlyOwner {
        IMPACT_REGISTRY_ADDRESS = impactRegistryAddress;
    }

    function setContractProvider(address _contractProvider) onlyOwner {
        CONTRACT_PROVIDER_ADDRESS = _contractProvider;
    }

    function notify(address _from, uint _amount) onlyOwner {
        registerDonation(_from, _amount);
    }

    function registerDonation(address _from, uint _amount) internal {
        total = total.add(_amount);
        ImpactRegistry(IMPACT_REGISTRY_ADDRESS).registerDonation(_from, _amount);
        DonationEvent(_from, _amount);
    }

    function donateFromWallet(ERC20 _token, uint _amount) {
        _token.transferFrom(msg.sender, address(this), _amount);
        registerDonation(msg.sender, _amount);
    }

    function fund(uint _value) onlyOwner {
        total = total.add(_value);
    }

    function unlockOutcome(ERC20 _token, string _name, uint _value) {
        require (msg.sender == judgeAddress);
        require (_value <= total);

        _token.transfer(beneficiaryAddress, _value);
        total = total.sub(_value);

        ImpactRegistry(IMPACT_REGISTRY_ADDRESS).registerOutcome(_name, _value);

        OutcomeEvent(_name, _value);
    }

    function payBack(ERC20 _token, address account) onlyOwner {
        uint balance = getBalance(account);
        if (balance > 0) {
            _token.transfer(account, balance);
            total = total.sub(accountBalances[account]);
            ImpactRegistry(IMPACT_REGISTRY_ADDRESS).payBack(account);
        }
    }

    function getBalance(address donor) constant returns(uint) {
        return ImpactRegistry(IMPACT_REGISTRY_ADDRESS).getBalance(donor);
    }

    /* Extra security measure to save funds in case of critical error or attack */
    function escape(ERC20 _token, address escapeAddress) onlyOwner {
        _token.transfer(escapeAddress, total);
        total = 0;
    }
}


Convert public to external where possible

pragma solidity ^0.4.19;

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

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

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

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

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

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

	modifier onlyEnded {
		require(ended);
		_;
	}

	/* Public functions */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	/* Admin only functions */

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

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

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

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

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

pragma solidity ^0.4.19;

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

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

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

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

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

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

	modifier onlyEnded {
		require(ended);
		_;
	}

	/* Public functions */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	/* Admin only functions */

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

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

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

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

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


use arrays for doc signatures

use arrays for doc signatures

contract SimpleSign {

    event Created(
        address indexed from,
        bytes32 id
    );
    event Signed(
        address indexed from,
        bytes32 docId,
        uint id,
        bytes16 signType,
        bytes sign
    );

    address owner;

    mapping (bytes32 => Document) documents;
    uint documentsCount;
    mapping (uint => bytes32) ids;

    struct Document {
        address organizer;
        Sign[] signs;
    }

    struct Sign {
        address signer;
        bytes16 signType;
        bytes   sign;
    }

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

    function createDocument(uint nonce) returns (bytes32 docId) {
        docId = generateId(nonce);
        if (documents[docId].organizer != 0) throw;
        uint index = documentsCount++;
        ids[index] = docId;
        documents[docId].organizer = msg.sender;
        Created(msg.sender, docId);
    }

    function addSignature(bytes32 docId, bytes16 _type, bytes _sign) {
        Document doc = documents[docId];
        if (doc.organizer != msg.sender) throw;
        uint idx = doc.signs.push(Sign(msg.sender, _type, _sign));
        Signed(msg.sender, docId, idx, _type, _sign);
    }

    function getDocumentsCount() returns (uint) {
        return documentsCount;
    }

    function getDocumentDetails(bytes32 docId) returns (address organizer, uint count) {
        Document doc = documents[docId];
        organizer = doc.organizer;
        count = doc.signs.length;
    }

    function getSignsCount(bytes32 docId) returns (uint) {
        return documents[docId].signs.length;
    }

    function getSignDetails(bytes32 docId, uint signId) returns (address, bytes16) {
        Document doc = documents[docId];
        Sign s = doc.signs[signId];
        return (s.signer, s.signType);
    }

    function getSignData(bytes32 docId, uint signId) returns (bytes) {
        Document doc = documents[docId];
        Sign s = doc.signs[signId];
        return s.sign;
    }

    function generateId(uint nonce) returns (bytes32) {
        return sha3(msg.sender, nonce);
    }

    function getIdAtIndex(uint index) returns (bytes32) {
        return ids[index];
    }

}

contract SimpleSign {

    event Created(
        address indexed from,
        bytes32 id
    );
    event Signed(
        address indexed from,
        bytes32 docId,
        uint id,
        bytes16 signType,
        bytes sign
    );

    address owner;

    mapping (bytes32 => Document) documents;
    uint documentsCount;
    mapping (uint => bytes32) ids;

    struct Document {
        address organizer;
        uint signsCount;
        mapping (uint => Sign) signs;
    }

    struct Sign {
        address signer;
        bytes16 signType;
        bytes   sign;
    }

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

    function createDocument(uint nonce) returns (bytes32 docId) {
        docId = generateId(nonce);
        if (documents[docId].organizer != 0) throw;
        uint index = documentsCount++;
        ids[index] = docId;
        documents[docId] = Document(msg.sender, 0);
        Created(msg.sender, docId);
    }

    function addSignature(bytes32 docId, bytes16 _type, bytes _sign) {
        Document doc = documents[docId];
        if (doc.organizer != msg.sender) throw;
        uint idx = doc.signsCount++;
        doc.signs[idx] = Sign(msg.sender, _type, _sign);
        Signed(msg.sender, docId, idx, _type, _sign);
    }

    function getDocumentsCount() returns (uint) {
        return documentsCount;
    }

    function getDocumentDetails(bytes32 docId) returns (address organizer, uint count) {
        Document doc = documents[docId];
        organizer = doc.organizer;
        count = doc.signsCount;
    }

    function getSignsCount(bytes32 docId) returns (uint) {
        return documents[docId].signsCount;
    }

    function getSignDetails(bytes32 docId, uint signId) returns (address, bytes16) {
        Document doc = documents[docId];
        Sign s = doc.signs[signId];
        return (s.signer, s.signType);
    }

    function getSignData(bytes32 docId, uint signId) returns (bytes) {
        Document doc = documents[docId];
        Sign s = doc.signs[signId];
        return s.sign;
    }

    function generateId(uint nonce) returns (bytes32) {
        return sha3(msg.sender, nonce);
    }

    function getIdAtIndex(uint index) returns (bytes32) {
        return ids[index];
    }

}