Latest 25 transactions from a total of 270 transactions

TxHash Age From To Value [TxFee]
0xbd8fc33923fdb881b71d164667d5b0ee46dfeddf7dc725257352988e70d2f63e5 days 1 hr ago0x5ccf02a24536834c704ee793ea24e83c208a11b3  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.0000990208
0xe9ee1de6946f84fca991e0ed946b636682dff097c7b84d9efd8e8c883762931068 days 22 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000729083
0xfd42ac9d6214174e7a1d0bcb20af5278fd5f0937addb6c1a3b30d8bcf3b1619268 days 22 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000067002
0x3f2db8921380d051445e2a6f6c7cbbd17517cc8c1ab81cbac6ab7ad5dc380bab68 days 22 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000067002
0xfafc33cfabe09ccd399fcdc445b27436bb9faaa4990f702d215b7eee587295a769 days 19 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000067002
0x4f63fd9e8590666e3964eb55f36a1cfc7b437f63be1ac3e5840289f4fd2c27d369 days 19 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000067002
0x3d052531262b3edda3a585b383ba7d43641ec37f8c28ad32b112f1151de85c7f69 days 19 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000067002
0xafbf4ed53467f97e3515958da544b7fa22e4ae3d07279c5032e5631188d2605569 days 19 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000200067
0x1525d845a665b169217045a5e531dc0250b9c6a380d24aa2957ed8d57971963e69 days 19 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000570229
0xf84ea8b264209ddba6fabf0ffd7b3ee87a1ce307457bf9860284e03e76b0276869 days 19 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000570229
0xd8abafec440a135be1da5dca7d4d7760a040771ab79a9f784f871312f1cfad3b69 days 19 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000570229
0xe1f5b5629c03e871663b77519851741c1123dca48145ed42401b602cc82a322469 days 19 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000570229
0x38f6238d9cf19aabdf26d65456d77689d1fe2ccad9508d412f2d9d3c7381388169 days 19 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000570229
0xe0644c91520b2253fc58385aaf505da8b95f5a9cdbf58fa634d9b3e9a5d002b969 days 19 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000495808
0xc5c7e3c77e0e40b8d4108a5e3cac4f571aec9fc823253979a1490f96b99b38cd69 days 19 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000067002
0x44c070581e464186975c42585169a259f6818cdb0951e7e90626822bf88e836869 days 20 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000495808
0x6028c8effd32ab01d4c44a9c6f790819f26daf26606e1dd1d3beec2fddd3429c69 days 20 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000067002
0x325991d73968c95c3cb1e4cc61fce0ec4492b1da41e5c777098da26b3e21aa3069 days 20 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000067002
0x46affcc03476ddfb737de35dc4b221ab8c6989e566b95fecf7ef3675ff92617569 days 20 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000067002
0x56dfbeb6256854109b86c7dc3e9c19de6f8dde0611d8beff01e3375422818d6469 days 20 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000067002
0xbf903dc3bc544221d219264effc4e6b0e19a9bec8ef31e7a4d638ed18832d09769 days 20 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000495808
0x3be2a5e77e7d461363e8a68d0f822849589204463bc962b6932f8859bf0266a369 days 20 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000067002
0x957e392553ef913274e1faf5e99602cd48a75f6d9135f3cf605854434b40b0a075 days 1 hr ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.002187249
0xb21573b9055baa60c6f03acb6ea2624924eecb21d850bc714399a3e12beb1c1675 days 1 hr ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.001485312
0xadec6f5d19f3e8894ac12b4ea3ffe4251ac38a20717c16e1f5a64a2cbe7a4c6075 days 2 hrs ago0x0fb80359dd096a1ec1fbfdc07ddebc2003272b0c  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.001485312
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
 Latest 25 Internal Txns, Click here To View More View All
ParentTxHash Block Age From To Value
0xbd8fc33923fdb881b71d164667d5b0ee46dfeddf7dc725257352988e70d2f63e50001235 days 1 hr ago0x8011df4830b4f696cd81393997e5371b933388780x666495528e96a6fc3bb809151d3a73f1cf2585f90 Ether
0xbd8fc33923fdb881b71d164667d5b0ee46dfeddf7dc725257352988e70d2f63e50001235 days 1 hr ago0x8011df4830b4f696cd81393997e5371b933388780x666495528e96a6fc3bb809151d3a73f1cf2585f90 Ether
0xbd8fc33923fdb881b71d164667d5b0ee46dfeddf7dc725257352988e70d2f63e50001235 days 1 hr ago0x8011df4830b4f696cd81393997e5371b933388780x489d3a2c3b0f392fa780ab76a17f1586fd19e77c0 Ether
0xbd8fc33923fdb881b71d164667d5b0ee46dfeddf7dc725257352988e70d2f63e50001235 days 1 hr ago0x8011df4830b4f696cd81393997e5371b933388780x489d3a2c3b0f392fa780ab76a17f1586fd19e77c0 Ether
0xbd8fc33923fdb881b71d164667d5b0ee46dfeddf7dc725257352988e70d2f63e50001235 days 1 hr ago0x8011df4830b4f696cd81393997e5371b933388780x489d3a2c3b0f392fa780ab76a17f1586fd19e77c0 Ether
0xbd8fc33923fdb881b71d164667d5b0ee46dfeddf7dc725257352988e70d2f63e50001235 days 1 hr ago0x8011df4830b4f696cd81393997e5371b933388780x489d3a2c3b0f392fa780ab76a17f1586fd19e77c0 Ether
0xbd8fc33923fdb881b71d164667d5b0ee46dfeddf7dc725257352988e70d2f63e50001235 days 1 hr ago0x8011df4830b4f696cd81393997e5371b933388780x5b745832e56ab7b97990890161b43db4ce0aa6cc0 Ether
0xbd8fc33923fdb881b71d164667d5b0ee46dfeddf7dc725257352988e70d2f63e50001235 days 1 hr ago0x8011df4830b4f696cd81393997e5371b933388780x666495528e96a6fc3bb809151d3a73f1cf2585f90 Ether
0xbd8fc33923fdb881b71d164667d5b0ee46dfeddf7dc725257352988e70d2f63e50001235 days 1 hr ago0x8011df4830b4f696cd81393997e5371b933388780x666495528e96a6fc3bb809151d3a73f1cf2585f90 Ether
0xbd8fc33923fdb881b71d164667d5b0ee46dfeddf7dc725257352988e70d2f63e50001235 days 1 hr ago0x8011df4830b4f696cd81393997e5371b933388780x06658b994d95d1e8432192b9e3c0b2dbce6fe66f0 Ether
0xe9ee1de6946f84fca991e0ed946b636682dff097c7b84d9efd8e8c8837629310459574768 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x666495528e96a6fc3bb809151d3a73f1cf2585f90 Ether
0xe9ee1de6946f84fca991e0ed946b636682dff097c7b84d9efd8e8c8837629310459574768 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x666495528e96a6fc3bb809151d3a73f1cf2585f90 Ether
0xe9ee1de6946f84fca991e0ed946b636682dff097c7b84d9efd8e8c8837629310459574768 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x489d3a2c3b0f392fa780ab76a17f1586fd19e77c0 Ether
0xe9ee1de6946f84fca991e0ed946b636682dff097c7b84d9efd8e8c8837629310459574768 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x489d3a2c3b0f392fa780ab76a17f1586fd19e77c0 Ether
0xe9ee1de6946f84fca991e0ed946b636682dff097c7b84d9efd8e8c8837629310459574768 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x489d3a2c3b0f392fa780ab76a17f1586fd19e77c0 Ether
0xe9ee1de6946f84fca991e0ed946b636682dff097c7b84d9efd8e8c8837629310459574768 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x489d3a2c3b0f392fa780ab76a17f1586fd19e77c0 Ether
0xe9ee1de6946f84fca991e0ed946b636682dff097c7b84d9efd8e8c8837629310459574768 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x489d3a2c3b0f392fa780ab76a17f1586fd19e77c0 Ether
0xe9ee1de6946f84fca991e0ed946b636682dff097c7b84d9efd8e8c8837629310459574768 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x5b745832e56ab7b97990890161b43db4ce0aa6cc0 Ether
0xe9ee1de6946f84fca991e0ed946b636682dff097c7b84d9efd8e8c8837629310459574768 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x666495528e96a6fc3bb809151d3a73f1cf2585f90 Ether
0xe9ee1de6946f84fca991e0ed946b636682dff097c7b84d9efd8e8c8837629310459574768 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x666495528e96a6fc3bb809151d3a73f1cf2585f90 Ether
0xe9ee1de6946f84fca991e0ed946b636682dff097c7b84d9efd8e8c8837629310459574768 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x06658b994d95d1e8432192b9e3c0b2dbce6fe66f0 Ether
0xfd42ac9d6214174e7a1d0bcb20af5278fd5f0937addb6c1a3b30d8bcf3b16192459574268 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x5b745832e56ab7b97990890161b43db4ce0aa6cc0 Ether
0xfd42ac9d6214174e7a1d0bcb20af5278fd5f0937addb6c1a3b30d8bcf3b16192459574268 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x666495528e96a6fc3bb809151d3a73f1cf2585f90 Ether
0xfd42ac9d6214174e7a1d0bcb20af5278fd5f0937addb6c1a3b30d8bcf3b16192459574268 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x666495528e96a6fc3bb809151d3a73f1cf2585f90 Ether
0xfd42ac9d6214174e7a1d0bcb20af5278fd5f0937addb6c1a3b30d8bcf3b16192459574268 days 22 hrs ago0x8011df4830b4f696cd81393997e5371b933388780x06658b994d95d1e8432192b9e3c0b2dbce6fe66f0 Ether
[ Download CSV Export  ] 
Contract Name: PackageIndex
Compiler Version: v0.4.8+commit.60cc1668
Optimization Enabled: Yes
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

pragma solidity ^0.4.0;

