Latest 25 txns From a total of 235 Transactions

TxHash Age From To Value [TxFee]
0x1f686f3744c9ec7c8b7dad00d52b4ee446611a4e113ab32ca27e07e3b5a4d13810 days 18 hrs ago0x5ccf02a24536834c704ee793ea24e83c208a11b3  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000713395
0x27f838e9b16828e560cb13a745b1934e6fba2ff74eea104ad7458de5335aa83c65 days 56 mins ago0x959fd7ef9089b7142b6b908dc3a8af7aa8ff0fa1  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000066362
0x7b47eb787c802a5a4f82412faac14d9904da26a2c68a7c3febc50c67b82cb7cd67 days 54 mins ago0x24ae8b17032640108eed4fca01168515033dab4e  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000493415
0xef0fb47722bedd94c7beb046d75a01b13f2e12b648dec15d570dbd3fe7a172fd67 days 55 mins ago0x24ae8b17032640108eed4fca01168515033dab4e  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000066554
0xab6067e41f2208bff77e10df78b15c2cdeacef8d97f94441124a707d1e4b455a79 days 2 hrs ago0x8f386b6eede79260e6a2093f71b3fc3555d435c4  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000515899
0xa359117b1fe8eee53fc2f53dc1c46f8301ae0c52b5f1c2fa5115691e935fab5e81 days 1 hr ago0x188ad5b5d5d068554e61feb73fbf1f833c88b6b4  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000495936
0x087c4b79ea84f52cb4bc8b283d335b0d5e88ea4002d1ac6bc30ccdd223e6d5e681 days 2 hrs ago0x188ad5b5d5d068554e61feb73fbf1f833c88b6b4  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000495936
0xed91195bebd86f60e5c033419f4ea7a9df22d40c705fb2abb579e1b96456fe1281 days 7 hrs ago0x188ad5b5d5d068554e61feb73fbf1f833c88b6b4  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000495936
0x99bdeb8c7ff2916672abd9f7a1c9d899ce6bca2937aae075327cdcf366e592b582 days 1 hr ago0x959fd7ef9089b7142b6b908dc3a8af7aa8ff0fa1  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000054946
0x02a2d1730bc8aa13bb689f0ed2616b48d64c8aa21dedf953706eeef1b8401e6782 days 1 hr ago0x188ad5b5d5d068554e61feb73fbf1f833c88b6b4  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000143767
0x544dc298e1621dd41fe74c5117f1445ffcbcba4cd51bc51bbe1ba08bbc0bbf4282 days 2 hrs ago0x959fd7ef9089b7142b6b908dc3a8af7aa8ff0fa1  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000495168
0xaea9d780024730726460181d823858ed4a4dac3984550010a9fbfc26eb20a71082 days 2 hrs ago0x959fd7ef9089b7142b6b908dc3a8af7aa8ff0fa1  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000066362
0x18852febda322c16d018009f46ea7f030d3d5548401d3329ca83d07e48e448e082 days 2 hrs ago0x959fd7ef9089b7142b6b908dc3a8af7aa8ff0fa1  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000066362
0xfe0c8af04953c85423a9b877296740c2595dcfee92b4003d8175d45474ebef5b82 days 2 hrs ago0x959fd7ef9089b7142b6b908dc3a8af7aa8ff0fa1  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000066362
0x8d0cfd5bb9a08439ae8e1363e80472cd800a275c0b0db7109d595750ff01108d82 days 3 hrs ago0x959fd7ef9089b7142b6b908dc3a8af7aa8ff0fa1  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000495168
0xc1ff5a70699bd9606ff83a9041cf101e9eb9f6fde8d9947f4fe7c8513dffef0c82 days 3 hrs ago0x959fd7ef9089b7142b6b908dc3a8af7aa8ff0fa1  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000066362
0xc9c3c4790b3773495b082120000a4bce99a8ba51d54d2d68fa5f055374fd6e0b82 days 3 hrs ago0x959fd7ef9089b7142b6b908dc3a8af7aa8ff0fa1  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000066362
0xc53308288f0aeed6ca2d44090ef96524ededc49bcca122a770fd324442bfb0bd82 days 4 hrs ago0x959fd7ef9089b7142b6b908dc3a8af7aa8ff0fa1  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.0001518426
0xcc39700e9892fee48c0e80c07efe11231eb88dacc335bdffc8ca5fc840afad1382 days 6 hrs ago0x188ad5b5d5d068554e61feb73fbf1f833c88b6b4  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000020139
0xd6fb038d1e3ca33d1e388ea92ac723bc7ff200311e1e236a66278652e917891282 days 7 hrs ago0x188ad5b5d5d068554e61feb73fbf1f833c88b6b4  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000020139
0x02670029c5d93dda22532749d718442d9d22e15decb582881b3b571abd4cd97782 days 7 hrs ago0x188ad5b5d5d068554e61feb73fbf1f833c88b6b4  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000020139
0xadc0313ec2ed3ffb2ea43ac42b19f3dda60ecf8e5e7cdf3413cdfd9c9cd5a67182 days 7 hrs ago0x188ad5b5d5d068554e61feb73fbf1f833c88b6b4  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000020139
0x2fe696dfd08b091107b8bc63b7852703fdfe19b577b379a196d4ef5f5c449ec084 days 23 hrs ago0x188ad5b5d5d068554e61feb73fbf1f833c88b6b4  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000740705
0x0552e2fb83a16e0dae1070e58f788b3aaeaf5e458e9e2699249bf9ad3d5fcbaf86 days 28 mins ago0xdae6a0e9e9032270dc88a8f6a6967c0321470bf3  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000990592
0xae458f1cee1a3aec54c9fd5158a2d5424794608bf6f068873999585900774ef086 days 1 hr ago0xdae6a0e9e9032270dc88a8f6a6967c0321470bf3  IN   0x8011df4830b4f696cd81393997e5371b933388780 Ether0.000727537
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
View All
ParentTxHash Block Age From To Value
Contract Name: PackageIndex
Compiler Text: 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