/// @title Library which implements a semver datatype and comparisons.
/// @author Piper Merriam <[email protected]>
library SemVersionLib {
  struct SemVersion {
    bytes32 hash;
    uint32 major;
    uint32 minor;
    uint32 patch;
    string preRelease;
    string build;
    string[] preReleaseIdentifiers;
  }

  enum Comparison {
    Before,
    Same,
    After
  }

  /// @dev Initialize a SemVersion struct
  /// @param self The SemVersion object to initialize.
  /// @param major The major portion of the semver version string.
  /// @param minor The minor portion of the semver version string.
  /// @param patch The patch portion of the semver version string.
  /// @param preRelease The pre-release portion of the semver version string.  Use empty string if the version string has no pre-release portion.
  /// @param build The build portion of the semver version string.  Use empty string if the version string has no build portion.
  function init(SemVersion storage self,
                uint32 major,
                uint32 minor,
                uint32 patch,
                string preRelease,
                string build) public returns (bool) {
    self.major = major;
    self.minor = minor;
    self.patch = patch;
    self.preRelease = preRelease;
    self.preReleaseIdentifiers = splitIdentifiers(preRelease);
    self.build = build;
    self.hash = sha3(major, minor, patch, preRelease);
    return true;
  }

  //
  // Storage Operations
  //
  /// @dev Return boolean indicating if the two SemVersion objects are considered equal
  /// @param self The first SemVersion
  /// @param other The second SemVersion
  function isEqual(SemVersion storage self, SemVersion storage other) public returns (bool) {
    return self.hash == other.hash;
  }

  /// @dev Return boolean indicating if the first SemVersion object is considered strictly greater than the second.
  /// @param self The first SemVersion
  /// @param other The second SemVersion
  function isGreater(SemVersion storage self, SemVersion storage other) public returns (bool) {
    if (self.hash == other.hash) {
      return false;
    } else if (self.major > other.major) {
      return true;
    } else if (self.major < other.major) {
      return false;
    } else if (self.minor > other.minor) {
      return true;
    } else if (self.minor < other.minor) {
      return false;
    } else if (self.patch > other.patch) {
      return true;
    } else if (self.patch < other.patch) {
      return false;
    } else if (!isPreRelease(self) && isPreRelease(other)) {
      return true;
    } else if (isPreRelease(self) && !isPreRelease(other)) {
      return false;
    } else if (isPreReleaseGreater(self, other)) {
      return true;
    } else {
      return false;
    }
  }

  /// @dev Return boolean indicating if the first SemVersion object is considered greater than or equal to the second.
  /// @param self The first SemVersion
  /// @param other The second SemVersion
  function isGreaterOrEqual(SemVersion storage self, SemVersion storage other) public returns (bool) {
    return isEqual(self, other) || isGreater(self, other);
  }

  /*
   *  PreRelease comparisons
   */
  /// @dev Return boolean indicating if the pre-release string from the first SemVersion object is considered greater than the pre-release string from the second SemVersion object.
  /// @param left The first SemVersion
  /// @param right The second SemVersion
  function isPreReleaseGreater(SemVersion storage left, SemVersion storage right) internal returns (bool) {
    return comparePreReleases(left, right) == Comparison.After;
  }

  /// @dev Return boolean indicating if the provided SemVersion is a pre-release.
  /// @param self The SemVersion
  function isPreRelease(SemVersion storage self) internal returns (bool) {
    return self.preReleaseIdentifiers.length > 0;
  }

  /// @dev Return a comparison of the pre-release strings for the two provided SemVersion objects.
  /// @param left The first SemVersion
  /// @param right The second SemVersion
  function comparePreReleases(SemVersion storage left, SemVersion storage right) internal returns (Comparison comparisonResult) {
    uint minLength = min(left.preReleaseIdentifiers.length,
                         right.preReleaseIdentifiers.length);
    for (uint i = 0; i < minLength; i++) {
      if (isNumericString(left.preReleaseIdentifiers[i]) && isNumericString(right.preReleaseIdentifiers[i])) {
        comparisonResult = compareNumericStrings(left.preReleaseIdentifiers[i], right.preReleaseIdentifiers[i]);
      } else {
        comparisonResult = compareStrings(left.preReleaseIdentifiers[i], right.preReleaseIdentifiers[i]);
      }

      if (comparisonResult != Comparison.Same) {
        return comparisonResult;
      }
      continue;
    }

    if (left.preReleaseIdentifiers.length < right.preReleaseIdentifiers.length) {
      return Comparison.Before;
    } else if (left.preReleaseIdentifiers.length > right.preReleaseIdentifiers.length) {
      return Comparison.After;
    } else {
      return Comparison.Same;
    }
  }

  //
  // PreRelease String Utils
  //
  /// @dev Return a comparison based on the ASCII ordering of the two strings
  /// @param left The first string
  /// @param right The second string
  function compareStrings(string left, string right) internal returns (Comparison) {
    for (uint i = 0; i < min(bytes(left).length, bytes(right).length); i++) {
      if (bytes(left)[i] == bytes(right)[i]) {
        continue;
      } else if (uint(bytes(left)[i]) < uint(bytes(right)[i])) {
        return Comparison.Before;
      } else {
        return Comparison.After;
      }
    }

    if (bytes(left).length < bytes(right).length) {
      return Comparison.Before;
    } else if (bytes(left).length > bytes(right).length) {
      return Comparison.After;
    } else {
      return Comparison.Same;
    }
  }

  /// @dev Return a comparison based on the integer representation of the two string.
  /// @param left The first string
  /// @param right The second string
  function compareNumericStrings(string left, string right) internal returns (Comparison) {
    uint leftAsNumber = castStringToUInt(left);
    uint rightAsNumber = castStringToUInt(right);

    if (leftAsNumber < rightAsNumber) {
      return Comparison.Before;
    } else if (leftAsNumber > rightAsNumber) {
      return Comparison.After;
    } else {
      return Comparison.Same;
    }
  }

  /// @dev Splits a string on periods.
  /// @param preRelease The string to split.
  function splitIdentifiers(string preRelease) internal returns (string[]) {
    if (bytes(preRelease).length == 0) {
      return new string[](0);
    }

    uint i;
    uint leftBound = 0;
    uint numIdentifiers = 1;

    for (i = 0; i < bytes(preRelease).length; i++) {
      if (bytes(preRelease)[i] == PERIOD) {
        numIdentifiers += 1;
      }
    }

    string[] memory preReleaseIdentifiers = new string[](numIdentifiers);

    numIdentifiers = 0;

    for (i = 0; i <= bytes(preRelease).length; i++) {
      if (i == bytes(preRelease).length || bytes(preRelease)[i] == PERIOD) {
        uint identifierLength = i - leftBound;

        bytes memory buffer = new bytes(identifierLength);
        for (uint j = 0; j < identifierLength; j++) {
          buffer[j] = bytes(preRelease)[j + leftBound];
        }
        preReleaseIdentifiers[numIdentifiers] = string(buffer);
        leftBound = i + 1;
        numIdentifiers += 1;
      }
    }
    return preReleaseIdentifiers;
  }

  //
  // Math utils
  //
  /// @dev Returns the minimum of two unsigned integers
  /// @param a The first unsigned integer
  /// @param b The first unsigned integer
  function min(uint a, uint b) internal returns (uint) {
    if (a <= b) {
      return a;
    } else {
      return b;
    }
  }

  //
  // Char Utils
  //
  uint constant DIGIT_0 = uint(bytes1('0'));
  uint constant DIGIT_9 = uint(bytes1('9'));
  bytes1 constant PERIOD = bytes1('.');

  /// @dev Returns boolean indicating if the provided character is a numeric digit.
  /// @param v The character to check.
  function isDigit(bytes1 v) internal returns (bool) {
    return (uint(v) >= DIGIT_0 && uint(v) <= DIGIT_9);
  }

  //
  // String Utils
  //
  /// @dev Returns boolean indicating if the provided string is all numeric.
  /// @param value The string to check.
  function isNumericString(string value) internal returns (bool) {
    for (uint i = 0; i < bytes(value).length; i++) {
      if (!isDigit(bytes(value)[i])) {
        return false;
      }
    }

    return bytes(value).length > 0;
  }

  /// @dev Returns the integer representation of a numeric string.
  /// @param numericString The string to convert.
  function castStringToUInt(string numericString) internal returns (uint) {
    uint value = 0;

    for (uint i = 0; i < bytes(numericString).length; i++) {
      value *= 10;
      value += uint(bytes(numericString)[i]) - 48;
    }

    return value;
  }

  /// @dev Concatenates the two strings together.
  /// @param _head The first string
  /// @param tail The second string
  function concat(string storage _head, string tail) returns (bool) {
    bytes head = bytes(_head);

    for (uint i = 0; i < bytes(tail).length; i++) {
      head.push(bytes(tail)[i]);
    }

    _head = string(head);

    return true;
  }

  /// @dev Concatenates the provided byte to the end of the provided string.
  /// @param value The string to append the byte to.
  /// @param b The byte.
  function concatByte(string storage value, bytes1 b) returns (bool) {
    bytes memory _b = new bytes(1);
    _b[0] = b;
    return concat(value, string(_b));
  }
}
/// @title Library implementing an array type which allows O(1) lookups on values.
/// @author Piper Merriam <[email protected]>
library IndexedOrderedSetLib {
  struct IndexedOrderedSet {
    bytes32[] _values;
    mapping (bytes32 => uint) _valueIndices;
    mapping (bytes32 => bool) _exists;
  }

  modifier requireValue(IndexedOrderedSet storage self, bytes32 value) {
    if (contains(self, value)) {
      _;
    } else {
      throw;
    }
  }

  /// @dev Returns the size of the set
  /// @param self The set
  function size(IndexedOrderedSet storage self) constant returns (uint) {
    return self._values.length;
  }

  /// @dev Returns boolean if the key is in the set
  /// @param self The set
  /// @param value The value to check
  function contains(IndexedOrderedSet storage self, bytes32 value) constant returns (bool) {
    return self._exists[value];
  }

  /// @dev Returns the index of the value in the set.
  /// @param self The set
  /// @param value The value to look up the index for.
  function indexOf(IndexedOrderedSet storage self, bytes32 value) requireValue(self, value) 
                                                                  constant 
                                                                  returns (uint) {
    return self._valueIndices[value];
  }

  /// @dev Removes the element at index idx from the set and returns it.
  /// @param self The set
  /// @param idx The index to remove and return.
  function pop(IndexedOrderedSet storage self, uint idx) public returns (bytes32) {
    bytes32 value = get(self, idx);

    if (idx != self._values.length - 1) {
      bytes32 movedValue = self._values[self._values.length - 1];
      self._values[idx] = movedValue;
      self._valueIndices[movedValue] = idx;
    }
    self._values.length -= 1;

    delete self._valueIndices[value];
    delete self._exists[value];

    return value;
  }

  /// @dev Removes the element at index idx from the set
  /// @param self The set
  /// @param value The value to remove from the set.
  function remove(IndexedOrderedSet storage self, bytes32 value) requireValue(self, value)
                                                                 public 
                                                                 returns (bool) {
    uint idx = indexOf(self, value);
    pop(self, idx);
    return true;
  }

  /// @dev Retrieves the element at the provided index.
  /// @param self The set
  /// @param idx The index to retrieve.
  function get(IndexedOrderedSet storage self, uint idx) public returns (bytes32) {
    return self._values[idx];
  }

  /// @dev Pushes the new value onto the set
  /// @param self The set
  /// @param value The value to push.
  function add(IndexedOrderedSet storage self, bytes32 value) public returns (bool) {
    if (contains(self, value)) return true;

    self._valueIndices[value] = self._values.length;
    self._values.push(value);
    self._exists[value] = true;

    return true;
  }
}
contract Authority {
    function canCall(address callerAddress,
                     address codeAddress,
                     bytes4 sig) constant returns (bool);
}


contract AuthorizedInterface {
    address public owner;
    Authority public authority;

    modifier auth {
        if (!isAuthorized()) throw;
        _;
    }

    event OwnerUpdate(address indexed oldOwner, address indexed newOwner);
    event AuthorityUpdate(address indexed oldAuthority, address indexed newAuthority);

    function setOwner(address newOwner) public auth returns (bool);

    function setAuthority(Authority newAuthority) public auth returns (bool);

    function isAuthorized() internal returns (bool);
}


contract Authorized is AuthorizedInterface {
    function Authorized() {
        owner = msg.sender;
        OwnerUpdate(0x0, owner);
    }

    function setOwner(address newOwner) public auth returns (bool) {
        OwnerUpdate(owner, newOwner);
        owner = newOwner;
        return true;
    }

    function setAuthority(Authority newAuthority) public auth returns (bool) {
        AuthorityUpdate(authority, newAuthority);
        authority = newAuthority;
        return true;
    }

    function isAuthorized() internal returns (bool) {
        if (msg.sender == owner) {
            return true;
        } else if (address(authority) == (0)) {
            return false;
        } else {
            return authority.canCall(msg.sender, this, msg.sig);
        }
    }
}


contract WhitelistAuthorityInterface is Authority, AuthorizedInterface {
    event SetCanCall(address indexed callerAddress,
                     address indexed codeAddress,
                     bytes4 indexed sig,
                     bool can);

    event SetAnyoneCanCall(address indexed codeAddress,
                           bytes4 indexed sig,
                           bool can);

    function setCanCall(address callerAddress,
                        address codeAddress,
                        bytes4 sig,
                        bool can) auth public returns (bool);

    function setAnyoneCanCall(address codeAddress,
                              bytes4 sig,
                              bool can) auth public returns (bool);
}


contract WhitelistAuthority is WhitelistAuthorityInterface, Authorized {
    mapping (address =>
             mapping (address =>
                      mapping (bytes4 => bool))) _canCall;
    mapping (address => mapping (bytes4 => bool)) _anyoneCanCall;

    function canCall(address callerAddress,
                     address codeAddress,
                     bytes4 sig) constant returns (bool) {
        if (_anyoneCanCall[codeAddress][sig]) {
          return true;
        } else {
          return _canCall[callerAddress][codeAddress][sig];
        }
    }

    function setCanCall(address callerAddress,
                        address codeAddress,
                        bytes4 sig,
                        bool can) auth public returns (bool) {
        _canCall[callerAddress][codeAddress][sig] = can;
        SetCanCall(callerAddress, codeAddress, sig, can);
        return true;
    }

    function setAnyoneCanCall(address codeAddress,
                              bytes4 sig,
                              bool can) auth public returns (bool) {
        _anyoneCanCall[codeAddress][sig] = can;
        SetAnyoneCanCall(codeAddress, sig, can);
        return true;
    }
}
/// @title Database contract for a package index package data.
/// @author Tim Coulter <[email protected]>, Piper Merriam <[email protected]>
contract PackageDB is Authorized {
  using SemVersionLib for SemVersionLib.SemVersion;
  using IndexedOrderedSetLib for IndexedOrderedSetLib.IndexedOrderedSet;

  struct Package {
      bool exists;
      uint createdAt;
      uint updatedAt;
      string name;
      address owner;
  }

  // Package Data: (nameHash => value)
  mapping (bytes32 => Package) _recordedPackages;
  IndexedOrderedSetLib.IndexedOrderedSet _allPackageNameHashes;

  // Events
  event PackageReleaseAdd(bytes32 indexed nameHash, bytes32 indexed releaseHash);
  event PackageReleaseRemove(bytes32 indexed nameHash, bytes32 indexed releaseHash);
  event PackageCreate(bytes32 indexed nameHash);
  event PackageDelete(bytes32 indexed nameHash, string reason);
  event PackageOwnerUpdate(bytes32 indexed nameHash, address indexed oldOwner, address indexed newOwner);

  /*
   *  Modifiers
   */
  modifier onlyIfPackageExists(bytes32 nameHash) {
    if (packageExists(nameHash)) {
      _;
    } else {
      throw;
    }
  }

  //
  //  +-------------+
  //  |  Write API  |
  //  +-------------+
  //

  /// @dev Creates or updates a release for a package.  Returns success.
  /// @param name Package name
  function setPackage(string name) public auth returns (bool){
    // Hash the name and the version for storing data
    bytes32 nameHash = hashName(name);

    var package = _recordedPackages[nameHash];

    // Mark the package as existing if it isn't already tracked.
    if (!packageExists(nameHash)) {

      // Set package data
      package.exists = true;
      package.createdAt = now;
      package.name = name;

      // Add the nameHash to the list of all package nameHashes.
      _allPackageNameHashes.add(nameHash);

      PackageCreate(nameHash);
    }

    package.updatedAt = now;

    return true;
  }

  /// @dev Removes a package from the package db.  Packages with existing releases may not be removed.  Returns success.
  /// @param nameHash The name hash of a package.
  function removePackage(bytes32 nameHash, string reason) public 
                                                          auth 
                                                          onlyIfPackageExists(nameHash) 
                                                          returns (bool) {
    PackageDelete(nameHash, reason);

    delete _recordedPackages[nameHash];
    _allPackageNameHashes.remove(nameHash);

    return true;
  }

  /// @dev Sets the owner of a package to the provided address.  Returns success.
  /// @param nameHash The name hash of a package.
  /// @param newPackageOwner The address of the new owner.
  function setPackageOwner(bytes32 nameHash,
                           address newPackageOwner) public 
                                                    auth 
                                                    onlyIfPackageExists(nameHash)
                                                    returns (bool) {
    PackageOwnerUpdate(nameHash, _recordedPackages[nameHash].owner, newPackageOwner);

    _recordedPackages[nameHash].owner = newPackageOwner;
    _recordedPackages[nameHash].updatedAt = now;

    return true;
  }

  //
  //  +------------+
  //  |  Read API  |
  //  +------------+
  //

  /// @dev Query the existence of a package with the given name.  Returns boolean indicating whether the package exists.
  /// @param nameHash The name hash of a package.
  function packageExists(bytes32 nameHash) constant returns (bool) {
    return _recordedPackages[nameHash].exists;
  }

  /// @dev Return the total number of packages
  function getNumPackages() constant returns (uint) {
    return _allPackageNameHashes.size();
  }

  /// @dev Returns package namehash at the provided index from the set of all known name hashes.
  /// @param idx The index of the package name hash to retrieve.
  function getPackageNameHash(uint idx) constant returns (bytes32) {
    return _allPackageNameHashes.get(idx);
  }

  /// @dev Returns information about the package.
  /// @param nameHash The name hash to look up.
  function getPackageData(bytes32 nameHash) constant 
                                            onlyIfPackageExists(nameHash) 
                                            returns (address packageOwner,
                                                     uint createdAt,
                                                     uint updatedAt) {
    var package = _recordedPackages[nameHash];
    return (package.owner, package.createdAt, package.updatedAt);
  }

  /// @dev Returns the package name for the given namehash
  /// @param nameHash The name hash to look up.
  function getPackageName(bytes32 nameHash) constant 
                                            onlyIfPackageExists(nameHash) 
                                            returns (string) {
    return _recordedPackages[nameHash].name;
  }

  /*
   *  Hash Functions
   */
  /// @dev Returns name hash for a given package name.
  /// @param name Package name
  function hashName(string name) constant returns (bytes32) {
    return sha3(name);
  }
}
contract ReleaseDB is Authorized {
  using SemVersionLib for SemVersionLib.SemVersion;
  using IndexedOrderedSetLib for IndexedOrderedSetLib.IndexedOrderedSet;

  struct Release {
    bool exists;
    uint createdAt;
    uint updatedAt;
    bytes32 nameHash;
    bytes32 versionHash;
    string releaseLockfileURI;
  }

  // Release Data: (releaseHash => value)
  mapping (bytes32 => Release) _recordedReleases;
  IndexedOrderedSetLib.IndexedOrderedSet _allReleaseHashes;
  mapping (bytes32 => IndexedOrderedSetLib.IndexedOrderedSet) _releaseHashesByNameHash;

  // Version Data: (versionHash => value)
  mapping (bytes32 => SemVersionLib.SemVersion) _recordedVersions;
  mapping (bytes32 => bool) _versionExists;

  // Events
  event ReleaseCreate(bytes32 indexed releaseHash);
  event ReleaseUpdate(bytes32 indexed releaseHash);
  event ReleaseDelete(bytes32 indexed releaseHash, string reason);

  /*
   * Latest released version tracking for each branch of the release tree.
   */
  // (nameHash => releaseHash);
  mapping (bytes32 => bytes32) _latestMajor;

  // (nameHash => major => releaseHash);
  mapping (bytes32 => mapping(uint32 => bytes32)) _latestMinor;

  // (nameHash => major => minor => releaseHash);
  mapping (bytes32 => mapping (uint32 => mapping(uint32 => bytes32))) _latestPatch;

  // (nameHash => major => minor => patch => releaseHash);
  mapping (bytes32 => mapping (uint32 => mapping(uint32 => mapping (uint32 => bytes32)))) _latestPreRelease;

  /*
   *  Modifiers
   */
  modifier onlyIfVersionExists(bytes32 versionHash) {
    if (versionExists(versionHash)) {
      _;
    } else {
      throw;
    }
  }

  modifier onlyIfReleaseExists(bytes32 releaseHash) {
    if (releaseExists(releaseHash)) {
      _;
    } else {
      throw;
    }
  }

  //
  // +-------------+
  // |  Write API  |
  // +-------------+
  //

  /// @dev Creates or updates a release for a package.  Returns success.
  /// @param nameHash The name hash of the package.
  /// @param versionHash The version hash for the release version.
  /// @param releaseLockfileURI The URI for the release lockfile for this release.
  function setRelease(bytes32 nameHash,
                      bytes32 versionHash,
                      string releaseLockfileURI) public auth returns (bool) {
    bytes32 releaseHash = hashRelease(nameHash, versionHash);

    var release = _recordedReleases[releaseHash];

    // If this is a new version push it onto the array of version hashes for
    // this package.
    if (release.exists) {
      ReleaseUpdate(releaseHash);
    } else {
      // Populate the basic rlease data.
      release.exists = true;
      release.createdAt = now;
      release.nameHash = nameHash;
      release.versionHash = versionHash;

      // Push the release hash into the array of all release hashes.
      _allReleaseHashes.add(releaseHash);
      _releaseHashesByNameHash[nameHash].add(releaseHash);

      ReleaseCreate(releaseHash);
    }

    // Record the last time the release was updated.
    release.updatedAt = now;

    // Save the release lockfile URI
    release.releaseLockfileURI = releaseLockfileURI;

    // Track latest released versions for each branch of the release tree.
    updateLatestTree(releaseHash);

    return true;
  }

  /// @dev Removes a release from a package.  Returns success.
  /// @param releaseHash The release hash to be removed
  /// @param reason Explanation for why the removal happened.
  function removeRelease(bytes32 releaseHash, string reason) public
                                                             auth
                                                             onlyIfReleaseExists(releaseHash) 
                                                             returns (bool) {
    var (nameHash, versionHash,) = getReleaseData(releaseHash);
    var (major, minor, patch) = getMajorMinorPatch(versionHash);

    // In any branch of the release tree in which this version is the latest we
    // remove it.  This will leave the release tree for this package in an
    // invalid state.  The `updateLatestTree` function` provides a path to
    // recover from this state.  The naive approach would be to call it on all
    // release hashes in the array of remaining package release hashes which
    // will properly repopulate the release tree for this package.
    if (isLatestMajorTree(nameHash, versionHash)) {
      delete _latestMajor[nameHash];
    }
    if (isLatestMinorTree(nameHash, versionHash)) {
      delete _latestMinor[nameHash][major];
    }
    if (isLatestPatchTree(nameHash, versionHash)) {
      delete _latestPatch[nameHash][major][minor];
    }
    if (isLatestPreReleaseTree(nameHash, versionHash)) {
      delete _latestPreRelease[nameHash][major][minor][patch];
    }

    // Zero out the release data.
    delete _recordedReleases[releaseHash];

    // Remove the release hash from the list of all release hashes
    _allReleaseHashes.remove(releaseHash);
    _releaseHashesByNameHash[nameHash].remove(releaseHash);

    // Log the removal.
    ReleaseDelete(releaseHash, reason);

    return true;
  }

  /// @dev Updates each branch of the tree, replacing the current leaf node with this release hash if this release hash should be the new leaf.  Returns success.
  /// @param releaseHash The releaseHash to check.
  function updateLatestTree(bytes32 releaseHash) public auth returns (bool) {
    updateMajorTree(releaseHash);
    updateMinorTree(releaseHash);
    updatePatchTree(releaseHash);
    updatePreReleaseTree(releaseHash);
    return true;
  }

  /// @dev Adds the given version to the local version database.  Returns the versionHash for the provided version.
  /// @param major The major portion of the semver version string.
  /// @param minor The minor portion of the semver version string.
  /// @param patch The patch portion of the semver version string.
  /// @param preRelease The pre-release portion of the semver version string.  Use empty string if the version string has no pre-release portion.
  /// @param build The build portion of the semver version string.  Use empty string if the version string has no build portion.
  function setVersion(uint32 major,
                      uint32 minor,
                      uint32 patch,
                      string preRelease,
                      string build) public auth returns (bytes32) {
    bytes32 versionHash = hashVersion(major, minor, patch, preRelease, build);

    if (!_versionExists[versionHash]) {
      _recordedVersions[versionHash].init(major, minor, patch, preRelease, build);
      _versionExists[versionHash] = true;
    }
    return versionHash;
  }

  //
  // +------------+
  // |  Read API  |
  // +------------+
  //

  /// @dev Get the total number of releases
  function getNumReleases() constant returns (uint) {
    return _allReleaseHashes.size();
  }

  /// @dev Get the total number of releases
  /// @param idx The index of the release hash to retrieve.
  function getReleaseHash(uint idx) constant returns (bytes32) {
    return _allReleaseHashes.get(idx);
  }

  /// @dev Get the total number of releases
  /// @param nameHash the name hash to lookup.
  function getNumReleasesForNameHash(bytes32 nameHash) constant returns (uint) {
    return _releaseHashesByNameHash[nameHash].size();
  }

  /// @dev Get the total number of releases
  /// @param nameHash the name hash to lookup.
  /// @param idx The index of the release hash to retrieve.
  function getReleaseHashForNameHash(bytes32 nameHash, uint idx) constant returns (bytes32) {
    return _releaseHashesByNameHash[nameHash].get(idx);
  }

  /// @dev Query the existence of a release at the provided version for a package.  Returns boolean indicating whether such a release exists.
  /// @param releaseHash The release hash to query.
  function releaseExists(bytes32 releaseHash) constant returns (bool) {
    return _recordedReleases[releaseHash].exists;
  }

  /// @dev Query the existence of the provided version in the recorded versions.  Returns boolean indicating whether such a version exists.
  /// @param versionHash the version hash to check.
  function versionExists(bytes32 versionHash) constant returns (bool) {
    return _versionExists[versionHash];
  }

  /// @dev Returns the releaseHash at the given index for a package.
  /// @param releaseHash The release hash.
  function getReleaseData(bytes32 releaseHash) onlyIfReleaseExists(releaseHash)
                                               constant 
                                               returns (bytes32 nameHash,
                                                        bytes32 versionHash,
                                                        uint createdAt,
                                                        uint updatedAt) {
    var release = _recordedReleases[releaseHash];
    return (release.nameHash, release.versionHash, release.createdAt, release.updatedAt);
  }

  /// @dev Returns a 3-tuple of the major, minor, and patch components from the version of the given release hash.
  /// @param versionHash the version hash
  function getMajorMinorPatch(bytes32 versionHash) onlyIfVersionExists(versionHash) 
                                                   constant 
                                                   returns (uint32, uint32, uint32) {
    var version = _recordedVersions[versionHash];
    return (version.major, version.minor, version.patch);
  }

  /// @dev Returns the pre-release string from the version of the given release hash.
  /// @param releaseHash Release hash
  function getPreRelease(bytes32 releaseHash) onlyIfReleaseExists(releaseHash) 
                                              constant 
                                              returns (string) {
    return _recordedVersions[_recordedReleases[releaseHash].versionHash].preRelease;
  }

  /// @dev Returns the build string from the version of the given release hash.
  /// @param releaseHash Release hash
  function getBuild(bytes32 releaseHash) onlyIfReleaseExists(releaseHash) 
                                         constant 
                                         returns (string) {
    return _recordedVersions[_recordedReleases[releaseHash].versionHash].build;
  }

  /// @dev Returns the URI of the release lockfile for the given release hash.
  /// @param releaseHash Release hash
  function getReleaseLockfileURI(bytes32 releaseHash) onlyIfReleaseExists(releaseHash)
                                                      constant 
                                                      returns (string) {
    return _recordedReleases[releaseHash].releaseLockfileURI;
  }

  /*
   *  Hash Functions
   */
  /// @dev Returns version hash for the given semver version.
  /// @param major The major portion of the semver version string.
  /// @param minor The minor portion of the semver version string.
  /// @param patch The patch portion of the semver version string.
  /// @param preRelease The pre-release portion of the semver version string.  Use empty string if the version string has no pre-release portion.
  /// @param build The build portion of the semver version string.  Use empty string if the version string has no build portion.
  function hashVersion(uint32 major,
                       uint32 minor,
                       uint32 patch,
                       string preRelease,
                       string build) constant returns (bytes32) {
    return sha3(major, minor, patch, preRelease, build);
  }

  /// @dev Returns release hash for the given release
  /// @param nameHash The name hash of the package name.
  /// @param versionHash The version hash for the release version.
  function hashRelease(bytes32 nameHash,
                       bytes32 versionHash) constant returns (bytes32) {
    return sha3(nameHash, versionHash);
  }

  /*
   *  Latest version querying API
   */

  /// @dev Returns the release hash of the latest release in the major branch of the package release tree.
  /// @param nameHash The nameHash of the package
  function getLatestMajorTree(bytes32 nameHash) constant returns (bytes32) {
    return _latestMajor[nameHash];
  }

  /// @dev Returns the release hash of the latest release in the minor branch of the package release tree.
  /// @param nameHash The nameHash of the package
  /// @param major The branch of the major portion of the release tree to check.
  function getLatestMinorTree(bytes32 nameHash, uint32 major) constant returns (bytes32) {
    return _latestMinor[nameHash][major];
  }

  /// @dev Returns the release hash of the latest release in the patch branch of the package release tree.
  /// @param nameHash The nameHash of the package
  /// @param major The branch of the major portion of the release tree to check.
  /// @param minor The branch of the minor portion of the release tree to check.
  function getLatestPatchTree(bytes32 nameHash,
                              uint32 major,
                              uint32 minor) constant returns (bytes32) {
    return _latestPatch[nameHash][major][minor];
  }

  /// @dev Returns the release hash of the latest release in the pre-release branch of the package release tree.
  /// @param nameHash The nameHash of the package
  /// @param major The branch of the major portion of the release tree to check.
  /// @param minor The branch of the minor portion of the release tree to check.
  /// @param patch The branch of the patch portion of the release tree to check.
  function getLatestPreReleaseTree(bytes32 nameHash,
                                   uint32 major,
                                   uint32 minor,
                                   uint32 patch) constant returns (bytes32) {
    return _latestPreRelease[nameHash][major][minor][patch];
  }

  /// @dev Returns boolean indicating whethe the given version hash is the latest version in the major branch of the release tree.
  /// @param nameHash The nameHash of the package to check against.
  /// @param versionHash The versionHash of the version to check.
  function isLatestMajorTree(bytes32 nameHash,
                             bytes32 versionHash) onlyIfVersionExists(versionHash) 
                                                  constant 
                                                  returns (bool) {
    var version = _recordedVersions[versionHash];
    var latestMajor = _recordedVersions[_recordedReleases[getLatestMajorTree(nameHash)].versionHash];
    return version.isGreaterOrEqual(latestMajor);
  }

  /// @dev Returns boolean indicating whethe the given version hash is the latest version in the minor branch of the release tree.
  /// @param nameHash The nameHash of the package to check against.
  /// @param versionHash The versionHash of the version to check.
  function isLatestMinorTree(bytes32 nameHash,
                             bytes32 versionHash) onlyIfVersionExists(versionHash) 
                                                  constant 
                                                  returns (bool) {
    var version = _recordedVersions[versionHash];
    var latestMinor = _recordedVersions[_recordedReleases[getLatestMinorTree(nameHash, version.major)].versionHash];
    return version.isGreaterOrEqual(latestMinor);
  }

  /// @dev Returns boolean indicating whethe the given version hash is the latest version in the patch branch of the release tree.
  /// @param nameHash The nameHash of the package to check against.
  /// @param versionHash The versionHash of the version to check.
  function isLatestPatchTree(bytes32 nameHash,
                             bytes32 versionHash) onlyIfVersionExists(versionHash) 
                                                  constant 
                                                  returns (bool) {
    var version = _recordedVersions[versionHash];
    var latestPatch = _recordedVersions[_recordedReleases[getLatestPatchTree(nameHash, version.major, version.minor)].versionHash];
    return version.isGreaterOrEqual(latestPatch);
  }

  /// @dev Returns boolean indicating whethe the given version hash is the latest version in the pre-release branch of the release tree.
  /// @param nameHash The nameHash of the package to check against.
  /// @param versionHash The versionHash of the version to check.
  function isLatestPreReleaseTree(bytes32 nameHash,
                                  bytes32 versionHash) onlyIfVersionExists(versionHash) 
                                                       constant 
                                                       returns (bool) {
    var version = _recordedVersions[versionHash];
    var latestPreRelease = _recordedVersions[_recordedReleases[getLatestPreReleaseTree(nameHash, version.major, version.minor, version.patch)].versionHash];
    return version.isGreaterOrEqual(latestPreRelease);
  }

  //
  // +----------------+
  // |  Internal API  |
  // +----------------+
  //

  /*
   *  Tracking of latest releases for each branch of the release tree.
   */

  /// @dev Sets the given release as the new leaf of the major branch of the release tree if it is greater or equal to the current leaf.
  /// @param releaseHash The release hash of the release to check.
  function updateMajorTree(bytes32 releaseHash) onlyIfReleaseExists(releaseHash) 
                                                internal 
                                                returns (bool) {
    var (nameHash, versionHash,) = getReleaseData(releaseHash);

    if (isLatestMajorTree(nameHash, versionHash)) {
      _latestMajor[nameHash] = releaseHash;
      return true;
    } else {
      return false;
    }
  }

  /// @dev Sets the given release as the new leaf of the minor branch of the release tree if it is greater or equal to the current leaf.
  /// @param releaseHash The release hash of the release to check.
  function updateMinorTree(bytes32 releaseHash) internal returns (bool) {
    var (nameHash, versionHash,) = getReleaseData(releaseHash);

    if (isLatestMinorTree(nameHash, versionHash)) {
      var (major,) = getMajorMinorPatch(versionHash);
      _latestMinor[nameHash][major] = releaseHash;
      return true;
    } else {
      return false;
    }
  }

  /// @dev Sets the given release as the new leaf of the patch branch of the release tree if it is greater or equal to the current leaf.
  /// @param releaseHash The release hash of the release to check.
  function updatePatchTree(bytes32 releaseHash) internal returns (bool) {
    var (nameHash, versionHash,) = getReleaseData(releaseHash);

    if (isLatestPatchTree(nameHash, versionHash)) {
      var (major, minor,) = getMajorMinorPatch(versionHash);
      _latestPatch[nameHash][major][minor] = releaseHash;
      return true;
    } else {
      return false;
    }
  }

  /// @dev Sets the given release as the new leaf of the pre-release branch of the release tree if it is greater or equal to the current leaf.
  /// @param releaseHash The release hash of the release to check.
  function updatePreReleaseTree(bytes32 releaseHash) internal returns (bool) {
    var (nameHash, versionHash,) = getReleaseData(releaseHash);

    if (isLatestPreReleaseTree(nameHash, versionHash)) {
      var (major, minor, patch) = getMajorMinorPatch(versionHash);
      _latestPreRelease[nameHash][major][minor][patch] = releaseHash;
      return true;
    } else {
      return false;
    }
  }
}
contract ReleaseValidator {
  /// @dev Runs validation on all of the data needed for releasing a package.  Returns success.
  /// @param packageDb The address of the PackageDB
  /// @param releaseDb The address of the ReleaseDB
  /// @param callerAddress The address which is attempting to create the release.
  /// @param name The name of the package.
  /// @param majorMinorPatch The major/minor/patch portion of the version string.
  /// @param preRelease The pre-release portion of the version string.
  /// @param build The build portion of the version string.
  /// @param releaseLockfileURI The URI of the release lockfile.
  function validateRelease(PackageDB packageDb,
                           ReleaseDB releaseDb,
                           address callerAddress,
                           string name,
                           uint32[3] majorMinorPatch,
                           string preRelease,
                           string build,
                           string releaseLockfileURI) constant returns (bool) {
    if (address(packageDb) == 0x0 || address(releaseDb) == 0x0) throw;

    if (!validateAuthorization(packageDb, callerAddress, name)) {
      // package exists and msg.sender is not the owner not the package owner.
      return false;
    } else if (!validateIsNewRelease(packageDb, releaseDb, name, majorMinorPatch, preRelease, build)) {
      // this version has already been released.
      return false;
    } else if (!validatePackageName(packageDb, name)) {
      // invalid package name.
      return false;
    } else if (!validateReleaseLockfileURI(releaseLockfileURI)) {
      // disallow empty release lockfile URI
      return false;
    } else if (!validateReleaseVersion(majorMinorPatch)) {
      // disallow version 0.0.0
      return false;
    } else if (!validateIsAnyLatest(packageDb, releaseDb, name, majorMinorPatch, preRelease, build)) {
      // Only allow releasing of versions which are the latest in their
      // respective branch of the release tree.
      return false;
    }
    return true;
  }

  /// @dev Validate whether the callerAddress is authorized to make this release.
  /// @param packageDb The address of the PackageDB
  /// @param callerAddress The address which is attempting to create the release.
  /// @param name The name of the package.
  function validateAuthorization(PackageDB packageDb,
                                 address callerAddress,
                                 string name) constant returns (bool) {
    bytes32 nameHash = packageDb.hashName(name);
    if (!packageDb.packageExists(nameHash)) {
      return true;
    }
    var (packageOwner,) = packageDb.getPackageData(nameHash);
    if (packageOwner == callerAddress) {
      return true;
    }
    return false;
  }

  /// @dev Validate that the version being released has not already been released.
  /// @param packageDb The address of the PackageDB
  /// @param releaseDb The address of the ReleaseDB
  /// @param name The name of the package.
  /// @param majorMinorPatch The major/minor/patch portion of the version string.
  /// @param preRelease The pre-release portion of the version string.
  /// @param build The build portion of the version string.
  function validateIsNewRelease(PackageDB packageDb,
                                ReleaseDB releaseDb,
                                string name,
                                uint32[3] majorMinorPatch,
                                string preRelease,
                                string build) constant returns (bool) {
    var nameHash = packageDb.hashName(name);
    var versionHash = releaseDb.hashVersion(majorMinorPatch[0], majorMinorPatch[1], majorMinorPatch[2], preRelease, build);
    var releaseHash = releaseDb.hashRelease(nameHash, versionHash);
    return !releaseDb.releaseExists(releaseHash);
  }

  uint constant DIGIT_0 = uint(bytes1('0'));
  uint constant DIGIT_9 = uint(bytes1('9'));
  uint constant LETTER_a = uint(bytes1('a'));
  uint constant LETTER_z = uint(bytes1('z'));
  bytes1 constant DASH = bytes1('-');

  /// @dev Returns boolean whether the provided package name is valid.
  /// @param packageDb The address of the PackageDB
  /// @param name The name of the package.
  function validatePackageName(PackageDB packageDb, string name) constant returns (bool) {
    var nameHash = packageDb.hashName(name);

    if (packageDb.packageExists(nameHash)) {
      // existing names are always valid.
      return true;
    }

    if (bytes(name).length < 2 || bytes(name).length > 214) {
      return false;
    }
    for (uint i=0; i < bytes(name).length; i++) {
      if (bytes(name)[i] == DASH && i > 0) {
        continue;
      } else if (i > 0 && uint(bytes(name)[i]) >= DIGIT_0 && uint(bytes(name)[i]) <= DIGIT_9) {
        continue;
      } else if (uint(bytes(name)[i]) >= LETTER_a && uint(bytes(name)[i]) <= LETTER_z) {
        continue;
      } else {
        return false;
      }
    }
    return true;
  }

  /// @dev Returns boolean whether the provided release lockfile URI is valid.
  /// @param releaseLockfileURI The URI for a release lockfile.
  function validateReleaseLockfileURI(string releaseLockfileURI) constant returns (bool) {
    if (bytes(releaseLockfileURI).length ==0) {
      return false;
    }
    return true;
  }

  /// @dev Validate that the version is not 0.0.0.
  /// @param majorMinorPatch The major/minor/patch portion of the version string.
  function validateReleaseVersion(uint32[3] majorMinorPatch) constant returns (bool) {
    if (majorMinorPatch[0] > 0) {
      return true;
    } else if (majorMinorPatch[1] > 0) {
      return true;
    } else if (majorMinorPatch[2] > 0) {
      return true;
    } else {
      return false;
    }
  }

  /// @dev Validate that the version being released is the latest in at least one branch of the release tree.
  /// @param packageDb The address of the PackageDB
  /// @param releaseDb The address of the ReleaseDB
  /// @param name The name of the package.
  /// @param majorMinorPatch The major/minor/patch portion of the version string.
  /// @param preRelease The pre-release portion of the version string.
  /// @param build The build portion of the version string.
  function validateIsAnyLatest(PackageDB packageDb,
                               ReleaseDB releaseDb,
                               string name,
                               uint32[3] majorMinorPatch,
                               string preRelease,
                               string build) constant returns (bool) {
    var nameHash = packageDb.hashName(name);
    var versionHash = releaseDb.hashVersion(majorMinorPatch[0], majorMinorPatch[1], majorMinorPatch[2], preRelease, build);
    if (releaseDb.isLatestMajorTree(nameHash, versionHash)) {
      return true;
    } else if (hasLatestMinor(releaseDb, nameHash, versionHash) && releaseDb.isLatestMinorTree(nameHash, versionHash)) {
      return true;
    } else if (hasLatestPatch(releaseDb, nameHash, versionHash) && releaseDb.isLatestPatchTree(nameHash, versionHash)) {
      return true;
    } else if (hasLatestPreRelease(releaseDb, nameHash, versionHash) && releaseDb.isLatestPreReleaseTree(nameHash, versionHash)) {
      return true;
    } else {
      return false;
    }
  }

  /// @dev Returns boolean indicating whether there is a latest minor version in the version tree indicated by the provided version has for the package indicated by the provided name hash.
  /// @param releaseDb The address of the ReleaseDB
  /// @param nameHash The nameHash of the package to check against.
  /// @param versionHash The versionHash of the version to check.
  function hasLatestMinor(ReleaseDB releaseDb, bytes32 nameHash, bytes32 versionHash) constant returns (bool) {
    var (major,) = releaseDb.getMajorMinorPatch(versionHash);
    return releaseDb.getLatestMinorTree(nameHash, major) != 0x0;
  }

  /// @dev Returns boolean indicating whether there is a latest patch version in the version tree indicated by the provided version has for the package indicated by the provided name hash.
  /// @param releaseDb The address of the ReleaseDB
  /// @param nameHash The nameHash of the package to check against.
  /// @param versionHash The versionHash of the version to check.
  function hasLatestPatch(ReleaseDB releaseDb, bytes32 nameHash, bytes32 versionHash) constant returns (bool) {
    var (major, minor,) = releaseDb.getMajorMinorPatch(versionHash);
    return releaseDb.getLatestPatchTree(nameHash, major, minor) != 0x0;
  }

  /// @dev Returns boolean indicating whether there is a latest pre-release version in the version tree indicated by the provided version has for the package indicated by the provided name hash.
  /// @param releaseDb The address of the ReleaseDB
  /// @param nameHash The nameHash of the package to check against.
  /// @param versionHash The versionHash of the version to check.
  function hasLatestPreRelease(ReleaseDB releaseDb, bytes32 nameHash, bytes32 versionHash) constant returns (bool) {
    var (major, minor, patch) = releaseDb.getMajorMinorPatch(versionHash);
    return releaseDb.getLatestPreReleaseTree(nameHash, major, minor, patch) != 0x0;
  }
}
/// @title Database contract for a package index.
/// @author Tim Coulter <[email protected]>, Piper Merriam <[email protected]>
contract PackageIndexInterface is AuthorizedInterface {
  //
  // Events
  //
  event PackageRelease(bytes32 indexed nameHash, bytes32 indexed releaseHash);
  event PackageTransfer(address indexed oldOwner, address indexed newOwner);

  //
  // Administrative API
  //
  /// @dev Sets the address of the PackageDb contract.
  /// @param newPackageDb The address to set for the PackageDb.
  function setPackageDb(address newPackageDb) public auth returns (bool);

  /// @dev Sets the address of the ReleaseDb contract.
  /// @param newReleaseDb The address to set for the ReleaseDb.
  function setReleaseDb(address newReleaseDb) public auth returns (bool);

  /// @dev Sets the address of the ReleaseValidator contract.
  /// @param newReleaseValidator The address to set for the ReleaseValidator.
  function setReleaseValidator(address newReleaseValidator) public auth returns (bool);

  //
  // +-------------+
  // |  Write API  |
  // +-------------+
  //
  /// @dev Creates a a new release for the named package.  If this is the first release for the given package then this will also assign msg.sender as the owner of the package.  Returns success.
  /// @notice Will create a new release the given package with the given release information.
  /// @param name Package name
  /// @param major The major portion of the semver version string.
  /// @param minor The minor portion of the semver version string.
  /// @param patch The patch portion of the semver version string.
  /// @param preRelease The pre-release portion of the semver version string.  Use empty string if the version string has no pre-release portion.
  /// @param build The build portion of the semver version string.  Use empty string if the version string has no build portion.
  /// @param releaseLockfileURI The URI for the release lockfile for this release.
  function release(string name,
                   uint32 major,
                   uint32 minor,
                   uint32 patch,
                   string preRelease,
                   string build,
                   string releaseLockfileURI) public auth returns (bool);

  /// @dev Transfers package ownership to the provider new owner address.
  /// @notice Will transfer ownership of this package to the provided new owner address.
  /// @param name Package name
  /// @param newPackageOwner The address of the new owner.
  function transferPackageOwner(string name,
                                address newPackageOwner) public auth returns (bool);

  //
  // +------------+
  // |  Read API  |
  // +------------+
  //

  /// @dev Returns the address of the packageDb
  function getPackageDb() constant returns (address);

  /// @dev Returns the address of the releaseDb
  function getReleaseDb() constant returns (address);

  /// @dev Returns the address of the releaseValidator
  function getReleaseValidator() constant returns (address);

  /// @dev Query the existence of a package with the given name.  Returns boolean indicating whether the package exists.
  /// @param name Package name
  function packageExists(string name) constant returns (bool);

  /// @dev Query the existence of a release at the provided version for the named package.  Returns boolean indicating whether such a release exists.
  /// @param name Package name
  /// @param major The major portion of the semver version string.
  /// @param minor The minor portion of the semver version string.
  /// @param patch The patch portion of the semver version string.
  /// @param preRelease The pre-release portion of the semver version string.  Use empty string if the version string has no pre-release portion.
  /// @param build The build portion of the semver version string.  Use empty string if the version string has no build portion.
  function releaseExists(string name,
                         uint32 major,
                         uint32 minor,
                         uint32 patch,
                         string preRelease,
                         string build) constant returns (bool);

  /// @dev Returns the number of packages in the index
  function getNumPackages() constant returns (uint);

  /// @dev Returns the name of the package at the provided index
  /// @param idx The index of the name hash to lookup.
  function getPackageName(uint idx) constant returns (string);

  /// @dev Returns the package data.
  /// @param name Package name
  function getPackageData(string name) constant
                                       returns (address packageOwner,
                                                uint createdAt,
                                                uint numReleases,
                                                uint updatedAt);

  /// @dev Returns the release data for the release associated with the given release hash.
  /// @param releaseHash The release hash.
  function getReleaseData(bytes32 releaseHash) constant returns (uint32 major,
                                                                 uint32 minor,
                                                                 uint32 patch,
                                                                 string preRelease,
                                                                 string build,
                                                                 string releaseLockfileURI,
                                                                 uint createdAt,
                                                                 uint updatedAt);

  /// @dev Returns the release hash at the provide index in the array of all release hashes.
  /// @param idx The index of the release to retrieve.
  function getReleaseHash(uint idx) constant returns (bytes32);

  /// @dev Returns the release hash at the provide index in the array of release hashes for the given package.
  /// @param name Package name
  /// @param releaseIdx The index of the release to retrieve.
  function getReleaseHashForPackage(string name,
                                    uint releaseIdx) constant returns (bytes32);

  /// @dev Returns an array of all release hashes for the named package.
  /// @param name Package name
  function getAllPackageReleaseHashes(string name) constant returns (bytes32[]);

  /// @dev Returns a slice of the array of all release hashes for the named package.
  /// @param name Package name
  /// @param offset The starting index for the slice.
  /// @param numReleases The length of the slice
  function getPackageReleaseHashes(string name,
                                   uint offset,
                                   uint numReleases) constant returns (bytes32[]);

  function getNumReleases() constant returns (uint);

  /// @dev Returns an array of all release hashes for the named package.
  function getAllReleaseHashes() constant returns (bytes32[]);

  /// @dev Returns a slice of the array of all release hashes for the named package.
  /// @param offset The starting index for the slice.
  /// @param numReleases The length of the slice
  function getReleaseHashes(uint offset, uint numReleases) constant returns (bytes32[]);

  /// @dev Returns the release lockfile for the given release data
  /// @param name Package name
  /// @param major The major portion of the semver version string.
  /// @param minor The minor portion of the semver version string.
  /// @param patch The patch portion of the semver version string.
  /// @param preRelease The pre-release portion of the semver version string.  Use empty string if the version string has no pre-release portion.
  /// @param build The build portion of the semver version string.  Use empty string if the version string has no build portion.
  function getReleaseLockfileURI(string name,
                                uint32 major,
                                uint32 minor,
                                uint32 patch,
                                string preRelease,
                                string build) constant returns (string);
}
/// @title Database contract for a package index.
/// @author Tim Coulter <[email protected]>, Piper Merriam <[email protected]>
contract PackageIndex is Authorized, PackageIndexInterface {
  PackageDB private packageDb;
  ReleaseDB private releaseDb;
  ReleaseValidator private releaseValidator;

  //
  // Administrative API
  //
  /// @dev Sets the address of the PackageDb contract.
  /// @param newPackageDb The address to set for the PackageDb.
  function setPackageDb(address newPackageDb) public auth returns (bool) {
    packageDb = PackageDB(newPackageDb);
    return true;
  }

  /// @dev Sets the address of the ReleaseDb contract.
  /// @param newReleaseDb The address to set for the ReleaseDb.
  function setReleaseDb(address newReleaseDb) public auth returns (bool) {
    releaseDb = ReleaseDB(newReleaseDb);
    return true;
  }

  /// @dev Sets the address of the ReleaseValidator contract.
  /// @param newReleaseValidator The address to set for the ReleaseValidator.
  function setReleaseValidator(address newReleaseValidator) public auth returns (bool) {
    releaseValidator = ReleaseValidator(newReleaseValidator);
    return true;
  }

  //
  // +-------------+
  // |  Write API  |
  // +-------------+
  //
  /// @dev Creates a a new release for the named package.  If this is the first release for the given package then this will also assign msg.sender as the owner of the package.  Returns success.
  /// @notice Will create a new release the given package with the given release information.
  /// @param name Package name
  /// @param major The major portion of the semver version string.
  /// @param minor The minor portion of the semver version string.
  /// @param patch The patch portion of the semver version string.
  /// @param preRelease The pre-release portion of the semver version string.  Use empty string if the version string has no pre-release portion.
  /// @param build The build portion of the semver version string.  Use empty string if the version string has no build portion.
  /// @param releaseLockfileURI The URI for the release lockfile for this release.
  function release(string name,
                   uint32 major,
                   uint32 minor,
                   uint32 patch,
                   string preRelease,
                   string build,
                   string releaseLockfileURI) public auth returns (bool) {
    if (address(packageDb) == 0x0 || address(releaseDb) == 0x0 || address(releaseValidator) == 0x0) throw;
    return release(name, [major, minor, patch], preRelease, build, releaseLockfileURI);
  }

  /// @dev Creates a a new release for the named package.  If this is the first release for the given package then this will also assign msg.sender as the owner of the package.  Returns success.
  /// @notice Will create a new release the given package with the given release information.
  /// @param name Package name
  /// @param majorMinorPatch The major/minor/patch portion of the version string.
  /// @param preRelease The pre-release portion of the semver version string.  Use empty string if the version string has no pre-release portion.
  /// @param build The build portion of the semver version string.  Use empty string if the version string has no build portion.
  /// @param releaseLockfileURI The URI for the release lockfile for this release.
  function release(string name,
                   uint32[3] majorMinorPatch,
                   string preRelease,
                   string build,
                   string releaseLockfileURI) internal returns (bool) {
    bytes32 versionHash = releaseDb.hashVersion(majorMinorPatch[0], majorMinorPatch[1], majorMinorPatch[2], preRelease, build);

    // If the version for this release is not in the version database, populate
    // it.  This must happen prior to validation to ensure that the version is
    // present in the releaseDb.
    if (!releaseDb.versionExists(versionHash)) {
      releaseDb.setVersion(majorMinorPatch[0], majorMinorPatch[1], majorMinorPatch[2], preRelease, build);
    }

    if (!releaseValidator.validateRelease(packageDb, releaseDb, msg.sender, name, majorMinorPatch, preRelease, build, releaseLockfileURI)) {
      // Release is invalid
      return false;
    }

    // Compute hashes
    bool _packageExists = packageExists(name);

    // Both creates the package if it is new as well as updating the updatedAt
    // timestamp on the package.
    packageDb.setPackage(name);

    bytes32 nameHash = packageDb.hashName(name);

    // If the package does not yet exist create it and set the owner
    if (!_packageExists) {
      packageDb.setPackageOwner(nameHash, msg.sender);
    }

    // Create the release and add it to the list of package release hashes.
    releaseDb.setRelease(nameHash, versionHash, releaseLockfileURI);

    // Log the release.
    PackageRelease(nameHash, releaseDb.hashRelease(nameHash, versionHash));

    return true;
  }

  /// @dev Transfers package ownership to the provider new owner address.
  /// @notice Will transfer ownership of this package to the provided new owner address.
  /// @param name Package name
  /// @param newPackageOwner The address of the new owner.
  function transferPackageOwner(string name,
                                address newPackageOwner) public auth returns (bool) {
    if (isPackageOwner(name, msg.sender)) {
      // Only the package owner may transfer package ownership.
      return false;
    }

    // Lookup the current owne
    var (packageOwner,) = getPackageData(name);

    // Log the transfer
    PackageTransfer(packageOwner, newPackageOwner);

    // Update the owner.
    packageDb.setPackageOwner(packageDb.hashName(name), newPackageOwner);

    return true;
  }

  //
  // +------------+
  // |  Read API  |
  // +------------+
  //

  /// @dev Returns the address of the packageDb
  function getPackageDb() constant returns (address) {
    return address(packageDb);
  }

  /// @dev Returns the address of the releaseDb
  function getReleaseDb() constant returns (address) {
    return address(releaseDb);
  }

  /// @dev Returns the address of the releaseValidator
  function getReleaseValidator() constant returns (address) {
    return address(releaseValidator);
  }

  /// @dev Query the existence of a package with the given name.  Returns boolean indicating whether the package exists.
  /// @param name Package name
  function packageExists(string name) constant returns (bool) {
    return packageDb.packageExists(packageDb.hashName(name));
  }

  /// @dev Query the existence of a release at the provided version for the named package.  Returns boolean indicating whether such a release exists.
  /// @param name Package name
  /// @param major The major portion of the semver version string.
  /// @param minor The minor portion of the semver version string.
  /// @param patch The patch portion of the semver version string.
  /// @param preRelease The pre-release portion of the semver version string.  Use empty string if the version string has no pre-release portion.
  /// @param build The build portion of the semver version string.  Use empty string if the version string has no build portion.
  function releaseExists(string name,
                         uint32 major,
                         uint32 minor,
                         uint32 patch,
                         string preRelease,
                         string build) constant returns (bool) {
    var nameHash = packageDb.hashName(name);
    var versionHash = releaseDb.hashVersion(major, minor, patch, preRelease, build);
    return releaseDb.releaseExists(releaseDb.hashRelease(nameHash, versionHash));
  }

  /// @dev Returns the number of packages in the index
  function getNumPackages() constant returns (uint) {
    return packageDb.getNumPackages();
  }

  /// @dev Returns the name of the package at the provided index
  /// @param idx The index of the name hash to lookup.
  function getPackageName(uint idx) constant returns (string) {
    return getPackageName(packageDb.getPackageNameHash(idx));
  }

  /// @dev Returns the package data.
  /// @param name Package name
  function getPackageData(string name) constant
                                       returns (address packageOwner,
                                                uint createdAt,
                                                uint numReleases,
                                                uint updatedAt) {
    var nameHash = packageDb.hashName(name);
    (packageOwner, createdAt, updatedAt) = packageDb.getPackageData(nameHash);
    numReleases = releaseDb.getNumReleasesForNameHash(nameHash);
    return (packageOwner, createdAt, numReleases, updatedAt);
  }

  /// @dev Returns the release data for the release associated with the given release hash.
  /// @param releaseHash The release hash.
  function getReleaseData(bytes32 releaseHash) constant returns (uint32 major,
                                                                 uint32 minor,
                                                                 uint32 patch,
                                                                 string preRelease,
                                                                 string build,
                                                                 string releaseLockfileURI,
                                                                 uint createdAt,
                                                                 uint updatedAt) {
    bytes32 versionHash;
    (,versionHash, createdAt, updatedAt) = releaseDb.getReleaseData(releaseHash);
    (major, minor, patch) = releaseDb.getMajorMinorPatch(versionHash);
    preRelease = getPreRelease(releaseHash);
    build = getBuild(releaseHash);
    releaseLockfileURI = getReleaseLockfileURI(releaseHash);
    return (major, minor, patch, preRelease, build, releaseLockfileURI, createdAt, updatedAt);
  }

  /// @dev Returns the release hash at the provide index in the array of all release hashes.
  /// @param idx The index of the release to retrieve.
  function getReleaseHash(uint idx) constant returns (bytes32) {
    return releaseDb.getReleaseHash(idx);
  }

  /// @dev Returns the release hash at the provide index in the array of release hashes for the given package.
  /// @param name Package name
  /// @param releaseIdx The index of the release to retrieve.
  function getReleaseHashForPackage(string name,
                                    uint releaseIdx) constant returns (bytes32) {
    bytes32 nameHash = packageDb.hashName(name);
    return releaseDb.getReleaseHashForNameHash(nameHash, releaseIdx);
  }

  /// @dev Returns an array of all release hashes for the named package.
  /// @param name Package name
  function getAllPackageReleaseHashes(string name) constant returns (bytes32[]) {
    bytes32 nameHash = packageDb.hashName(name);
    var (,,numReleases,) = getPackageData(name);
    return getPackageReleaseHashes(name, 0, numReleases);
  }

  /// @dev Returns a slice of the array of all release hashes for the named package.
  /// @param name Package name
  /// @param offset The starting index for the slice.
  /// @param numReleases The length of the slice
  function getPackageReleaseHashes(string name, uint offset, uint numReleases) constant returns (bytes32[]) {
    bytes32 nameHash = packageDb.hashName(name);
    bytes32[] memory releaseHashes = new bytes32[](numReleases);

    for (uint i = offset; i < offset + numReleases; i++) {
      releaseHashes[i] = releaseDb.getReleaseHashForNameHash(nameHash, i);
    }

    return releaseHashes;
  }

  function getNumReleases() constant returns (uint) {
    return releaseDb.getNumReleases();
  }

  /// @dev Returns an array of all release hashes for the named package.
  function getAllReleaseHashes() constant returns (bytes32[]) {
    return getReleaseHashes(0, getNumReleases());
  }

  /// @dev Returns a slice of the array of all release hashes for the named package.
  /// @param offset The starting index for the slice.
  /// @param numReleases The length of the slice
  function getReleaseHashes(uint offset, uint numReleases) constant returns (bytes32[]) {
    bytes32[] memory releaseHashes = new bytes32[](numReleases);
    bytes32 buffer;

    for (uint i = offset; i < offset + numReleases; i++) {
      releaseHashes[i] = releaseDb.getReleaseHash(i);
    }

    return releaseHashes;
  }

  /// @dev Returns the release lockfile for the given release data
  /// @param name Package name
  /// @param major The major portion of the semver version string.
  /// @param minor The minor portion of the semver version string.
  /// @param patch The patch portion of the semver version string.
  /// @param preRelease The pre-release portion of the semver version string.  Use empty string if the version string has no pre-release portion.
  /// @param build The build portion of the semver version string.  Use empty string if the version string has no build portion.
  function getReleaseLockfileURI(string name,
                                uint32 major,
                                uint32 minor,
                                uint32 patch,
                                string preRelease,
                                string build) constant returns (string) {
    bytes32 versionHash = releaseDb.hashVersion(major, minor, patch, preRelease, build);
    bytes32 releaseHash = releaseDb.hashRelease(packageDb.hashName(name), versionHash);
    return getReleaseLockfileURI(releaseHash);
  }


  //
  // +----------------+
  // |  Internal API  |
  // +----------------+
  //
  /// @dev Returns boolean whether the provided address is the package owner
  /// @param name The name of the package
  /// @param _address The address to check
  function isPackageOwner(string name, address _address) internal returns (bool) {
    var (packageOwner,) = getPackageData(name);
    return (packageOwner != _address);
  }

  bytes4 constant GET_PACKAGE_NAME_SIG = bytes4(sha3("getPackageName(bytes32)"));

  /// @dev Retrieves the name for the given name hash.
  /// @param nameHash The name hash to lookup the name for.
  function getPackageName(bytes32 nameHash) internal returns (string) {
    return fetchString(address(packageDb), GET_PACKAGE_NAME_SIG, nameHash);
  }

  bytes4 constant GET_RELEASE_LOCKFILE_URI_SIG = bytes4(sha3("getReleaseLockfileURI(bytes32)"));

  /// @dev Retrieves the release lockfile URI from the package db.
  /// @param releaseHash The release hash to retrieve the URI from.
  function getReleaseLockfileURI(bytes32 releaseHash) internal returns (string) {
    return fetchString(address(releaseDb), GET_RELEASE_LOCKFILE_URI_SIG, releaseHash);
  }

  bytes4 constant GET_PRE_RELEASE_SIG = bytes4(sha3("getPreRelease(bytes32)"));

  /// @dev Retrieves the pre-release string from the package db.
  /// @param releaseHash The release hash to retrieve the string from.
  function getPreRelease(bytes32 releaseHash) internal returns (string) {
    return fetchString(address(releaseDb), GET_PRE_RELEASE_SIG, releaseHash);
  }

  bytes4 constant GET_BUILD_SIG = bytes4(sha3("getBuild(bytes32)"));

  /// @dev Retrieves the build string from the package db.
  /// @param releaseHash The release hash to retrieve the string from.
  function getBuild(bytes32 releaseHash) internal returns (string) {
    return fetchString(address(releaseDb), GET_BUILD_SIG, releaseHash);
  }

  /// @dev Retrieves a string from a function on the package db indicated by the provide function selector
  /// @param sig The 4-byte function selector to retrieve the signature from.
  /// @param arg The bytes32 argument that should be passed into the function.
  function fetchString(address codeAddress, bytes4 sig, bytes32 arg) internal constant returns (string s) {
    bool success;

    assembly {
      let m := mload(0x40) //Free memory pointer
      mstore(m,sig)
      mstore(add(m,4), arg) // Write arguments to memory- align directly after function sig.
      success := call( //Fetch string size
        sub(gas,8000), // g
        codeAddress,   // a
        0,             // v
        m,             // in
        0x24,          // insize: 4 byte sig + 32 byte uint
        add(m,0x24),   // Out pointer: don't overwrite the call data, we need it again
        0x40           // Only fetch the first 64 bytes of the string data.
      )
      let l := mload(add(m,0x44)) // returned data stats at 0x24, length is stored in the second 32-byte slot
      success :=  and(success,call(sub(gas,4000),codeAddress, 0,
        m, // Reuse the same argument data
        0x24,
        m,  // We can overwrite the calldata now to save space
        add(l, 0x40) // The length of the returned data will be 64 bytes of metadata + string length
      ))
      s := add(m, mload(m)) // First slot points to the start of the string (will almost always be m+0x20)
      mstore(0x40, add(m,add(l,0x40))) //Move free memory pointer so string doesn't get overwritten
    }
    if(!success) throw;

    return s;
  }
}

    Contract ABI  
[{"constant":true,"inputs":[],"name":"getNumReleases","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newReleaseValidator","type":"address"}],"name":"setReleaseValidator","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"},{"name":"offset","type":"uint256"},{"name":"numReleases","type":"uint256"}],"name":"getPackageReleaseHashes","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"setOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"},{"name":"major","type":"uint32"},{"name":"minor","type":"uint32"},{"name":"patch","type":"uint32"},{"name":"preRelease","type":"string"},{"name":"build","type":"string"}],"name":"getReleaseLockfileURI","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getPackageDb","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newPackageDb","type":"address"}],"name":"setPackageDb","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"},{"name":"major","type":"uint32"},{"name":"minor","type":"uint32"},{"name":"patch","type":"uint32"},{"name":"preRelease","type":"string"},{"name":"build","type":"string"}],"name":"releaseExists","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getReleaseValidator","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"releaseHash","type":"bytes32"}],"name":"getReleaseData","outputs":[{"name":"major","type":"uint32"},{"name":"minor","type":"uint32"},{"name":"patch","type":"uint32"},{"name":"preRelease","type":"string"},{"name":"build","type":"string"},{"name":"releaseLockfileURI","type":"string"},{"name":"createdAt","type":"uint256"},{"name":"updatedAt","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getAllReleaseHashes","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"newPackageOwner","type":"address"}],"name":"transferPackageOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"idx","type":"uint256"}],"name":"getReleaseHash","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"major","type":"uint32"},{"name":"minor","type":"uint32"},{"name":"patch","type":"uint32"},{"name":"preRelease","type":"string"},{"name":"build","type":"string"},{"name":"releaseLockfileURI","type":"string"}],"name":"release","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getNumPackages","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"offset","type":"uint256"},{"name":"numReleases","type":"uint256"}],"name":"getReleaseHashes","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newAuthority","type":"address"}],"name":"setAuthority","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"}],"name":"packageExists","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"}],"name":"getPackageData","outputs":[{"name":"packageOwner","type":"address"},{"name":"createdAt","type":"uint256"},{"name":"numReleases","type":"uint256"},{"name":"updatedAt","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"}],"name":"getAllPackageReleaseHashes","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"},{"name":"releaseIdx","type":"uint256"}],"name":"getReleaseHashForPackage","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"idx","type":"uint256"}],"name":"getPackageName","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newReleaseDb","type":"address"}],"name":"setReleaseDb","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getReleaseDb","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"nameHash","type":"bytes32"},{"indexed":true,"name":"releaseHash","type":"bytes32"}],"name":"PackageRelease","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oldOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"PackageTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oldOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnerUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"oldAuthority","type":"address"},{"indexed":true,"name":"newAuthority","type":"address"}],"name":"AuthorityUpdate","type":"event"}]

  Contract Creation Code Switch To Opcodes View
60606040525b60008054600160a060020a03191633600160a060020a0390811691909117808355604051911691907f343765429aea5a34b3ff6a3785a98a5abb2597aca87bfbb58632c173d585373a908290a35b5b6130a5806100636000396000f300606060405236156101385763ffffffff60e060020a6000350416630ccec396811461013d57806310ae4ce21461015c57806312cc08f21461018957806313af40351461023e5780631f6b0a9d1461026b578063271cd760146103d457806334c0d654146103fd5780634188d79c1461042a5780634961b40c146105275780634c4aea87146105505780634cb71b9b1461070e5780634f197ee71461077657806357b07cd9146107e85780635fcb568c1461080a5780637370a38d1461094457806379cce1c5146109635780637a9e5e4b146109d157806383ea0620146109fe5780638da5cb5b14610a65578063bf7e214f14610a8e578063c2ba5b4014610ab7578063c392f5a014610b3a578063cec95aa114610be8578063cfe9a7b814610c4f578063f314bf4614610cdf578063fb3a1fb214610d0c575b610000565b346100005761014a610d35565b60408051918252519081900360200190f35b3461000057610175600160a060020a0360043516610dac565b604080519115158252519081900360200190f35b34610000576101e3600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375094965050843594602001359350610de692505050565b604080516020808252835181830152835191928392908301918581019102808383821561022b575b80518252602083111561022b57601f19909201916020918201910161020b565b5050509050019250505060405180910390f35b3461000057610175600160a060020a0360043516610f99565b604080519115158252519081900360200190f35b3461000057610354600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f60608a01358b0180359182018390048302840183018552818452989a63ffffffff8b3581169b8481013582169b968101359091169950909750608001955091935091820191819084018382808284375050604080516020601f89358b0180359182018390048302840183019094528083529799988101979196509182019450925082915084018382808284375094965061100c95505050505050565b60408051602080825283518183015283519192839290830191850190808383821561039a575b80518252602083111561039a57601f19909201916020918201910161037a565b505050905090810190601f1680156103c65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576103e1611304565b60408051600160a060020a039092168252519081900360200190f35b3461000057610175600160a060020a0360043516611314565b604080519115158252519081900360200190f35b3461000057610175600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f60608a01358b0180359182018390048302840183018552818452989a63ffffffff8b3581169b8481013582169b968101359091169950909750608001955091935091820191819084018382808284375050604080516020601f89358b0180359182018390048302840183019094528083529799988101979196509182019450925082915084018382808284375094965061134e95505050505050565b604080519115158252519081900360200190f35b34610000576103e1611669565b60408051600160a060020a039092168252519081900360200190f35b3461000057610560600435611679565b604051808963ffffffff1663ffffffff1681526020018863ffffffff1663ffffffff1681526020018763ffffffff1663ffffffff1681526020018060200180602001806020018681526020018581526020018481038452898181518152602001915080519060200190808383600083146105f5575b8051825260208311156105f557601f1990920191602091820191016105d5565b505050905090810190601f1680156106215780820380516001836020036101000a031916815260200191505b5084810383528851815288516020918201918a01908083838215610660575b80518252602083111561066057601f199092019160209182019101610640565b505050905090810190601f16801561068c5780820380516001836020036101000a031916815260200191505b50848103825287518152875160209182019189019080838382156106cb575b8051825260208311156106cb57601f1990920191602091820191016106ab565b505050905090810190601f1680156106f75780820380516001836020036101000a031916815260200191505b509b50505050505050505050505060405180910390f35b34610000576101e36117ee565b604080516020808252835181830152835191928392908301918581019102808383821561022b575b80518252602083111561022b57601f19909201916020918201910161020b565b5050509050019250505060405180910390f35b3461000057610175600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375094965050509235600160a060020a03169250611817915050565b604080519115158252519081900360200190f35b346100005761014a6004356119dd565b60408051918252519081900360200190f35b3461000057610175600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f60608a01358b0180359182018390048302840183018552818452989a63ffffffff8b3581169b8481013582169b968101359091169950909750608001955091935091820191819084018382808284375050604080516020601f89358b0180359182018390048302840183019094528083529799988101979196509182019450925082915084018382808284375050604080516020601f89358b01803591820183900483028401830190945280835297999881019791965091820194509250829150840183828082843750949650611a4795505050505050565b604080519115158252519081900360200190f35b346100005761014a611add565b60408051918252519081900360200190f35b34610000576101e3600435602435611b54565b604080516020808252835181830152835191928392908301918581019102808383821561022b575b80518252602083111561022b57601f19909201916020918201910161020b565b5050509050019250505060405180910390f35b3461000057610175600160a060020a0360043516611c3b565b604080519115158252519081900360200190f35b3461000057610175600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843750949650611cad95505050505050565b604080519115158252519081900360200190f35b34610000576103e1611de3565b60408051600160a060020a039092168252519081900360200190f35b34610000576103e1611df2565b60408051600160a060020a039092168252519081900360200190f35b3461000057610b0a600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843750949650611e0195505050505050565b60408051600160a060020a0390951685526020850193909352838301919091526060830152519081900360800190f35b34610000576101e3600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843750949650611ff995505050505050565b604080516020808252835181830152835191928392908301918581019102808383821561022b575b80518252602083111561022b57601f19909201916020918201910161020b565b5050509050019250505060405180910390f35b346100005761014a600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375094965050933593506120fe92505050565b60408051918252519081900360200190f35b3461000057610354600435612247565b60408051602080825283518183015283519192839290830191850190808383821561039a575b80518252602083111561039a57601f19909201916020918201910161037a565b505050905090810190601f1680156103c65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3461000057610175600160a060020a03600435166122dd565b604080519115158252519081900360200190f35b34610000576103e1612317565b60408051600160a060020a039092168252519081900360200190f35b600354604080516000602091820181905282517f0ccec39600000000000000000000000000000000000000000000000000000000815292519093600160a060020a031692630ccec39692600480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b90565b6000610db6612327565b1515610dc157610000565b5060048054600160a060020a031916600160a060020a03831617905560015b5b919050565b604080516020818101835260008083528351808301855281815260025485518401839052945160e060020a63af9a3f9b028152600481018481528951602483015289519596939592948694600160a060020a03169363af9a3f9b938c93928392604490920191908501908083838215610e7a575b805182526020831115610e7a57601f199092019160209182019101610e5a565b505050905090810190601f168015610ea65780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b156100005760325a03f11561000057505060405180519450869150805910610ede5750595b908082528060200260200182016040525b5091508590505b848601811015610f8b576003546040805160006020918201819052825160e160020a630613721702815260048101889052602481018690529251600160a060020a0390941693630c26e42e9360448082019493918390030190829087803b156100005760325a03f11561000057505050604051805190508282815181101561000057602090810290910101525b600101610ef6565b8193505b5050509392505050565b6000610fa3612327565b1515610fae57610000565b60008054604051600160a060020a03808616939216917f343765429aea5a34b3ff6a3785a98a5abb2597aca87bfbb58632c173d585373a91a35060008054600160a060020a031916600160a060020a03831617905560015b5b919050565b6040805160208181018352600080835260035484518301829052935160e260020a630397fecf02815263ffffffff808b1660048301908152818b166024840152908916604483015260a060648301908152885160a48401528851959693958695600160a060020a0390951694630e5ffb3c948e948e948e948e948e94608481019260c49091019187019080838382156110c0575b8051825260208311156110c057601f1990920191602091820191016110a0565b505050905090810190601f1680156110ec5780820380516001836020036101000a031916815260200191505b508381038252845181528451602091820191860190808383821561112b575b80518252602083111561112b57601f19909201916020918201910161110b565b505050905090810190601f1680156111575780820380516001836020036101000a031916815260200191505b50975050505050505050602060405180830381600087803b156100005760325a03f11561000057505050604051805190509150600360009054906101000a9004600160a060020a0316600160a060020a03166393d79105600260009054906101000a9004600160a060020a0316600160a060020a031663af9a3f9b8c6000604051602001526040518263ffffffff1660e060020a0281526004018080602001828103825283818151815260200191508051906020019080838360008314611239575b80518252602083111561123957601f199092019160209182019101611219565b505050905090810190601f1680156112655780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b156100005760325a03f11561000057505060408051805160006020928301819052835160e060020a63ffffffff8816028152600481019290925260248201899052925160448083019550929390929183900390910190829087803b156100005760325a03f1156100005750506040515191506112f590508161241b565b92505b50509695505050505050565b600254600160a060020a03165b90565b600061131e612327565b151561132957610000565b5060028054600160a060020a031916600160a060020a03831617905560015b5b919050565b6002546040805160006020918201819052915160e060020a63af9a3f9b028152600481018281528a5160248301528a51939485948594600160a060020a039092169363af9a3f9b938e93909283926044019185019080838382156113cd575b8051825260208311156113cd57601f1990920191602091820191016113ad565b505050905090810190601f1680156113f95780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b156100005760325a03f1156100005750506040805180516003546000602093840152925160e260020a630397fecf02815263ffffffff808e1660048301908152818e166024840152908c16604483015260a0606483019081528b5160a48401528b51939850600160a060020a039095169550630e5ffb3c948e948e948e948e948e9490939092608483019260c4019187019080838382156114c8575b8051825260208311156114c857601f1990920191602091820191016114a8565b505050905090810190601f1680156114f45780820380516001836020036101000a031916815260200191505b5083810382528451815284516020918201918601908083838215611533575b80518252602083111561153357601f199092019160209182019101611513565b505050905090810190601f16801561155f5780820380516001836020036101000a031916815260200191505b50975050505050505050602060405180830381600087803b156100005760325a03f11561000057505060408051805160035460006020938401819052845160e060020a6393d7910502815260048101899052602481018490529451929650600160a060020a039091169450633f4157729385936393d791059360448084019492939192918390030190829087803b156100005760325a03f11561000057505050604051805190506000604051602001526040518263ffffffff1660e060020a028152600401808260001916600019168152602001915050602060405180830381600087803b156100005760325a03f115610000575050604051519350505b50509695505050505050565b600454600160a060020a03165b90565b6040805160208181018352600080835283518083018552818152845192830185528183526003548551608090810184905286517f4c4aea8700000000000000000000000000000000000000000000000000000000815260048101899052965193968796879690959093879384938493600160a060020a0390931692634c4aea879260248084019391929182900301818787803b156100005760325a03f115610000575050604080516020810151818301516060928301805160035460009283905286517f0c4326a0000000000000000000000000000000000000000000000000000000008152600481018690529651939a50909850929650600160a060020a039092169450630c4326a09360248082019493918390030190829087803b156100005760325a03f11561000057505060408051805160208201519190920151919b50995097506117c990508a61247d565b95506117d48a6124df565b94506117df8a61241b565b93505b50919395975091939597565b6020604051908101604052806000815250611811600061180c610d35565b611b54565b90505b90565b60006000611823612327565b151561182e57610000565b6118388433612541565b1561184657600091506119d5565b61184f84611e01565b505060405191925050600160a060020a0380851691908316907fa99a0b26852fc94fb40663ad64c63bac913f2e345ff098ea82209694879cb95e90600090a3600254604080516000602091820152905160e060020a63af9a3f9b02815260048101828152875160248301528751600160a060020a0390941693632406cedb93859363af9a3f9b938b93909283926044019190850190808383821561190e575b80518252602083111561190e57601f1990920191602091820191016118ee565b505050905090810190601f16801561193a5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b156100005760325a03f1156100005750505060405180519050856000604051602001526040518363ffffffff1660e060020a02815260040180836000191660001916815260200182600160a060020a0316600160a060020a0316815260200192505050602060405180830381600087803b156100005760325a03f11561000057506001935050505b5b5092915050565b6003546040805160006020918201819052825160e060020a6357b07cd90281526004810186905292519093600160a060020a0316926357b07cd992602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b6000611a51612327565b1515611a5c57610000565b600254600160a060020a03161580611a7d5750600354600160a060020a0316155b80611a915750600454600160a060020a0316155b15611a9b57610000565b6040805160608101825263ffffffff808a1682528881166020830152871691810191909152611ace908990868686612573565b90505b5b979650505050505050565b600254604080516000602091820181905282517f7370a38d00000000000000000000000000000000000000000000000000000000815292519093600160a060020a031692637370a38d92600480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b90565b602060405190810160405280600081525060206040519081016040528060008152506000600084604051805910611b885750595b908082528060200260200182016040525b5092508590505b848601811015611c2e576003546040805160006020918201819052825160e060020a6357b07cd9028152600481018690529251600160a060020a03909416936357b07cd99360248082019493918390030190829087803b156100005760325a03f11561000057505050604051805190508382815181101561000057602090810290910101525b600101611ba0565b8293505b50505092915050565b6000611c45612327565b1515611c5057610000565b600154604051600160a060020a038085169216907fa1d9e0b26ffdd95159e4605308c755be7b756e3e5dd5c5756b4c77f644a5236490600090a35060018054600160a060020a031916600160a060020a0383161781555b5b919050565b6002546040805160006020918201819052915160e060020a63af9a3f9b028152600481018281528551602483015285519394600160a060020a03169363a9b3524093859363af9a3f9b9389939092839260440191908501908083838215611d2f575b805182526020831115611d2f57601f199092019160209182019101611d0f565b505050905090810190601f168015611d5b5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b156100005760325a03f11561000057505050604051805190506000604051602001526040518263ffffffff1660e060020a028152600401808260001916600019168152602001915050602060405180830381600087803b156100005760325a03f115610000575050604051519150505b919050565b600054600160a060020a031681565b600154600160a060020a031681565b60006000600060006000600260009054906101000a9004600160a060020a0316600160a060020a031663af9a3f9b876000604051602001526040518263ffffffff1660e060020a0281526004018080602001828103825283818151815260200191508051906020019080838360008314611e96575b805182526020831115611e9657601f199092019160209182019101611e76565b505050905090810190601f168015611ec25780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b156100005760325a03f1156100005750506040805180516002546000606093840181905284517fb4d6d4c7000000000000000000000000000000000000000000000000000000008152600481018490529451929650600160a060020a03909116945063b4d6d4c7936024808201949392918390030190829087803b156100005760325a03f115610000575050604080518051602080830180519385015160035460009283905286517f173cb7de000000000000000000000000000000000000000000000000000000008152600481018a90529651949c50949a509750600160a060020a03909316945063173cb7de93602480820194929392918390030190829087803b156100005760325a03f115610000575050604051519350505b509193509193565b6040805160208181018352600080835260025484518301829052935160e060020a63af9a3f9b02815260048101838152865160248301528651949592948594600160a060020a039094169363af9a3f9b9389939283926044909201918501908083838215612082575b80518252602083111561208257601f199092019160209182019101612062565b505050905090810190601f1680156120ae5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b156100005760325a03f1156100005750506040515192506120e3905084611e01565b50925050506120f484600083610de6565b92505b5050919050565b6002546040805160006020918201819052915160e060020a63af9a3f9b0281526004810182815286516024830152865193948594600160a060020a039091169363af9a3f9b938993928392604490920191850190808383821561217c575b80518252602083111561217c57601f19909201916020918201910161215c565b505050905090810190601f1680156121a85780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b156100005760325a03f11561000057505060408051805160035460006020938401819052845160e160020a630613721702815260048101849052602481018a90529451929650600160a060020a039091169450630c26e42e936044808201949392918390030190829087803b156100005760325a03f115610000575050604051519250505b5092915050565b604080516020818101835260008083526002548451830182905284517f95f0684b00000000000000000000000000000000000000000000000000000000815260048101879052945193946122d594600160a060020a03909216936395f0684b9360248084019492938390030190829087803b156100005760325a03f115610000575050604051519050612fa8565b90505b919050565b60006122e7612327565b15156122f257610000565b5060038054600160a060020a031916600160a060020a03831617905560015b5b919050565b600354600160a060020a03165b90565b6000805433600160a060020a039081169116141561234757506001610da9565b600154600160a060020a0316151561236157506000610da9565b600154604080516000602091820181905282517fb7009613000000000000000000000000000000000000000000000000000000008152600160a060020a033381166004830152308116602483015282357fffffffff000000000000000000000000000000000000000000000000000000001660448301529351939094169363b7009613936064808301949391928390030190829087803b156100005760325a03f115610000575050604051519150610da99050565b5b5b90565b604080516020810182526000815260035482517f67657452656c656173654c6f636b66696c6555524928627974657333322900008152925192839003601e0190922090916122d591600160a060020a03909116908461300a565b90505b919050565b604080516020810182526000815260035482517f67657450726552656c6561736528627974657333322900000000000000000000815292519283900360160190922090916122d591600160a060020a03909116908461300a565b90505b919050565b604080516020810182526000815260035482517f6765744275696c64286279746573333229000000000000000000000000000000815292519283900360110190922090916122d591600160a060020a03909116908461300a565b90505b919050565b6000600061254e84611e01565b505050905082600160a060020a031681600160a060020a0316141591505b5092915050565b600354600090819081908190600160a060020a0316630e5ffb3c898360200201518a600160200201518b600260200201518b8b6000604051602001526040518663ffffffff1660e060020a028152600401808663ffffffff1663ffffffff1681526020018563ffffffff1663ffffffff1681526020018463ffffffff1663ffffffff1681526020018060200180602001838103835285818151815260200191508051906020019080838360008314612646575b80518252602083111561264657601f199092019160209182019101612626565b505050905090810190601f1680156126725780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838382156126b1575b8051825260208311156126b157601f199092019160209182019101612691565b505050905090810190601f1680156126dd5780820380516001836020036101000a031916815260200191505b50975050505050505050602060405180830381600087803b156100005760325a03f1156100005750506040805180516003546000602093840181905284517fbb814e9e000000000000000000000000000000000000000000000000000000008152600481018490529451929850600160a060020a03909116945063bb814e9e936024808201949392918390030190829087803b156100005760325a03f115610000575050604051511515905061291a57600354600160a060020a031663a10889fa89600060200201518a600160200201518b600260200201518b8b6000604051602001526040518663ffffffff1660e060020a028152600401808663ffffffff1663ffffffff1681526020018563ffffffff1663ffffffff1681526020018463ffffffff1663ffffffff1681526020018060200180602001838103835285818151815260200191508051906020019080838360008314612858575b80518252602083111561285857601f199092019160209182019101612838565b505050905090810190601f1680156128845780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838382156128c3575b8051825260208311156128c357601f1990920191602091820191016128a3565b505050905090810190601f1680156128ef5780820380516001836020036101000a031916815260200191505b50975050505050505050602060405180830381600087803b156100005760325a03f115610000575050505b60048054600254600354604080516000602090910152517fea735d29000000000000000000000000000000000000000000000000000000008152600160a060020a0392831694810185815291831660248201819052338085166044840152939094169463ea735d29949093909290918f918f918f918f918f919060648101906084018660608083835b8051825260208311156129c357601f1990920191602091820191016129a3565b50505090500180602001806020018060200185810385528a818151815260200191508051906020019080838360008314612a18575b805182526020831115612a1857601f1990920191602091820191016129f8565b505050905090810190601f168015612a445780820380516001836020036101000a031916815260200191505b5085810384528851815288516020918201918a01908083838215612a83575b805182526020831115612a8357601f199092019160209182019101612a63565b505050905090810190601f168015612aaf5780820380516001836020036101000a031916815260200191505b5085810383528751815287516020918201918901908083838215612aee575b805182526020831115612aee57601f199092019160209182019101612ace565b505050905090810190601f168015612b1a5780820380516001836020036101000a031916815260200191505b5085810382528651815286516020918201918801908083838215612b59575b805182526020831115612b5957601f199092019160209182019101612b39565b505050905090810190601f168015612b855780820380516001836020036101000a031916815260200191505b509c50505050505050505050505050602060405180830381600087803b156100005760325a03f1156100005750506040515115159050612bc85760009350612f9c565b612bd189611cad565b60025460408051600060209182015290517f083ae1fe000000000000000000000000000000000000000000000000000000008152600481018281528d5160248301528d51949650600160a060020a039093169363083ae1fe938e93909283926044909101918501908083838215612c63575b805182526020831115612c6357601f199092019160209182019101612c43565b505050905090810190601f168015612c8f5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b156100005760325a03f115610000575050604080516002546000602092830152915160e060020a63af9a3f9b028152600481018281528d5160248301528d51600160a060020a03909416945063af9a3f9b938e9391928392604490910191908501908083838215612d2e575b805182526020831115612d2e57601f199092019160209182019101612d0e565b505050905090810190601f168015612d5a5780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b156100005760325a03f11561000057505060405151915050811515612e0c57600254604080516000602091820181905282517f2406cedb00000000000000000000000000000000000000000000000000000000815260048101869052600160a060020a03338116602483015293519390941693632406cedb936044808301949391928390030190829087803b156100005760325a03f115610000575050505b60035460408051600060209182015290517f8b8594090000000000000000000000000000000000000000000000000000000081526004810184815260248201879052606060448301908152895160648401528951600160a060020a0390951694638b8594099487948a948d94909390926084909201918501908083838215612eaf575b805182526020831115612eaf57601f199092019160209182019101612e8f565b505050905090810190601f168015612edb5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b156100005760325a03f1156100005750506040805160035460006020928301819052835160e060020a6393d7910502815260048101879052602481018990529351600160a060020a0390921694506393d79105936044808201949392918390030190829087803b156100005760325a03f1156100005750506040518051915082907fac0f7a48e2519eee455114a50e2ccd53b8f68a28609b5532bdb924638d3d4a0790600090a3600193505b50505095945050505050565b604080516020810182526000815260025482517f6765745061636b6167654e616d65286279746573333229000000000000000000815292519283900360170190922090916122d591600160a060020a03909116908461300a565b90505b919050565b6020604051908101604052806000815250600060405184815283600482015260406024820160248360008a611f405a03f191506044810151604081018260248460008b610fa05a03f1825191830160409081019052910192501680151561307057610000565b5b5093925050505600a165627a7a72305820e303a9490f6e94c90855b0e4f119b7913bf9f451198abeb81943828feee4a88c0029

   Swarm Source:
bzzr://e303a9490f6e94c90855b0e4f119b7913bf9f451198abeb81943828feee4a88c

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward